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
11#include <http/connection.h>
13#include <http/http_acceptor.h>
14#include <http/listener.h>
15#include <boost/scoped_ptr.hpp>
16
17using namespace isc::asiolink;
18
19namespace isc {
20namespace http {
21
24public:
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
71private:
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
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
148const TCPEndpoint&
150 return (*endpoint_);
151}
152
153void
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
170void
172 connections_.stopAll();
173 acceptor_.close();
174}
175
176void
177HttpListenerImpl::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
194void
195HttpListenerImpl::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
218 return (impl_->getEndpoint().getAddress());
219}
220
221uint16_t
223 return (impl_->getEndpoint().getPort());
224}
225
226void
228 impl_->start();
229}
230
231void
233 impl_->stop();
234}
235
236
237} // end of namespace isc::http
238} // end of namespace isc
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
Pool of active HTTP connections.
void stopAll()
Stops all connections and removes them from the pool.
void start(const HttpConnectionPtr &connection)
Start new connection.
Accepts and handles a single HTTP connection.
Definition: connection.h:43
A generic error raised by the HttpListener class.
Definition: listener.h:21
Implementation of the HttpListener.
Definition: listener.cc:23
void start()
Starts accepting new connections.
Definition: listener.cc:154
HttpListenerImpl(asiolink::IOService &io_service, const asiolink::IOAddress &server_address, const unsigned short server_port, const HttpResponseCreatorFactoryPtr &creator_factory, const long request_timeout, const long idle_timeout)
Constructor.
Definition: listener.cc:111
const TCPEndpoint & getEndpoint() const
Returns reference to the current listener endpoint.
Definition: listener.cc:149
void stop()
Stops all active connections and shuts down the service.
Definition: listener.cc:171
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
uint16_t getLocalPort() const
Returns local port on which server is listening.
Definition: listener.cc:222
asiolink::IOAddress getLocalAddress() const
Returns local address on which server is listening.
Definition: listener.cc:217
~HttpListener()
Destructor.
Definition: listener.cc:212
void stop()
Stops all active connections and shuts down the service.
Definition: listener.cc:232
void start()
Starts accepting new connections.
Definition: listener.cc:227
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
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
boost::shared_ptr< HttpResponseCreator > HttpResponseCreatorPtr
Pointer to the HttpResponseCreator object.
boost::shared_ptr< HttpResponseCreatorFactory > HttpResponseCreatorFactoryPtr
Pointer to the HttpResponseCreatorFactory.
boost::shared_ptr< HttpConnection > HttpConnectionPtr
Pointer to the HttpConnection.
Definition: connection.h:40
Defines the logger used by the top-level component of kea-dhcp-ddns.
Idle connection timeout.
Definition: listener.h:66
HTTP request timeout value.
Definition: listener.h:55