Skip to content

Commit 794a0b9

Browse files
committed
Test for Less Copy Connection Write
This commit basically is a test for the case where the range passed to the call to connection::write is actually a Boost.Asio const_buffer derivative. This removes the requirement to make copies of the range passed into the call to connection::write. This is a backward-compatible change which means code that used to work with the range-based solution will still be supported while Boost.Asio const_buffer derivatives passed in will be supported as first-class elements that get used be the implementation directly. Note: Boost.Asio const_buffers explicitly do not own the memory that has been wrapped to it. Care should be taken when passing in Boost.Asio const_buffer sequences into the connection::write interface to make sure that the data is still accessible until at least the provided callback is provided. Note: Backported from 0.9-devel into 0.8-devel.
1 parent 6e4253c commit 794a0b9

File tree

2 files changed

+78
-3
lines changed

2 files changed

+78
-3
lines changed

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

+6-3
Original file line numberDiff line numberDiff line change
@@ -666,10 +666,13 @@ namespace boost { namespace network { namespace http {
666666
if (error_encountered)
667667
boost::throw_exception(boost::system::system_error(*error_encountered));
668668

669+
boost::function<void(boost::system::error_code)> callback_function =
670+
callback;
671+
669672
boost::function<void()> continuation = boost::bind(
670-
&async_connection<Tag,Handler>::write_vec_impl<ConstBufferSeq, Callback>
673+
&async_connection<Tag,Handler>::write_vec_impl<ConstBufferSeq, boost::function<void(boost::system::error_code)> >
671674
,async_connection<Tag,Handler>::shared_from_this()
672-
,seq, callback, temporaries, buffers
675+
,seq, callback_function, temporaries, buffers
673676
);
674677

675678
if (!headers_already_sent && !headers_in_progress) {
@@ -686,7 +689,7 @@ namespace boost { namespace network { namespace http {
686689
,boost::bind(
687690
&async_connection<Tag,Handler>::handle_write
688691
,async_connection<Tag,Handler>::shared_from_this()
689-
,callback
692+
,callback_function
690693
,temporaries
691694
,buffers
692695
,asio::placeholders::error
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
2+
// Copyright 2010 Dean Michael Berris.
3+
// Distributed under the Boost Software License, Version 1.0.
4+
// (See accompanying file LICENSE_1_0.txt or copy at
5+
// http://www.boost.org/LICENSE_1_0.txt)
6+
7+
#define BOOST_TEST_MODULE HTTP Asynchronous Server Tests
8+
9+
#include <boost/config/warning_disable.hpp>
10+
#include <boost/network/include/http/server.hpp>
11+
#include <boost/network/utils/thread_pool.hpp>
12+
#include <boost/range/algorithm/find_if.hpp>
13+
14+
namespace net = boost::network;
15+
namespace http = boost::network::http;
16+
namespace utils = boost::network::utils;
17+
18+
struct async_hello_world;
19+
typedef http::async_server<async_hello_world> server;
20+
21+
struct async_hello_world {
22+
23+
struct is_content_length {
24+
template <class Header>
25+
bool operator()(Header const & header) {
26+
return boost::iequals(name(header), "content-length");
27+
}
28+
};
29+
30+
void operator()(server::request const & request, server::connection_ptr connection) {
31+
static server::response_header headers[] = {
32+
{"Connection", "close"}
33+
, {"Content-Type", "text/plain"}
34+
, {"Server", "cpp-netlib/0.9-devel"}
35+
};
36+
if (request.method == "HEAD") {
37+
connection->set_status(server::connection::ok);
38+
connection->set_headers(boost::make_iterator_range(headers, headers+3));
39+
} else {
40+
if (request.method == "PUT" || request.method == "POST") {
41+
static std::string bad_request("Bad Request.");
42+
server::request::headers_container_type::iterator found =
43+
boost::find_if(request.headers, is_content_length());
44+
if (found == request.headers.end()) {
45+
connection->set_status(server::connection::bad_request);
46+
connection->set_headers(boost::make_iterator_range(headers, headers+3));
47+
connection->write(bad_request);
48+
return;
49+
}
50+
}
51+
static char const * hello_world = "Hello, World!";
52+
connection->set_status(server::connection::ok);
53+
connection->set_headers(boost::make_iterator_range(headers, headers+3));
54+
connection->write(
55+
boost::asio::const_buffers_1(hello_world, 13)
56+
, boost::bind(&async_hello_world::error, this, _1));
57+
}
58+
}
59+
60+
void error(boost::system::error_code const & ec) {
61+
// do nothing here.
62+
}
63+
};
64+
65+
int main(int argc, char * argv[]) {
66+
utils::thread_pool thread_pool(2);
67+
async_hello_world handler;
68+
server instance("127.0.0.1", "8000", handler, thread_pool, http::_reuse_address=true);
69+
instance.run();
70+
return 0;
71+
}
72+

0 commit comments

Comments
 (0)