Kea  2.1.7-git
listener_impl.cc
Go to the documentation of this file.
1 // Copyright (C) 2019-2021 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 
7 #include <config.h>
9 #include <http/connection_pool.h>
10 #include <http/listener.h>
11 #include <http/listener_impl.h>
12 
13 using namespace isc::asiolink;
14 namespace ph = std::placeholders;
15 
16 namespace isc {
17 namespace http {
18 
19 HttpListenerImpl::HttpListenerImpl(IOService& io_service,
20  const asiolink::IOAddress& server_address,
21  const unsigned short server_port,
22  const TlsContextPtr& tls_context,
23  const HttpResponseCreatorFactoryPtr& creator_factory,
24  const long request_timeout,
25  const long idle_timeout)
26  : io_service_(io_service), tls_context_(tls_context), acceptor_(),
27  endpoint_(), connections_(),
28  creator_factory_(creator_factory),
29  request_timeout_(request_timeout), idle_timeout_(idle_timeout) {
30  // Create the TCP or TLS acceptor.
31  if (!tls_context) {
32  acceptor_.reset(new HttpAcceptor(io_service));
33  } else {
34  acceptor_.reset(new HttpsAcceptor(io_service));
35  }
36 
37  // Try creating an endpoint. This may cause exceptions.
38  try {
39  endpoint_.reset(new TCPEndpoint(server_address, server_port));
40 
41  } catch (...) {
42  isc_throw(HttpListenerError, "unable to create TCP endpoint for "
43  << server_address << ":" << server_port);
44  }
45 
46  // The factory must not be null.
47  if (!creator_factory_) {
48  isc_throw(HttpListenerError, "HttpResponseCreatorFactory must not"
49  " be null");
50  }
51 
52  // Request timeout is signed and must be greater than 0.
53  if (request_timeout_ <= 0) {
54  isc_throw(HttpListenerError, "Invalid desired HTTP request timeout "
55  << request_timeout_);
56  }
57 
58  // Idle persistent connection timeout is signed and must be greater than 0.
59  if (idle_timeout_ <= 0) {
60  isc_throw(HttpListenerError, "Invalid desired HTTP idle persistent connection"
61  " timeout " << idle_timeout_);
62  }
63 }
64 
65 const TCPEndpoint&
67  return (*endpoint_);
68 }
69 
70 void
72  try {
73  acceptor_->open(*endpoint_);
74  acceptor_->setOption(HttpAcceptor::ReuseAddress(true));
75  acceptor_->bind(*endpoint_);
76  acceptor_->listen();
77 
78  } catch (const boost::system::system_error& ex) {
79  stop();
80  isc_throw(HttpListenerError, "unable to setup TCP acceptor for "
81  "listening to the incoming HTTP requests: " << ex.what());
82  }
83 
84  accept();
85 }
86 
87 void
90  acceptor_->close();
91 }
92 
93 void
95  // In some cases we may need HttpResponseCreator instance per connection.
96  // But, the factory may also return the same instance each time. It
97  // depends on the use case.
98  HttpResponseCreatorPtr response_creator = creator_factory_->create();
99  HttpAcceptorCallback acceptor_callback =
100  std::bind(&HttpListenerImpl::acceptHandler, this, ph::_1);
101  HttpConnectionPtr conn = createConnection(response_creator,
102  acceptor_callback);
103  // Add this new connection to the pool.
104  connections_.start(conn);
105 }
106 
107 void
108 HttpListenerImpl::acceptHandler(const boost::system::error_code&) {
109  // The new connection has arrived. Set the acceptor to continue
110  // accepting new connections.
111  accept();
112 }
113 
116  const HttpAcceptorCallback& callback) {
119  connections_, response_creator, callback,
121  return (conn);
122 }
123 
124 } // end of namespace isc::http
125 } // end of namespace isc
boost::shared_ptr< HttpResponseCreatorFactory > HttpResponseCreatorFactoryPtr
Pointer to the HttpResponseCreatorFactory.
asiolink::IOService & io_service_
Reference to the IO service.
void start(const HttpConnectionPtr &connection)
Start new connection.
Accepts and handles a single HTTP connection.
Definition: connection.h:43
asiolink::TCPAcceptor< HttpAcceptorCallback > HttpAcceptor
Type of the TCP acceptor used in this library.
Definition: http_acceptor.h:23
long idle_timeout_
Timeout after which idle persistent connection is closed by the server.
HttpResponseCreatorFactoryPtr creator_factory_
Pointer to the HttpResponseCreatorFactory.
virtual HttpConnectionPtr createConnection(const HttpResponseCreatorPtr &response_creator, const HttpAcceptorCallback &callback)
Creates an instance of the HttpConnection.
A generic error raised by the HttpListener class.
Definition: listener.h:22
void start()
Starts accepting new connections.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
std::function< void(const boost::system::error_code &)> HttpAcceptorCallback
Type of the callback for the TCP acceptor used in this library.
Definition: http_acceptor.h:20
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
long request_timeout_
Timeout for HTTP Request Timeout desired.
void accept()
Creates HttpConnection instance and adds it to the pool of active connections.
void acceptHandler(const boost::system::error_code &ec)
Callback invoked when the new connection is accepted.
asiolink::TLSAcceptor< HttpAcceptorCallback > HttpsAcceptor
Type of the TLS acceptor used in this library.
Definition: http_acceptor.h:28
boost::shared_ptr< HttpResponseCreator > HttpResponseCreatorPtr
Pointer to the HttpResponseCreator object.
Defines the logger used by the top-level component of kea-lfc.
HttpConnectionPool connections_
Pool of active connections.
void stopAll()
Stops all connections and removes them from the pool.
boost::shared_ptr< HttpConnection > HttpConnectionPtr
Pointer to the HttpConnection.
Definition: connection.h:38
void stop()
Stops all active connections and shuts down the service.
boost::scoped_ptr< asiolink::TCPEndpoint > endpoint_
Pointer to the endpoint representing IP address and port on which the service is running.
HttpAcceptorPtr acceptor_
Acceptor instance.
asiolink::TlsContextPtr tls_context_
TLS context.
const asiolink::TCPEndpoint & getEndpoint() const
Returns reference to the current listener endpoint.