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

Commit96084b8

Browse files
committed
Merge branch '0.7-devel' of github.com:mikhailberis/cpp-netlib
2 parentsf068c5c +abc6f01 commit96084b8

File tree

1 file changed

+323
-0
lines changed

1 file changed

+323
-0
lines changed
Lines changed: 323 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,323 @@
1+
#ifndef BOOST_NETWORK_PROTOCOL_HTTP_IMPL_HTTP_ASYNC_PROTOCOL_HANDLER_HPP_20101015
2+
#defineBOOST_NETWORK_PROTOCOL_HTTP_IMPL_HTTP_ASYNC_PROTOCOL_HANDLER_HPP_20101015
3+
4+
// Copyright 2010 (C) 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+
namespaceboost {namespacenetwork {namespacehttp {namespaceimpl {
10+
11+
template<classTag,unsigned version_major,unsigned version_minor>
12+
structhttp_async_protocol_handler {
13+
protected:
14+
15+
typedeftypename string<Tag>::type string_type;
16+
17+
template<classResponseType>
18+
voidinit_response(ResponseType & response_,bool get_body) {
19+
boost::shared_future<string_type>source_future(source_promise.get_future());
20+
source(response_, source_future);
21+
boost::shared_future<string_type>destination_future(destination_promise.get_future());
22+
destination(response_, destination_future);
23+
boost::shared_future<typename headers_container<Tag>::type>headers_future(headers_promise.get_future());
24+
headers(response_, headers_future);
25+
boost::shared_future<string_type>body_future(body_promise.get_future());
26+
body(response_, body_future);
27+
boost::shared_future<string_type>version_future(version_promise.get_future());
28+
version(response_, version_future);
29+
boost::shared_future<boost::uint16_t>status_future(status_promise.get_future());
30+
status(response_, status_future);
31+
boost::shared_future<string_type>status_message_future(status_message_promise.get_future());
32+
status_message(response_, status_message_future);
33+
}
34+
35+
structto_http_headers {
36+
typedeftypename string<Tag>::type string_type;
37+
template<classU>
38+
string_typeconstoperator() (Uconst & pair)const {
39+
typedeftypename ostringstream<Tag>::type ostringstream_type;
40+
typedef constants<Tag> constants;
41+
ostringstream_type header_line;
42+
header_line << pair.first
43+
<<constants::colon()
44+
<<constants::space()
45+
<< pair.second
46+
<<constants::crlf();
47+
return header_line.str();
48+
}
49+
};
50+
51+
template<classRequestType>
52+
string_typeinit_command_stream(RequestTypeconst & request, string_typeconst & method) {
53+
typename ostringstream<Tag>::type command_stream;
54+
string_type path_str;
55+
path_str =path(request);
56+
typedef constants<Tag> constants;
57+
command_stream
58+
<< method <<constants::space()
59+
<< path_str <<constants::space()
60+
<<constants::http_slash() << version_major
61+
<<constants::dot() << version_minor
62+
<<constants::crlf();
63+
64+
typedeftypename headers_range<RequestType>::type headers_range_type;
65+
headers_range_type headers_ =headers(request);
66+
boost::range::transform(
67+
headers_,
68+
typename ostream_iterator<Tag, string_type>::type (command_stream),
69+
to_http_headers());
70+
71+
if (boost::empty(headers(request)[constants::host()])) {
72+
string_type host_str =host(request);
73+
command_stream
74+
<<constants::host() <<constants::colon() <<constants::space() << host_str <<constants::crlf();
75+
}
76+
77+
if (boost::empty(headers(request)[constants::accept()])) {
78+
command_stream
79+
<<constants::accept() <<constants::colon() <<constants::space() <<constants::default_accept_mime() <<constants::crlf();
80+
}
81+
82+
if (version_major ==1u && version_minor ==1u &&boost::empty(headers(request)[constants::accept_encoding()])) {
83+
command_stream
84+
<<constants::accept_encoding() <<constants::colon() <<constants::space() <<constants::default_accept_encoding() <<constants::crlf();
85+
}
86+
87+
if (boost::empty(headers(request)[constants::user_agent()])) {
88+
command_stream
89+
<<constants::user_agent() <<constants::colon() <<constants::space() <<constants::cpp_netlib_slash() << BOOST_NETLIB_VERSION <<constants::crlf();
90+
}
91+
92+
command_stream <<constants::crlf();
93+
94+
return command_stream.str();
95+
}
96+
97+
template<classSocket,classCallback>
98+
logic::triboolparse_version(Socket & socket_, Callback callback) {
99+
logic::tribool parsed_ok;
100+
typename boost::iterator_range<typename buffer_type::const_iterator> result_range;
101+
fusion::tie(parsed_ok, result_range) = response_parser_.parse_until(
102+
response_parser_type::http_version_done,
103+
part);
104+
if (parsed_ok ==true) {
105+
string_type version;
106+
std::swap(version, partial_parsed);
107+
version.append(boost::begin(result_range),boost::end(result_range));
108+
algorithm::trim(version);
109+
version_promise.set_value(version);
110+
part_begin =boost::end(result_range);
111+
}elseif (parsed_ok ==false) {
112+
std::runtime_errorerror("Invalid Version Part.");
113+
version_promise.set_exception(boost::copy_exception(error));
114+
status_promise.set_exception(boost::copy_exception(error));
115+
status_message_promise.set_exception(boost::copy_exception(error));
116+
headers_promise.set_exception(boost::copy_exception(error));
117+
source_promise.set_exception(boost::copy_exception(error));
118+
destination_promise.set_exception(boost::copy_exception(error));
119+
body_promise.set_exception(boost::copy_exception(error));
120+
}else {
121+
partial_parsed.append(
122+
boost::begin(result_range),
123+
boost::end(result_range)
124+
);
125+
part_begin = part.begin();
126+
boost::asio::async_read(
127+
socket_,
128+
boost::asio::mutable_buffers_1(part.c_array(), part.size()),
129+
callback
130+
);
131+
}
132+
return parsed_ok;
133+
}
134+
135+
template<classSocket,classCallback>
136+
logic::triboolparse_status(Socket & socket_, Callback callback) {
137+
logic::tribool parsed_ok;
138+
typename buffer_type::const_iterator part_end = part.end();
139+
typename boost::iterator_range<typename buffer_type::const_iterator> result_range,
140+
input_range =boost::make_iterator_range(part_begin, part_end);
141+
fusion::tie(parsed_ok, result_range) = response_parser_.parse_until(
142+
response_parser_type::http_status_done,
143+
input_range);
144+
if (parsed_ok ==true) {
145+
string_type status;
146+
std::swap(status, partial_parsed);
147+
status.append(boost::begin(result_range),boost::end(result_range));
148+
trim(status);
149+
boost::uint16_t status_int = lexical_cast<boost::uint16_t>(status);
150+
status_promise.set_value(status_int);
151+
part_begin =boost::end(result_range);
152+
}elseif (parsed_ok ==false) {
153+
std::runtime_errorerror("Invalid status part.");
154+
status_promise.set_exception(boost::copy_exception(error));
155+
status_message_promise.set_exception(boost::copy_exception(error));
156+
headers_promise.set_exception(boost::copy_exception(error));
157+
source_promise.set_exception(boost::copy_exception(error));
158+
destination_promise.set_exception(boost::copy_exception(error));
159+
body_promise.set_exception(boost::copy_exception(error));
160+
}else {
161+
partial_parsed.append(
162+
boost::begin(result_range),
163+
boost::end(result_range)
164+
);
165+
part_begin = part.begin();
166+
boost::asio::async_read(socket_,
167+
boost::asio::mutable_buffers_1(part.c_array(), part.size()),
168+
callback
169+
);
170+
}
171+
return parsed_ok;
172+
}
173+
174+
template<classSocket,classCallback>
175+
logic::triboolparse_status_message(Socket & socket_, Callback callback) {
176+
logic::tribool parsed_ok;
177+
typename buffer_type::const_iterator part_end = part.end();
178+
typename boost::iterator_range<typename buffer_type::const_iterator> result_range,
179+
input_range =boost::make_iterator_range(part_begin, part_end);
180+
fusion::tie(parsed_ok, result_range) = response_parser_.parse_until(
181+
response_parser_type::http_status_message_done,
182+
input_range);
183+
if (parsed_ok ==true) {
184+
string_type status_message;
185+
std::swap(status_message, partial_parsed);
186+
status_message.append(boost::begin(result_range),boost::end(result_range));
187+
algorithm::trim(status_message);
188+
status_message_promise.set_value(status_message);
189+
part_begin =boost::end(result_range);
190+
}elseif (parsed_ok ==false) {
191+
std::runtime_errorerror("Invalid status message part.");
192+
status_message_promise.set_exception(boost::copy_exception(error));
193+
headers_promise.set_exception(boost::copy_exception(error));
194+
source_promise.set_exception(boost::copy_exception(error));
195+
destination_promise.set_exception(boost::copy_exception(error));
196+
body_promise.set_exception(boost::copy_exception(error));
197+
}else {
198+
partial_parsed.append(
199+
boost::begin(result_range),
200+
boost::end(result_range));
201+
part_begin = part.begin();
202+
boost::asio::async_read(
203+
socket_,
204+
boost::asio::mutable_buffers_1(part.c_array(), part.size()),
205+
callback
206+
);
207+
}
208+
return parsed_ok;
209+
}
210+
211+
voidparse_headers_real(string_type & headers_part) {
212+
typename boost::iterator_range<typename string_type::const_iterator>
213+
input_range =boost::make_iterator_range(headers_part)
214+
, result_range;
215+
logic::tribool parsed_ok;
216+
response_parser_typeheaders_parser(response_parser_type::http_header_line_done);
217+
typename headers_container<Tag>::type headers;
218+
std::pair<string_type,string_type> header_pair;
219+
while (!boost::empty(input_range)) {
220+
fusion::tie(parsed_ok, result_range) = headers_parser.parse_until(
221+
response_parser_type::http_header_colon
222+
, input_range);
223+
if (headers_parser.state() != response_parser_type::http_header_colon)break;
224+
header_pair.first =string_type(
225+
boost::begin(result_range),
226+
boost::end(result_range));
227+
input_range.advance_begin(boost::distance(result_range));
228+
fusion::tie(parsed_ok, result_range) = headers_parser.parse_until(
229+
response_parser_type::http_header_line_done
230+
, input_range);
231+
header_pair.second =string_type(
232+
boost::begin(result_range),
233+
boost::end(result_range));
234+
input_range.advance_begin(boost::distance(result_range));
235+
236+
trim(header_pair.first);
237+
if (header_pair.first.size() >1) {
238+
header_pair.first.erase(
239+
header_pair.first.size() -1
240+
);
241+
}
242+
trim(header_pair.second);
243+
headers.insert(header_pair);
244+
}
245+
headers_promise.set_value(headers);
246+
}
247+
248+
template<classSocket,classCallback>
249+
fusion::tuple<logic::tribool,size_t>parse_headers(Socket & socket_, Callback callback) {
250+
logic::tribool parsed_ok;
251+
typename buffer_type::const_iterator part_end = part.end();
252+
typename boost::iterator_range<typename buffer_type::const_iterator> result_range,
253+
input_range =boost::make_iterator_range(part_begin, part_end);
254+
fusion::tie(parsed_ok, result_range) = response_parser_.parse_until(
255+
response_parser_type::http_headers_done,
256+
input_range);
257+
if (parsed_ok ==true) {
258+
string_type headers_string;
259+
std::swap(headers_string, partial_parsed);
260+
headers_string.append(boost::begin(result_range),boost::end(result_range));
261+
part_begin =boost::end(result_range);
262+
this->parse_headers_real(headers_string);
263+
}elseif (parsed_ok ==false) {
264+
std::runtime_errorerror("Invalid header part.");
265+
headers_promise.set_exception(boost::copy_exception(error));
266+
body_promise.set_exception(boost::copy_exception(error));
267+
source_promise.set_exception(boost::copy_exception(error));
268+
destination_promise.set_exception(boost::copy_exception(error));
269+
}else {
270+
partial_parsed.append(boost::begin(result_range),boost::end(result_range));
271+
part_begin = part.begin();
272+
boost::asio::async_read(
273+
socket_,
274+
boost::asio::mutable_buffers_1(part.c_array(), part.size()),
275+
callback
276+
);
277+
}
278+
returnfusion::make_tuple(
279+
parsed_ok,
280+
std::distance(
281+
boost::end(result_range)
282+
, part_end
283+
)
284+
);
285+
}
286+
287+
template<classSocket,classCallback>
288+
voidparse_body(Socket & socket_, Callback callback,size_t bytes) {
289+
partial_parsed.append(part_begin, bytes);
290+
part_begin = part.begin();
291+
boost::asio::async_read(
292+
socket_,
293+
boost::asio::mutable_buffers_1(part.c_array(), part.size()),
294+
callback
295+
);
296+
}
297+
298+
typedef response_parser<Tag> response_parser_type;
299+
typedef boost::array<typename char_<Tag>::type,1024> buffer_type;
300+
301+
response_parser_type response_parser_;
302+
boost::promise<string_type> version_promise;
303+
boost::promise<boost::uint16_t> status_promise;
304+
boost::promise<string_type> status_message_promise;
305+
boost::promise<typename headers_container<Tag>::type> headers_promise;
306+
boost::promise<string_type> source_promise;
307+
boost::promise<string_type> destination_promise;
308+
boost::promise<string_type> body_promise;
309+
buffer_type part;
310+
typename buffer_type::const_iterator part_begin;
311+
string_type partial_parsed;
312+
};
313+
314+
315+
}/* impl*/
316+
317+
}/* http*/
318+
319+
}/* network*/
320+
321+
}/* boost*/
322+
323+
#endif/* BOOST_NETWORK_PROTOCOL_HTTP_IMPL_HTTP_ASYNC_PROTOCOL_HANDLER_HPP_20101015*/

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp