1+ #include < http.h>
2+ #include " doctest.h"
3+
4+ TEST_SUITE (" [MESSAGE]" )
5+ {
6+ TEST_CASE (" serialise & parse bad requests" )
7+ {
8+ http::request req;
9+
10+ SUBCASE (" empty" )
11+ {
12+ }
13+
14+ SUBCASE (" missing uri" )
15+ {
16+ req.verb = http::GET;
17+ }
18+
19+ SUBCASE (" missing http version" )
20+ {
21+ req.verb = http::GET;
22+ req.uri = " /index" ;
23+ }
24+
25+ SUBCASE (" missing host" )
26+ {
27+ req.verb = http::GET;
28+ req.uri = " /index" ;
29+ req.http_version_minor = 1 ;
30+ }
31+
32+ SUBCASE (" bad http version" )
33+ {
34+ req.verb = http::GET;
35+ req.uri = " /index" ;
36+ req.http_version_minor = 100 ;
37+ req.add_header (http::host, " www.example.com" );
38+ }
39+
40+ std::error_code ec{};
41+ std::string buf;
42+ http::serialize_header (req, buf, ec);
43+ REQUIRE (bool (ec));
44+ }
45+
46+ TEST_CASE (" serialize & parse good request" )
47+ {
48+ http::request req0;
49+ req0.verb = http::GET;
50+ req0.uri = " /path/to/resource/with%20spaces?q=search+term&empty=&weird=%26%25%3F" ;
51+ req0.http_version_minor = 1 ;
52+ req0.add_header (http::host, " www.example.com:8080" );
53+ req0.add_header (http::user_agent, " CustomTestAgent/7.4.2 (compatible; FancyBot/1.0; +https://example.com/bot)" );
54+ req0.add_header (http::accept, " text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" );
55+ req0.add_header (http::accept_language, " en-US,en;q=0.5" );
56+ req0.add_header (http::accept_encoding, " gzip, deflate, br" );
57+ req0.add_header (http::connection, " keep-alive, Upgrade" );
58+ req0.add_header (http::upgrade, " websocket" );
59+ req0.add_header (http::sec_websocket_key, " x3JJHMbDL1EzLkh9GBhXDw==" );
60+ req0.add_header (http::sec_websocket_version, " 13" );
61+ req0.add_header (http::cache_control, " no-cache, no-store, must-revalidate" );
62+ req0.add_header (http::pragma, " no-cache" );
63+ req0.add_header (http::content_type, " application/json; charset=\" utf-8\" " );
64+ req0.content = " {\" message\" : \" This is a test body with some content.\" }" ;
65+ REQUIRE (req0.keep_alive ());
66+ REQUIRE (req0.is_websocket_req ());
67+
68+ // Serialize
69+ std::error_code ec{};
70+ std::string buf;
71+ http::serialize_header (req0, buf, ec);
72+ buf.append (req0.content );
73+ REQUIRE (!bool (ec));
74+
75+ http::request req1;
76+
77+ SUBCASE (" parse entire message" )
78+ {
79+ const bool finished = http::parser<http::request>{}.parse (req1, buf, ec);
80+ REQUIRE (!bool (ec));
81+ REQUIRE (finished);
82+ }
83+
84+ SUBCASE (" parse block by block" )
85+ {
86+ http::parser<http::request> parser;
87+
88+ size_t blocksize{};
89+
90+ SUBCASE (" " ) { blocksize = 1 ;}
91+ SUBCASE (" " ) { blocksize = 10 ;}
92+ SUBCASE (" " ) { blocksize = 99 ;}
93+ SUBCASE (" " ) { blocksize = 128 ;}
94+ SUBCASE (" " ) { blocksize = 1024 ;}
95+
96+ size_t nblocks = (buf.size () + blocksize - 1 ) / blocksize;
97+ std::string block;
98+
99+ for (size_t i = 0 ; i < nblocks ; ++i)
100+ {
101+ const size_t len = std::min (blocksize, buf.size ());
102+ block.append (&buf[0 ], len);
103+ buf.erase (begin (buf), begin (buf) + len);
104+ const bool finished = parser.parse (req1, block, ec);
105+ REQUIRE (!bool (ec));
106+ REQUIRE (finished == (i == (nblocks-1 )));
107+ }
108+ REQUIRE (block.empty ());
109+ }
110+
111+ REQUIRE (buf.empty ());
112+ REQUIRE (req0.verb == req1.verb );
113+ REQUIRE (req0.http_version_minor == req1.http_version_minor );
114+ REQUIRE (req0.uri == req1.uri );
115+ REQUIRE (req0.headers .size () == req1.headers .size ());
116+ for (size_t i = 0 ; i < req0.headers .size () ; ++i)
117+ {
118+ REQUIRE (req0.headers [i].key == req1.headers [i].key );
119+ REQUIRE (req0.headers [i].value == req1.headers [i].value );
120+ }
121+ REQUIRE (req0.content == req1.content );
122+ }
123+ }
0 commit comments