Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitbb76f2c

Browse files
committed
Adding more to the asynchronous server implementation.
1 parent961f68d commitbb76f2c

File tree

14 files changed

+372
-32
lines changed

14 files changed

+372
-32
lines changed
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#ifndef BOOST_NETWORK_PROTOCOL_HTTP_ALGORITHMS_LINEARIZE_HPP_20101028
2+
#defineBOOST_NETWORK_PROTOCOL_HTTP_ALGORITHMS_LINEARIZE_HPP_20101028
3+
4+
// Copyright 2010 Dean Michael Berris.
5+
// Distributed under the Boost Software License, Version 1.0.
6+
// (See accompanying file LICENSE_1_0.txt or copy at
7+
// http://www.boost.org/LICENSE_1_0.txt)
8+
9+
#include<boost/network/protocol/http/server/header/name.hpp>
10+
#include<boost/network/protocol/http/server/header/value.hpp>
11+
#include<boost/network/protocol/http/server/header/concept.hpp>
12+
#include<boost/network/constants.hpp>
13+
#include<boost/concept_check.hpp>
14+
15+
namespaceboost {namespacenetwork {namespacehttp {
16+
17+
template<classTag,classValueType>
18+
structlinearize {
19+
typedeftypename string<Tag>::type string_type;
20+
21+
template<classArguments>
22+
structresult {
23+
typedef string_type type;
24+
};
25+
26+
BOOST_CONCEPT_REQUIRES(
27+
(Header<ValueType),
28+
(string_type)
29+
)operator()(ValueType & header) {
30+
typedeftypename ostringstream<Tag>::type output_stream;
31+
typedef constants<Tag> consts;
32+
output_stream header_line;
33+
header_line <<name(header)
34+
<<consts::colon() <<consts::space()
35+
<<value(header) <<consts::crlf();
36+
return header_line.str();
37+
}
38+
};
39+
40+
}/* linearize*/
41+
42+
}/* net*/
43+
44+
}/* boost*/
45+
46+
#endif/* BOOST_NETWORK_PROTOCOL_HTTP_ALGORITHMS_LINEARIZE_HPP_20101028*/

‎boost/network/protocol/http/connection.hpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ namespace boost { namespace network { namespace http {
8686
if (done) {
8787
if (request_.method[0] =='P') {
8888
// look for the content-length header
89-
std::vector<request_header>::iterator it =
89+
typenamestd::vector<request_header<Tag>>::iterator it =
9090
find_if(
9191
request_.headers.begin(),
9292
request_.headers.end(),

‎boost/network/protocol/http/header.hpp‎

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// ~~~~~~~~~~
44
//
55
// Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6-
// Copyright (c) 2009 Dean Michael Berris (mikhailberis@gmail.com)
6+
// Copyright (c) 2009,2010 Dean Michael Berris (mikhailberis@gmail.com)
77
// Copyright (c) 2009 Tarroo, Inc.
88
//
99
// Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -13,20 +13,23 @@
1313
#ifndef HTTP_SERVER3_HEADER_HPP
1414
#defineHTTP_SERVER3_HEADER_HPP
1515

16-
#include<string>
16+
#include<boost/network/traits/string.hpp>
1717

1818
namespaceboost {namespacenetwork {namespacehttp {
1919

20-
structrequest_header
21-
{
22-
std::string name;
23-
std::string value;
24-
};
25-
26-
inlinevoidswap(request_header & l, request_header & r) {
27-
swap(l.name, r.name);
28-
swap(l.value, r.value);
29-
}
20+
template<classTag>
21+
structrequest_header
22+
{
23+
typedeftypename string<Tag>::type string_type;
24+
string_type name;
25+
std::string value;
26+
};
27+
28+
template<classTag>
29+
inlinevoidswap(request_header<Tag> & l, request_header<Tag> & r) {
30+
swap(l.name, r.name);
31+
swap(l.value, r.value);
32+
}
3033

3134
}// namespace http
3235

‎boost/network/protocol/http/impl/request.hpp‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ namespace boost { namespace network { namespace http {
120120
typedef Tag tag;
121121
typedeftypename string<Tag>::type string_type;
122122
typedeftypename vector<tags::http_server>::
123-
templateapply<request_header>::type
123+
templateapply<request_header<Tag>>::type
124124
vector_type;
125125
typedef vector_type headers_container_type;
126126
typedef boost::uint16_t port_type;
@@ -160,12 +160,12 @@ namespace boost { namespace network { namespace http {
160160
/** Specialize the traits for the http_server tag.*/
161161
template<>
162162
structheaders_container<http::tags::http_server> :
163-
vector<http::tags::http_server>::apply<http::request_header>
163+
vector<http::tags::http_server>::apply<http::request_header<http::tags::http_server>>
164164
{};
165165

166166
template<>
167167
structheaders_container<http::tags::http_async_server> :
168-
vector<http::tags::http_async_server>::apply<http::request_header>
168+
vector<http::tags::http_async_server>::apply<http::request_header<http::tags::http_async_server>>
169169
{};
170170

171171
namespacehttp {namespaceimpl {

‎boost/network/protocol/http/impl/request_parser.ipp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ boost::tribool basic_request_parser<Tag>::consume(basic_request<Tag> & req, char
207207
}
208208
else
209209
{
210-
req.headers.push_back(request_header());
210+
req.headers.push_back(request_header<Tag>());
211211
req.headers.back().name.push_back(input);
212212
state_ = header_name;
213213
return boost::indeterminate;

‎boost/network/protocol/http/impl/response.ipp‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ namespace boost { namespace network { namespace http {
5151
} status;
5252

5353
/// The headers to be included in the reply.
54-
typedef vector<tags::http_server>::apply<request_header>::type headers_vector;
54+
typedef vector<tags::http_server>::apply<request_header<tags::http_server>>::type headers_vector;
5555
headers_vector headers;
5656

5757
/// The content to be sent in the reply.
@@ -69,7 +69,7 @@ namespace boost { namespace network { namespace http {
6969
std::vector<const_buffer> buffers;
7070
buffers.push_back(to_buffer(status));
7171
for (std::size_t i =0; i < headers.size(); ++i) {
72-
request_header& h = headers[i];
72+
request_header<tags::http_server>& h = headers[i];
7373
buffers.push_back(buffer(h.name));
7474
buffers.push_back(buffer(name_value_separator));
7575
buffers.push_back(buffer(h.value));

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

Lines changed: 116 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,129 @@
66
// (See accompanying file LICENSE_1_0.txt or copy at
77
// http://www.boost.org/LICENSE_1_0.txt)
88

9+
#include<boost/throw_exception.hpp>
10+
#include<boost/scope_exit.hpp>
11+
#include<boost/network/protocol/http/algorithms/linearize.hpp>
12+
#include<boost/network/utils/thread_pool.hpp>
13+
#include<boost/range/algorithm/transform.hpp>
14+
#include<boost/asio/ip/tcp.hpp>
15+
#include<boost/asio/streambuf.hpp>
16+
#include<iterator>
17+
918
namespaceboost {namespacenetwork {namespacehttp {
1019

1120
template<classTag,classHandler>
12-
structasync_connection {
21+
structasync_connection: boost::enable_shared_from_this<async_connection<Tag,Handler> >{
1322
enumstatus_t {
1423
ok =200
15-
, method_not_supported =306
24+
, created =201
25+
, accepted =202
26+
, no_content =204
27+
, multiple_choices =300
28+
, moved_permanently =301
29+
, moved_temporarily =302
30+
, not_modified =304
31+
, bad_request =400
32+
, unauthorized =401
33+
, forbidden =403
34+
, not_found =404
35+
, not_supported =405
36+
, not_acceptable =406
37+
, internal_server_error =500
38+
, not_implemented =501
39+
, bad_gateway =502
40+
, service_unavailable =503
1641
};
42+
43+
async_connection(
44+
asio::io_service & io_service
45+
, Handler & handler
46+
, utils::thread_pool & thread_pool
47+
)
48+
: socket_(io_service)
49+
, handler(handler)
50+
, thread_pool_(thread_pool)
51+
, headers_already_set(false)
52+
{}
53+
54+
/** Function: template <class Range> set_headers(Range headers)
55+
* Precondition: headers have not been set yet
56+
* Postcondition: headers have been set, and cannot be modified anymore.
57+
* Throws: std::logic_error in case the headers have already been set
58+
* and the precondition is not satisfied.
59+
*
60+
* A call to set_headers takes a Range where each element models the
61+
* Header concept. This Range will be linearized onto a buffer, which is
62+
* then sent as soon as the first call to `write` or `flush` commences.
63+
*/
1764
template<classRange>
18-
voidset_headers(Range);
19-
voidset_status(status_t);
65+
voidset_headers(Range headers) {
66+
if (headers_already_set)
67+
boost::throw_exception(std::logic_error("Headers have already been set."));
68+
69+
bool commit =false;
70+
BOOST_SCOPE_EXIT_TPL((&commit)(&headers_already_set))
71+
{
72+
if (!commit) {
73+
headers_already_set =false;
74+
}
75+
} BOOST_SCOPE_EXIT_END
76+
77+
typedef constants<Tag> consts;
78+
79+
std::ostreamstream(&headers_buffer);
80+
if (!boost::empty(headers)) {
81+
typedeftypename Range::const_iterator iterator;
82+
typedeftypename Range::value_type value_type;
83+
typedeftypename string<Tag>::type string_type;
84+
boost::transform(headers,
85+
std::ostream_iterator<string_type>(stream),
86+
linearize<Tag, value_type>());
87+
}else {
88+
stream <<consts::crlf();
89+
}
90+
stream <<consts::crlf();
91+
commit = headers_already_set =true;
92+
}
93+
94+
voidset_status(status_t new_status) {
95+
status = new_status;
96+
}
97+
2098
template<classRange>
21-
voidwrite(Range);
22-
voidflush();
23-
voidclose();
99+
voidwrite(Range) {
100+
// linearize the range into a shared array
101+
// schedule a stranded asynchronous write
102+
}
103+
104+
voidflush() {
105+
// use this as a synchronization point to ensure
106+
// that data has been written; use a unique_future
107+
}
108+
109+
voidclose() {
110+
flush();
111+
socket_.shutdown(asio::ip::tcp::socket::shutdown_both);
112+
socket_.close();
113+
}
114+
115+
asio::ip::tcp::socket &socket() {return socket_; }
116+
utils::thread_pool &thread_pool() {return thread_pool_; }
117+
118+
private:
119+
asio::ip::tcp::socket socket_;
120+
Handler & handler;
121+
utils::thread_pool & thread_pool_;
122+
bool headers_already_set;
123+
asio::streambuf headers_buffer;
124+
boost::uint16_t status;
125+
126+
template<class,class>friendstructasync_server_base;
127+
128+
voidstart() {
129+
// FIXME do something!
130+
}
131+
24132
};
25133

26134
}/* http*/
@@ -30,3 +138,4 @@ namespace boost { namespace network { namespace http {
30138
}/* boost*/
31139

32140
#endif/* BOOST_NETWORK_PROTOCOL_HTTP_SERVER_CONNECTION_HPP_20101027*/
141+

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

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,67 @@ namespace boost { namespace network { namespace http {
2424
, string_typeconst & port
2525
, Handler & handler
2626
, utils::thread_pool & thread_pool)
27-
{}
27+
: handler(handler)
28+
, thread_pool(thread_pool)
29+
, io_service()
30+
, acceptor(io_service)
31+
, stopping(false)
32+
{
33+
using boost::asio::ip::tcp;
34+
tcp::resolverresolver(io_service);
35+
tcp::resolver::queryquery(address, port);
36+
tcp::endpoint endpoint = *resolver.resolve(query);
37+
acceptor.open(endpoint.protocol());
38+
acceptor.bind(endpoint);
39+
acceptor.listen();
40+
new_connection.reset(newconnection(io_service, handler, thread_pool));
41+
acceptor.async_accept(new_connection->socket(),
42+
boost::bind(
43+
&async_server_base<Tag,Handler>::handle_accept
44+
,this
45+
, boost::asio::placeholders::error));
46+
}
2847

29-
voidrun() {};
48+
voidrun() {
49+
io_service.run();
50+
};
3051

52+
voidstop() {
53+
// stop accepting new requests and let all the existing
54+
// handlers finish.
55+
stopping =true;
56+
acceptor.cancel();
57+
}
58+
59+
private:
60+
Handler & handler;
61+
utils::thread_pool & thread_pool;
62+
asio::io_service io_service;
63+
asio::ip::tcp::acceptor acceptor;
64+
bool stopping;
65+
boost::shared_ptr<async_connection<Tag,Handler> > new_connection;
66+
67+
voidhandle_accept(boost::system::error_codeconst & ec) {
68+
if (!ec) {
69+
new_connection->start();
70+
if (!stopping) {
71+
new_connection.reset(
72+
newconnection(
73+
io_service
74+
, handler
75+
, thread_pool
76+
)
77+
);
78+
acceptor.async_accept(new_connection->socket(),
79+
boost::bind(
80+
&async_server_base<Tag,Handler>::handle_accept
81+
,this
82+
, boost::asio::placeholders::error
83+
)
84+
);
85+
}
86+
}
87+
}
3188
};
3289

3390
}/* http*/

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp