Skip to content

Commit e46a746

Browse files
committed
Merge pull request cpp-netlib#397 from jellevdd/0.11-devel-integration
Add SSL support to async_server
2 parents 4522975 + a9e23a8 commit e46a746

File tree

4 files changed

+237
-20
lines changed

4 files changed

+237
-20
lines changed

boost/network/protocol/http/server/async_connection.hpp

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define BOOST_NETWORK_PROTOCOL_HTTP_SERVER_CONNECTION_HPP_20101027
33

44
// Copyright 2010 Dean Michael Berris.
5+
// Copyright 2014 Jelle Van den Driessche.
56
// Distributed under the Boost Software License, Version 1.0.
67
// (See accompanying file LICENSE_1_0.txt or copy at
78
// http://www.boost.org/LICENSE_1_0.txt)
@@ -18,6 +19,7 @@
1819
#include <boost/asio/strand.hpp>
1920
#include <boost/asio/buffer.hpp>
2021
#include <boost/make_shared.hpp>
22+
#include <boost/network/protocol/stream_handler.hpp>
2123
#include <boost/network/protocol/http/server/request_parser.hpp>
2224
#include <boost/range/iterator_range.hpp>
2325
#include <boost/optional.hpp>
@@ -149,14 +151,16 @@ namespace boost { namespace network { namespace http {
149151
asio::io_service & io_service
150152
, Handler & handler
151153
, utils::thread_pool & thread_pool
154+
, boost::shared_ptr<boost::asio::ssl::context> ctx = boost::shared_ptr<boost::asio::ssl::context>( )
152155
)
153-
: socket_(io_service)
154-
, strand(io_service)
156+
: strand(io_service)
155157
, handler(handler)
156158
, thread_pool_(thread_pool)
157159
, headers_already_sent(false)
158160
, headers_in_progress(false)
161+
, handshake_done(false)
159162
, headers_buffer(BOOST_NETWORK_HTTP_SERVER_CONNECTION_HEADER_BUFFER_MAX_SIZE)
163+
, socket_(io_service, ctx)
160164
{
161165
new_start = read_buffer_.begin();
162166
}
@@ -285,7 +289,7 @@ namespace boost { namespace network { namespace http {
285289
, asio::placeholders::error, asio::placeholders::bytes_transferred)));
286290
}
287291

288-
asio::ip::tcp::socket & socket() { return socket_; }
292+
boost::network::stream_handler & socket() { return socket_; }
289293
utils::thread_pool & thread_pool() { return thread_pool_; }
290294
bool has_error() { return (!!error_encountered); }
291295
optional<boost::system::system_error> error()
@@ -319,12 +323,13 @@ namespace boost { namespace network { namespace http {
319323
typedef boost::lock_guard<boost::recursive_mutex> lock_guard;
320324
typedef std::list<boost::function<void()> > pending_actions_list;
321325

322-
asio::ip::tcp::socket socket_;
326+
boost::network::stream_handler socket_;
323327
asio::io_service::strand strand;
324328
Handler & handler;
325329
utils::thread_pool & thread_pool_;
326330
volatile bool headers_already_sent, headers_in_progress;
327331
asio::streambuf headers_buffer;
332+
bool handshake_done;
328333

329334
boost::recursive_mutex headers_mutex;
330335
buffer_type read_buffer_;
@@ -350,21 +355,29 @@ namespace boost { namespace network { namespace http {
350355
read_more(method);
351356
}
352357

358+
353359
void read_more(state_t state) {
354-
socket_.async_read_some(
355-
asio::buffer(read_buffer_)
356-
, strand.wrap(
357-
boost::bind(
358-
&async_connection<Tag,Handler>::handle_read_data,
359-
async_connection<Tag,Handler>::shared_from_this(),
360-
state,
361-
boost::asio::placeholders::error,
362-
boost::asio::placeholders::bytes_transferred
360+
if(socket_.is_ssl_enabled() && !handshake_done) {
361+
socket_.async_handshake(boost::asio::ssl::stream_base::server,
362+
boost::bind(&async_connection::handle_handshake, async_connection<Tag,Handler>::shared_from_this(),
363+
boost::asio::placeholders::error, state));
364+
} else {
365+
socket_.async_read_some(
366+
asio::buffer(read_buffer_)
367+
, strand.wrap(
368+
boost::bind(
369+
&async_connection<Tag,Handler>::handle_read_data,
370+
async_connection<Tag,Handler>::shared_from_this(),
371+
state,
372+
boost::asio::placeholders::error,
373+
boost::asio::placeholders::bytes_transferred
363374
)
364375
)
365376
);
377+
}
366378
}
367379

380+
368381
void handle_read_data(state_t state, boost::system::error_code const & ec, std::size_t bytes_transferred) {
369382
if (!ec) {
370383
logic::tribool parsed_ok;
@@ -645,6 +658,14 @@ namespace boost { namespace network { namespace http {
645658
,asio::placeholders::bytes_transferred)
646659
);
647660
}
661+
void handle_handshake(const boost::system::error_code& ec, state_t state) {
662+
if (!ec) {
663+
handshake_done = true;
664+
read_more(state);
665+
} else {
666+
error_encountered = in_place<boost::system::system_error>(ec);
667+
}
668+
}
648669
};
649670

650671
} /* http */

boost/network/protocol/http/server/async_server.hpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define BOOST_NETWORK_PROTOCOL_HTTP_SERVER_ASYNC_SERVER_HPP_20101025
33

44
// Copyright 2010 Dean Michael Berris.
5+
// Copyright 2014 Jelle Van den Driessche.
56
// Distributed under the Boost Software License, Version 1.0.
67
// (See accompanying file LICENSE_1_0.txt or copy at
78
// http://www.boost.org/LICENSE_1_0.txt)
@@ -38,6 +39,7 @@ namespace boost { namespace network { namespace http {
3839
, listening_mutex_()
3940
, stopping_mutex_()
4041
, listening(false)
42+
, ctx_(options.context())
4143
{}
4244

4345
void run() {
@@ -79,6 +81,7 @@ namespace boost { namespace network { namespace http {
7981
boost::mutex listening_mutex_;
8082
boost::mutex stopping_mutex_;
8183
bool listening;
84+
boost::shared_ptr<boost::asio::ssl::context> ctx_;
8285

8386
void handle_stop() {
8487
scoped_mutex_lock stopping_lock(stopping_mutex_);
@@ -96,13 +99,14 @@ namespace boost { namespace network { namespace http {
9699
<< ec);
97100
}
98101

99-
socket_options_base::socket_options(new_connection->socket());
102+
socket_options_base::socket_options(new_connection->socket().next_layer());
103+
100104
new_connection->start();
101105
new_connection.reset(
102-
new connection(service_, handler, *thread_pool));
106+
new connection(service_, handler, *thread_pool, ctx_));
103107
acceptor.async_accept(
104-
new_connection->socket(),
105-
boost::bind(&async_server_base<Tag, Handler>::handle_accept,
108+
new_connection->socket().next_layer(),
109+
boost::bind(&async_server_base<Tag, Handler>::handle_accept,
106110
this,
107111
boost::asio::placeholders::error));
108112
}
@@ -135,8 +139,8 @@ namespace boost { namespace network { namespace http {
135139
BOOST_NETWORK_MESSAGE("Error listening on socket: '" << error << "' on " << address_ << ":" << port_);
136140
return;
137141
}
138-
new_connection.reset(new connection(service_, handler, *thread_pool));
139-
acceptor.async_accept(new_connection->socket(),
142+
new_connection.reset(new connection(service_, handler, *thread_pool, ctx_));
143+
acceptor.async_accept(new_connection->socket().next_layer(),
140144
boost::bind(
141145
&async_server_base<Tag,Handler>::handle_accept
142146
, this

boost/network/protocol/http/server/options.hpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33

44
// Copyright 2013 Google, Inc.
55
// Copyright 2013 Dean Michael Berris <dberris@google.com>
6+
// Copyright 2014 Jelle Van den Driessche
67
// Distributed under the Boost Software License, Version 1.0.
78
// (See accompanying file LICENSE_1_0.txt or copy at
89
// http://www.boost.org/LICENSE_1_0.txt)
910

1011
#include <boost/asio/io_service.hpp>
1112
#include <boost/asio/socket_base.hpp>
13+
#include <boost/asio/ssl.hpp>
1214
#include <boost/network/traits/string.hpp>
1315
#include <boost/network/utils/thread_pool.hpp>
1416
#include <boost/optional.hpp>
@@ -35,6 +37,7 @@ struct server_options {
3537
, receive_low_watermark_()
3638
, send_low_watermark_()
3739
, thread_pool_()
40+
, context_()
3841
{}
3942

4043
server_options(const server_options &other)
@@ -52,6 +55,7 @@ struct server_options {
5255
, receive_low_watermark_(other.receive_low_watermark_)
5356
, send_low_watermark_(other.send_low_watermark_)
5457
, thread_pool_(other.thread_pool_)
58+
, context_(other.context_)
5559
{}
5660

5761
server_options &operator= (server_options other) {
@@ -74,8 +78,10 @@ struct server_options {
7478
swap(receive_low_watermark_, other.receive_low_watermark_);
7579
swap(send_low_watermark_, other.send_low_watermark_);
7680
swap(thread_pool_, other.thread_pool_);
81+
swap(context_, other.context_);
7782
}
7883

84+
server_options &context(boost::shared_ptr<boost::asio::ssl::context> v) { context_ = v; return *this; }
7985
server_options &io_service(boost::shared_ptr<boost::asio::io_service> v) { io_service_ = v; return *this; }
8086
server_options &address(string_type const &v) { address_ = v; return *this; }
8187
server_options &port(string_type const &v) { port_ = v; return *this; }
@@ -104,8 +110,9 @@ struct server_options {
104110
boost::optional<boost::asio::socket_base::receive_low_watermark> receive_low_watermark() const { return receive_low_watermark_; }
105111
boost::optional<boost::asio::socket_base::send_low_watermark> send_low_watermark() const { return send_low_watermark_; }
106112
boost::shared_ptr<utils::thread_pool> thread_pool() const { return thread_pool_; }
107-
113+
boost::shared_ptr<boost::asio::ssl::context> context() const { return context_; }
108114
private:
115+
boost::shared_ptr<boost::asio::ssl::context> context_;
109116
boost::shared_ptr<boost::asio::io_service> io_service_;
110117
Handler &handler_;
111118
string_type address_;

0 commit comments

Comments
 (0)