From 8498eac940ae69bf4057665f2f07094cbbd2300c Mon Sep 17 00:00:00 2001 From: Oleg Malashenko Date: Mon, 13 Dec 2010 19:19:29 +1000 Subject: [PATCH 1/9] Reuse bind address in async_server --- boost/network/protocol/http/server/async_server.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/boost/network/protocol/http/server/async_server.hpp b/boost/network/protocol/http/server/async_server.hpp index abc05d688..74628cdea 100644 --- a/boost/network/protocol/http/server/async_server.hpp +++ b/boost/network/protocol/http/server/async_server.hpp @@ -37,6 +37,8 @@ namespace boost { namespace network { namespace http { tcp::endpoint endpoint = *resolver.resolve(query); acceptor.open(endpoint.protocol()); acceptor.bind(endpoint); + boost::asio::ip::tcp::socket::reuse_address opt(true); + acceptor.set_option(opt); acceptor.listen(); new_connection.reset(new connection(io_service, handler, thread_pool)); acceptor.async_accept(new_connection->socket(), From e91984460061340c4c21aa027d801463f7152453 Mon Sep 17 00:00:00 2001 From: Oleg Malashenko Date: Tue, 11 Jan 2011 20:15:09 +1000 Subject: [PATCH 2/9] Implemented async_connection::write_vec() Convenience function for writing asio::const_buffer sequence --- .../protocol/http/server/async_connection.hpp | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/boost/network/protocol/http/server/async_connection.hpp b/boost/network/protocol/http/server/async_connection.hpp index 8ff34b7ff..01d7fc611 100644 --- a/boost/network/protocol/http/server/async_connection.hpp +++ b/boost/network/protocol/http/server/async_connection.hpp @@ -212,10 +212,37 @@ namespace boost { namespace network { namespace http { void write(Range const & range, Callback const & callback) { lock_guard lock(headers_mutex); if (error_encountered) boost::throw_exception(boost::system::system_error(*error_encountered)); - boost::function f = callback; write_impl(boost::make_iterator_range(range), callback); } + template + void write_vec(ConstBufferSeq const & seq, Callback const & callback) + { + lock_guard lock(headers_mutex); + if (error_encountered) + boost::throw_exception(boost::system::system_error(*error_encountered)); + + boost::function continuation = boost::bind( + &async_connection::write_vec + ,async_connection::shared_from_this() + ,seq, callback + ); + + if (!headers_already_sent && !headers_in_progress) { + write_headers_only(continuation); + return; + } else if (headers_in_progress && !headers_already_sent) { + pending_actions.push_back(continuation); + return; + } + + asio::async_write( + socket_ + ,seq + ,boost::bind(callback, asio::placeholders::error) + ); + } + private: typedef boost::array buffer_type; From df6fd2422ba40c2a8b14fb6b19b8355effd84910 Mon Sep 17 00:00:00 2001 From: Oleg Malashenko Date: Wed, 12 Jan 2011 13:47:36 +1000 Subject: [PATCH 3/9] async_connection::write_impl implemented via write_vec_impl --- .../protocol/http/server/async_connection.hpp | 108 +++++++----------- 1 file changed, 39 insertions(+), 69 deletions(-) diff --git a/boost/network/protocol/http/server/async_connection.hpp b/boost/network/protocol/http/server/async_connection.hpp index 01d7fc611..23e13722a 100644 --- a/boost/network/protocol/http/server/async_connection.hpp +++ b/boost/network/protocol/http/server/async_connection.hpp @@ -218,29 +218,7 @@ namespace boost { namespace network { namespace http { template void write_vec(ConstBufferSeq const & seq, Callback const & callback) { - lock_guard lock(headers_mutex); - if (error_encountered) - boost::throw_exception(boost::system::system_error(*error_encountered)); - - boost::function continuation = boost::bind( - &async_connection::write_vec - ,async_connection::shared_from_this() - ,seq, callback - ); - - if (!headers_already_sent && !headers_in_progress) { - write_headers_only(continuation); - return; - } else if (headers_in_progress && !headers_already_sent) { - pending_actions.push_back(continuation); - return; - } - - asio::async_write( - socket_ - ,seq - ,boost::bind(callback, asio::placeholders::error) - ); + write_vec_impl(seq, callback, shared_array_list(), shared_buffers()); } private: @@ -537,15 +515,6 @@ namespace boost { namespace network { namespace http { void do_nothing() {} - template - void continue_write(Range range, boost::function callback) { - thread_pool().post( - boost::bind( - &async_connection::write_impl - , async_connection::shared_from_this() - , range, callback)); - } - template void write_first_line(Callback callback) { lock_guard lock(headers_mutex); @@ -630,27 +599,6 @@ namespace boost { namespace network { namespace http { template void write_impl(Range range, boost::function callback) { - lock_guard lock(headers_mutex); - boost::function callback_function = - callback; - - if (!headers_already_sent && !headers_in_progress) { - write_headers_only( - boost::bind( - &async_connection::continue_write - , async_connection::shared_from_this() - , range, callback_function - )); - return; - } else if (headers_in_progress && !headers_already_sent) { - pending_actions.push_back( - boost::bind( - &async_connection::continue_write - , async_connection::shared_from_this() - , range, callback_function)); - return; - } - // linearize the whole range into a vector // of fixed-sized buffers, then schedule an asynchronous // write of these buffers -- make sure they are live @@ -697,25 +645,47 @@ namespace boost { namespace network { namespace http { } if (!buffers->empty()) { - boost::function f = callback; - asio::async_write( - socket_ - , *buffers - , strand.wrap( - boost::bind( - &async_connection::handle_write - , async_connection::shared_from_this() - , f - , temporaries - , buffers // keep these alive until the handler is called! - , boost::asio::placeholders::error - , boost::asio::placeholders::bytes_transferred - ) - ) - ); + write_vec_impl(*buffers, callback, temporaries, buffers); } } + template + void write_vec_impl(ConstBufferSeq const & seq + ,Callback const & callback + ,shared_array_list temporaries + ,shared_buffers buffers) + { + lock_guard lock(headers_mutex); + if (error_encountered) + boost::throw_exception(boost::system::system_error(*error_encountered)); + + boost::function continuation = boost::bind( + &async_connection::write_vec_impl + ,async_connection::shared_from_this() + ,seq, callback, temporaries, buffers + ); + + if (!headers_already_sent && !headers_in_progress) { + write_headers_only(continuation); + return; + } else if (headers_in_progress && !headers_already_sent) { + pending_actions.push_back(continuation); + return; + } + + asio::async_write( + socket_ + ,seq + ,boost::bind( + &async_connection::handle_write + ,async_connection::shared_from_this() + ,callback + ,temporaries + ,buffers + ,asio::placeholders::error + ,asio::placeholders::bytes_transferred) + ); + } }; } /* http */ From 051e1f3350c3e6f8ef2c371824008e66ff204c23 Mon Sep 17 00:00:00 2001 From: "U-OFFICE\\g-zhivotnikov" Date: Mon, 15 Oct 2012 16:55:19 +0400 Subject: [PATCH 4/9] v-kir: 1861: leak fixed --- boost/network/protocol/http/server/async_connection.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boost/network/protocol/http/server/async_connection.hpp b/boost/network/protocol/http/server/async_connection.hpp index c400541bc..4d43ff4d9 100644 --- a/boost/network/protocol/http/server/async_connection.hpp +++ b/boost/network/protocol/http/server/async_connection.hpp @@ -587,10 +587,10 @@ namespace boost { namespace network { namespace http { while (start != end) { thread_pool().post(*start++); } - pending_actions_list().swap(pending_actions); } else { error_encountered = in_place(ec); } + pending_actions_list().swap(pending_actions); } void handle_write( From 0909c7dac20872aaf4b9f437cf4e93d6351c4c29 Mon Sep 17 00:00:00 2001 From: v-shmelev Date: Tue, 22 Jan 2013 17:29:22 +0400 Subject: [PATCH 5/9] =?UTF-8?q?=D0=A3=D0=B2=D0=B5=D0=BB=D0=B8=D1=87=D0=B5?= =?UTF-8?q?=D0=BD=20=D1=80=D0=B0=D0=B7=D0=BC=D0=B5=D1=80=20=D0=BE=D1=82?= =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D1=8F=D1=8E=D1=89=D0=B5=D0=B3?= =?UTF-8?q?=D0=BE=20=D0=B1=D1=83=D1=84=D0=B5=D1=80=D0=B0=20=D0=B2=D0=BE=20?= =?UTF-8?q?=D0=B8=D0=B7=D0=B1=D0=B5=D0=B6=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=BF?= =?UTF-8?q?=D0=BE=D1=82=D0=B5=D1=80=D1=8C=20=D0=BF=D1=80=D0=B8=20=D0=BE?= =?UTF-8?q?=D1=82=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B5=20=D0=B1=D0=BE=D0=BB?= =?UTF-8?q?=D1=8C=D1=88=D0=B8=D1=85=20=D0=BF=D0=BE=D1=82=D0=BE=D0=BA=D0=BE?= =?UTF-8?q?=D0=B2=20=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- boost/network/protocol/http/server/async_connection.hpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/boost/network/protocol/http/server/async_connection.hpp b/boost/network/protocol/http/server/async_connection.hpp index 8ff34b7ff..e68dd515e 100644 --- a/boost/network/protocol/http/server/async_connection.hpp +++ b/boost/network/protocol/http/server/async_connection.hpp @@ -308,6 +308,12 @@ namespace boost { namespace network { namespace http { }; void start() { + static const size_t buffer_size = 1048576; + + boost::system::error_code ec; + boost::asio::socket_base::receive_buffer_size option(buffer_size); + socket_.set_option(option, ec); + typename ostringstream::type ip_stream; ip_stream << socket_.remote_endpoint().address().to_v4().to_string() << ':' << socket_.remote_endpoint().port(); From 76f76fec43802dc230702ab3508947208c1b53e8 Mon Sep 17 00:00:00 2001 From: v-shmelev Date: Tue, 22 Jan 2013 18:25:28 +0400 Subject: [PATCH 6/9] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=BE=20=D0=BD=D0=B5=D0=BA=D0=BE=D1=80=D1=80=D0=B5?= =?UTF-8?q?=D0=BA=D1=82=D0=BD=D0=BE=D0=B5=20=D0=BF=D0=BE=D0=B2=D0=B5=D0=B4?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BF=D0=BE=D0=B4=20Windows=20XP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../protocol/http/server/async_server.hpp | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/boost/network/protocol/http/server/async_server.hpp b/boost/network/protocol/http/server/async_server.hpp index 74628cdea..a2c1b0d73 100644 --- a/boost/network/protocol/http/server/async_server.hpp +++ b/boost/network/protocol/http/server/async_server.hpp @@ -11,7 +11,7 @@ #include namespace boost { namespace network { namespace http { - + template struct async_server_base { typedef basic_request request; @@ -30,6 +30,8 @@ namespace boost { namespace network { namespace http { , io_service() , acceptor(io_service) , stopping(false) + , socket_exception(false) + { using boost::asio::ip::tcp; tcp::resolver resolver(io_service); @@ -49,6 +51,11 @@ namespace boost { namespace network { namespace http { } void run() { + if (socket_exception) + { + boost::system::error_code ec; + acceptor.open(boost::asio::ip::tcp::v4(), ec); + } io_service.run(); }; @@ -56,7 +63,18 @@ namespace boost { namespace network { namespace http { // stop accepting new requests and let all the existing // handlers finish. stopping = true; - acceptor.cancel(); + + if (!socket_exception) + { + try + { acceptor.cancel(); } + catch(...) + { socket_exception = true; } + } + + boost::system::error_code ec; + if (socket_exception) + acceptor.close(ec); } private: @@ -66,6 +84,7 @@ namespace boost { namespace network { namespace http { asio::ip::tcp::acceptor acceptor; bool stopping; connection_ptr new_connection; + bool socket_exception; void handle_accept(boost::system::error_code const & ec) { if (!ec) { From 984161c076da4bbd4cb516f62cb6421ed24edbfb Mon Sep 17 00:00:00 2001 From: v-shmelev Date: Thu, 21 Feb 2013 14:55:23 +0400 Subject: [PATCH 7/9] Aborted connections didn't notify their clients --- .../protocol/http/server/async_connection.hpp | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/boost/network/protocol/http/server/async_connection.hpp b/boost/network/protocol/http/server/async_connection.hpp index cf9e5932f..fd9c69c3c 100644 --- a/boost/network/protocol/http/server/async_connection.hpp +++ b/boost/network/protocol/http/server/async_connection.hpp @@ -584,17 +584,16 @@ namespace boost { namespace network { namespace http { void handle_write_headers(boost::function callback, boost::system::error_code const & ec, std::size_t bytes_transferred) { lock_guard lock(headers_mutex); - if (!ec) { - headers_buffer.consume(headers_buffer.size()); - headers_already_sent = true; - thread_pool().post(callback); - pending_actions_list::iterator start = pending_actions.begin() - , end = pending_actions.end(); - while (start != end) { - thread_pool().post(*start++); - } - } else { + if(ec) error_encountered = in_place(ec); + + headers_buffer.consume(headers_buffer.size()); + headers_already_sent = true; + thread_pool().post(callback); + pending_actions_list::iterator start = pending_actions.begin() + , end = pending_actions.end(); + while (start != end) { + thread_pool().post(*start++); } pending_actions_list().swap(pending_actions); } @@ -669,8 +668,11 @@ namespace boost { namespace network { namespace http { ,shared_buffers buffers) { lock_guard lock(headers_mutex); - if (error_encountered) - boost::throw_exception(boost::system::system_error(*error_encountered)); + if(error_encountered) + { + callback(error_encountered->code()); + return; + } boost::function callback_function = callback; From 86ae5b583df6c5062f33cf1ed85ed798cac9706d Mon Sep 17 00:00:00 2001 From: v-kir Date: Wed, 27 Feb 2013 10:33:32 +0400 Subject: [PATCH 8/9] =?UTF-8?q?=D0=A3=D0=B2=D0=B5=D0=B4=D0=BE=D0=BC=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BE=D0=B1=20=D0=BE=D1=88=D0=B8?= =?UTF-8?q?=D0=B1=D0=BA=D0=B5=20=D0=B4=D0=BE=D0=BB=D0=B6=D0=BD=D0=BE=20?= =?UTF-8?q?=D0=B1=D1=8B=D1=82=D1=8C=20=D0=B0=D1=81=D0=B8=D0=BD=D1=85=D1=80?= =?UTF-8?q?=D0=BE=D0=BD=D0=BD=D1=8B=D0=BC.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- boost/network/protocol/http/server/async_connection.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boost/network/protocol/http/server/async_connection.hpp b/boost/network/protocol/http/server/async_connection.hpp index fd9c69c3c..334a8e772 100644 --- a/boost/network/protocol/http/server/async_connection.hpp +++ b/boost/network/protocol/http/server/async_connection.hpp @@ -670,7 +670,7 @@ namespace boost { namespace network { namespace http { lock_guard lock(headers_mutex); if(error_encountered) { - callback(error_encountered->code()); + thread_pool().post(boost::bind(callback, error_encountered->code())); return; } From 073588742ec251a00f4e74c4de90e800cb3e9250 Mon Sep 17 00:00:00 2001 From: gzh Date: Wed, 17 Apr 2013 11:53:13 +0300 Subject: [PATCH 9/9] Compatibility with new ASIO --- boost/network/protocol/http/impl/http_sync_connection.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boost/network/protocol/http/impl/http_sync_connection.hpp b/boost/network/protocol/http/impl/http_sync_connection.hpp index 885c33f78..48a86206e 100644 --- a/boost/network/protocol/http/impl/http_sync_connection.hpp +++ b/boost/network/protocol/http/impl/http_sync_connection.hpp @@ -24,7 +24,7 @@ namespace boost { namespace network { namespace http { namespace impl { typedef sync_connection_base_impl connection_base; http_sync_connection(resolver_type & resolver, resolver_function_type resolve) - : connection_base(), resolver_(resolver), resolve_(resolve), socket_(resolver.io_service()) { } + : connection_base(), resolver_(resolver), resolve_(resolve), socket_(resolver.get_io_service()) { } void init_socket(string_type const & hostname, string_type const & port) { connection_base::init_socket(socket_, resolver_, hostname, port, resolve_);