1 /*
2 * Copyright (c) 2011, Peter Thorson. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution.
11 * * Neither the name of the WebSocket++ Project nor the
12 * names of its contributors may be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
19 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 */
27 //#define BOOST_TEST_DYN_LINK
28 #define BOOST_TEST_MODULE http_parser
29 #include <boost/test/unit_test.hpp>
30
31 #include <iostream>
32 #include <string>
33
34 #include <websocketpp/http/request.hpp>
35 #include <websocketpp/http/response.hpp>
36
BOOST_AUTO_TEST_CASE(is_token_char)37 BOOST_AUTO_TEST_CASE( is_token_char ) {
38 // Valid characters
39
40 // misc
41 BOOST_CHECK( websocketpp::http::is_token_char('!') );
42 BOOST_CHECK( websocketpp::http::is_token_char('#') );
43 BOOST_CHECK( websocketpp::http::is_token_char('$') );
44 BOOST_CHECK( websocketpp::http::is_token_char('%') );
45 BOOST_CHECK( websocketpp::http::is_token_char('&') );
46 BOOST_CHECK( websocketpp::http::is_token_char('\'') );
47 BOOST_CHECK( websocketpp::http::is_token_char('*') );
48 BOOST_CHECK( websocketpp::http::is_token_char('+') );
49 BOOST_CHECK( websocketpp::http::is_token_char('-') );
50 BOOST_CHECK( websocketpp::http::is_token_char('.') );
51 BOOST_CHECK( websocketpp::http::is_token_char('^') );
52 BOOST_CHECK( websocketpp::http::is_token_char('_') );
53 BOOST_CHECK( websocketpp::http::is_token_char('`') );
54 BOOST_CHECK( websocketpp::http::is_token_char('~') );
55
56 // numbers
57 for (int i = 0x30; i < 0x3a; i++) {
58 BOOST_CHECK( websocketpp::http::is_token_char((unsigned char)(i)) );
59 }
60
61 // upper
62 for (int i = 0x41; i < 0x5b; i++) {
63 BOOST_CHECK( websocketpp::http::is_token_char((unsigned char)(i)) );
64 }
65
66 // lower
67 for (int i = 0x61; i < 0x7b; i++) {
68 BOOST_CHECK( websocketpp::http::is_token_char((unsigned char)(i)) );
69 }
70
71 // invalid characters
72
73 // lower unprintable
74 for (int i = 0; i < 33; i++) {
75 BOOST_CHECK( !websocketpp::http::is_token_char((unsigned char)(i)) );
76 }
77
78 // misc
79 BOOST_CHECK( !websocketpp::http::is_token_char('(') );
80 BOOST_CHECK( !websocketpp::http::is_token_char(')') );
81 BOOST_CHECK( !websocketpp::http::is_token_char('<') );
82 BOOST_CHECK( !websocketpp::http::is_token_char('>') );
83 BOOST_CHECK( !websocketpp::http::is_token_char('@') );
84 BOOST_CHECK( !websocketpp::http::is_token_char(',') );
85 BOOST_CHECK( !websocketpp::http::is_token_char(';') );
86 BOOST_CHECK( !websocketpp::http::is_token_char(':') );
87 BOOST_CHECK( !websocketpp::http::is_token_char('\\') );
88 BOOST_CHECK( !websocketpp::http::is_token_char('"') );
89 BOOST_CHECK( !websocketpp::http::is_token_char('/') );
90 BOOST_CHECK( !websocketpp::http::is_token_char('[') );
91 BOOST_CHECK( !websocketpp::http::is_token_char(']') );
92 BOOST_CHECK( !websocketpp::http::is_token_char('?') );
93 BOOST_CHECK( !websocketpp::http::is_token_char('=') );
94 BOOST_CHECK( !websocketpp::http::is_token_char('{') );
95 BOOST_CHECK( !websocketpp::http::is_token_char('}') );
96
97 // upper unprintable and out of ascii range
98 for (int i = 127; i < 256; i++) {
99 BOOST_CHECK( !websocketpp::http::is_token_char((unsigned char)(i)) );
100 }
101
102 // is not
103 BOOST_CHECK( !websocketpp::http::is_not_token_char('!') );
104 BOOST_CHECK( websocketpp::http::is_not_token_char('(') );
105 }
106
BOOST_AUTO_TEST_CASE(extract_token)107 BOOST_AUTO_TEST_CASE( extract_token ) {
108 std::string d1 = "foo";
109 std::string d2 = " foo ";
110
111 std::pair<std::string,std::string::const_iterator> ret;
112
113 ret = websocketpp::http::parser::extract_token(d1.begin(),d1.end());
114 BOOST_CHECK( ret.first == "foo" );
115 BOOST_CHECK( ret.second == d1.begin()+3 );
116
117 ret = websocketpp::http::parser::extract_token(d2.begin(),d2.end());
118 BOOST_CHECK( ret.first.empty() );
119 BOOST_CHECK( ret.second == d2.begin()+0 );
120
121 ret = websocketpp::http::parser::extract_token(d2.begin()+1,d2.end());
122 BOOST_CHECK( ret.first == "foo" );
123 BOOST_CHECK( ret.second == d2.begin()+4 );
124 }
125
BOOST_AUTO_TEST_CASE(extract_quoted_string)126 BOOST_AUTO_TEST_CASE( extract_quoted_string ) {
127 std::string d1 = "\"foo\"";
128 std::string d2 = "\"foo\\\"bar\\\"baz\"";
129 std::string d3 = "\"foo\" ";
130 std::string d4;
131 std::string d5 = "foo";
132
133 std::pair<std::string,std::string::const_iterator> ret;
134
135 using websocketpp::http::parser::extract_quoted_string;
136
137 ret = extract_quoted_string(d1.begin(),d1.end());
138 BOOST_CHECK( ret.first == "foo" );
139 BOOST_CHECK( ret.second == d1.end() );
140
141 ret = extract_quoted_string(d2.begin(),d2.end());
142 BOOST_CHECK( ret.first == "foo\"bar\"baz" );
143 BOOST_CHECK( ret.second == d2.end() );
144
145 ret = extract_quoted_string(d3.begin(),d3.end());
146 BOOST_CHECK( ret.first == "foo" );
147 BOOST_CHECK( ret.second == d3.begin()+5 );
148
149 ret = extract_quoted_string(d4.begin(),d4.end());
150 BOOST_CHECK( ret.first.empty() );
151 BOOST_CHECK( ret.second == d4.begin() );
152
153 ret = extract_quoted_string(d5.begin(),d5.end());
154 BOOST_CHECK( ret.first.empty() );
155 BOOST_CHECK( ret.second == d5.begin() );
156 }
157
BOOST_AUTO_TEST_CASE(extract_all_lws)158 BOOST_AUTO_TEST_CASE( extract_all_lws ) {
159 std::string d1 = " foo bar";
160 d1.append(1,char(9));
161 d1.append("baz\r\n d\r\n \r\n e\r\nf");
162
163 std::string::const_iterator ret;
164
165 ret = websocketpp::http::parser::extract_all_lws(d1.begin(),d1.end());
166 BOOST_CHECK( ret == d1.begin()+1 );
167
168 ret = websocketpp::http::parser::extract_all_lws(d1.begin()+1,d1.end());
169 BOOST_CHECK( ret == d1.begin()+1 );
170
171 ret = websocketpp::http::parser::extract_all_lws(d1.begin()+4,d1.end());
172 BOOST_CHECK( ret == d1.begin()+9 );
173
174 ret = websocketpp::http::parser::extract_all_lws(d1.begin()+12,d1.end());
175 BOOST_CHECK( ret == d1.begin()+13 );
176
177 ret = websocketpp::http::parser::extract_all_lws(d1.begin()+16,d1.end());
178 BOOST_CHECK( ret == d1.begin()+19 );
179
180 ret = websocketpp::http::parser::extract_all_lws(d1.begin()+20,d1.end());
181 BOOST_CHECK( ret == d1.begin()+28 );
182
183 ret = websocketpp::http::parser::extract_all_lws(d1.begin()+29,d1.end());
184 BOOST_CHECK( ret == d1.begin()+29 );
185 }
186
BOOST_AUTO_TEST_CASE(extract_attributes_blank)187 BOOST_AUTO_TEST_CASE( extract_attributes_blank ) {
188 std::string s;
189
190 websocketpp::http::attribute_list a;
191 std::string::const_iterator it;
192
193 it = websocketpp::http::parser::extract_attributes(s.begin(),s.end(),a);
194 BOOST_CHECK( it == s.begin() );
195 BOOST_CHECK_EQUAL( a.size(), 0 );
196 }
197
BOOST_AUTO_TEST_CASE(extract_attributes_simple)198 BOOST_AUTO_TEST_CASE( extract_attributes_simple ) {
199 std::string s = "foo";
200
201 websocketpp::http::attribute_list a;
202 std::string::const_iterator it;
203
204 it = websocketpp::http::parser::extract_attributes(s.begin(),s.end(),a);
205 BOOST_CHECK( it == s.end() );
206 BOOST_CHECK_EQUAL( a.size(), 1 );
207 BOOST_CHECK( a.find("foo") != a.end() );
208 BOOST_CHECK_EQUAL( a.find("foo")->second, "" );
209 }
210
BOOST_AUTO_TEST_CASE(extract_parameters)211 BOOST_AUTO_TEST_CASE( extract_parameters ) {
212 std::string s1;
213 std::string s2 = "foo";
214 std::string s3 = " foo \r\nAbc";
215 std::string s4 = " \r\n foo ";
216 std::string s5 = "foo,bar";
217 std::string s6 = "foo;bar";
218 std::string s7 = "foo;baz,bar";
219 std::string s8 = "foo;bar;baz";
220 std::string s9 = "foo;bar=baz";
221 std::string s10 = "foo;bar=baz;boo";
222 std::string s11 = "foo;bar=baz;boo,bob";
223 std::string s12 = "foo;bar=\"a b c\"";
224 std::string s13 = "foo;bar=\"a \\\"b\\\" c\"";
225
226
227 std::string sx = "foo;bar=\"a \\\"b\\\" c\"";
228 websocketpp::http::parameter_list p;
229 websocketpp::http::attribute_list a;
230 std::string::const_iterator it;
231
232 using websocketpp::http::parser::extract_parameters;
233
234 it = extract_parameters(s1.begin(),s1.end(),p);
235 BOOST_CHECK( it == s1.begin() );
236
237 p.clear();
238 it = extract_parameters(s2.begin(),s2.end(),p);
239 BOOST_CHECK( it == s2.end() );
240 BOOST_CHECK_EQUAL( p.size(), 1 );
241 BOOST_CHECK( p[0].first == "foo" );
242 BOOST_CHECK_EQUAL( p[0].second.size(), 0 );
243
244 p.clear();
245 it = extract_parameters(s3.begin(),s3.end(),p);
246 BOOST_CHECK( it == s3.begin()+5 );
247 BOOST_CHECK_EQUAL( p.size(), 1 );
248 BOOST_CHECK( p[0].first == "foo" );
249 BOOST_CHECK_EQUAL( p[0].second.size(), 0 );
250
251 p.clear();
252 it = extract_parameters(s4.begin(),s4.end(),p);
253 BOOST_CHECK( it == s4.end() );
254 BOOST_CHECK_EQUAL( p.size(), 1 );
255 BOOST_CHECK( p[0].first == "foo" );
256 BOOST_CHECK_EQUAL( p[0].second.size(), 0 );
257
258 p.clear();
259 it = extract_parameters(s5.begin(),s5.end(),p);
260 BOOST_CHECK( it == s5.end() );
261 BOOST_CHECK_EQUAL( p.size(), 2 );
262 BOOST_CHECK( p[0].first == "foo" );
263 BOOST_CHECK_EQUAL( p[0].second.size(), 0 );
264 BOOST_CHECK( p[1].first == "bar" );
265 BOOST_CHECK_EQUAL( p[1].second.size(), 0 );
266
267 p.clear();
268 it = extract_parameters(s6.begin(),s6.end(),p);
269 BOOST_CHECK( it == s6.end() );
270 BOOST_CHECK_EQUAL( p.size(), 1 );
271 BOOST_CHECK( p[0].first == "foo" );
272 a = p[0].second;
273 BOOST_CHECK_EQUAL( a.size(), 1 );
274 BOOST_CHECK( a.find("bar") != a.end() );
275 BOOST_CHECK_EQUAL( a.find("bar")->second, "" );
276
277 p.clear();
278 it = extract_parameters(s7.begin(),s7.end(),p);
279 BOOST_CHECK( it == s7.end() );
280 BOOST_CHECK_EQUAL( p.size(), 2 );
281 BOOST_CHECK( p[0].first == "foo" );
282 a = p[0].second;
283 BOOST_CHECK_EQUAL( a.size(), 1 );
284 BOOST_CHECK( a.find("baz") != a.end() );
285 BOOST_CHECK_EQUAL( a.find("baz")->second, "" );
286 BOOST_CHECK( p[1].first == "bar" );
287 a = p[1].second;
288 BOOST_CHECK_EQUAL( a.size(), 0 );
289
290 p.clear();
291 it = extract_parameters(s8.begin(),s8.end(),p);
292 BOOST_CHECK( it == s8.end() );
293 BOOST_CHECK_EQUAL( p.size(), 1 );
294 BOOST_CHECK( p[0].first == "foo" );
295 a = p[0].second;
296 BOOST_CHECK_EQUAL( a.size(), 2 );
297 BOOST_CHECK( a.find("bar") != a.end() );
298 BOOST_CHECK_EQUAL( a.find("bar")->second, "" );
299 BOOST_CHECK( a.find("baz") != a.end() );
300 BOOST_CHECK_EQUAL( a.find("baz")->second, "" );
301
302 p.clear();
303 it = extract_parameters(s9.begin(),s9.end(),p);
304 BOOST_CHECK( it == s9.end() );
305 BOOST_CHECK_EQUAL( p.size(), 1 );
306 BOOST_CHECK( p[0].first == "foo" );
307 a = p[0].second;
308 BOOST_CHECK_EQUAL( a.size(), 1 );
309 BOOST_CHECK( a.find("bar") != a.end() );
310 BOOST_CHECK_EQUAL( a.find("bar")->second, "baz" );
311
312 p.clear();
313 it = extract_parameters(s10.begin(),s10.end(),p);
314 BOOST_CHECK( it == s10.end() );
315 BOOST_CHECK_EQUAL( p.size(), 1 );
316 BOOST_CHECK( p[0].first == "foo" );
317 a = p[0].second;
318 BOOST_CHECK_EQUAL( a.size(), 2 );
319 BOOST_CHECK( a.find("bar") != a.end() );
320 BOOST_CHECK_EQUAL( a.find("bar")->second, "baz" );
321 BOOST_CHECK( a.find("boo") != a.end() );
322 BOOST_CHECK_EQUAL( a.find("boo")->second, "" );
323
324 p.clear();
325 it = extract_parameters(s11.begin(),s11.end(),p);
326 BOOST_CHECK( it == s11.end() );
327 BOOST_CHECK_EQUAL( p.size(), 2 );
328 BOOST_CHECK( p[0].first == "foo" );
329 a = p[0].second;
330 BOOST_CHECK_EQUAL( a.size(), 2 );
331 BOOST_CHECK( a.find("bar") != a.end() );
332 BOOST_CHECK_EQUAL( a.find("bar")->second, "baz" );
333 BOOST_CHECK( a.find("boo") != a.end() );
334 BOOST_CHECK_EQUAL( a.find("boo")->second, "" );
335 a = p[1].second;
336 BOOST_CHECK_EQUAL( a.size(), 0 );
337
338 p.clear();
339 it = extract_parameters(s12.begin(),s12.end(),p);
340 BOOST_CHECK( it == s12.end() );
341 BOOST_CHECK_EQUAL( p.size(), 1 );
342 BOOST_CHECK( p[0].first == "foo" );
343 a = p[0].second;
344 BOOST_CHECK_EQUAL( a.size(), 1 );
345 BOOST_CHECK( a.find("bar") != a.end() );
346 BOOST_CHECK_EQUAL( a.find("bar")->second, "a b c" );
347
348 p.clear();
349 it = extract_parameters(s13.begin(),s13.end(),p);
350 BOOST_CHECK( it == s13.end() );
351 BOOST_CHECK_EQUAL( p.size(), 1 );
352 BOOST_CHECK( p[0].first == "foo" );
353 a = p[0].second;
354 BOOST_CHECK_EQUAL( a.size(), 1 );
355 BOOST_CHECK( a.find("bar") != a.end() );
356 BOOST_CHECK_EQUAL( a.find("bar")->second, "a \"b\" c" );
357 }
358
BOOST_AUTO_TEST_CASE(strip_lws)359 BOOST_AUTO_TEST_CASE( strip_lws ) {
360 std::string test1 = "foo";
361 std::string test2 = " foo ";
362 std::string test3 = "foo ";
363 std::string test4 = " foo";
364 std::string test5 = " foo ";
365 std::string test6 = " \r\n foo ";
366 std::string test7 = " \t foo ";
367 std::string test8 = " \t ";
368 std::string test9 = " \n\r";
369
370 BOOST_CHECK_EQUAL( websocketpp::http::parser::strip_lws(test1), "foo" );
371 BOOST_CHECK_EQUAL( websocketpp::http::parser::strip_lws(test2), "foo" );
372 BOOST_CHECK_EQUAL( websocketpp::http::parser::strip_lws(test3), "foo" );
373 BOOST_CHECK_EQUAL( websocketpp::http::parser::strip_lws(test4), "foo" );
374 BOOST_CHECK_EQUAL( websocketpp::http::parser::strip_lws(test5), "foo" );
375 BOOST_CHECK_EQUAL( websocketpp::http::parser::strip_lws(test6), "foo" );
376 BOOST_CHECK_EQUAL( websocketpp::http::parser::strip_lws(test7), "foo" );
377 BOOST_CHECK_EQUAL( websocketpp::http::parser::strip_lws(test8), "" );
378 BOOST_CHECK_EQUAL( websocketpp::http::parser::strip_lws(test9), "" );
379 }
380
BOOST_AUTO_TEST_CASE(case_insensitive_headers)381 BOOST_AUTO_TEST_CASE( case_insensitive_headers ) {
382 websocketpp::http::parser::parser r;
383
384 r.replace_header("foo","bar");
385
386 BOOST_CHECK_EQUAL( r.get_header("foo"), "bar" );
387 BOOST_CHECK_EQUAL( r.get_header("FOO"), "bar" );
388 BOOST_CHECK_EQUAL( r.get_header("Foo"), "bar" );
389 }
390
BOOST_AUTO_TEST_CASE(case_insensitive_headers_overwrite)391 BOOST_AUTO_TEST_CASE( case_insensitive_headers_overwrite ) {
392 websocketpp::http::parser::parser r;
393
394 r.replace_header("foo","bar");
395
396 BOOST_CHECK_EQUAL( r.get_header("foo"), "bar" );
397 BOOST_CHECK_EQUAL( r.get_header("Foo"), "bar" );
398
399 r.replace_header("Foo","baz");
400
401 BOOST_CHECK_EQUAL( r.get_header("foo"), "baz" );
402 BOOST_CHECK_EQUAL( r.get_header("Foo"), "baz" );
403
404 r.remove_header("FoO");
405
406 BOOST_CHECK_EQUAL( r.get_header("foo"), "" );
407 BOOST_CHECK_EQUAL( r.get_header("Foo"), "" );
408 }
409
BOOST_AUTO_TEST_CASE(blank_consume)410 BOOST_AUTO_TEST_CASE( blank_consume ) {
411 websocketpp::http::parser::request r;
412
413 std::string raw;
414
415 bool exception = false;
416
417 try {
418 r.consume(raw.c_str(),raw.size());
419 } catch (...) {
420 exception = true;
421 }
422
423 BOOST_CHECK( exception == false );
424 BOOST_CHECK( r.ready() == false );
425 }
426
BOOST_AUTO_TEST_CASE(blank_request)427 BOOST_AUTO_TEST_CASE( blank_request ) {
428 websocketpp::http::parser::request r;
429
430 std::string raw = "\r\n\r\n";
431
432 bool exception = false;
433
434 try {
435 r.consume(raw.c_str(),raw.size());
436 } catch (...) {
437 exception = true;
438 }
439
440 BOOST_CHECK( exception == true );
441 BOOST_CHECK( r.ready() == false );
442 }
443
BOOST_AUTO_TEST_CASE(bad_request_no_host)444 BOOST_AUTO_TEST_CASE( bad_request_no_host ) {
445 websocketpp::http::parser::request r;
446
447 std::string raw = "GET / HTTP/1.1\r\n\r\n";
448
449 bool exception = false;
450
451 try {
452 r.consume(raw.c_str(),raw.size());
453 } catch (...) {
454 exception = true;
455 }
456
457 BOOST_CHECK( exception == true );
458 BOOST_CHECK( r.ready() == false );
459 }
460
BOOST_AUTO_TEST_CASE(basic_request)461 BOOST_AUTO_TEST_CASE( basic_request ) {
462 websocketpp::http::parser::request r;
463
464 std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n";
465
466 bool exception = false;
467 size_t pos = 0;
468
469 try {
470 pos = r.consume(raw.c_str(),raw.size());
471 } catch (std::exception &e) {
472 exception = true;
473 std::cout << e.what() << std::endl;
474 }
475
476 BOOST_CHECK( exception == false );
477 BOOST_CHECK( pos == 41 );
478 BOOST_CHECK( r.ready() == true );
479 BOOST_CHECK( r.get_version() == "HTTP/1.1" );
480 BOOST_CHECK( r.get_method() == "GET" );
481 BOOST_CHECK( r.get_uri() == "/" );
482 BOOST_CHECK( r.get_header("Host") == "www.example.com" );
483 }
484
BOOST_AUTO_TEST_CASE(basic_request_with_body)485 BOOST_AUTO_TEST_CASE( basic_request_with_body ) {
486 websocketpp::http::parser::request r;
487
488 std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\nContent-Length: 5\r\n\r\nabcdef";
489
490 bool exception = false;
491 size_t pos = 0;
492
493 try {
494 pos = r.consume(raw.c_str(),raw.size());
495 } catch (std::exception &e) {
496 exception = true;
497 std::cout << e.what() << std::endl;
498 }
499
500 BOOST_CHECK( exception == false );
501 BOOST_CHECK_EQUAL( pos, 65 );
502 BOOST_CHECK( r.ready() == true );
503 BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
504 BOOST_CHECK_EQUAL( r.get_method(), "GET" );
505 BOOST_CHECK_EQUAL( r.get_uri(), "/" );
506 BOOST_CHECK_EQUAL( r.get_header("Host"), "www.example.com" );
507 BOOST_CHECK_EQUAL( r.get_header("Content-Length"), "5" );
508 BOOST_CHECK_EQUAL( r.get_body(), "abcde" );
509
510 BOOST_CHECK_EQUAL( r.get_headers().size(), 2);
511
512 websocketpp::http::parser::header_list::const_iterator it = r.get_headers().begin();
513
514 BOOST_CHECK_EQUAL( it->first, "Content-Length");
515 BOOST_CHECK_EQUAL( it->second, "5");
516
517 it++;
518
519 BOOST_CHECK_EQUAL( it->first, "Host");
520 BOOST_CHECK_EQUAL( it->second, "www.example.com");
521 }
522
BOOST_AUTO_TEST_CASE(basic_request_with_body_split)523 BOOST_AUTO_TEST_CASE( basic_request_with_body_split ) {
524 websocketpp::http::parser::request r;
525
526 std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\nContent-Length: 6\r\n\r\nabc";
527 std::string raw2 = "def";
528
529 bool exception = false;
530 size_t pos = 0;
531
532 try {
533 pos += r.consume(raw.c_str(),raw.size());
534 pos += r.consume(raw2.c_str(),raw2.size());
535 } catch (std::exception &e) {
536 exception = true;
537 std::cout << e.what() << std::endl;
538 }
539
540 BOOST_CHECK( exception == false );
541 BOOST_CHECK_EQUAL( pos, 66 );
542 BOOST_CHECK( r.ready() == true );
543 BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
544 BOOST_CHECK_EQUAL( r.get_method(), "GET" );
545 BOOST_CHECK_EQUAL( r.get_uri(), "/" );
546 BOOST_CHECK_EQUAL( r.get_header("Host"), "www.example.com" );
547 BOOST_CHECK_EQUAL( r.get_header("Content-Length"), "6" );
548 BOOST_CHECK_EQUAL( r.get_body(), "abcdef" );
549 }
550
551
552
BOOST_AUTO_TEST_CASE(trailing_body_characters)553 BOOST_AUTO_TEST_CASE( trailing_body_characters ) {
554 websocketpp::http::parser::request r;
555
556 std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\na";
557
558 bool exception = false;
559 size_t pos = 0;
560
561 try {
562 pos = r.consume(raw.c_str(),raw.size());
563 } catch (...) {
564 exception = true;
565 }
566
567 BOOST_CHECK( exception == false );
568 BOOST_CHECK( pos == 41 );
569 BOOST_CHECK( r.ready() == true );
570 BOOST_CHECK( r.get_version() == "HTTP/1.1" );
571 BOOST_CHECK( r.get_method() == "GET" );
572 BOOST_CHECK( r.get_uri() == "/" );
573 BOOST_CHECK( r.get_header("Host") == "www.example.com" );
574 }
575
BOOST_AUTO_TEST_CASE(trailing_body_characters_beyond_max_lenth)576 BOOST_AUTO_TEST_CASE( trailing_body_characters_beyond_max_lenth ) {
577 websocketpp::http::parser::request r;
578
579 std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n";
580 raw.append(websocketpp::http::max_header_size,'*');
581
582 bool exception = false;
583 size_t pos = 0;
584
585 try {
586 pos = r.consume(raw.c_str(),raw.size());
587 } catch (...) {
588 exception = true;
589 }
590
591 BOOST_CHECK( exception == false );
592 BOOST_CHECK( pos == 41 );
593 BOOST_CHECK( r.ready() == true );
594 BOOST_CHECK( r.get_version() == "HTTP/1.1" );
595 BOOST_CHECK( r.get_method() == "GET" );
596 BOOST_CHECK( r.get_uri() == "/" );
597 BOOST_CHECK( r.get_header("Host") == "www.example.com" );
598 }
599
BOOST_AUTO_TEST_CASE(basic_split1)600 BOOST_AUTO_TEST_CASE( basic_split1 ) {
601 websocketpp::http::parser::request r;
602
603 std::string raw = "GET / HTTP/1.1\r\n";
604 std::string raw2 = "Host: www.example.com\r\n\r\na";
605
606 bool exception = false;
607 size_t pos = 0;
608
609 try {
610 pos += r.consume(raw.c_str(),raw.size());
611 pos += r.consume(raw2.c_str(),raw2.size());
612 } catch (std::exception &e) {
613 exception = true;
614 std::cout << e.what() << std::endl;
615 }
616
617 BOOST_CHECK( exception == false );
618 BOOST_CHECK( pos == 41 );
619 BOOST_CHECK( r.ready() == true );
620 BOOST_CHECK( r.get_version() == "HTTP/1.1" );
621 BOOST_CHECK( r.get_method() == "GET" );
622 BOOST_CHECK( r.get_uri() == "/" );
623 BOOST_CHECK( r.get_header("Host") == "www.example.com" );
624 }
625
BOOST_AUTO_TEST_CASE(basic_split2)626 BOOST_AUTO_TEST_CASE( basic_split2 ) {
627 websocketpp::http::parser::request r;
628
629 std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r";
630 std::string raw2 = "\n\r\na";
631
632 bool exception = false;
633 size_t pos = 0;
634
635 try {
636 pos += r.consume(raw.c_str(),raw.size());
637 pos += r.consume(raw2.c_str(),raw2.size());
638 } catch (std::exception &e) {
639 exception = true;
640 std::cout << e.what() << std::endl;
641 }
642
643 BOOST_CHECK( exception == false );
644 BOOST_CHECK( pos == 41 );
645 BOOST_CHECK( r.ready() == true );
646 BOOST_CHECK( r.get_version() == "HTTP/1.1" );
647 BOOST_CHECK( r.get_method() == "GET" );
648 BOOST_CHECK( r.get_uri() == "/" );
649 BOOST_CHECK( r.get_header("Host") == "www.example.com" );
650 }
651
BOOST_AUTO_TEST_CASE(max_header_len)652 BOOST_AUTO_TEST_CASE( max_header_len ) {
653 websocketpp::http::parser::request r;
654
655 std::string raw(websocketpp::http::max_header_size-1,'*');
656 raw += "\r\n";
657
658 bool exception = false;
659 size_t pos = 0;
660
661 try {
662 pos += r.consume(raw.c_str(),raw.size());
663 } catch (const websocketpp::http::exception& e) {
664 if (e.m_error_code == websocketpp::http::status_code::request_header_fields_too_large) {
665 exception = true;
666 }
667 }
668
669 BOOST_CHECK( exception == true );
670 }
671
BOOST_AUTO_TEST_CASE(max_header_len_split)672 BOOST_AUTO_TEST_CASE( max_header_len_split ) {
673 websocketpp::http::parser::request r;
674
675 std::string raw(websocketpp::http::max_header_size-1,'*');
676 std::string raw2(2,'*');
677
678 bool exception = false;
679 size_t pos = 0;
680
681 try {
682 pos += r.consume(raw.c_str(),raw.size());
683 pos += r.consume(raw2.c_str(),raw2.size());
684 } catch (const websocketpp::http::exception& e) {
685 if (e.m_error_code == websocketpp::http::status_code::request_header_fields_too_large) {
686 exception = true;
687 }
688 }
689
690 BOOST_CHECK( exception == true );
691 }
692
BOOST_AUTO_TEST_CASE(max_body_len)693 BOOST_AUTO_TEST_CASE( max_body_len ) {
694 websocketpp::http::parser::request r;
695
696 r.set_max_body_size(5);
697
698 std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\nContent-Length: 6\r\n\r\nabcdef";
699
700 bool exception = false;
701 size_t pos = 0;
702
703 try {
704 pos += r.consume(raw.c_str(),raw.size());
705 } catch (websocketpp::http::exception const & e) {
706 exception = true;
707 BOOST_CHECK_EQUAL(e.m_error_code,websocketpp::http::status_code::request_entity_too_large);
708 }
709
710 BOOST_CHECK_EQUAL(r.get_max_body_size(),5);
711 BOOST_CHECK( exception == true );
712 }
713
BOOST_AUTO_TEST_CASE(firefox_full_request)714 BOOST_AUTO_TEST_CASE( firefox_full_request ) {
715 websocketpp::http::parser::request r;
716
717 std::string raw = "GET / HTTP/1.1\r\nHost: localhost:5000\r\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:10.0) Gecko/20100101 Firefox/10.0\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: en-us,en;q=0.5\r\nAccept-Encoding: gzip, deflate\r\nConnection: keep-alive, Upgrade\r\nSec-WebSocket-Version: 8\r\nSec-WebSocket-Origin: http://zaphoyd.com\r\nSec-WebSocket-Key: pFik//FxwFk0riN4ZiPFjQ==\r\nPragma: no-cache\r\nCache-Control: no-cache\r\nUpgrade: websocket\r\n\r\n";
718
719 bool exception = false;
720 size_t pos = 0;
721
722 try {
723 pos += r.consume(raw.c_str(),raw.size());
724 } catch (...) {
725 exception = true;
726 }
727
728 BOOST_CHECK( exception == false );
729 BOOST_CHECK( pos == 482 );
730 BOOST_CHECK( r.ready() == true );
731 BOOST_CHECK( r.get_version() == "HTTP/1.1" );
732 BOOST_CHECK( r.get_method() == "GET" );
733 BOOST_CHECK( r.get_uri() == "/" );
734 BOOST_CHECK( r.get_header("Host") == "localhost:5000" );
735 BOOST_CHECK( r.get_header("User-Agent") == "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:10.0) Gecko/20100101 Firefox/10.0" );
736 BOOST_CHECK( r.get_header("Accept") == "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" );
737 BOOST_CHECK( r.get_header("Accept-Language") == "en-us,en;q=0.5" );
738 BOOST_CHECK( r.get_header("Accept-Encoding") == "gzip, deflate" );
739 BOOST_CHECK( r.get_header("Connection") == "keep-alive, Upgrade" );
740 BOOST_CHECK( r.get_header("Sec-WebSocket-Version") == "8" );
741 BOOST_CHECK( r.get_header("Sec-WebSocket-Origin") == "http://zaphoyd.com" );
742 BOOST_CHECK( r.get_header("Sec-WebSocket-Key") == "pFik//FxwFk0riN4ZiPFjQ==" );
743 BOOST_CHECK( r.get_header("Pragma") == "no-cache" );
744 BOOST_CHECK( r.get_header("Cache-Control") == "no-cache" );
745 BOOST_CHECK( r.get_header("Upgrade") == "websocket" );
746 }
747
BOOST_AUTO_TEST_CASE(bad_method)748 BOOST_AUTO_TEST_CASE( bad_method ) {
749 websocketpp::http::parser::request r;
750
751 std::string raw = "GE]T / HTTP/1.1\r\nHost: www.example.com\r\n\r\n";
752
753 bool exception = false;
754
755 try {
756 r.consume(raw.c_str(),raw.size());
757 } catch (...) {
758 exception = true;
759 }
760
761 BOOST_CHECK( exception == true );
762 }
763
BOOST_AUTO_TEST_CASE(bad_header_name)764 BOOST_AUTO_TEST_CASE( bad_header_name ) {
765 websocketpp::http::parser::request r;
766
767 std::string raw = "GET / HTTP/1.1\r\nHo]st: www.example.com\r\n\r\n";
768
769 bool exception = false;
770
771 try {
772 r.consume(raw.c_str(),raw.size());
773 } catch (...) {
774 exception = true;
775 }
776
777 BOOST_CHECK( exception == true );
778 }
779
BOOST_AUTO_TEST_CASE(old_http_version)780 BOOST_AUTO_TEST_CASE( old_http_version ) {
781 websocketpp::http::parser::request r;
782
783 std::string raw = "GET / HTTP/1.0\r\nHost: www.example.com\r\n\r\n";
784
785 bool exception = false;
786 size_t pos = 0;
787
788 try {
789 pos = r.consume(raw.c_str(),raw.size());
790 } catch (...) {
791 exception = true;
792 }
793
794 BOOST_CHECK( exception == false );
795 BOOST_CHECK_EQUAL( pos, 41 );
796 BOOST_CHECK( r.ready() == true );
797 BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.0" );
798 BOOST_CHECK_EQUAL( r.get_method(), "GET" );
799 BOOST_CHECK_EQUAL( r.get_uri(), "/" );
800 BOOST_CHECK_EQUAL( r.get_header("Host"), "www.example.com" );
801 }
802
BOOST_AUTO_TEST_CASE(new_http_version1)803 BOOST_AUTO_TEST_CASE( new_http_version1 ) {
804 websocketpp::http::parser::request r;
805
806 std::string raw = "GET / HTTP/1.12\r\nHost: www.example.com\r\n\r\n";
807
808 bool exception = false;
809 size_t pos = 0;
810
811 try {
812 pos = r.consume(raw.c_str(),raw.size());
813 } catch (...) {
814 exception = true;
815 }
816
817 BOOST_CHECK( exception == false );
818 BOOST_CHECK_EQUAL( pos, 42 );
819 BOOST_CHECK( r.ready() == true );
820 BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.12" );
821 BOOST_CHECK_EQUAL( r.get_method(), "GET" );
822 BOOST_CHECK_EQUAL( r.get_uri(), "/" );
823 BOOST_CHECK_EQUAL( r.get_header("Host"), "www.example.com" );
824 }
825
BOOST_AUTO_TEST_CASE(new_http_version2)826 BOOST_AUTO_TEST_CASE( new_http_version2 ) {
827 websocketpp::http::parser::request r;
828
829 std::string raw = "GET / HTTP/12.12\r\nHost: www.example.com\r\n\r\n";
830
831 bool exception = false;
832 size_t pos = 0;
833
834 try {
835 pos = r.consume(raw.c_str(),raw.size());
836 } catch (...) {
837 exception = true;
838 }
839
840 BOOST_CHECK( exception == false );
841 BOOST_CHECK_EQUAL( pos, 43 );
842 BOOST_CHECK( r.ready() == true );
843 BOOST_CHECK_EQUAL( r.get_version(), "HTTP/12.12" );
844 BOOST_CHECK_EQUAL( r.get_method(), "GET" );
845 BOOST_CHECK_EQUAL( r.get_uri(), "/" );
846 BOOST_CHECK_EQUAL( r.get_header("Host"), "www.example.com" );
847 }
848
849 /* commented out due to not being implemented yet
850
851 BOOST_AUTO_TEST_CASE( new_http_version3 ) {
852 websocketpp::http::parser::request r;
853
854 std::string raw = "GET / HTTPS/12.12\r\nHost: www.example.com\r\n\r\n";
855
856 bool exception = false;
857 size_t pos = 0;
858
859 try {
860 pos = r.consume(raw.c_str(),raw.size());
861 } catch (...) {
862 exception = true;
863 }
864
865 BOOST_CHECK( exception == true );
866 }*/
867
BOOST_AUTO_TEST_CASE(header_whitespace1)868 BOOST_AUTO_TEST_CASE( header_whitespace1 ) {
869 websocketpp::http::parser::request r;
870
871 std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com \r\n\r\n";
872
873 bool exception = false;
874 size_t pos = 0;
875
876 try {
877 pos = r.consume(raw.c_str(),raw.size());
878 } catch (...) {
879 exception = true;
880 }
881
882 BOOST_CHECK( exception == false );
883 BOOST_CHECK_EQUAL( pos, 43 );
884 BOOST_CHECK( r.ready() == true );
885 BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
886 BOOST_CHECK_EQUAL( r.get_method(), "GET" );
887 BOOST_CHECK_EQUAL( r.get_uri(), "/" );
888 BOOST_CHECK_EQUAL( r.get_header("Host"), "www.example.com" );
889 }
890
BOOST_AUTO_TEST_CASE(header_whitespace2)891 BOOST_AUTO_TEST_CASE( header_whitespace2 ) {
892 websocketpp::http::parser::request r;
893
894 std::string raw = "GET / HTTP/1.1\r\nHost:www.example.com\r\n\r\n";
895
896 bool exception = false;
897 size_t pos = 0;
898
899 try {
900 pos = r.consume(raw.c_str(),raw.size());
901 } catch (...) {
902 exception = true;
903 }
904
905 BOOST_CHECK( exception == false );
906 BOOST_CHECK_EQUAL( pos, 40 );
907 BOOST_CHECK( r.ready() == true );
908 BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
909 BOOST_CHECK_EQUAL( r.get_method(), "GET" );
910 BOOST_CHECK_EQUAL( r.get_uri(), "/" );
911 BOOST_CHECK_EQUAL( r.get_header("Host"), "www.example.com" );
912 }
913
BOOST_AUTO_TEST_CASE(header_aggregation)914 BOOST_AUTO_TEST_CASE( header_aggregation ) {
915 websocketpp::http::parser::request r;
916
917 std::string raw = "GET / HTTP/1.1\r\nHost: www.example.com\r\nFoo: bar\r\nFoo: bat\r\n\r\n";
918
919 bool exception = false;
920 size_t pos = 0;
921
922 try {
923 pos = r.consume(raw.c_str(),raw.size());
924 } catch (...) {
925 exception = true;
926 }
927
928 BOOST_CHECK( exception == false );
929 BOOST_CHECK_EQUAL( pos, 61 );
930 BOOST_CHECK( r.ready() == true );
931 BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
932 BOOST_CHECK_EQUAL( r.get_method(), "GET" );
933 BOOST_CHECK_EQUAL( r.get_uri(), "/" );
934 BOOST_CHECK_EQUAL( r.get_header("Foo"), "bar, bat" );
935 }
936
BOOST_AUTO_TEST_CASE(wikipedia_example_response)937 BOOST_AUTO_TEST_CASE( wikipedia_example_response ) {
938 websocketpp::http::parser::response r;
939
940 std::string raw = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=\r\nSec-WebSocket-Protocol: chat\r\n\r\n";
941
942 bool exception = false;
943 size_t pos = 0;
944
945 try {
946 pos += r.consume(raw.c_str(),raw.size());
947 } catch (std::exception &e) {
948 exception = true;
949 std::cout << e.what() << std::endl;
950 }
951
952 BOOST_CHECK( exception == false );
953 BOOST_CHECK_EQUAL( pos, 159 );
954 BOOST_CHECK( r.headers_ready() == true );
955 BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
956 BOOST_CHECK_EQUAL( r.get_status_code(), websocketpp::http::status_code::switching_protocols );
957 BOOST_CHECK_EQUAL( r.get_status_msg(), "Switching Protocols" );
958 BOOST_CHECK_EQUAL( r.get_header("Upgrade"), "websocket" );
959 BOOST_CHECK_EQUAL( r.get_header("Connection"), "Upgrade" );
960 BOOST_CHECK_EQUAL( r.get_header("Sec-WebSocket-Accept"), "HSmrc0sMlYUkAGmm5OPpG2HaGWk=" );
961 BOOST_CHECK_EQUAL( r.get_header("Sec-WebSocket-Protocol"), "chat" );
962 }
963
BOOST_AUTO_TEST_CASE(wikipedia_example_response_trailing)964 BOOST_AUTO_TEST_CASE( wikipedia_example_response_trailing ) {
965 websocketpp::http::parser::response r;
966
967 std::string raw = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=\r\nSec-WebSocket-Protocol: chat\r\n\r\n";
968 raw += "a";
969
970 bool exception = false;
971 size_t pos = 0;
972
973 try {
974 pos += r.consume(raw.c_str(),raw.size());
975 } catch (std::exception &e) {
976 exception = true;
977 std::cout << e.what() << std::endl;
978 }
979
980 BOOST_CHECK( exception == false );
981 BOOST_CHECK_EQUAL( pos, 159 );
982 BOOST_CHECK( r.headers_ready() == true );
983 BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
984 BOOST_CHECK_EQUAL( r.get_status_code(), websocketpp::http::status_code::switching_protocols );
985 BOOST_CHECK_EQUAL( r.get_status_msg(), "Switching Protocols" );
986 BOOST_CHECK_EQUAL( r.get_header("Upgrade"), "websocket" );
987 BOOST_CHECK_EQUAL( r.get_header("Connection"), "Upgrade" );
988 BOOST_CHECK_EQUAL( r.get_header("Sec-WebSocket-Accept"), "HSmrc0sMlYUkAGmm5OPpG2HaGWk=" );
989 BOOST_CHECK_EQUAL( r.get_header("Sec-WebSocket-Protocol"), "chat" );
990 }
991
BOOST_AUTO_TEST_CASE(wikipedia_example_response_trailing_large)992 BOOST_AUTO_TEST_CASE( wikipedia_example_response_trailing_large ) {
993 websocketpp::http::parser::response r;
994
995 std::string raw = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=\r\nSec-WebSocket-Protocol: chat\r\n\r\n";
996 raw.append(websocketpp::http::max_header_size,'*');
997
998 bool exception = false;
999 size_t pos = 0;
1000
1001 try {
1002 pos += r.consume(raw.c_str(),raw.size());
1003 } catch (std::exception &e) {
1004 exception = true;
1005 std::cout << e.what() << std::endl;
1006 }
1007
1008 BOOST_CHECK( exception == false );
1009 BOOST_CHECK_EQUAL( pos, 159 );
1010 BOOST_CHECK( r.headers_ready() == true );
1011 BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
1012 BOOST_CHECK_EQUAL( r.get_status_code(), websocketpp::http::status_code::switching_protocols );
1013 BOOST_CHECK_EQUAL( r.get_status_msg(), "Switching Protocols" );
1014 BOOST_CHECK_EQUAL( r.get_header("Upgrade"), "websocket" );
1015 BOOST_CHECK_EQUAL( r.get_header("Connection"), "Upgrade" );
1016 BOOST_CHECK_EQUAL( r.get_header("Sec-WebSocket-Accept"), "HSmrc0sMlYUkAGmm5OPpG2HaGWk=" );
1017 BOOST_CHECK_EQUAL( r.get_header("Sec-WebSocket-Protocol"), "chat" );
1018 }
1019
BOOST_AUTO_TEST_CASE(response_with_non_standard_lws)1020 BOOST_AUTO_TEST_CASE( response_with_non_standard_lws ) {
1021 websocketpp::http::parser::response r;
1022
1023 std::string raw = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept:HSmrc0sMlYUkAGmm5OPpG2HaGWk=\r\nSec-WebSocket-Protocol: chat\r\n\r\n";
1024
1025 bool exception = false;
1026 size_t pos = 0;
1027
1028 try {
1029 pos += r.consume(raw.c_str(),raw.size());
1030 } catch (std::exception &e) {
1031 exception = true;
1032 std::cout << e.what() << std::endl;
1033 }
1034
1035 BOOST_CHECK( exception == false );
1036 BOOST_CHECK_EQUAL( pos, 158 );
1037 BOOST_CHECK( r.headers_ready() );
1038 BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
1039 BOOST_CHECK_EQUAL( r.get_status_code(), websocketpp::http::status_code::switching_protocols );
1040 BOOST_CHECK_EQUAL( r.get_status_msg(), "Switching Protocols" );
1041 BOOST_CHECK_EQUAL( r.get_header("Upgrade"), "websocket" );
1042 BOOST_CHECK_EQUAL( r.get_header("Connection"), "Upgrade" );
1043 BOOST_CHECK_EQUAL( r.get_header("Sec-WebSocket-Accept"), "HSmrc0sMlYUkAGmm5OPpG2HaGWk=" );
1044 BOOST_CHECK_EQUAL( r.get_header("Sec-WebSocket-Protocol"), "chat" );
1045 }
1046
BOOST_AUTO_TEST_CASE(plain_http_response)1047 BOOST_AUTO_TEST_CASE( plain_http_response ) {
1048 websocketpp::http::parser::response r;
1049
1050 std::string raw = "HTTP/1.1 200 OK\r\nDate: Thu, 10 May 2012 11:59:25 GMT\r\nServer: Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/0.9.8r DAV/2 PHP/5.3.8 with Suhosin-Patch\r\nLast-Modified: Tue, 30 Mar 2010 17:41:28 GMT\r\nETag: \"16799d-55-4830823a78200\"\r\nAccept-Ranges: bytes\r\nContent-Length: 85\r\nVary: Accept-Encoding\r\nContent-Type: text/html\r\n\r\n<!doctype html>\n<html>\n<head>\n<title>Thor</title>\n</head>\n<body> \n<p>Thor</p>\n</body>";
1051
1052 bool exception = false;
1053 size_t pos = 0;
1054
1055 try {
1056 pos += r.consume(raw.c_str(),raw.size());
1057 } catch (std::exception &e) {
1058 exception = true;
1059 std::cout << e.what() << std::endl;
1060 }
1061
1062 BOOST_CHECK( exception == false );
1063 BOOST_CHECK_EQUAL( pos, 405 );
1064 BOOST_CHECK( r.headers_ready() == true );
1065 BOOST_CHECK( r.ready() == true );
1066 BOOST_CHECK_EQUAL( r.get_version(), "HTTP/1.1" );
1067 BOOST_CHECK_EQUAL( r.get_status_code(), websocketpp::http::status_code::ok );
1068 BOOST_CHECK_EQUAL( r.get_status_msg(), "OK" );
1069 BOOST_CHECK_EQUAL( r.get_header("Date"), "Thu, 10 May 2012 11:59:25 GMT" );
1070 BOOST_CHECK_EQUAL( r.get_header("Server"), "Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/0.9.8r DAV/2 PHP/5.3.8 with Suhosin-Patch" );
1071 BOOST_CHECK_EQUAL( r.get_header("Last-Modified"), "Tue, 30 Mar 2010 17:41:28 GMT" );
1072 BOOST_CHECK_EQUAL( r.get_header("ETag"), "\"16799d-55-4830823a78200\"" );
1073 BOOST_CHECK_EQUAL( r.get_header("Accept-Ranges"), "bytes" );
1074 BOOST_CHECK_EQUAL( r.get_header("Content-Length"), "85" );
1075 BOOST_CHECK_EQUAL( r.get_header("Vary"), "Accept-Encoding" );
1076 BOOST_CHECK_EQUAL( r.get_header("Content-Type"), "text/html" );
1077 BOOST_CHECK_EQUAL( r.get_body(), "<!doctype html>\n<html>\n<head>\n<title>Thor</title>\n</head>\n<body> \n<p>Thor</p>\n</body>" );
1078 }
1079
BOOST_AUTO_TEST_CASE(parse_istream)1080 BOOST_AUTO_TEST_CASE( parse_istream ) {
1081 websocketpp::http::parser::response r;
1082
1083 std::stringstream s;
1084
1085 s << "HTTP/1.1 200 OK\r\nDate: Thu, 10 May 2012 11:59:25 GMT\r\nServer: Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/0.9.8r DAV/2 PHP/5.3.8 with Suhosin-Patch\r\nLast-Modified: Tue, 30 Mar 2010 17:41:28 GMT\r\nETag: \"16799d-55-4830823a78200\"\r\nAccept-Ranges: bytes\r\nContent-Length: 85\r\nVary: Accept-Encoding\r\nContent-Type: text/html\r\n\r\n<!doctype html>\n<html>\n<head>\n<title>Thor</title>\n</head>\n<body> \n<p>Thor</p>\n</body>";
1086
1087 bool exception = false;
1088 size_t pos = 0;
1089
1090 try {
1091 pos += r.consume(s);
1092 } catch (std::exception &e) {
1093 exception = true;
1094 std::cout << e.what() << std::endl;
1095 }
1096
1097 BOOST_CHECK_EQUAL( exception, false );
1098 BOOST_CHECK_EQUAL( pos, 405 );
1099 BOOST_CHECK_EQUAL( r.headers_ready(), true );
1100 BOOST_CHECK_EQUAL( r.ready(), true );
1101 }
1102
BOOST_AUTO_TEST_CASE(write_request_basic)1103 BOOST_AUTO_TEST_CASE( write_request_basic ) {
1104 websocketpp::http::parser::request r;
1105
1106 std::string raw = "GET / HTTP/1.1\r\n\r\n";
1107
1108 r.set_version("HTTP/1.1");
1109 r.set_method("GET");
1110 r.set_uri("/");
1111
1112 BOOST_CHECK_EQUAL( r.raw(), raw );
1113 }
1114
BOOST_AUTO_TEST_CASE(write_request_with_header)1115 BOOST_AUTO_TEST_CASE( write_request_with_header ) {
1116 websocketpp::http::parser::request r;
1117
1118 std::string raw = "GET / HTTP/1.1\r\nHost: http://example.com\r\n\r\n";
1119
1120 r.set_version("HTTP/1.1");
1121 r.set_method("GET");
1122 r.set_uri("/");
1123 r.replace_header("Host","http://example.com");
1124
1125 BOOST_CHECK_EQUAL( r.raw(), raw );
1126 }
1127
BOOST_AUTO_TEST_CASE(write_request_with_body)1128 BOOST_AUTO_TEST_CASE( write_request_with_body ) {
1129 websocketpp::http::parser::request r;
1130
1131 std::string raw = "POST / HTTP/1.1\r\nContent-Length: 48\r\nContent-Type: application/x-www-form-urlencoded\r\nHost: http://example.com\r\n\r\nlicenseID=string&content=string¶msXML=string";
1132
1133 r.set_version("HTTP/1.1");
1134 r.set_method("POST");
1135 r.set_uri("/");
1136 r.replace_header("Host","http://example.com");
1137 r.replace_header("Content-Type","application/x-www-form-urlencoded");
1138 r.set_body("licenseID=string&content=string¶msXML=string");
1139
1140 BOOST_CHECK_EQUAL( r.raw(), raw );
1141 }
1142