Skip to content

Commit 9ada74a

Browse files
committed
merged upstream/0.8-devel
2 parents df6fd24 + 6e3770e commit 9ada74a

File tree

4 files changed

+94
-5
lines changed

4 files changed

+94
-5
lines changed

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

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <boost/utility/typed_in_place_factory.hpp>
2626
#include <boost/thread/locks.hpp>
2727
#include <boost/thread/recursive_mutex.hpp>
28+
#include <boost/utility/enable_if.hpp>
2829
#include <list>
2930
#include <vector>
3031
#include <iterator>
@@ -36,6 +37,10 @@
3637
* This is the maximum size though and Boost.Asio's internal representation
3738
* of a streambuf would make appropriate decisions on how big a buffer
3839
* is to begin with.
40+
*
41+
* This kinda assumes that a page is by default 4096. Since we're using
42+
* the default allocator with the static buffers, it's not guaranteed that
43+
* the static buffers will be page-aligned when they are allocated.
3944
*/
4045
#define BOOST_NETWORK_HTTP_SERVER_CONNECTION_HEADER_BUFFER_MAX_SIZE 4096
4146
#endif /* BOOST_NETWORK_HTTP_SERVER_CONNECTION_HEADER_BUFFER_MAX_SIZE */
@@ -209,14 +214,16 @@ namespace boost { namespace network { namespace http {
209214
}
210215

211216
template <class Range, class Callback>
212-
void write(Range const & range, Callback const & callback) {
217+
typename disable_if<is_base_of<asio::const_buffer, typename Range::value_type>, void>::type
218+
write(Range const & range, Callback const & callback) {
213219
lock_guard lock(headers_mutex);
214220
if (error_encountered) boost::throw_exception(boost::system::system_error(*error_encountered));
215221
write_impl(boost::make_iterator_range(range), callback);
216222
}
217223

218224
template <class ConstBufferSeq, class Callback>
219-
void write_vec(ConstBufferSeq const & seq, Callback const & callback)
225+
typename enable_if<is_base_of<asio::const_buffer, typename ConstBufferSeq::value_type>, void>::type
226+
write(ConstBufferSeq const & seq, Callback const & callback)
220227
{
221228
write_vec_impl(seq, callback, shared_array_list(), shared_buffers());
222229
}
@@ -659,10 +666,13 @@ namespace boost { namespace network { namespace http {
659666
if (error_encountered)
660667
boost::throw_exception(boost::system::system_error(*error_encountered));
661668

669+
boost::function<void(boost::system::error_code)> callback_function =
670+
callback;
671+
662672
boost::function<void()> continuation = boost::bind(
663-
&async_connection<Tag,Handler>::write_vec_impl<ConstBufferSeq, Callback>
673+
&async_connection<Tag,Handler>::template write_vec_impl<ConstBufferSeq, boost::function<void(boost::system::error_code)> >
664674
,async_connection<Tag,Handler>::shared_from_this()
665-
,seq, callback, temporaries, buffers
675+
,seq, callback_function, temporaries, buffers
666676
);
667677

668678
if (!headers_already_sent && !headers_in_progress) {
@@ -679,7 +689,7 @@ namespace boost { namespace network { namespace http {
679689
,boost::bind(
680690
&async_connection<Tag,Handler>::handle_write
681691
,async_connection<Tag,Handler>::shared_from_this()
682-
,callback
692+
,callback_function
683693
,temporaries
684694
,buffers
685695
,asio::placeholders::error

libs/network/example/http/fileserver.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,11 @@ struct file_cache {
4747
boost::upgrade_lock<boost::shared_mutex> lock(cache_mutex);
4848
std::string real_filename = doc_root_+path;
4949
if (regions.find(real_filename) != regions.end()) return true;
50+
#ifdef O_NOATIME
5051
int fd = open(real_filename.c_str(), O_RDONLY|O_NOATIME|O_NONBLOCK);
52+
#else
53+
int fd = open(real_filename.c_str(), O_RDONLY|O_NONBLOCK);
54+
#endif
5155
if (fd == -1) return false;
5256
std::size_t size = lseek(fd, 0, SEEK_END);
5357
void * region = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0);

libs/network/test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ if (Boost_FOUND)
4747
set(SERVER_TESTS
4848
hello_world
4949
http_async_server
50+
http_server_async_less_copy
5051
)
5152
foreach (test ${SERVER_TESTS})
5253
set_source_files_properties(${test}.cpp
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
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 <vector>
10+
11+
#include <boost/config/warning_disable.hpp>
12+
#include <boost/network/include/http/server.hpp>
13+
#include <boost/network/utils/thread_pool.hpp>
14+
#include <boost/range/algorithm/find_if.hpp>
15+
16+
namespace net = boost::network;
17+
namespace http = boost::network::http;
18+
namespace utils = boost::network::utils;
19+
20+
struct async_hello_world;
21+
typedef http::async_server<async_hello_world> server;
22+
23+
struct async_hello_world {
24+
25+
struct is_content_length {
26+
template <class Header>
27+
bool operator()(Header const & header) {
28+
return boost::iequals(header.name, "content-length");
29+
}
30+
};
31+
32+
void operator()(server::request const & request, server::connection_ptr connection) {
33+
static server::response_header headers[] = {
34+
{"Connection", "close"}
35+
, {"Content-Type", "text/plain"}
36+
, {"Server", "cpp-netlib/0.9-devel"}
37+
};
38+
if (request.method == "HEAD") {
39+
connection->set_status(server::connection::ok);
40+
connection->set_headers(boost::make_iterator_range(headers, headers+3));
41+
} else {
42+
if (request.method == "PUT" || request.method == "POST") {
43+
static std::string bad_request("Bad Request.");
44+
server::request::headers_container_type::iterator found =
45+
boost::find_if(request.headers, is_content_length());
46+
if (found == request.headers.end()) {
47+
connection->set_status(server::connection::bad_request);
48+
connection->set_headers(boost::make_iterator_range(headers, headers+3));
49+
connection->write(bad_request);
50+
return;
51+
}
52+
}
53+
static char const * hello_world = "Hello, World!";
54+
connection->set_status(server::connection::ok);
55+
connection->set_headers(boost::make_iterator_range(headers, headers+3));
56+
std::vector<boost::asio::const_buffer> iovec;
57+
iovec.push_back(boost::asio::const_buffer(hello_world, 13));
58+
connection->write(iovec, boost::bind(&async_hello_world::error, this, _1));
59+
}
60+
}
61+
62+
void error(boost::system::error_code const & ec) {
63+
// do nothing here.
64+
}
65+
};
66+
67+
int main(int argc, char * argv[]) {
68+
utils::thread_pool thread_pool(2);
69+
async_hello_world handler;
70+
server instance("127.0.0.1", "8000", handler, thread_pool);
71+
instance.run();
72+
return 0;
73+
}
74+

0 commit comments

Comments
 (0)