Kea  1.5.0
listener.cc
Go to the documentation of this file.
1 // Copyright (C) 2017-2018 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>
8 
10 #include <asiolink/tcp_endpoint.h>
11 #include <http/connection.h>
12 #include <http/connection_pool.h>
13 #include <http/http_acceptor.h>
14 #include <http/listener.h>
15 #include <boost/scoped_ptr.hpp>
16 
17 using namespace isc::asiolink;
18 
19 namespace isc {
20 namespace http {
21 
24 public:
25 
48  const asiolink::IOAddress& server_address,
49  const unsigned short server_port,
50  const HttpResponseCreatorFactoryPtr& creator_factory,
51  const long request_timeout,
52  const long idle_timeout);
53 
55  const TCPEndpoint& getEndpoint() const;
56 
66  void start();
67 
69  void stop();
70 
71 private:
72 
77  void accept();
78 
85  void acceptHandler(const boost::system::error_code& ec);
86 
88  asiolink::IOService& io_service_;
89 
91  HttpAcceptor acceptor_;
92 
95  boost::scoped_ptr<asiolink::TCPEndpoint> endpoint_;
96 
98  HttpConnectionPool connections_;
99 
101  HttpResponseCreatorFactoryPtr creator_factory_;
102 
104  long request_timeout_;
105 
108  long idle_timeout_;
109 };
110 
111 HttpListenerImpl::HttpListenerImpl(IOService& io_service,
112  const asiolink::IOAddress& server_address,
113  const unsigned short server_port,
114  const HttpResponseCreatorFactoryPtr& creator_factory,
115  const long request_timeout,
116  const long idle_timeout)
117  : io_service_(io_service), acceptor_(io_service),
118  endpoint_(), creator_factory_(creator_factory),
119  request_timeout_(request_timeout), idle_timeout_(idle_timeout) {
120  // Try creating an endpoint. This may cause exceptions.
121  try {
122  endpoint_.reset(new TCPEndpoint(server_address, server_port));
123 
124  } catch (...) {
125  isc_throw(HttpListenerError, "unable to create TCP endpoint for "
126  << server_address << ":" << server_port);
127  }
128 
129  // The factory must not be null.
130  if (!creator_factory_) {
131  isc_throw(HttpListenerError, "HttpResponseCreatorFactory must not"
132  " be null");
133  }
134 
135  // Request timeout is signed and must be greater than 0.
136  if (request_timeout_ <= 0) {
137  isc_throw(HttpListenerError, "Invalid desired HTTP request timeout "
138  << request_timeout_);
139  }
140 
141  // Idle persistent connection timeout is signed and must be greater than 0.
142  if (idle_timeout_ <= 0) {
143  isc_throw(HttpListenerError, "Invalid desired HTTP idle persistent connection"
144  " timeout " << idle_timeout_);
145  }
146 }
147 
148 const TCPEndpoint&
150  return (*endpoint_);
151 }
152 
153 void
155  try {
156  acceptor_.open(*endpoint_);
157  acceptor_.setOption(HttpAcceptor::ReuseAddress(true));
158  acceptor_.bind(*endpoint_);
159  acceptor_.listen();
160 
161  } catch (const boost::system::system_error& ex) {
162  stop();
163  isc_throw(HttpListenerError, "unable to setup TCP acceptor for "
164  "listening to the incoming HTTP requests: " << ex.what());
165  }
166 
167  accept();
168 }
169 
170 void
172  connections_.stopAll();
173  acceptor_.close();
174 }
175 
176 void
177 HttpListenerImpl::accept() {
178  // In some cases we may need HttpResponseCreator instance per connection.
179  // But, the factory may also return the same instance each time. It
180  // depends on the use case.
181  HttpResponseCreatorPtr response_creator = creator_factory_->create();
182  HttpAcceptorCallback acceptor_callback =
183  boost::bind(&HttpListenerImpl::acceptHandler, this, _1);
184  HttpConnectionPtr conn(new HttpConnection(io_service_, acceptor_,
185  connections_,
186  response_creator,
187  acceptor_callback,
188  request_timeout_,
189  idle_timeout_));
190  // Add this new connection to the pool.
191  connections_.start(conn);
192 }
193 
194 void
195 HttpListenerImpl::acceptHandler(const boost::system::error_code&) {
196  // The new connection has arrived. Set the acceptor to continue
197  // accepting new connections.
198  accept();
199 }
200 
202  const asiolink::IOAddress& server_address,
203  const unsigned short server_port,
204  const HttpResponseCreatorFactoryPtr& creator_factory,
205  const HttpListener::RequestTimeout& request_timeout,
206  const HttpListener::IdleTimeout& idle_timeout)
207  : impl_(new HttpListenerImpl(io_service, server_address, server_port,
208  creator_factory, request_timeout.value_,
209  idle_timeout.value_)) {
210 }
211 
213  stop();
214 }
215 
216 IOAddress
218  return (impl_->getEndpoint().getAddress());
219 }
220 
221 uint16_t
223  return (impl_->getEndpoint().getPort());
224 }
225 
226 void
228  impl_->start();
229 }
230 
231 void
233  impl_->stop();
234 }
235 
236 
237 } // end of namespace isc::http
238 } // end of namespace isc
isc::http::HttpListener::start
void start()
Starts accepting new connections.
Definition: listener.cc:227
isc::http::HttpConnectionPool::start
void start(const HttpConnectionPtr &connection)
Start new connection.
Definition: connection_pool.cc:16
isc::http::HttpConnectionPool
Pool of active HTTP connections.
Definition: connection_pool.h:28
isc::http::HttpAcceptorCallback
boost::function< void(const boost::system::error_code &)> HttpAcceptorCallback
Type of the callback for the TCP acceptor used in this library.
Definition: http_acceptor.h:19
isc::http::HttpListener::HttpListener
HttpListener(asiolink::IOService &io_service, const asiolink::IOAddress &server_address, const unsigned short server_port, const HttpResponseCreatorFactoryPtr &creator_factory, const RequestTimeout &request_timeout, const IdleTimeout &idle_timeout)
Constructor.
Definition: listener.cc:201
isc::http::HttpListener::stop
void stop()
Stops all active connections and shuts down the service.
Definition: listener.cc:232
isc::http::HttpListenerImpl
Implementation of the HttpListener.
Definition: listener.cc:23
connection_pool.h
isc::http::HttpListenerError
A generic error raised by the HttpListener class.
Definition: listener.h:21
listener.h
http_acceptor.h
isc
Defines the logger used by the top-level component of kea-dhcp-ddns.
Definition: agent_parser.cc:144
isc::Exception::what
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
Definition: exceptions/exceptions.cc:32
tcp_endpoint.h
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition: exceptions/exceptions.h:192
isc::http::HttpConnection
Accepts and handles a single HTTP connection.
Definition: connection.h:43
isc::http::HttpListener::getLocalAddress
asiolink::IOAddress getLocalAddress() const
Returns local address on which server is listening.
Definition: listener.cc:217
isc::http::HttpResponseCreatorPtr
boost::shared_ptr< HttpResponseCreator > HttpResponseCreatorPtr
Pointer to the HttpResponseCreator object.
Definition: response_creator.h:17
isc::http::HttpListener::getLocalPort
uint16_t getLocalPort() const
Returns local port on which server is listening.
Definition: listener.cc:222
isc::http::HttpResponseCreatorFactoryPtr
boost::shared_ptr< HttpResponseCreatorFactory > HttpResponseCreatorFactoryPtr
Pointer to the HttpResponseCreatorFactory.
Definition: response_creator_factory.h:54
isc::http::HttpListener::RequestTimeout
HTTP request timeout value.
Definition: listener.h:55
isc::http::HttpListenerImpl::getEndpoint
const TCPEndpoint & getEndpoint() const
Returns reference to the current listener endpoint.
Definition: listener.cc:149
isc::http::HttpListener::IdleTimeout
Idle connection timeout.
Definition: listener.h:66
connection.h
isc::http::HttpConnectionPool::stopAll
void stopAll()
Stops all connections and removes them from the pool.
Definition: connection_pool.cc:28
isc::http::HttpConnectionPtr
boost::shared_ptr< HttpConnection > HttpConnectionPtr
Pointer to the HttpConnection.
Definition: connection.h:38
asio_wrapper.h
isc::http::HttpListenerImpl::start
void start()
Starts accepting new connections.
Definition: listener.cc:154
isc::http::HttpListenerImpl::stop
void stop()
Stops all active connections and shuts down the service.
Definition: listener.cc:171
isc::http::HttpListener::~HttpListener
~HttpListener()
Destructor.
Definition: listener.cc:212