Toolbox snapshot
The Reactive C++ Toolbox
Loading...
Searching...
No Matches
HttpServ.cpp
Go to the documentation of this file.
1// The Reactive C++ Toolbox.
2// Copyright (C) 2013-2019 Swirly Cloud Limited
3// Copyright (C) 2022 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#include <toolbox/util.hpp>
21
22#include <map>
23
24using namespace std;
25using namespace toolbox;
26
27namespace {
28
29void on_foo(const Request& /*req*/, http::OStream& os)
30{
31 os << "Hello, Foo!";
32}
33
34void on_bar(const Request& /*req*/, http::OStream& os)
35{
36 os << "Hello, Bar!";
37}
38
39class ExampleApp final : public App {
40 public:
42 using SlotMap = std::map<std::string, Slot>;
43
44 ~ExampleApp() override = default;
45 void bind(const std::string& path, Slot slot) { slot_map_[path] = slot; }
46
47 protected:
48 void do_on_http_connect(CyclTime /*now*/, const Endpoint& ep) noexcept override
49 {
50 TOOLBOX_INFO << "http session connected: " << ep;
51 }
52 void do_on_http_disconnect(CyclTime /*now*/, const Endpoint& ep) noexcept override
53 {
54 TOOLBOX_INFO << "http session disconnected: " << ep;
55 }
56 void do_on_http_error(CyclTime /*now*/, const Endpoint& ep, const std::exception& e,
57 http::OStream& /*os*/) noexcept override
58 {
59 TOOLBOX_ERROR << "http session error: " << ep << ": " << e.what();
60 }
61 void do_on_http_message(CyclTime /*now*/, const Endpoint& /*ep*/, const Request& req,
62 http::OStream& os) override
63 {
64 const auto it = slot_map_.find(string{req.path()});
65 if (it != slot_map_.end()) {
66 os.reset(Status::Ok, TextPlain);
67 it->second(req, os);
68 } else {
69 os.reset(Status::NotFound, TextPlain);
70 os << "Error 404 - Page not found";
71 }
72 os.commit();
73 }
74 void do_on_http_timeout(CyclTime /*now*/, const Endpoint& ep) noexcept override
75 {
76 TOOLBOX_WARN << "http session timeout: " << ep;
77 }
78
79 private:
80 SlotMap slot_map_;
81};
82
83} // namespace
84
85int main()
86{
87 int ret = 1;
88 try {
89
90 const auto start_time = CyclTime::now();
91
92 Reactor reactor{1024};
93 ExampleApp app;
94 app.bind("/foo", bind<on_foo>());
95 app.bind("/bar", bind<on_bar>());
96
97 const TcpEndpoint ep{TcpProtocol::v4(), 8888};
99
100 // Start service threads.
102 ReactorRunner reactor_runner{reactor, 100, "reactor"s};
103
104 // Wait for termination.
106 for (;;) {
107 switch (const auto sig = sig_wait()) {
108 case SIGHUP:
109 TOOLBOX_INFO << "received SIGHUP";
110 continue;
111 case SIGINT:
112 TOOLBOX_INFO << "received SIGINT";
113 break;
114 case SIGTERM:
115 TOOLBOX_INFO << "received SIGTERM";
116 break;
117 default:
118 TOOLBOX_INFO << "received signal: " << sig;
119 continue;
120 }
121 break;
122 }
123 ret = 0;
124
125 } catch (const std::exception& e) {
126 TOOLBOX_ERROR << "exception on main thread: " << e.what();
127 }
128 return ret;
129}
int main()
Definition HttpServ.cpp:85
#define TOOLBOX_WARN
Definition Log.hpp:94
#define TOOLBOX_INFO
Definition Log.hpp:97
#define TOOLBOX_ERROR
Definition Log.hpp:93
void reset() noexcept
Definition Stream.hpp:85
void commit() noexcept
Definition Stream.cpp:56
STL namespace.
constexpr char TextPlain[]
Definition Stream.hpp:29
IpEndpoint< TcpProtocol > TcpEndpoint
Definition Endpoint.hpp:41
constexpr auto bind() noexcept
Definition Slot.hpp:92