HttpServer.hpp
Go to the documentation of this file.
1 // @formatter:off
2 //
3 // Balau core C++ library
4 //
5 // Copyright (C) 2017 Bora Software (contact@borasoftware.com)
6 //
7 // Licensed under the Boost Software License - Version 1.0 - August 17th, 2003.
8 // See the LICENSE file for the full license text.
9 //
10 
16 
17 #ifndef COM_BORA_SOFTWARE__BALAU_NETWORK_HTTP_SERVER__HTTP_SERVER
18 #define COM_BORA_SOFTWARE__BALAU_NETWORK_HTTP_SERVER__HTTP_SERVER
19 
23 #include <Balau/Resource/File.hpp>
24 #include <Balau/System/Clock.hpp>
26 
27 #include <boost/asio/signal_set.hpp>
28 
29 #include <condition_variable>
30 #include <mutex>
31 #include <thread>
32 
33 // Avoid false positive (due to make_shared).
34 #pragma clang diagnostic push
35 #pragma ide diagnostic ignored "OCUnusedGlobalDeclarationInspection"
36 
37 namespace Balau {
38 
39 class Logger;
40 
41 namespace Network::Http {
42 
43 namespace Impl {
44 
45 class Listener;
46 
47 }
48 
79 class HttpServer {
82  , std::shared_ptr<System::Clock>, ""
83  , std::shared_ptr<EnvironmentProperties>, "http.server"
84  , bool, "http.server.register.signal.handler"
85  );
86 
88 
108  public: HttpServer(std::shared_ptr<System::Clock> clock,
109  const std::shared_ptr<EnvironmentProperties>& configuration,
110  bool registerSignalHandler = true);
111 
130  public: HttpServer(std::shared_ptr<System::Clock> clock,
131  const std::string & serverIdentification,
132  const TCP::endpoint & endpoint,
133  std::string threadNamePrefix_,
134  size_t workerCount_,
135  std::shared_ptr<HttpWebApp> httpHandler,
136  std::shared_ptr<WsWebApp> wsHandler = std::shared_ptr<WsWebApp>(nullptr),
137  const std::string & loggingNamespace = "balau.network.server",
138  std::string sessionCookieName = "session",
139  std::shared_ptr<MimeTypes> mimeTypes = MimeTypes::defaultMimeTypes,
140  bool registerSignalHandler = true);
141 
159  public: HttpServer(std::shared_ptr<System::Clock> clock,
160  const std::string & serverIdentification,
161  const TCP::endpoint & endpoint,
162  std::string threadNamePrefix_,
163  size_t workerCount_,
164  const Resource::File & documentRoot,
165  const std::string & defaultFile = "index.html",
166  const std::string & loggingNamespace = "balau.network.server",
167  std::string sessionCookieName = "session",
168  std::shared_ptr<MimeTypes> mimeTypes = MimeTypes::defaultMimeTypes,
169  bool registerSignalHandler = true);
170 
174  public: ~HttpServer();
175 
177 
188  public: void startAsync();
189 
198  public: void startSync();
199 
205  public: bool isRunning();
206 
214  public: void stop(bool warn = false);
215 
219  public: std::string getAddress() const {
220  return toString(state->endpoint.address());
221  }
222 
226  public: unsigned short getPort() const {
227  return state->endpoint.port();
228  }
229 
231 
232  // Used for injection for compilers without guaranteed copy elision.
233  private: HttpServer(HttpServer && rhs) noexcept
234  : state(std::move(rhs.state))
235  , threadNamePrefix(rhs.threadNamePrefix)
236  , workerCount(rhs.workerCount)
237  , workers(std::move(rhs.workers))
238  , launched(std::move(rhs.launched))
239  , listener(std::move(rhs.listener))
240  , ioContext(std::move(rhs.ioContext))
241  , mutex(std::move(rhs.mutex))
242  , signalSet(std::move(rhs.signalSet)) {}
243 
244  //
245  // Create the HTTP server configuration object.
246  //
247  private: static std::shared_ptr<HttpServerConfiguration> createState(std::shared_ptr<System::Clock> clock,
248  const std::shared_ptr<EnvironmentProperties> & configuration);
249 
250  //
251  // Create a mime type map from the environment configuration if one is
252  // supplied, otherwise use the default mime type map that is hard coded.
253  //
254  private: static std::shared_ptr<MimeTypes> createMimeTypes(const std::shared_ptr<EnvironmentProperties> & configuration,
255  BalauLogger & logger);
256 
257  //
258  // Create the HTTP handler, consisting of a HTTP routing handle at the base
259  // and other HTTP handlers at the leaves.
260  //
261  private: static std::shared_ptr<HttpWebApp> createHttpHandler(const std::shared_ptr<EnvironmentProperties> & configuration,
262  BalauLogger & logger);
263 
264  //
265  // Create the WebSocket handler, consisting of a WebSocket routing handle at the base
266  // and other WebSocket handlers at the leaves.
267  //
268  private: static std::shared_ptr<WsWebApp> createWsHandler(const std::shared_ptr<EnvironmentProperties> & configuration,
269  BalauLogger & logger);
270 
271  //
272  // Helper function that adds the HTTP web application to the supplied routing
273  // trie in the location(s) specified in the location string.
274  //
275  // An exception will be thrown a location is specified that already has a web
276  // application defined for it.
277  //
278  private: static void addToHttpRoutingTrie(HttpWebApps::RoutingHttpWebApp::Routing & routing,
279  const std::string & locationStr,
280  std::shared_ptr<HttpWebApp> & webApp);
281 
282  private: void launchListener();
283  private: void workerThreadFunction(size_t workerIndex);
284  private: void doRegisterSignalHandler();
285  private: void handleSignal(const boost::system::error_code & error, int sig);
286 
287  private: std::shared_ptr<HttpServerConfiguration> state;
288  private: const std::string threadNamePrefix;
289  private: const size_t workerCount;
290  private: std::vector<std::thread> workers;
291  private: std::unique_ptr<std::atomic_uint> launched;
292  private: std::shared_ptr<Impl::Listener> listener;
293  private: std::unique_ptr<boost::asio::io_context> ioContext;
294  private: std::unique_ptr<std::mutex> mutex;
295  private: std::unique_ptr<boost::asio::signal_set> signalSet;
296 };
297 
298 } // namespace Network::Http
299 
300 } // namespace Balau
301 
302 #pragma clang diagnostic pop
303 
304 #endif // COM_BORA_SOFTWARE__BALAU_NETWORK_HTTP_SERVER__HTTP_SERVER
A file on the local file system.
Injection macros used in injectable classes.
The root Balau namespace.
Definition: ApplicationConfiguration.hpp:23
An asynchronous HTTP/WebSocket server.
Definition: HttpServer.hpp:79
static std::shared_ptr< MimeTypes > defaultMimeTypes
The default set of mime types available.
Definition: MimeTypes.hpp:43
A file on the local file system.
Definition: File.hpp:35
An HTTP web application handler that routes to other handlers.
unsigned short getPort() const
Get the port being listened on.
Definition: HttpServer.hpp:226
Shared state between HTTP sessions.
#define BalauInjectNamedTypes(...)
Annotate an injectable class by specifying the class name and the named types of its dependencies...
Definition: Injectable.hpp:55
std::string getAddress() const
Get the address being listened on.
Definition: HttpServer.hpp:219
A WebSocket web application handler that routes to other handlers.
Balau::U8String< AllocatorT > toString(LoggingLevel level)
Print the logging level as a UTF-8 string.
Definition: LoggingLevel.hpp:73
Base interface of clocks.