Contents
HTTP server

Overview

An HTTP and WebSocket server that uses the Boost Asio and Beast libraries.

A Balau HTTP server instance contains two trees of web applications, one for HTTP and another for WebSockets. These trees allow the server to handle HTTP requests differently, according to the HTTP request paths. WebSocket clients are also connected to different WebSocket applications, based on the HTTP request path active during the WebSocket upgrade.

Complex routing and handling of HTTP requests by a single HTTP server may be created via the creation of a sophisticated HTTP web application tree. Similarly, the specification of the WebSockets application tree allows multiple WebSockets applications to be provided by the same HTTP server.

There are two ways to use the HTTP server:

The first type of usage is a more traditional approach to application development, where the web application framework is fixed at code creation.

The second type of usage allows different web application configurations to be specified for different environments whilst using the same pre-compiled application. The resulting environment configurations provide the configurable parameters of the main HTTP server and the web applications, modifiable independently of application compilation.

Quick start

#include <Balau/Network/Http/Server/HttpServer.hpp>

Environment configuration: http.server

Hardwired

There are two HTTP server constructors available for direct usage.

The first constructor accepts global server configuration and both predefined HTTP and WebSocket handlers. By specifying routing web application handlers, this constructor also allows full HTTP and WebSockets application trees to be specified. If no WebSockets handler or application tree is required, a null handler may be specified.

The second constructor accepts global server configuration and a document root. This constructor is useful in order to create a simple file serving HTTP server.

Both these constructors may be used within an injector provider if required, in order to integrate them into the application's bindings tree.

Please refer to the HTTP server source code or the Balau API documentation to see the exact signatures of the two constructors.

Injected

The injectable constructor of the HTTP server takes an EnvironmentProperties instance. When supplied from the injector, this is bound to the root EnvironmentProperties binding with name "http.server".

			HttpServer(std::shared_ptr<System::Clock> clock,
			           std::shared_ptr<EnvironmentProperties> configuration,
			           bool registerSignalHandler = true);
		

The clock instance should be provided by another binding in the injector's application configuration. The http.server.register.signal.handler boolean binding is defaulted to true via the Balau environment configuration specifications. If you intend to set up your own signal handlers which will manage the HTTP server's shutdown, your environment configuration should have a http.server.register.signal.handler root property set to false.

The above constructor will be called by the injector when a suitable binding is added to the application configuration.

			// Example application configuration for the HTTP server.
			class AppConfig : public Balau::ApplicationConfiguration {
				public: void configure() const override {
					bind<Balau::System::Clock>().toSingleton<Balau::System::SystemClock>();
					bind<Balau::Network::Http::HttpServer>().toSingleton();
				}
			};
		

Once the HTTP server binding has been specified in the application configuration, an environment configuration entry for the HTTP server will need to be created, with name "http.server" binding. The contents of the HTTP server's environment configuration will depend on the usage requirements and the required web application trees. Please refer to the http.server environment configuration documentation for more information.

During instantiation, the HTTP server will create an HTTP routing web application and a WebSockets routing web application, and will populate them with instances of the web applications specified in the HTTP server's environment configuration.

Below is an example of environment configuration for an HTTP server configured with file server and email sender HTTP web applications.

			http.server {
				info.log     = file:logs/access.log
				error.log    = file:logs/error.log
				server.id    = My server
				worker.count = 8
				listen       = 127.0.0.1:8080

				# Mime types specified in a different file.
				@file:mime.types.hconf

				http {
					files {
						location = /
						root     = file:www
					}

					email.sender {
						location   = /ajax/send
						host       = smtp.example.com
						port       = 465
						user       = email-sender
						subject    = MESSAGE RECEIVED
						from       = enquiry@example.com
						to         = enquiry@example.com
						user-agent = Balau

						# These will be served by the file serving web app.
						success    = /success.html
						failure    = /failure.html

						# These parameters should match the POST request form data.
						parameters {
							Name  = 1
							Email = 2
							Tel   = 3
							Body  = 4
						}
					}
				}
			}
		

In order to create a binding in the injector for the environment configuration, an EnvironmentConfiguration instance for the environment resource(s) will need to be created. In addition to a URI for the environment configuration, the instance should be supplied with a URI specifying the Balau environment specifications. These specifications will be used to provide type information and any default values not provided in the configuration.

			///////////// Create the application injector. /////////////

			// A file pointing to the environment configuration given above.
			auto env = Resource::File("path/to/env/env.hconf");

			// A file pointing to the environment's credentials configuration.
			// This is required for the email.sender user password.
			auto creds = Resource::File("path/to/env/creds.hconf");

			// A file pointing to the Balau environment specifications.
			auto specs = Resource::File("path/to/specs/balau.thconf");

			// Create the injector configurations.
			auto appConf = AppConfig();
			auto envConf = EnvironmentConfiguration({ env, creds }, { specs });

			// Create the injector.
			auto injector = Injector::create(appConf, envConf);
		

Configuration

This section discusses the HTTP server configuration in more detail.

Main configuration

The HTTP server main configuration properties are supplied within a composite http.server composite property. This property forms a container of all configuration required by the HTTP server and web applications, with the exception of credentials properties.

The hierarchical structure of the main configuration also specifies the HTTP and WebSocket web application hierarchies. During instantiation, the HTTP server will instantiate the appropriate web applications, according to the environment configuration.

The structure of the main configuration takes the form of a set of HTTP value properties, plus a hierarchical set of composite location properties. Each location property specifies a location, the web application handler, and the web application's configuration.

The following is an example of a simple HTTP server main configuration that has a file serving web application and an email sending web application.

			http.server {
				######### General server properties #########

				logging.ns   = http.server
				info.log     = file:logs/access.log
				error.log    = file:logs/error.log
				server.id    = My server
				worker.count = 8
				listen       = 127.0.0.1:8080

				# Include mime types file.
				@file:mime.types.hconf

				############ HTTP request filters ###########

				filters {
					# TODO
				}

				###### HTTP web application properties ######

				http {
					files {
						location = /
						root     = file:www
					}

					email.sender {
						location   = /ajax/send
						host       = smtp.example.com
						port       = 465
						user       = email-sender
						subject    = MESSAGE RECEIVED
						from       = enquiry@example.com
						to         = enquiry@example.com
						user-agent = Balau

						# These will be served by the file serving web app.
						success    = /success.html
						failure    = /failure.html

						# These parameters should match the POST request form data.
						parameters {
							Name  = 1
							Email = 2
							Tel   = 3
							Body  = 4
						}
					}
				}

				### WebSockets web application properties ###

				ws {
					# TODO
				}
			}
		

Credentials management

HTTP server web application credentials are supplied in the same hierarchy as the main web application configuration. In order to physically separate confidential credentials from the main environment configuration, a parallel tree may be created that contains only credentials information. The two configuration trees will then be merged together by the injector's environment configuration logic, resulting in a single tree.

In order to merge the two configuration files, a single EnvironmentConfiguration instance should be created.

			auto env = EnvironmentConfiguration({ env, creds }, { specs });