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

Lines changed: 6 additions & 3 deletions
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
Lines changed: 72 additions & 0 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy