alaCarte Maps
Renderer for OpenStreetMap tiles
http_server.cpp
Go to the documentation of this file.
1 
23 #include <boost/thread.hpp>
24 #include "server/http_server.hpp"
26 #include "server/http_request.hpp"
28 
35 HttpServer::HttpServer( const shared_ptr<Configuration>& config, const shared_ptr<RequestManager>& manager )
36  : config(config)
37  , manager(manager)
38  , io_service()
39  , signals(io_service)
40  , acceptor(io_service)
41 {
42  // Register to handle the signals that indicate when the server should exit.
43  // It is safe to register for the same signal multiple times in a program,
44  // provided all registration for the specified signal is made through Asio.
45  signals.add(SIGINT);
46  signals.add(SIGTERM);
47  #if defined(SIGQUIT)
48  signals.add(SIGQUIT);
49  #endif // defined(SIGQUIT)
50  signals.async_wait(boost::bind(&HttpServer::quit, this));
51 }
52 
53 
58 {
59  // Open the acceptor with the option to reuse the address (i.e. SO_REUSEADDR).
60  boost::asio::ip::tcp::resolver resolver(io_service);
61  boost::asio::ip::tcp::resolver::query query(
62  config->get<string>(opt::server::server_address),
63  config->get<string>(opt::server::server_port)
64  );
65  boost::asio::ip::tcp::endpoint endpoint = *resolver.resolve(query);
66  acceptor.open(endpoint.protocol());
67  acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
68  try {
69  acceptor.bind(endpoint);
70  } catch (boost::system::system_error ex) {
71  LOG_SEV(server_log, error) << "Invalid host name: " << ex.what()
72  << " (" << config->get<string>(opt::server::server_address) << ":"
73  << config->get<string>(opt::server::server_port) << ")";
74  return;
75  }
76  acceptor.listen();
77  start_accept();
78 
79  LOG_SEV(server_log, info) << "Server is now waiting for new connections ...";
80  LOG_SEV(server_log, info) << "Send a \"SIGINT\", \"SIGTERM\" or \"SIGQUIT\" signal to shut down the server. (ctrl-c)";
81  // The io_service::run() call will block until all asynchronous operations
82  // have finished. While the server is running, there is always at least one
83  // asynchronous operation outstanding: the asynchronous accept call waiting
84  // for new incoming connections.
85  io_service.run();
86 }
87 
93 void HttpServer::stopRequest ( shared_ptr<HttpRequest> request ) {
94  requests.erase(request);
95  request->close();
96 }
97 
102 {
103  nextRequest.reset(new HttpRequest(io_service, this->shared_from_this(), manager));
104  acceptor.async_accept(nextRequest->getSocket(), boost::bind(&HttpServer::handle_accept, this, boost::asio::placeholders::error));
105 }
109 void HttpServer::handle_accept(const boost::system::error_code& e)
110 {
111  // Check whether the server was stopped by a signal before this completion
112  // handler had a chance to run.
113  if (!acceptor.is_open())
114  {
115  return;
116  }
117 
118  if (!e)
119  {
120  requests.insert(nextRequest);
121  nextRequest->startCollectingData();
122  }
123 
124  start_accept();
125 }
126 
132 {
133  // The server is stopped by cancelling all outstanding asynchronous
134  // operations. Once all operations have finished the io_service::run() call
135  // will exit.
136  acceptor.close();
137 
138  //Stop all open Requests
139  std::for_each(requests.begin(), requests.end(), boost::bind(&HttpRequest::close, _1));
140  requests.clear();
141 
142  Statistic::Get()->printStatistic();
143 }
144 
void stopRequest(shared_ptr< HttpRequest > request)
Stops a HttpRequest and deletes it from the request list.
Definition: http_server.cpp:93
static const char * server_address
Address of the server (type: string)
shared_ptr< Configuration > config
Definition: http_server.hpp:66
TESTABLE void quit()
Cleans up the HttpServer.
std::set< shared_ptr< HttpRequest > > requests
The managed requests.
Definition: http_server.hpp:64
#define LOG_SEV(log, lvl)
Definition: settings.hpp:78
void start_accept()
Prepares the HttpServer for a new connection and waits asynchronous for it.
TESTABLE void listen()
The HttpServer starts listening for new connections.
Definition: http_server.cpp:57
boost::asio::ip::tcp::acceptor acceptor
Acceptor used to listen for incoming requests.
Definition: http_server.hpp:58
boost::asio::signal_set signals
The signal_set is used to register process termination notifications.
Definition: http_server.hpp:55
static const shared_ptr< Statistic > & Get()
Definition: statistic.hpp:83
shared_ptr< HttpRequest > nextRequest
The next connection to be accepted.
Definition: http_server.hpp:61
static const char * config
Option to get the configuration filename (type: string)
HttpServer(const shared_ptr< Configuration > &config, const shared_ptr< RequestManager > &manager)
This file is part of alaCarte.
Definition: http_server.cpp:35
void close()
Stop all asynchronous operations associated with the connection.
shared_ptr< RequestManager > manager
Definition: http_server.hpp:67
boost::asio::io_service io_service
The io_service used to perform asynchronous operations.
Definition: http_server.hpp:52
static const char * server_port
Port the server should listen at (type: int)
void handle_accept(const boost::system::error_code &e)
Called when a new client connects to the server.