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

Commitf0eaf48

Browse files
committed
Merge pull request#408 from leecoder/0.11-devel
Fixes#393: enhancing response incremental parser
2 parents7af6653 +80826f0 commitf0eaf48

File tree

3 files changed

+178
-21
lines changed

3 files changed

+178
-21
lines changed

‎boost/network/protocol/http/parser/incremental.hpp

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -168,26 +168,35 @@ namespace boost { namespace network { namespace http {
168168
}elseif (*current =='') {
169169
state_ = http_status_done;
170170
++current;
171+
}elseif (*current =='\r' || *current =='\n') {
172+
state_ = http_status_done;
171173
}else {
172174
parsed_ok =false;
173175
}
174176
break;
175177
case http_status_done:
176-
if (algorithm::is_alnum()(*current)) {
177-
state_ = http_status_message_char;
178+
if (*current =='') {
179+
++current;
180+
}elseif (*current =='\r') {
181+
state_ = http_status_message_cr;
182+
++current;
183+
}elseif (*current =='\n') {
184+
state_ = http_status_message_done;
178185
++current;
179186
}else {
180-
parsed_ok =false;
187+
state_ = http_status_message_char;
188+
++current;
181189
}
182190
break;
183191
case http_status_message_char:
184-
if (algorithm::is_alnum()(*current) ||algorithm::is_punct()(*current) || (*current =='')) {
185-
++current;
186-
}elseif (*current =='\r') {
192+
if (*current =='\r') {
187193
state_ = http_status_message_cr;
188194
++current;
195+
}elseif (*current =='\n') {
196+
state_ = http_status_message_done;
197+
++current;
189198
}else {
190-
parsed_ok =false;
199+
++current;
191200
}
192201
break;
193202
case http_status_message_cr:
@@ -200,12 +209,17 @@ namespace boost { namespace network { namespace http {
200209
break;
201210
case http_status_message_done:
202211
case http_header_line_done:
203-
if (algorithm::is_alnum()(*current)) {
212+
if (*current =='') {
213+
++current;
214+
}elseif (algorithm::is_alnum()(*current) ||algorithm::is_punct()(*current)) {
204215
state_ = http_header_name_char;
205216
++current;
206217
}elseif (*current =='\r') {
207218
state_ = http_headers_end_cr;
208219
++current;
220+
}elseif (*current =='\n') {
221+
state_ = http_headers_done;
222+
++current;
209223
}else {
210224
parsed_ok =false;
211225
}
@@ -221,21 +235,26 @@ namespace boost { namespace network { namespace http {
221235
}
222236
break;
223237
case http_header_colon:
224-
if (algorithm::is_space()(*current)) {
238+
if (*current =='\r') {
239+
state_ = http_header_line_cr;
225240
++current;
226-
}elseif (algorithm::is_alnum()(*current) ||algorithm::is_punct()(*current)) {
227-
state_ = http_header_value_char;
241+
}elseif (*current =='\n') {
242+
state_ = http_header_line_done;
243+
++current;
244+
}elseif (algorithm::is_space()(*current)) {
228245
++current;
229246
}else {
230-
parsed_ok =false;
247+
state_ = http_header_value_char;
248+
++current;
231249
}
232250
break;
233251
case http_header_value_char:
234252
if (*current =='\r') {
235253
state_ = http_header_line_cr;
236254
++current;
237-
}elseif (algorithm::is_cntrl()(*current)) {
238-
parsed_ok =false;
255+
}elseif (*current =='\n') {
256+
state_ = http_header_line_done;
257+
++current;
239258
}else {
240259
++current;
241260
}

‎libs/network/test/http/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ endif()
1313

1414
if (Boost_FOUND)
1515
set (TESTS
16+
response_incremental_parser_test
1617
request_incremental_parser_test
1718
request_linearize_test
1819
)

‎libs/network/test/http/response_incremental_parser_test.cpp

Lines changed: 144 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,17 @@ namespace logic = boost::logic;
5353
namespacefusion= boost::fusion;
5454
usingnamespaceboost::network::http;
5555

56+
structcrlf {
57+
staticconst std::string literal;
58+
};
59+
const std::string crlf::literal ="\r\n";
60+
structlf {
61+
staticconst std::string literal;
62+
};
63+
const std::string lf::literal ="\n";
64+
typedef boost::mpl::vector<crlf, lf> eol_types;
65+
66+
5667
BOOST_AUTO_TEST_CASE(incremental_parser_constructor) {
5768
response_parser<tags::default_string> p;// default constructible
5869
}
@@ -114,7 +125,7 @@ BOOST_AUTO_TEST_CASE(incremental_parser_parse_http_version) {
114125
* the parser doesn't do any conversions from string to integer
115126
* and outsource that part to the user of the parser.
116127
*/
117-
BOOST_AUTO_TEST_CASE(incremental_parser_parse_status) {
128+
BOOST_AUTO_TEST_CASE_TEMPLATE(incremental_parser_parse_status, eol, eol_types) {
118129
typedef response_parser<tags::default_string> response_parser_type;
119130
typedef boost::iterator_range<std::string::const_iterator> range_type;
120131
// We want to create a parser that has been initialized to a specific
@@ -140,17 +151,25 @@ BOOST_AUTO_TEST_CASE(incremental_parser_parse_status) {
140151
BOOST_CHECK_EQUAL(parsed_ok,false);
141152
parsed =std::string(boost::begin(result_range),boost::end(result_range));
142153
std::cout <<"PARSED:" << parsed <<" state=" << p.state() << std::endl;
154+
155+
valid_status ="200" + eol::literal;
156+
fusion::tie(parsed_ok, result_range) = p.parse_until(
157+
response_parser_type::http_status_done,
158+
valid_status);
159+
BOOST_CHECK_EQUAL(parsed_ok,true);
160+
parsed =std::string(boost::begin(result_range),boost::end(result_range));
161+
std::cout <<"PARSED:" << parsed <<" state=" << p.state() << std::endl;
143162
}
144163

145164
/** In this test then we get the rest of the first line of the HTTP
146165
* Response, and treat it as the status message.
147166
*/
148-
BOOST_AUTO_TEST_CASE(incremental_parser_parse_status_message) {
167+
BOOST_AUTO_TEST_CASE_TEMPLATE(incremental_parser_parse_status_message, eol, eol_types) {
149168
typedef response_parser<tags::default_string> response_parser_type;
150169
typedef boost::iterator_range<std::string::const_iterator> range_type;
151170
response_parser_typep(response_parser_type::http_status_done);
152171

153-
std::string valid_status_message ="OK\r\nServer: Foo";
172+
std::string valid_status_message ="OK" + eol::literal +"Server: Foo";
154173
logic::tribool parsed_ok;
155174
range_type result_range;
156175
fusion::tie(parsed_ok, result_range) = p.parse_until(
@@ -161,7 +180,25 @@ BOOST_AUTO_TEST_CASE(incremental_parser_parse_status_message) {
161180
std::cout <<"PARSED:" << parsed <<" state=" << p.state() << std::endl;
162181

163182
p.reset(response_parser_type::http_status_done);
164-
valid_status_message ="OK\r\n";
183+
valid_status_message ="OK" + eol::literal;
184+
fusion::tie(parsed_ok, result_range) = p.parse_until(
185+
response_parser_type::http_status_message_done,
186+
valid_status_message);
187+
BOOST_CHECK_EQUAL(parsed_ok,true);
188+
parsed =std::string(boost::begin(result_range),boost::end(result_range));
189+
std::cout <<"PARSED:" << parsed <<" state=" << p.state() << std::endl;
190+
191+
p.reset(response_parser_type::http_status_done);
192+
valid_status_message ="Internal Server Error" + eol::literal;
193+
fusion::tie(parsed_ok, result_range) = p.parse_until(
194+
response_parser_type::http_status_message_done,
195+
valid_status_message);
196+
BOOST_CHECK_EQUAL(parsed_ok,true);
197+
parsed =std::string(boost::begin(result_range),boost::end(result_range));
198+
std::cout <<"PARSED:" << parsed <<" state=" << p.state() << std::endl;
199+
200+
p.reset(response_parser_type::http_status_done);
201+
valid_status_message = eol::literal;
165202
fusion::tie(parsed_ok, result_range) = p.parse_until(
166203
response_parser_type::http_status_message_done,
167204
valid_status_message);
@@ -170,7 +207,7 @@ BOOST_AUTO_TEST_CASE(incremental_parser_parse_status_message) {
170207
std::cout <<"PARSED:" << parsed <<" state=" << p.state() << std::endl;
171208

172209
p.reset(response_parser_type::http_status_done);
173-
valid_status_message ="Internal Server Error\r\n";
210+
valid_status_message ="한글메시지" + eol::literal;
174211
fusion::tie(parsed_ok, result_range) = p.parse_until(
175212
response_parser_type::http_status_message_done,
176213
valid_status_message);
@@ -181,12 +218,12 @@ BOOST_AUTO_TEST_CASE(incremental_parser_parse_status_message) {
181218

182219
/** This test specifices how one-line-per-header parsing happens incrementally.
183220
*/
184-
BOOST_AUTO_TEST_CASE(incremental_parser_parse_header_lines) {
221+
BOOST_AUTO_TEST_CASE_TEMPLATE(incremental_parser_parse_header_lines, eol, eol_types) {
185222
typedef response_parser<tags::default_string> response_parser_type;
186223
typedef boost::iterator_range<std::string::const_iterator> range_type;
187224
response_parser_typep(response_parser_type::http_status_message_done);
188225

189-
std::string valid_headers ="Server: Foo\r\nContent-Type: application/json\r\n\r\n";
226+
std::string valid_headers ="Server: Foo" + eol::literal +"Content-Type: application/json" + eol::literal + eol::literal;
190227
logic::tribool parsed_ok;
191228
range_type result_range;
192229
fusion::tie(parsed_ok, result_range) = p.parse_until(
@@ -211,5 +248,105 @@ BOOST_AUTO_TEST_CASE(incremental_parser_parse_header_lines) {
211248
valid_headers);
212249
BOOST_CHECK_EQUAL(parsed_ok,true);
213250
BOOST_CHECK(parsed1 != parsed2);
251+
252+
p.reset(response_parser_type::http_status_message_done);
253+
valid_headers =" Server: Foo" + eol::literal +" Content-Type: application/json" + eol::literal + eol::literal;
254+
fusion::tie(parsed_ok, result_range) = p.parse_until(
255+
response_parser_type::http_header_line_done,
256+
valid_headers);
257+
BOOST_CHECK_EQUAL(parsed_ok,true);
258+
parsed1 =std::string(boost::begin(result_range),boost::end(result_range));
259+
std::cout <<"PARSED:" << parsed1 <<" state=" << p.state() << std::endl;
260+
p.reset(response_parser_type::http_status_message_done);
261+
end = valid_headers.end();
262+
valid_headers.assign(boost::end(result_range), end);
263+
fusion::tie(parsed_ok, result_range) = p.parse_until(
264+
response_parser_type::http_header_line_done,
265+
valid_headers);
266+
BOOST_CHECK_EQUAL(parsed_ok,true);
267+
parsed2 =std::string(boost::begin(result_range),boost::end(result_range));
268+
std::cout <<"PARSED:" << parsed2 <<" state=" << p.state() << std::endl;
269+
valid_headers.assign(boost::end(result_range), end);
270+
p.reset(response_parser_type::http_status_message_done);
271+
fusion::tie(parsed_ok, result_range) = p.parse_until(
272+
response_parser_type::http_headers_done,
273+
valid_headers);
274+
BOOST_CHECK_EQUAL(parsed_ok,true);
275+
BOOST_CHECK(parsed1 != parsed2);
276+
277+
p.reset(response_parser_type::http_status_message_done);
278+
valid_headers ="_Server: Foo" + eol::literal +"_Content-Type: application/json" + eol::literal + eol::literal;
279+
fusion::tie(parsed_ok, result_range) = p.parse_until(
280+
response_parser_type::http_header_line_done,
281+
valid_headers);
282+
BOOST_CHECK_EQUAL(parsed_ok,true);
283+
parsed1 =std::string(boost::begin(result_range),boost::end(result_range));
284+
std::cout <<"PARSED:" << parsed1 <<" state=" << p.state() << std::endl;
285+
p.reset(response_parser_type::http_status_message_done);
286+
end = valid_headers.end();
287+
valid_headers.assign(boost::end(result_range), end);
288+
fusion::tie(parsed_ok, result_range) = p.parse_until(
289+
response_parser_type::http_header_line_done,
290+
valid_headers);
291+
BOOST_CHECK_EQUAL(parsed_ok,true);
292+
parsed2 =std::string(boost::begin(result_range),boost::end(result_range));
293+
std::cout <<"PARSED:" << parsed2 <<" state=" << p.state() << std::endl;
294+
valid_headers.assign(boost::end(result_range), end);
295+
p.reset(response_parser_type::http_status_message_done);
296+
fusion::tie(parsed_ok, result_range) = p.parse_until(
297+
response_parser_type::http_headers_done,
298+
valid_headers);
299+
BOOST_CHECK_EQUAL(parsed_ok,true);
300+
BOOST_CHECK(parsed1 != parsed2);
301+
302+
p.reset(response_parser_type::http_status_message_done);
303+
valid_headers ="Server:" + eol::literal +"Content-Type: application/json" + eol::literal + eol::literal;
304+
fusion::tie(parsed_ok, result_range) = p.parse_until(
305+
response_parser_type::http_header_line_done,
306+
valid_headers);
307+
BOOST_CHECK_EQUAL(parsed_ok,true);
308+
parsed1 =std::string(boost::begin(result_range),boost::end(result_range));
309+
std::cout <<"PARSED:" << parsed1 <<" state=" << p.state() << std::endl;
310+
p.reset(response_parser_type::http_status_message_done);
311+
end = valid_headers.end();
312+
valid_headers.assign(boost::end(result_range), end);
313+
fusion::tie(parsed_ok, result_range) = p.parse_until(
314+
response_parser_type::http_header_line_done,
315+
valid_headers);
316+
BOOST_CHECK_EQUAL(parsed_ok,true);
317+
parsed2 =std::string(boost::begin(result_range),boost::end(result_range));
318+
std::cout <<"PARSED:" << parsed2 <<" state=" << p.state() << std::endl;
319+
valid_headers.assign(boost::end(result_range), end);
320+
p.reset(response_parser_type::http_status_message_done);
321+
fusion::tie(parsed_ok, result_range) = p.parse_until(
322+
response_parser_type::http_headers_done,
323+
valid_headers);
324+
BOOST_CHECK_EQUAL(parsed_ok,true);
325+
BOOST_CHECK(parsed1 != parsed2);
326+
327+
p.reset(response_parser_type::http_status_message_done);
328+
valid_headers ="Server: 서버" + eol::literal +"Content-Type: application/json" + eol::literal + eol::literal;
329+
fusion::tie(parsed_ok, result_range) = p.parse_until(
330+
response_parser_type::http_header_line_done,
331+
valid_headers);
332+
BOOST_CHECK_EQUAL(parsed_ok,true);
333+
parsed1 =std::string(boost::begin(result_range),boost::end(result_range));
334+
std::cout <<"PARSED:" << parsed1 <<" state=" << p.state() << std::endl;
335+
p.reset(response_parser_type::http_status_message_done);
336+
end = valid_headers.end();
337+
valid_headers.assign(boost::end(result_range), end);
338+
fusion::tie(parsed_ok, result_range) = p.parse_until(
339+
response_parser_type::http_header_line_done,
340+
valid_headers);
341+
BOOST_CHECK_EQUAL(parsed_ok,true);
342+
parsed2 =std::string(boost::begin(result_range),boost::end(result_range));
343+
std::cout <<"PARSED:" << parsed2 <<" state=" << p.state() << std::endl;
344+
valid_headers.assign(boost::end(result_range), end);
345+
p.reset(response_parser_type::http_status_message_done);
346+
fusion::tie(parsed_ok, result_range) = p.parse_until(
347+
response_parser_type::http_headers_done,
348+
valid_headers);
349+
BOOST_CHECK_EQUAL(parsed_ok,true);
350+
BOOST_CHECK(parsed1 != parsed2);
214351
}
215352

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp