Skip to content

Commit 260e2ba

Browse files
committed
Http server and examples
HTTP server components and example program. These components were originally part of the Swirly Cloud project. The parser is based on the Node.js parser. Resolves: #13
1 parent 89bf9ac commit 260e2ba

43 files changed

Lines changed: 5205 additions & 34 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

doc/Dependencies.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,6 @@
1414

1515
## Net Package
1616
![Net Package](@ref toolbox-net.png)
17+
18+
## Http Package
19+
![Http Package](@ref toolbox-http.png)

example/CMakeLists.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616

1717
set(examples
1818
toolbox-echo-clnt
19-
toolbox-echo-serv)
19+
toolbox-echo-serv
20+
toolbox-http-serv)
2021

2122
add_custom_target(toolbox-example DEPENDS ${examples})
2223

@@ -25,3 +26,6 @@ target_link_libraries(toolbox-echo-clnt ${toolbox_LIBRARY})
2526

2627
add_executable(toolbox-echo-serv EchoServ.cpp)
2728
target_link_libraries(toolbox-echo-serv ${toolbox_LIBRARY})
29+
30+
add_executable(toolbox-http-serv HttpServ.cpp)
31+
target_link_libraries(toolbox-http-serv ${toolbox_LIBRARY})

example/EchoClnt.cpp

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,10 @@
1414
// See the License for the specific language governing permissions and
1515
// limitations under the License.
1616

17-
#include <toolbox/io/EpollReactor.hpp>
18-
#include <toolbox/io/Runner.hpp>
19-
#include <toolbox/net/Resolver.hpp>
20-
#include <toolbox/net/Runner.hpp>
21-
#include <toolbox/net/StreamConnector.hpp>
22-
#include <toolbox/sys/Log.hpp>
23-
#include <toolbox/sys/Signal.hpp>
24-
#include <toolbox/util/Tokeniser.hpp>
17+
#include <toolbox/io.hpp>
18+
#include <toolbox/net.hpp>
19+
#include <toolbox/sys.hpp>
20+
#include <toolbox/util.hpp>
2521

2622
#include <boost/intrusive/list.hpp>
2723

example/EchoServ.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,10 @@
1414
// See the License for the specific language governing permissions and
1515
// limitations under the License.
1616

17-
#include <toolbox/io/EpollReactor.hpp>
18-
#include <toolbox/io/Runner.hpp>
19-
#include <toolbox/net/StreamAcceptor.hpp>
20-
#include <toolbox/sys/Log.hpp>
21-
#include <toolbox/sys/Signal.hpp>
22-
#include <toolbox/util/Tokeniser.hpp>
17+
#include <toolbox/io.hpp>
18+
#include <toolbox/net.hpp>
19+
#include <toolbox/sys.hpp>
20+
#include <toolbox/util.hpp>
2321

2422
#include <boost/intrusive/list.hpp>
2523

example/HttpServ.cpp

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
// The Reactive C++ Toolbox.
2+
// Copyright (C) 2013-2019 Swirly Cloud Limited
3+
// Copyright (C) 2019 Reactive Markets Limited
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
17+
#include <toolbox/http.hpp>
18+
#include <toolbox/io.hpp>
19+
#include <toolbox/sys.hpp>
20+
21+
using namespace std;
22+
using namespace toolbox;
23+
24+
namespace {
25+
26+
void on_foo(const HttpRequest& req, HttpStream& os)
27+
{
28+
os << "Hello, Foo!";
29+
}
30+
31+
void on_bar(const HttpRequest& req, HttpStream& os)
32+
{
33+
os << "Hello, Bar!";
34+
}
35+
36+
class HttpApp : public HttpAppBase {
37+
public:
38+
using Slot = BasicSlot<const HttpRequest&, HttpStream&>;
39+
using SlotMap = std::unordered_map<std::string, Slot>;
40+
41+
~HttpApp() override = default;
42+
void bind(const std::string& path, Slot slot) { slot_map_[path] = slot; }
43+
44+
protected:
45+
void do_on_connect(CyclTime now, const Endpoint& ep) noexcept override
46+
{
47+
TOOLBOX_INFO << "http session connected: " << ep;
48+
}
49+
void do_on_disconnect(CyclTime now, const Endpoint& ep) noexcept override
50+
{
51+
TOOLBOX_INFO << "http session disconnected: " << ep;
52+
}
53+
void do_on_error(CyclTime now, const Endpoint& ep, const std::exception& e,
54+
HttpStream& os) noexcept override
55+
{
56+
TOOLBOX_ERROR << "session error: " << ep << ": " << e.what();
57+
}
58+
void do_on_message(CyclTime now, const Endpoint& ep, const HttpRequest& req,
59+
HttpStream& os) override
60+
{
61+
const auto it = slot_map_.find(string{req.path()});
62+
if (it != slot_map_.end()) {
63+
os.reset(HttpStatus::Ok, TextPlain);
64+
it->second(req, os);
65+
} else {
66+
os.reset(HttpStatus::NotFound, TextPlain);
67+
os << "Error 404 - Page not found";
68+
}
69+
os.commit();
70+
}
71+
void do_on_timeout(CyclTime now, const Endpoint& ep) noexcept override
72+
{
73+
TOOLBOX_WARNING << "session timeout: " << ep;
74+
}
75+
76+
private:
77+
SlotMap slot_map_;
78+
};
79+
80+
} // namespace
81+
82+
int main(int argc, char* argv[])
83+
{
84+
int ret = 1;
85+
try {
86+
87+
const auto start_time = CyclTime::now();
88+
89+
EpollReactor reactor{1024};
90+
HttpApp app;
91+
app.bind("/foo", bind<on_foo>());
92+
app.bind("/bar", bind<on_bar>());
93+
94+
const TcpEndpoint ep{TcpProtocol::v4(), 8888};
95+
HttpServ http_serv{start_time, reactor, ep, app};
96+
97+
// Start service threads.
98+
pthread_setname_np(pthread_self(), "main");
99+
ReactorRunner reactor_runner{reactor, ThreadConfig{"reactor"s}};
100+
101+
// Wait for termination.
102+
SigWait sig_wait;
103+
for (;;) {
104+
switch (const auto sig = sig_wait()) {
105+
case SIGHUP:
106+
TOOLBOX_INFO << "received SIGHUP";
107+
continue;
108+
case SIGINT:
109+
TOOLBOX_INFO << "received SIGINT";
110+
break;
111+
case SIGTERM:
112+
TOOLBOX_INFO << "received SIGTERM";
113+
break;
114+
default:
115+
TOOLBOX_INFO << "received signal: " << sig;
116+
continue;
117+
}
118+
break;
119+
}
120+
ret = 0;
121+
122+
} catch (const std::exception& e) {
123+
TOOLBOX_ERROR << "exception: " << e.what();
124+
}
125+
return ret;
126+
}

image/CMakeLists.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,12 @@ if(DOT_EXECUTABLE)
2222
message(STATUS "Dot found: ${DOT_EXECUTABLE}")
2323

2424
set(names
25+
util
26+
sys
2527
io
2628
ipc
2729
net
28-
sys
29-
util
30+
http
3031
)
3132

3233
foreach(name ${names})

toolbox/CMakeLists.txt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,16 @@ include_directories(SYSTEM
3838
"${CMAKE_CURRENT_SOURCE_DIR}/contrib")
3939

4040
set(lib_SOURCES
41+
http/App.cpp
42+
http/Conn.cpp
43+
http/Error.cpp
44+
http/Exception.cpp
45+
http/Parser.cpp
46+
http/Request.cpp
47+
http/Serv.cpp
48+
http/Stream.cpp
49+
http/Types.cpp
50+
http/Url.cpp
4151
io/Buffer.cpp
4252
io/Epoll.cpp
4353
io/EpollReactor.cpp
@@ -89,6 +99,7 @@ set(lib_SOURCES
8999
util/Finally.cpp
90100
util/IntTypes.cpp
91101
util/Math.cpp
102+
util/MemAlloc.cpp
92103
util/RefCount.cpp
93104
util/RingBuffer.cpp
94105
util/Ryu.cpp
@@ -117,6 +128,13 @@ if(TOOLBOX_BUILD_SHARED)
117128
install(TARGETS toolbox-shared DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT shared)
118129
endif()
119130

131+
install(FILES http.hpp DESTINATION include/toolbox COMPONENT header)
132+
install(FILES io.hpp DESTINATION include/toolbox COMPONENT header)
133+
install(FILES ipc.hpp DESTINATION include/toolbox COMPONENT header)
134+
install(FILES net.hpp DESTINATION include/toolbox COMPONENT header)
135+
install(FILES sys.hpp DESTINATION include/toolbox COMPONENT header)
136+
install(FILES util.hpp DESTINATION include/toolbox COMPONENT header)
137+
120138
foreach(file ${lib_SOURCES})
121139
get_filename_component(dir "${file}" DIRECTORY)
122140
get_filename_component(name "${file}" NAME_WE)
@@ -128,7 +146,15 @@ foreach(file ${lib_SOURCES})
128146
endif()
129147
endforeach()
130148

149+
install(FILES contrib/http_parser.h
150+
DESTINATION include/toolbox/contrib
151+
COMPONENT header
152+
)
153+
131154
set(test_SOURCES
155+
http/Parser.ut.cpp
156+
http/Types.ut.cpp
157+
http/Url.ut.cpp
132158
io/Buffer.ut.cpp
133159
io/EpollReactor.ut.cpp
134160
io/Handle.ut.cpp
@@ -150,6 +176,7 @@ set(test_SOURCES
150176
util/Finally.ut.cpp
151177
util/IntTypes.ut.cpp
152178
util/Math.ut.cpp
179+
util/MemAlloc.ut.cpp
153180
util/RefCount.ut.cpp
154181
util/RingBuffer.ut.cpp
155182
util/Ryu.ut.cpp

0 commit comments

Comments
 (0)