The void uses monitor, acceptor and several worker threads.
monitor thread handles special port for gathering statistics information.
acceptor thread accepts new connections.
worker threads process connections: http parsing, logic and so on. Technically each worker has it's own boost::asio::io_service object, which run method is called in the separate thread. So each connection is processed by exactly one io_service and one thread, this makes possible not to think about synchronization mechanisms.
thevoid::acceptor_list is a helper object for handling new tcp/unix connections. As new socket is accepted the thevoid::connection object is initialized for it and server starts accepting next one.
Each incoming connection is handled by separate thevoid::connection object. Connection object is a protocol-logic wrapper around boost::asio::*::socket. It lives as long as the connection is alive. But there is an exception, it's not possible to know if the connection is dead in case if we don't listen the read handle. This situation is possible if user handler is timed-outed or corrupted, currently we can't do anything with it.
First, HTTP headers are parsed by thevoid::request_parser. Request parser is a simple HTTP parser which processes request and headers line-by-line. It's parse method returns false on error, true on success and boost::indeterminate if it needs more data. It returns pointer to the first character after the last processed one, so on success all characters left are part of the HTTP body.
After HTTP request has been parsed, user's handler may be constructed by one of the factories. Currently factory is chosen by the request path, but this behavior may be extended in the future. All the factories must be added to server in initialize method at start up.
After user's handler is created it can process swarm::http_request and HTTP body as soon as it is read from the socket.
When HTTP body has been read and user's handler called close method, connection can process next request by the same socket. It's possible only if keep-alive is enabled which by default is true for HTTP 1.1 requests or when “Connection: keep-alive” header is present. Otherwise socket is closed and connection is destroyed.
User's handlers are successors of thevoid::base_request_stream. As soon as this object as created it's on_headers method is called with the appropriate swarm::http_request container.
As soon as some part of HTTP body has been read from the socket, on_data method is invoked.
on_close method is called if the end of the data is reached or there was any error during reading/writing from/to socket.
thevoid::request_stream contains a lot of helper methods for logging, zero-copy writing and easy reply generation.
If you don't want to handle manually received HTTP body it's possible to use thevoid::simple_request_stream. It accumulates HTTP body into single chunk, so on_request is method called with http_request and full HTTP body after is has been fully received.