34 #define MAX_HEADERS 13 35 #define MAX_ELEMENT_SIZE 500 38 #define MIN(a,b) ((a) < (b) ? (a) : (b)) 84 ,.raw=
"GET /test HTTP/1.1\r\n" 85 "User-Agent: curl/7.18.0 (i486-pc-linux-gnu) libcurl/7.18.0 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/1.1\r\n" 86 "Host: 0.0.0.0=5000\r\n" 89 ,.should_keep_alive=
TRUE 90 ,.message_complete_on_eof=
FALSE 94 ,.request_url=
"/test" 97 { {
"User-Agent",
"curl/7.18.0 (i486-pc-linux-gnu) libcurl/7.18.0 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/1.1" }
98 , {
"Host",
"0.0.0.0=5000" }
104 #define FIREFOX_GET 1 105 , {.name=
"firefox get" 107 ,.raw=
"GET /favicon.ico HTTP/1.1\r\n" 108 "Host: 0.0.0.0=5000\r\n" 109 "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9) Gecko/2008061015 Firefox/3.0\r\n" 110 "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" 111 "Accept-Language: en-us,en;q=0.5\r\n" 112 "Accept-Encoding: gzip,deflate\r\n" 113 "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" 114 "Keep-Alive: 300\r\n" 115 "Connection: keep-alive\r\n" 117 ,.should_keep_alive=
TRUE 118 ,.message_complete_on_eof=
FALSE 122 ,.request_url=
"/favicon.ico" 125 { {
"Host",
"0.0.0.0=5000" }
126 , {
"User-Agent",
"Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9) Gecko/2008061015 Firefox/3.0" }
127 , {
"Accept",
"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" }
128 , {
"Accept-Language",
"en-us,en;q=0.5" }
129 , {
"Accept-Encoding",
"gzip,deflate" }
130 , {
"Accept-Charset",
"ISO-8859-1,utf-8;q=0.7,*;q=0.7" }
131 , {
"Keep-Alive",
"300" }
132 , {
"Connection",
"keep-alive" }
140 ,.raw=
"GET /dumbfuck HTTP/1.1\r\n" 141 "aaaaaaaaaaaaa:++++++++++\r\n" 143 ,.should_keep_alive=
TRUE 144 ,.message_complete_on_eof=
FALSE 148 ,.request_url=
"/dumbfuck" 151 { {
"aaaaaaaaaaaaa",
"++++++++++" }
156 #define FRAGMENT_IN_URI 3 157 , {.name=
"fragment in url" 159 ,.raw=
"GET /forums/1/topics/2375?page=1#posts-17408 HTTP/1.1\r\n" 161 ,.should_keep_alive=
TRUE 162 ,.message_complete_on_eof=
FALSE 167 ,.request_url=
"/forums/1/topics/2375?page=1#posts-17408" 172 #define GET_NO_HEADERS_NO_BODY 4 173 , {.name=
"get no headers no body" 175 ,.raw=
"GET /get_no_headers_no_body/world HTTP/1.1\r\n" 177 ,.should_keep_alive=
TRUE 178 ,.message_complete_on_eof=
FALSE 182 ,.request_url=
"/get_no_headers_no_body/world" 187 #define GET_ONE_HEADER_NO_BODY 5 188 , {.name=
"get one header no body" 190 ,.raw=
"GET /get_one_header_no_body HTTP/1.1\r\n" 193 ,.should_keep_alive=
TRUE 194 ,.message_complete_on_eof=
FALSE 198 ,.request_url=
"/get_one_header_no_body" 201 { {
"Accept" ,
"*/*" }
206 #define GET_FUNKY_CONTENT_LENGTH 6 207 , {.name=
"get funky content length body hello" 209 ,.raw=
"GET /get_funky_content_length_body_hello HTTP/1.0\r\n" 210 "conTENT-Length: 5\r\n" 213 ,.should_keep_alive=
FALSE 214 ,.message_complete_on_eof=
FALSE 218 ,.request_url=
"/get_funky_content_length_body_hello" 221 { {
"conTENT-Length" ,
"5" }
226 #define POST_IDENTITY_BODY_WORLD 7 227 , {.name=
"post identity body world" 229 ,.raw=
"POST /post_identity_body_world?q=search#hey HTTP/1.1\r\n" 231 "Transfer-Encoding: identity\r\n" 232 "Content-Length: 5\r\n" 235 ,.should_keep_alive=
TRUE 236 ,.message_complete_on_eof=
FALSE 240 ,.request_url=
"/post_identity_body_world?q=search#hey" 243 { {
"Accept",
"*/*" }
244 , {
"Transfer-Encoding",
"identity" }
245 , {
"Content-Length",
"5" }
250 #define POST_CHUNKED_ALL_YOUR_BASE 8 251 , {.name=
"post - chunked body: all your base are belong to us" 253 ,.raw=
"POST /post_chunked_all_your_base HTTP/1.1\r\n" 254 "Transfer-Encoding: chunked\r\n" 256 "1e\r\nall your base are belong to us\r\n" 259 ,.should_keep_alive=
TRUE 260 ,.message_complete_on_eof=
FALSE 264 ,.request_url=
"/post_chunked_all_your_base" 267 { {
"Transfer-Encoding" ,
"chunked" }
269 ,.body=
"all your base are belong to us" 271 ,.num_chunks_complete= 2
272 ,.chunk_lengths= { 0x1e }
275 #define TWO_CHUNKS_MULT_ZERO_END 9 276 , {.name=
"two chunks ; triple zero ending" 278 ,.raw=
"POST /two_chunks_mult_zero_end HTTP/1.1\r\n" 279 "Transfer-Encoding: chunked\r\n" 285 ,.should_keep_alive=
TRUE 286 ,.message_complete_on_eof=
FALSE 290 ,.request_url=
"/two_chunks_mult_zero_end" 293 { {
"Transfer-Encoding",
"chunked" }
295 ,.body=
"hello world" 297 ,.num_chunks_complete= 3
298 ,.chunk_lengths= { 5, 6 }
301 #define CHUNKED_W_TRAILING_HEADERS 10 302 , {.name=
"chunked with trailing headers. blech." 304 ,.raw=
"POST /chunked_w_trailing_headers HTTP/1.1\r\n" 305 "Transfer-Encoding: chunked\r\n" 311 "Content-Type: text/plain\r\n" 313 ,.should_keep_alive=
TRUE 314 ,.message_complete_on_eof=
FALSE 318 ,.request_url=
"/chunked_w_trailing_headers" 321 { {
"Transfer-Encoding",
"chunked" }
323 , {
"Content-Type",
"text/plain" }
325 ,.body=
"hello world" 327 ,.num_chunks_complete= 3
328 ,.chunk_lengths= { 5, 6 }
331 #define CHUNKED_W_BULLSHIT_AFTER_LENGTH 11 332 , {.name=
"with bullshit after the length" 334 ,.raw=
"POST /chunked_w_bullshit_after_length HTTP/1.1\r\n" 335 "Transfer-Encoding: chunked\r\n" 337 "5; ihatew3;whatthefuck=aretheseparametersfor\r\nhello\r\n" 338 "6; blahblah; blah\r\n world\r\n" 341 ,.should_keep_alive=
TRUE 342 ,.message_complete_on_eof=
FALSE 346 ,.request_url=
"/chunked_w_bullshit_after_length" 349 { {
"Transfer-Encoding",
"chunked" }
351 ,.body=
"hello world" 353 ,.num_chunks_complete= 3
354 ,.chunk_lengths= { 5, 6 }
357 #define WITH_QUOTES 12 358 , {.name=
"with quotes" 360 ,.raw=
"GET /with_\"stupid\"_quotes?foo=\"bar\" HTTP/1.1\r\n\r\n" 361 ,.should_keep_alive=
TRUE 362 ,.message_complete_on_eof=
FALSE 366 ,.request_url=
"/with_\"stupid\"_quotes?foo=\"bar\"" 372 #define APACHEBENCH_GET 13 378 , {.name =
"apachebench get" 380 ,.raw=
"GET /test HTTP/1.0\r\n" 381 "Host: 0.0.0.0:5000\r\n" 382 "User-Agent: ApacheBench/2.3\r\n" 383 "Accept: */*\r\n\r\n" 384 ,.should_keep_alive=
FALSE 385 ,.message_complete_on_eof=
FALSE 389 ,.request_url=
"/test" 391 ,.headers= { {
"Host",
"0.0.0.0:5000" }
392 , {
"User-Agent",
"ApacheBench/2.3" }
393 , {
"Accept",
"*/*" }
398 #define QUERY_URL_WITH_QUESTION_MARK_GET 14 401 , {.name =
"query url with question mark" 403 ,.raw=
"GET /test.cgi?foo=bar?baz HTTP/1.1\r\n\r\n" 404 ,.should_keep_alive=
TRUE 405 ,.message_complete_on_eof=
FALSE 409 ,.request_url=
"/test.cgi?foo=bar?baz" 415 #define PREFIX_NEWLINE_GET 15 419 , {.name =
"newline prefix get" 421 ,.raw=
"\r\nGET /test HTTP/1.1\r\n\r\n" 422 ,.should_keep_alive=
TRUE 423 ,.message_complete_on_eof=
FALSE 427 ,.request_url=
"/test" 433 #define UPGRADE_REQUEST 16 434 , {.name =
"upgrade request" 436 ,.raw=
"GET /demo HTTP/1.1\r\n" 437 "Host: example.com\r\n" 438 "Connection: Upgrade\r\n" 439 "Sec-WebSocket-Key2: 12998 5 Y3 1 .P00\r\n" 440 "Sec-WebSocket-Protocol: sample\r\n" 441 "Upgrade: WebSocket\r\n" 442 "Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5\r\n" 443 "Origin: http://example.com\r\n" 446 ,.should_keep_alive=
TRUE 447 ,.message_complete_on_eof=
FALSE 451 ,.request_url=
"/demo" 453 ,.upgrade=
"Hot diggity dogg" 454 ,.headers= { {
"Host",
"example.com" }
455 , {
"Connection",
"Upgrade" }
456 , {
"Sec-WebSocket-Key2",
"12998 5 Y3 1 .P00" }
457 , {
"Sec-WebSocket-Protocol",
"sample" }
458 , {
"Upgrade",
"WebSocket" }
459 , {
"Sec-WebSocket-Key1",
"4 @1 46546xW%0l 1 5" }
460 , {
"Origin",
"http://example.com" }
465 #define CONNECT_REQUEST 17 466 , {.name =
"connect request" 468 ,.raw=
"CONNECT 0-home0.netscape.com:443 HTTP/1.0\r\n" 469 "User-agent: Mozilla/1.1N\r\n" 470 "Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n" 473 "and yet even more data" 474 ,.should_keep_alive=
FALSE 475 ,.message_complete_on_eof=
FALSE 479 ,.request_url=
"0-home0.netscape.com:443" 481 ,.upgrade=
"some data\r\nand yet even more data" 482 ,.headers= { {
"User-agent",
"Mozilla/1.1N" }
483 , {
"Proxy-authorization",
"basic aGVsbG86d29ybGQ=" }
488 #define REPORT_REQ 18 489 , {.name=
"report request" 491 ,.raw=
"REPORT /test HTTP/1.1\r\n" 493 ,.should_keep_alive=
TRUE 494 ,.message_complete_on_eof=
FALSE 498 ,.request_url=
"/test" 504 #define NO_HTTP_VERSION 19 505 , {.name=
"request with no http version" 509 ,.should_keep_alive=
FALSE 510 ,.message_complete_on_eof=
FALSE 520 #define MSEARCH_REQ 20 521 , {.name=
"m-search request" 523 ,.raw=
"M-SEARCH * HTTP/1.1\r\n" 524 "HOST: 239.255.255.250:1900\r\n" 525 "MAN: \"ssdp:discover\"\r\n" 526 "ST: \"ssdp:all\"\r\n" 528 ,.should_keep_alive=
TRUE 529 ,.message_complete_on_eof=
FALSE 535 ,.headers= { {
"HOST",
"239.255.255.250:1900" }
536 , {
"MAN",
"\"ssdp:discover\"" }
537 , {
"ST",
"\"ssdp:all\"" }
542 #define LINE_FOLDING_IN_HEADER 20 543 , {.name=
"line folding in header value" 545 ,.raw=
"GET / HTTP/1.1\r\n" 552 "Line2: \t line2\t\r\n" 554 ,.should_keep_alive=
TRUE 555 ,.message_complete_on_eof=
FALSE 561 ,.headers= { {
"Line1",
"abc def ghi jkl mno qrs" }
562 , {
"Line2",
"line2\t" }
568 #define QUERY_TERMINATED_HOST 21 569 , {.name=
"host terminated by a query string" 571 ,.raw=
"GET http://hypnotoad.org?hail=all HTTP/1.1\r\n" 573 ,.should_keep_alive=
TRUE 574 ,.message_complete_on_eof=
FALSE 578 ,.request_url=
"http://hypnotoad.org?hail=all" 584 #define QUERY_TERMINATED_HOSTPORT 22 585 , {.name=
"host:port terminated by a query string" 587 ,.raw=
"GET http://hypnotoad.org:1234?hail=all HTTP/1.1\r\n" 589 ,.should_keep_alive=
TRUE 590 ,.message_complete_on_eof=
FALSE 594 ,.request_url=
"http://hypnotoad.org:1234?hail=all" 600 #define SPACE_TERMINATED_HOSTPORT 23 601 , {.name=
"host:port terminated by a space" 603 ,.raw=
"GET http://hypnotoad.org:1234 HTTP/1.1\r\n" 605 ,.should_keep_alive=
TRUE 606 ,.message_complete_on_eof=
FALSE 610 ,.request_url=
"http://hypnotoad.org:1234" 616 #if !HTTP_PARSER_STRICT 617 #define UTF8_PATH_REQ 24 618 , {.name=
"utf-8 path request" 620 ,.raw=
"GET /δ¶/δt/pope?q=1#narf HTTP/1.1\r\n" 621 "Host: github.com\r\n" 623 ,.should_keep_alive=
TRUE 624 ,.message_complete_on_eof=
FALSE 628 ,.request_url=
"/δ¶/δt/pope?q=1#narf" 630 ,.headers= { {
"Host",
"github.com" }
635 #define HOSTNAME_UNDERSCORE 25 636 , {.name =
"hostname underscore" 638 ,.raw=
"CONNECT home_0.netscape.com:443 HTTP/1.0\r\n" 639 "User-agent: Mozilla/1.1N\r\n" 640 "Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n" 642 ,.should_keep_alive=
FALSE 643 ,.message_complete_on_eof=
FALSE 647 ,.request_url=
"home_0.netscape.com:443" 650 ,.headers= { {
"User-agent",
"Mozilla/1.1N" }
651 , {
"Proxy-authorization",
"basic aGVsbG86d29ybGQ=" }
658 , {.name =
"PATCH request" 660 ,.raw=
"PATCH /file.txt HTTP/1.1\r\n" 661 "Host: www.example.com\r\n" 662 "Content-Type: application/example\r\n" 663 "If-Match: \"e0023aa4e\"\r\n" 664 "Content-Length: 10\r\n" 667 ,.should_keep_alive=
TRUE 668 ,.message_complete_on_eof=
FALSE 672 ,.request_url=
"/file.txt" 674 ,.headers= { {
"Host",
"www.example.com" }
675 , {
"Content-Type",
"application/example" }
676 , {
"If-Match",
"\"e0023aa4e\"" }
677 , {
"Content-Length",
"10" }
682 #define CONNECT_CAPS_REQUEST 27 683 , {.name =
"connect caps request" 685 ,.raw=
"CONNECT HOME0.NETSCAPE.COM:443 HTTP/1.0\r\n" 686 "User-agent: Mozilla/1.1N\r\n" 687 "Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n" 689 ,.should_keep_alive=
FALSE 690 ,.message_complete_on_eof=
FALSE 694 ,.request_url=
"HOME0.NETSCAPE.COM:443" 697 ,.headers= { {
"User-agent",
"Mozilla/1.1N" }
698 , {
"Proxy-authorization",
"basic aGVsbG86d29ybGQ=" }
703 #define IPV6_LITERAL_URI_GET 28 704 , {.name =
"IPv6 literal URI GET" 706 ,.raw=
"GET http://[2a03:2880:2050:1f01:face:b00c:0:9]/ HTTP/1.0\r\n" 708 ,.should_keep_alive=
FALSE 709 ,.message_complete_on_eof=
FALSE 713 ,.request_url=
"http://[2a03:2880:2050:1f01:face:b00c:0:9]/" 719 #define IPV6_LITERAL_URI_CONNECT 29 720 , {.name =
"IPv6 literal URI CONNECT" 722 ,.raw=
"CONNECT [2a03:2880:2050:1f01:face:b00c:0:9]:443 HTTP/1.0\r\n" 724 ,.should_keep_alive=
FALSE 725 ,.message_complete_on_eof=
FALSE 729 ,.request_url=
"[2a03:2880:2050:1f01:face:b00c:0:9]:443" 736 #define UPGRADE_POST_REQUEST 30 737 , {.name =
"upgrade post request" 739 ,.raw=
"POST /demo HTTP/1.1\r\n" 740 "Host: example.com\r\n" 741 "Connection: Upgrade\r\n" 742 "Upgrade: HTTP/2.0\r\n" 743 "Content-Length: 15\r\n" 747 ,.should_keep_alive=
TRUE 748 ,.message_complete_on_eof=
FALSE 752 ,.request_url=
"/demo" 754 ,.upgrade=
"Hot diggity dogg" 755 ,.headers= { {
"Host",
"example.com" }
756 , {
"Connection",
"Upgrade" }
757 , {
"Upgrade",
"HTTP/2.0" }
758 , {
"Content-Length",
"15" }
760 ,.body=
"sweet post body" 763 #define CONNECT_WITH_BODY_REQUEST 31 764 , {.name =
"connect with body request" 766 ,.raw=
"CONNECT foo.bar.com:443 HTTP/1.0\r\n" 767 "User-agent: Mozilla/1.1N\r\n" 768 "Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n" 769 "Content-Length: 10\r\n" 772 ,.should_keep_alive=
FALSE 773 ,.message_complete_on_eof=
FALSE 777 ,.request_url=
"foo.bar.com:443" 779 ,.upgrade=
"blarfcicle" 780 ,.headers= { {
"User-agent",
"Mozilla/1.1N" }
781 , {
"Proxy-authorization",
"basic aGVsbG86d29ybGQ=" }
782 , {
"Content-Length",
"10" }
793 { {.
name=
"google 301" 795 ,.raw=
"HTTP/1.1 301 Moved Permanently\r\n" 796 "Location: http://www.google.com/\r\n" 797 "Content-Type: text/html; charset=UTF-8\r\n" 798 "Date: Sun, 26 Apr 2009 11:11:49 GMT\r\n" 799 "Expires: Tue, 26 May 2009 11:11:49 GMT\r\n" 800 "X-$PrototypeBI-Version: 1.6.0.3\r\n" 801 "Cache-Control: public, max-age=2592000\r\n" 803 "Content-Length: 219 \r\n" 805 "<HTML><HEAD><meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\">\n" 806 "<TITLE>301 Moved</TITLE></HEAD><BODY>\n" 807 "<H1>301 Moved</H1>\n" 808 "The document has moved\n" 809 "<A HREF=\"http://www.google.com/\">here</A>.\r\n" 811 ,.should_keep_alive=
TRUE 812 ,.message_complete_on_eof=
FALSE 816 ,.response_reason=
"Moved Permanently" 819 { {
"Location",
"http://www.google.com/" }
820 , {
"Content-Type",
"text/html; charset=UTF-8" }
821 , {
"Date",
"Sun, 26 Apr 2009 11:11:49 GMT" }
822 , {
"Expires",
"Tue, 26 May 2009 11:11:49 GMT" }
823 , {
"X-$PrototypeBI-Version",
"1.6.0.3" }
824 , {
"Cache-Control",
"public, max-age=2592000" }
825 , {
"Server",
"gws" }
826 , {
"Content-Length",
"219 " }
828 ,.body=
"<HTML><HEAD><meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\">\n" 829 "<TITLE>301 Moved</TITLE></HEAD><BODY>\n" 830 "<H1>301 Moved</H1>\n" 831 "The document has moved\n" 832 "<A HREF=\"http://www.google.com/\">here</A>.\r\n" 836 #define NO_CONTENT_LENGTH_RESPONSE 1 842 , {.name=
"no content-length response" 844 ,.raw=
"HTTP/1.1 200 OK\r\n" 845 "Date: Tue, 04 Aug 2009 07:59:32 GMT\r\n" 847 "X-Powered-By: Servlet/2.5 JSP/2.1\r\n" 848 "Content-Type: text/xml; charset=utf-8\r\n" 849 "Connection: close\r\n" 851 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" 852 "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" 854 " <SOAP-ENV:Fault>\n" 855 " <faultcode>SOAP-ENV:Client</faultcode>\n" 856 " <faultstring>Client Error</faultstring>\n" 857 " </SOAP-ENV:Fault>\n" 858 " </SOAP-ENV:Body>\n" 859 "</SOAP-ENV:Envelope>" 860 ,.should_keep_alive=
FALSE 861 ,.message_complete_on_eof=
TRUE 865 ,.response_reason=
"OK" 868 { {
"Date",
"Tue, 04 Aug 2009 07:59:32 GMT" }
869 , {
"Server",
"Apache" }
870 , {
"X-Powered-By",
"Servlet/2.5 JSP/2.1" }
871 , {
"Content-Type",
"text/xml; charset=utf-8" }
872 , {
"Connection",
"close" }
874 ,.body=
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" 875 "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">\n" 877 " <SOAP-ENV:Fault>\n" 878 " <faultcode>SOAP-ENV:Client</faultcode>\n" 879 " <faultstring>Client Error</faultstring>\n" 880 " </SOAP-ENV:Fault>\n" 881 " </SOAP-ENV:Body>\n" 882 "</SOAP-ENV:Envelope>" 885 #define NO_HEADERS_NO_BODY_404 2 886 , {.name=
"404 no headers no body" 888 ,.raw=
"HTTP/1.1 404 Not Found\r\n\r\n" 889 ,.should_keep_alive=
FALSE 890 ,.message_complete_on_eof=
TRUE 894 ,.response_reason=
"Not Found" 895 ,.num_headers= 0 ,.headers= {}
900 #define NO_REASON_PHRASE 3 901 , {.name=
"304 no response phrase" 903 ,.raw=
"HTTP/1.1 304\r\n\r\n" 904 ,.should_keep_alive =
TRUE 905 ,.message_complete_on_eof=
FALSE 909 ,.response_reason=
"" 915 #define TRAILING_SPACE_ON_CHUNKED_BODY 4 916 , {.name=
"200 trailing space on chunked body" 918 ,.raw=
"HTTP/1.1 200 OK\r\n" 919 "Content-Type: text/plain\r\n" 920 "Transfer-Encoding: chunked\r\n" 923 "This is the data in the first chunk\r\n" 926 "and this is the second one\r\n" 930 ,.should_keep_alive=
TRUE 931 ,.message_complete_on_eof=
FALSE 935 ,.response_reason=
"OK" 938 { {
"Content-Type",
"text/plain" }
939 , {
"Transfer-Encoding",
"chunked" }
943 "This is the data in the first chunk\r\n" 944 "and this is the second one\r\n" 946 ,.num_chunks_complete= 3
947 ,.chunk_lengths= { 0x25, 0x1c }
951 #define NO_CARRIAGE_RET 5 952 , {.name=
"no carriage ret" 954 ,.raw=
"HTTP/1.1 200 OK\n" 955 "Content-Type: text/html; charset=utf-8\n" 956 "Connection: close\n" 958 "these headers are from http://news.ycombinator.com/" 959 ,.should_keep_alive=
FALSE 960 ,.message_complete_on_eof=
TRUE 964 ,.response_reason=
"OK" 967 { {
"Content-Type",
"text/html; charset=utf-8" }
968 , {
"Connection",
"close" }
970 ,.body=
"these headers are from http://news.ycombinator.com/" 973 #define PROXY_CONNECTION 6 974 , {.name=
"proxy connection" 976 ,.raw=
"HTTP/1.1 200 OK\r\n" 977 "Content-Type: text/html; charset=UTF-8\r\n" 978 "Content-Length: 11\r\n" 979 "Proxy-Connection: close\r\n" 980 "Date: Thu, 31 Dec 2009 20:55:48 +0000\r\n" 983 ,.should_keep_alive=
FALSE 984 ,.message_complete_on_eof=
FALSE 988 ,.response_reason=
"OK" 991 { {
"Content-Type",
"text/html; charset=UTF-8" }
992 , {
"Content-Length",
"11" }
993 , {
"Proxy-Connection",
"close" }
994 , {
"Date",
"Thu, 31 Dec 2009 20:55:48 +0000"}
996 ,.body=
"hello world" 999 #define UNDERSTORE_HEADER_KEY 7 1002 , {.name=
"underscore header key" 1004 ,.raw=
"HTTP/1.1 200 OK\r\n" 1005 "Server: DCLK-AdSvr\r\n" 1006 "Content-Type: text/xml\r\n" 1007 "Content-Length: 0\r\n" 1008 "DCLK_imp: v7;x;114750856;0-0;0;17820020;0/0;21603567/21621457/1;;~okv=;dcmt=text/xml;;~cs=o\r\n\r\n" 1009 ,.should_keep_alive=
TRUE 1010 ,.message_complete_on_eof=
FALSE 1014 ,.response_reason=
"OK" 1017 { {
"Server",
"DCLK-AdSvr" }
1018 , {
"Content-Type",
"text/xml" }
1019 , {
"Content-Length",
"0" }
1020 , {
"DCLK_imp",
"v7;x;114750856;0-0;0;17820020;0/0;21603567/21621457/1;;~okv=;dcmt=text/xml;;~cs=o" }
1025 #define BONJOUR_MADAME_FR 8 1029 , {.name=
"bonjourmadame.fr" 1031 ,.raw=
"HTTP/1.0 301 Moved Permanently\r\n" 1032 "Date: Thu, 03 Jun 2010 09:56:32 GMT\r\n" 1033 "Server: Apache/2.2.3 (Red Hat)\r\n" 1034 "Cache-Control: public\r\n" 1036 "Location: http://www.bonjourmadame.fr/\r\n" 1037 "Vary: Accept-Encoding\r\n" 1038 "Content-Length: 0\r\n" 1039 "Content-Type: text/html; charset=UTF-8\r\n" 1040 "Connection: keep-alive\r\n" 1042 ,.should_keep_alive=
TRUE 1043 ,.message_complete_on_eof=
FALSE 1047 ,.response_reason=
"Moved Permanently" 1050 { {
"Date",
"Thu, 03 Jun 2010 09:56:32 GMT" }
1051 , {
"Server",
"Apache/2.2.3 (Red Hat)" }
1052 , {
"Cache-Control",
"public" }
1054 , {
"Location",
"http://www.bonjourmadame.fr/" }
1055 , {
"Vary",
"Accept-Encoding" }
1056 , {
"Content-Length",
"0" }
1057 , {
"Content-Type",
"text/html; charset=UTF-8" }
1058 , {
"Connection",
"keep-alive" }
1063 #define RES_FIELD_UNDERSCORE 10 1065 , {.name=
"field underscore" 1067 ,.raw=
"HTTP/1.1 200 OK\r\n" 1068 "Date: Tue, 28 Sep 2010 01:14:13 GMT\r\n" 1069 "Server: Apache\r\n" 1070 "Cache-Control: no-cache, must-revalidate\r\n" 1071 "Expires: Mon, 26 Jul 1997 05:00:00 GMT\r\n" 1072 ".et-Cookie: PlaxoCS=1274804622353690521; path=/; domain=.plaxo.com\r\n" 1073 "Vary: Accept-Encoding\r\n" 1074 "_eep-Alive: timeout=45\r\n" 1075 "_onnection: Keep-Alive\r\n" 1076 "Transfer-Encoding: chunked\r\n" 1077 "Content-Type: text/html\r\n" 1078 "Connection: close\r\n" 1081 ,.should_keep_alive=
FALSE 1082 ,.message_complete_on_eof=
FALSE 1086 ,.response_reason=
"OK" 1089 { {
"Date",
"Tue, 28 Sep 2010 01:14:13 GMT" }
1090 , {
"Server",
"Apache" }
1091 , {
"Cache-Control",
"no-cache, must-revalidate" }
1092 , {
"Expires",
"Mon, 26 Jul 1997 05:00:00 GMT" }
1093 , {
".et-Cookie",
"PlaxoCS=1274804622353690521; path=/; domain=.plaxo.com" }
1094 , {
"Vary",
"Accept-Encoding" }
1095 , {
"_eep-Alive",
"timeout=45" }
1096 , {
"_onnection",
"Keep-Alive" }
1097 , {
"Transfer-Encoding",
"chunked" }
1098 , {
"Content-Type",
"text/html" }
1099 , {
"Connection",
"close" }
1103 ,.num_chunks_complete= 1
1107 #define NON_ASCII_IN_STATUS_LINE 11 1109 , {.name=
"non-ASCII in status line" 1111 ,.raw=
"HTTP/1.1 500 Oriëntatieprobleem\r\n" 1112 "Date: Fri, 5 Nov 2010 23:07:12 GMT+2\r\n" 1113 "Content-Length: 0\r\n" 1114 "Connection: close\r\n" 1116 ,.should_keep_alive=
FALSE 1117 ,.message_complete_on_eof=
FALSE 1121 ,.response_reason=
"Oriëntatieprobleem" 1124 { {
"Date",
"Fri, 5 Nov 2010 23:07:12 GMT+2" }
1125 , {
"Content-Length",
"0" }
1126 , {
"Connection",
"close" }
1139 { {.
name=
"Invalid response" 1142 ,.should_keep_alive=
FALSE 1143 ,.message_complete_on_eof=
FALSE 1148 {.name=
"Invalid request" 1151 ,.should_keep_alive=
FALSE 1152 ,.message_complete_on_eof=
FALSE 1157 {.name=
"Invalid 'both' 'request/response'" 1160 ,.should_keep_alive=
FALSE 1161 ,.message_complete_on_eof=
FALSE 1166 {.name=
"Simple valid 200 reponse" 1168 ,.raw=
"HTTP/1.1 200 OK\r\n" 1169 ,.should_keep_alive=
FALSE 1170 ,.message_complete_on_eof=
FALSE 1175 {.name=
"Simple valid request" 1177 ,.raw=
"GET / HTTP/1.1\r\n" 1178 ,.should_keep_alive=
FALSE 1179 ,.message_complete_on_eof=
FALSE 1184 {.name=
"Simple valid 'both' request" 1186 ,.raw=
"GET / HTTP/1.1\r\n" 1187 ,.should_keep_alive=
FALSE 1188 ,.message_complete_on_eof=
FALSE 1193 {.name=
"Simple valid 'both' response" 1195 ,.raw=
"GET / HTTP/1.1\r\n" 1196 ,.should_keep_alive=
FALSE 1197 ,.message_complete_on_eof=
FALSE 1206 assert(p == parser);
1214 assert(p == parser);
1230 assert(p == parser);
1248 assert(p == parser);
1258 assert(p == parser);
1267 assert(p == parser);
1275 assert(p == parser);
1288 assert(p == parser);
1300 assert(p == parser);
1308 assert(p == parser);
1326 assert(p == parser);
1337 fprintf(stderr,
"\n\n*** on_message_begin() called on paused parser ***\n\n");
1344 if (p || buf || len) { }
1345 fprintf(stderr,
"\n\n*** on_header_field() called on paused parser ***\n\n");
1352 if (p || buf || len) { }
1353 fprintf(stderr,
"\n\n*** on_header_value() called on paused parser ***\n\n");
1360 if (p || buf || len) { }
1361 fprintf(stderr,
"\n\n*** on_request_url() called on paused parser ***\n\n");
1368 if (p || buf || len) { }
1369 fprintf(stderr,
"\n\n*** on_body_cb() called on paused parser ***\n\n");
1376 if (p || buf || len) { }
1377 fprintf(stderr,
"\n\n*** on_headers_complete() called on paused " 1386 fprintf(stderr,
"\n\n*** on_message_complete() called on paused " 1394 if (p || buf || len) { }
1395 fprintf(stderr,
"\n\n*** on_reason() called on paused parser ***\n\n");
1403 fprintf(stderr,
"\n\n*** on_chunk_header() called on paused parser ***\n\n");
1411 fprintf(stderr,
"\n\n*** on_chunk_complete() " 1412 "called on paused parser ***\n\n");
1573 assert(parser == NULL);
1591 size_t parse (
const char *buf,
size_t len)
1613 current_pause_parser = &
s;
1621 const char *expected,
1622 const char *found) {
1623 if ((expected == NULL) != (found == NULL)) {
1624 printf(
"\n*** Error: %s in '%s' ***\n\n", prop, m->
name);
1625 printf(
"expected %s\n", (expected == NULL) ?
"NULL" : expected);
1626 printf(
" found %s\n", (found == NULL) ?
"NULL" : found);
1629 if (expected != NULL && 0 != strcmp(expected, found)) {
1630 printf(
"\n*** Error: %s in '%s' ***\n\n", prop, m->
name);
1631 printf(
"expected '%s'\n", expected);
1632 printf(
" found '%s'\n", found);
1643 if (expected != found) {
1644 printf(
"\n*** Error: %s in '%s' ***\n\n", prop, m->
name);
1645 printf(
"expected %d\n", expected);
1646 printf(
" found %d\n", found);
1652 #define MESSAGE_CHECK_STR_EQ(expected, found, prop) \ 1653 if (!check_str_eq(expected, #prop, expected->prop, found->prop)) return 0 1655 #define MESSAGE_CHECK_NUM_EQ(expected, found, prop) \ 1656 if (!check_num_eq(expected, #prop, expected->prop, found->prop)) return 0 1719 va_start(ap, nmsgs);
1721 for (i = 0; i < nmsgs; i++) {
1743 va_start(ap, nmsgs);
1745 for (i = 0; i < nmsgs; i++) {
1748 off += strlen(m->
raw);
1754 if (!
check_str_eq(m,
"upgrade", body + off, body + nread)) {
1760 *(body + nread + strlen(m->
upgrade)) =
'\0';
1769 printf(
"\n\n*** Error: expected a message with upgrade ***\n");
1777 fprintf(stderr,
"\n*** %s:%d -- %s ***\n\n",
1781 int this_line = 0, char_len = 0;
1782 size_t i, j, len = strlen(raw), error_location_line = 0;
1783 for (i = 0; i < len; i++) {
1784 if (i == error_location) this_line = 1;
1788 fprintf(stderr,
"\\r");
1793 fprintf(stderr,
"\\n\n");
1795 if (this_line)
goto print;
1797 error_location_line = 0;
1802 fputc(raw[i], stderr);
1805 if (!this_line) error_location_line += char_len;
1808 fprintf(stderr,
"[eof]\n");
1811 for (j = 0; j < error_location_line; j++) {
1814 fprintf(stderr,
"^\n\nerror location: %u\n", (
unsigned int)error_location);
1827 { {.
name=
"proxy request" 1828 ,.url=
"http://hostname/" 1846 , {.name=
"proxy request with port" 1847 ,.url=
"http://hostname:444/" 1865 , {.name=
"CONNECT request" 1866 ,.url=
"hostname:443" 1884 , {.name=
"CONNECT request but not connect" 1885 ,.url=
"hostname:443" 1890 , {.name=
"proxy ipv6 request" 1891 ,.url=
"http://[1:2::3:4]/" 1909 , {.name=
"proxy ipv6 request with port" 1910 ,.url=
"http://[1:2::3:4]:67/" 1928 , {.name=
"CONNECT ipv6 address" 1929 ,.url=
"[1:2::3:4]:443" 1947 , {.name=
"ipv4 in ipv6 address" 1948 ,.url=
"http://[2001:0000:0000:0000:0000:0000:1.9.1.1]/" 1966 , {.name=
"extra ? in query string" 1967 ,.url=
"http://a.tbcdn.cn/p/fp/2010c/??fp-header-min.css,fp-base-min.css," 1968 "fp-channel-min.css,fp-product-min.css,fp-mall-min.css,fp-category-min.css," 1969 "fp-sub-min.css,fp-gdp4p-min.css,fp-css3-min.css,fp-misc-min.css?t=20101022.css" 1987 , {.name=
"space URL encoded" 1988 ,.url=
"/toto.html?toto=a%20b" 2007 , {.name=
"URL fragment" 2008 ,.url=
"/toto.html#titi" 2026 , {.name=
"complex URL fragment" 2027 ,.url=
"http://www.webmasterworld.com/r.cgi?f=21&d=8405&url=" 2028 "http://www.example.com/index.html?foo=bar&hello=world#midpage" 2047 , {.name=
"complex URL from node js url parser doc" 2048 ,.url=
"http://host.com:8080/p/a/t/h?query=string#hash" 2067 , {.name=
"complex URL with basic auth from node js url parser doc" 2068 ,.url=
"http://a:b@host.com:8080/p/a/t/h?query=string#hash" 2088 ,.url=
"http://a:b@@hostname:443/" 2093 , {.name=
"proxy empty host" 2094 ,.url=
"http://:443/" 2099 , {.name=
"proxy empty port" 2100 ,.url=
"http://hostname:/" 2105 , {.name=
"CONNECT with basic auth" 2106 ,.url=
"a:b@hostname:443" 2111 , {.name=
"CONNECT empty host" 2117 , {.name=
"CONNECT empty port" 2123 , {.name=
"CONNECT with extra bits" 2124 ,.url=
"hostname:443/" 2129 , {.name=
"space in URL" 2134 , {.name=
"proxy basic auth with space url encoded" 2135 ,.url=
"http://a%20:b@host.com/" 2153 , {.name=
"carriage return in URL" 2158 , {.name=
"proxy double : in URL" 2159 ,.url=
"http://hostname::443/" 2163 , {.name=
"proxy basic auth with double :" 2164 ,.url=
"http://a::b@host.com/" 2182 , {.name=
"line feed in URL" 2187 , {.name=
"proxy empty basic auth" 2188 ,.url=
"http://@hostname/fo" 2204 , {.name=
"proxy line feed in hostname" 2205 ,.url=
"http://host\name/fo" 2209 , {.name=
"proxy % in hostname" 2210 ,.url=
"http://host%name/fo" 2214 , {.name=
"proxy ; in hostname" 2215 ,.url=
"http://host;ame/fo" 2219 , {.name=
"proxy basic auth with unreservedchars" 2220 ,.url=
"http://a!;-_!=+$@host.com/" 2238 , {.name=
"proxy only empty basic auth" 2243 , {.name=
"proxy only basic auth" 2244 ,.url=
"http://toto@/fo" 2248 , {.name=
"proxy emtpy hostname" 2253 , {.name=
"proxy = in URL" 2254 ,.url=
"http://host=ame/fo" 2258 #if HTTP_PARSER_STRICT 2260 , {.name=
"tab in URL" 2265 , {.name=
"form feed in URL" 2272 , {.name=
"tab in URL" 2289 , {.name=
"form feed in URL" 2313 printf(
"\tfield_set: 0x%x, port: %u\n", u->
field_set, u->
port);
2314 for (i = 0; i <
UF_MAX; i++) {
2316 printf(
"\tfield_data[%u]: unset\n", i);
2320 printf(
"\tfield_data[%u]: off: %u len: %u part: \"%.*s\n\"",
2337 for (i = 0; i < (
sizeof(
url_tests) /
sizeof(url_tests[0])); i++) {
2338 test = &url_tests[
i];
2339 memset(&u, 0,
sizeof(u));
2346 if (test->
rv == 0) {
2348 printf(
"\n*** http_parser_parse_url(\"%s\") \"%s\" test failed, " 2349 "unexpected rv %d ***\n\n", test->
url, test->
name, rv);
2353 if (memcmp(&u, &test->
u,
sizeof(u)) != 0) {
2354 printf(
"\n*** http_parser_parse_url(\"%s\") \"%s\" failed ***\n",
2357 printf(
"target http_parser_url:\n");
2359 printf(
"result http_parser_url:\n");
2367 printf(
"\n*** http_parser_parse_url(\"%s\") \"%s\" test failed, " 2368 "unexpected rv %d ***\n\n", test->
url, test->
name, rv);
2379 size_t raw_len = strlen(message->
raw);
2381 for (msg1len = 0; msg1len < raw_len; msg1len++) {
2385 const char *msg1 = message->
raw;
2386 const char *msg2 = msg1 + msg1len;
2387 size_t msg2len = raw_len - msg1len;
2390 read =
parse(msg1, msg1len);
2397 if (read != msg1len) {
2404 read =
parse(msg2, msg2len);
2411 if (read != msg2len) {
2416 read =
parse(NULL, 0);
2426 printf(
"\n*** num_messages != 1 after testing '%s' ***\n\n", message->
name);
2442 size_t l = strlen(message->
raw);
2444 size_t chunk = 4024;
2446 for (i = 0; i < l; i+= chunk) {
2447 toread =
MIN(l-i, chunk);
2449 if (read != toread) {
2463 printf(
"\n*** num_messages != 1 after testing '%s' ***\n\n", message->
name);
2481 parsed =
parse(buf, strlen(buf));
2482 pass = (parsed == strlen(buf));
2484 parsed =
parse(NULL, 0);
2485 pass &= (parsed == 0);
2492 #if HTTP_PARSER_STRICT 2495 if (err_expected != err) {
2497 fprintf(stderr,
"\n*** test_simple expected %s, but saw %s ***\n\n%s\n",
2510 buf = req ?
"GET / HTTP/1.1\r\n" :
"HTTP/1.0 200 OK\r\n";
2512 assert(parsed == strlen(buf));
2514 buf =
"header-key: header-value\r\n";
2515 size_t buflen = strlen(buf);
2518 for (i = 0; i < 10000; i++) {
2520 if (parsed != buflen) {
2527 fprintf(stderr,
"\n*** Error expected but none in header overflow test ***\n");
2539 size_t buf1len = sprintf(buf1,
"%s\r\nConnection: Keep-Alive\r\nContent-Length: %zu\r\n\r\n",
2540 req ?
"POST / HTTP/1.0" :
"HTTP/1.0 200 OK", length);
2542 if (parsed != buf1len)
2545 for (i = 0; i < length; i++) {
2553 if (parsed != buf1len)
goto err;
2558 "\n*** error in test_no_overflow_long_body %s of length %zu ***\n",
2559 req ?
"REQUEST" :
"RESPONSE",
2569 char total[ strlen(r1->
raw)
2576 strcat(total, r1->
raw);
2577 strcat(total, r2->
raw);
2578 strcat(total, r3->
raw);
2584 read =
parse(total, strlen(total));
2591 if (read != strlen(total)) {
2596 read =
parse(NULL, 0);
2606 fprintf(stderr,
"\n\n*** Parser didn't see 3 messages only %d *** \n",
num_messages);
2611 if (message_count > 1 && !
message_eq(1, r2)) exit(1);
2612 if (message_count > 2 && !
message_eq(2, r3)) exit(1);
2624 char total[80*1024] =
"\0";
2625 char buf1[80*1024] =
"\0";
2626 char buf2[80*1024] =
"\0";
2627 char buf3[80*1024] =
"\0";
2629 strcat(total, r1->
raw);
2630 strcat(total, r2->
raw);
2631 strcat(total, r3->
raw);
2635 int total_len = strlen(total);
2637 int total_ops = 2 * (total_len - 1) * (total_len - 2) / 2;
2640 size_t buf1_len, buf2_len, buf3_len;
2644 for (type_both = 0; type_both < 2; type_both ++ ) {
2645 for (j = 2; j < total_len; j ++ ) {
2646 for (i = 1; i < j; i ++ ) {
2648 if (ops % 1000 == 0) {
2649 printf(
"\b\b\b\b%3.0f%%", 100 * (
float)ops /(
float)total_ops);
2657 strncpy(buf1, total, buf1_len);
2661 strncpy(buf2, total+i, buf2_len);
2664 buf3_len = total_len - j;
2665 strncpy(buf3, total+j, buf3_len);
2668 read =
parse(buf1, buf1_len);
2672 if (read != buf1_len) {
2677 read +=
parse(buf2, buf2_len);
2681 if (read != buf1_len + buf2_len) {
2686 read +=
parse(buf3, buf3_len);
2689 if (read != buf1_len + buf2_len + buf3_len) {
2702 fprintf(stderr,
"\n\nParser didn't see %d messages only %d\n",
2708 fprintf(stderr,
"\n\nError matching messages[0] in test_scan.\n");
2712 if (message_count > 1 && !
message_eq(1, r2)) {
2713 fprintf(stderr,
"\n\nError matching messages[1] in test_scan.\n");
2717 if (message_count > 2 && !
message_eq(2, r3)) {
2718 fprintf(stderr,
"\n\nError matching messages[2] in test_scan.\n");
2726 puts(
"\b\b\b\b100%");
2730 fprintf(stderr,
"i=%d j=%d\n", i, j);
2731 fprintf(stderr,
"buf1 (%u) %s\n\n", (
unsigned int)buf1_len, buf1);
2732 fprintf(stderr,
"buf2 (%u) %s\n\n", (
unsigned int)buf2_len , buf2);
2733 fprintf(stderr,
"buf3 (%u) %s\n", (
unsigned int)buf3_len, buf3);
2744 size_t headers_len = strlen(headers);
2745 size_t bufsize = headers_len + (5+1024+2)*body_size_in_kb + 6;
2746 char * buf = malloc(bufsize);
2748 memcpy(buf, headers, headers_len);
2749 wrote += headers_len;
2751 for (i = 0; i < body_size_in_kb; i++) {
2753 memcpy(buf + wrote,
"400\r\n", 5);
2755 memset(buf + wrote,
'C', 1024);
2757 strcpy(buf + wrote,
"\r\n");
2761 memcpy(buf + wrote,
"0\r\n\r\n", 6);
2763 assert(wrote == bufsize);
2773 char *buf = (
char*) msg->
raw;
2774 size_t buflen = strlen(msg->
raw);
2791 if (nread < buflen) {
2805 }
while (buflen > 0);
2808 assert (nread == 0);
2812 printf(
"\n*** num_messages != 1 after testing '%s' ***\n\n", msg->
name);
2840 int on_message_begin_cb_count;
2842 printf(
"sizeof(http_parser) = %u\n", (
unsigned int)
sizeof(
http_parser));
2844 for (request_count = 0; requests[request_count].
name; request_count++);
2845 for (response_count = 0; responses[response_count].
name; response_count++);
2846 for (on_message_begin_cb_count = 0;
2847 on_message_begin_cb_test[on_message_begin_cb_count].
name;
2848 on_message_begin_cb_count++);
2854 for (i = 0 ; i < on_message_begin_cb_count; i++) {
2870 for (i = 0; i < response_count; i++) {
2874 for (i = 0; i < response_count; i++) {
2878 for (i = 0; i < response_count; i++) {
2880 for (j = 0; j < response_count; j++) {
2881 if (!responses[j].should_keep_alive)
continue;
2882 for (k = 0; k < response_count; k++) {
2894 "HTTP/1.0 200 OK\r\n" 2895 "Transfer-Encoding: chunked\r\n" 2896 "Content-Type: text/plain\r\n" 2898 struct message large_chunked =
2899 {.
name=
"large chunked" 2902 ,.should_keep_alive=
FALSE 2903 ,.message_complete_on_eof=
FALSE 2907 ,.response_reason=
"OK" 2910 { {
"Transfer-Encoding",
"chunked" }
2911 , {
"Content-Type",
"text/plain" }
2913 ,.body_size= 31337*1024
2915 ,.num_chunks_complete= 31338
2926 printf(
"response scan 1/2 ");
2927 test_scan( &responses[TRAILING_SPACE_ON_CHUNKED_BODY]
2929 , &responses[NO_HEADERS_NO_BODY_404]
2932 printf(
"response scan 2/2 ");
2938 puts(
"responses okay");
2953 "Content-Type: text/plain\r\n" 2954 "Content-Length: 6\r\n" 2959 static const char *all_methods[] = {
2985 const char **this_method;
2986 for (this_method = all_methods; *this_method; this_method++) {
2988 sprintf(buf,
"%s / HTTP/1.1\r\n\r\n", *this_method);
2992 static const char *bad_methods[] = {
2996 for (this_method = bad_methods; *this_method; this_method++) {
2998 sprintf(buf,
"%s / HTTP/1.1\r\n\r\n", *this_method);
3002 const char *dumbfuck2 =
3003 "GET / HTTP/1.1\r\n" 3004 "X-SSL-Bullshit: -----BEGIN CERTIFICATE-----\r\n" 3005 "\tMIIFbTCCBFWgAwIBAgICH4cwDQYJKoZIhvcNAQEFBQAwcDELMAkGA1UEBhMCVUsx\r\n" 3006 "\tETAPBgNVBAoTCGVTY2llbmNlMRIwEAYDVQQLEwlBdXRob3JpdHkxCzAJBgNVBAMT\r\n" 3007 "\tAkNBMS0wKwYJKoZIhvcNAQkBFh5jYS1vcGVyYXRvckBncmlkLXN1cHBvcnQuYWMu\r\n" 3008 "\tdWswHhcNMDYwNzI3MTQxMzI4WhcNMDcwNzI3MTQxMzI4WjBbMQswCQYDVQQGEwJV\r\n" 3009 "\tSzERMA8GA1UEChMIZVNjaWVuY2UxEzARBgNVBAsTCk1hbmNoZXN0ZXIxCzAJBgNV\r\n" 3010 "\tBAcTmrsogriqMWLAk1DMRcwFQYDVQQDEw5taWNoYWVsIHBhcmQYJKoZIhvcNAQEB\r\n" 3011 "\tBQADggEPADCCAQoCggEBANPEQBgl1IaKdSS1TbhF3hEXSl72G9J+WC/1R64fAcEF\r\n" 3012 "\tW51rEyFYiIeZGx/BVzwXbeBoNUK41OK65sxGuflMo5gLflbwJtHBRIEKAfVVp3YR\r\n" 3013 "\tgW7cMA/s/XKgL1GEC7rQw8lIZT8RApukCGqOVHSi/F1SiFlPDxuDfmdiNzL31+sL\r\n" 3014 "\t0iwHDdNkGjy5pyBSB8Y79dsSJtCW/iaLB0/n8Sj7HgvvZJ7x0fr+RQjYOUUfrePP\r\n" 3015 "\tu2MSpFyf+9BbC/aXgaZuiCvSR+8Snv3xApQY+fULK/xY8h8Ua51iXoQ5jrgu2SqR\r\n" 3016 "\twgA7BUi3G8LFzMBl8FRCDYGUDy7M6QaHXx1ZWIPWNKsCAwEAAaOCAiQwggIgMAwG\r\n" 3017 "\tA1UdEwEB/wQCMAAwEQYJYIZIAYb4QgHTTPAQDAgWgMA4GA1UdDwEB/wQEAwID6DAs\r\n" 3018 "\tBglghkgBhvhCAQ0EHxYdVUsgZS1TY2llbmNlIFVzZXIgQ2VydGlmaWNhdGUwHQYD\r\n" 3019 "\tVR0OBBYEFDTt/sf9PeMaZDHkUIldrDYMNTBZMIGaBgNVHSMEgZIwgY+AFAI4qxGj\r\n" 3020 "\tloCLDdMVKwiljjDastqooXSkcjBwMQswCQYDVQQGEwJVSzERMA8GA1UEChMIZVNj\r\n" 3021 "\taWVuY2UxEjAQBgNVBAsTCUF1dGhvcml0eTELMAkGA1UEAxMCQ0ExLTArBgkqhkiG\r\n" 3022 "\t9w0BCQEWHmNhLW9wZXJhdG9yQGdyaWQtc3VwcG9ydC5hYy51a4IBADApBgNVHRIE\r\n" 3023 "\tIjAggR5jYS1vcGVyYXRvckBncmlkLXN1cHBvcnQuYWMudWswGQYDVR0gBBIwEDAO\r\n" 3024 "\tBgwrBgEEAdkvAQEBAQYwPQYJYIZIAYb4QgEEBDAWLmh0dHA6Ly9jYS5ncmlkLXN1\r\n" 3025 "\tcHBvcnQuYWMudmT4sopwqlBWsvcHViL2NybC9jYWNybC5jcmwwPQYJYIZIAYb4QgEDBDAWLmh0\r\n" 3026 "\tdHA6Ly9jYS5ncmlkLXN1cHBvcnQuYWMudWsvcHViL2NybC9jYWNybC5jcmwwPwYD\r\n" 3027 "\tVR0fBDgwNjA0oDKgMIYuaHR0cDovL2NhLmdyaWQt5hYy51ay9wdWIv\r\n" 3028 "\tY3JsL2NhY3JsLmNybDANBgkqhkiG9w0BAQUFAAOCAQEAS/U4iiooBENGW/Hwmmd3\r\n" 3029 "\tXCy6Zrt08YjKCzGNjorT98g8uGsqYjSxv/hmi0qlnlHs+k/3Iobc3LjS5AMYr5L8\r\n" 3030 "\tUO7OSkgFFlLHQyC9JzPfmLCAugvzEbyv4Olnsr8hbxF1MbKZoQxUZtMVu29wjfXk\r\n" 3031 "\thTeApBv7eaKCWpSp7MCbvgzm74izKhu3vlDk9w6qVrxePfGgpKPqfHiOoGhFnbTK\r\n" 3032 "\twTC6o2xq5y0qZ03JonF7OJspEd3I5zKY3E+ov7/ZhW6DqT8UFvsAdjvQbXyhV8Eu\r\n" 3033 "\tYhixw1aKEPzNjNowuIseVogKOLXxWI5vAi5HgXdS0/ES5gDGsABo4fqovUKlgop3\r\n" 3035 "\t-----END CERTIFICATE-----\r\n" 3039 const char *corrupted_header_name =
3040 "GET / HTTP/1.1\r\n" 3041 "Host: www.example.com\r\n" 3042 "X-Some-Header\r\033\065\325eep-Alive\r\n" 3043 "Accept-Encoding: gzip\r\n" 3047 const char *header_with_space =
3048 "GET / HTTP/1.1\r\n" 3049 "Host: www.example.com\r\n" 3050 "Foo Foo: some_value\r\n" 3051 "Accept-Encoding: gzip\r\n" 3055 const char *header_with_curly_brace =
3056 "GET / HTTP/1.1\r\n" 3057 "Host: www.example.com\r\n" 3058 "Foo}Foo: some_value\r\n" 3059 "Accept-Encoding: gzip\r\n" 3063 const char *header_with_quote =
3064 "GET / HTTP/1.1\r\n" 3065 "Host: www.example.com\r\n" 3066 "Foo\"Foo: some_value\r\n" 3067 "Accept-Encoding: gzip\r\n" 3071 const char *header_with_forward_slash =
3072 "GET / HTTP/1.1\r\n" 3073 "Host: www.example.com\r\n" 3074 "Foo/Foo: some_value\r\n" 3075 "Accept-Encoding: gzip\r\n" 3079 const char *header_with_trailing_space =
3080 "GET / HTTP/1.1\r\n" 3081 "Host: www.example.com\r\n" 3082 "X-Some-Header : some_value\r\n" 3086 const char *bad_end_of_headers_1 =
3087 "GET / HTTP/1.1\r\n" 3088 "Host: www.example1.com\r\n" 3089 "X-Some-Header: some_value" 3093 const char *bad_end_of_headers_2 =
3094 "GET / HTTP/1.1\r\n" 3095 "Host: www.example2.com\r\n" 3096 "X-Some-Header: some_value" 3100 const char *empty_content_length_header =
3101 "GET / HTTP/1.1\r\n" 3102 "Host: www.example.com\r\n" 3103 "Content-Length:\r\n" 3104 "Accept-Encoding: gzip\r\n" 3108 const char *empty_transfer_encoding_header =
3109 "GET / HTTP/1.1\r\n" 3110 "Host: www.example.com\r\n" 3111 "Transfer-Encoding:\r\n" 3112 "Accept-Encoding: gzip\r\n" 3116 const char *empty_upgrade_header =
3117 "GET / HTTP/1.1\r\n" 3118 "Host: www.example.com\r\n" 3120 "Accept-Encoding: gzip\r\n" 3130 const char *bad_get_no_headers_no_body =
"GET /bad_get_no_headers_no_body/world HTTP/1.1\r\n" 3140 for (i = 0; requests[
i].
name; i++) {
3144 for (i = 0; i < request_count; i++) {
3148 for (i = 0; i < request_count; i++) {
3150 for (j = 0; j < request_count; j++) {
3151 if (!requests[j].should_keep_alive)
continue;
3152 for (k = 0; k < request_count; k++) {
3158 printf(
"request scan 1/4 ");
3161 , &requests[GET_NO_HEADERS_NO_BODY]
3164 printf(
"request scan 2/4 ");
3170 printf(
"request scan 3/4 ");
3176 printf(
"request scan 4/4 ");
3182 puts(
"requests okay");
void test_multiple3(const struct message *r1, const struct message *r2, const struct message *r3)
size_t parse(const char *buf, size_t len)
#define GET_FUNKY_CONTENT_LENGTH
static struct message messages[5]
int dontcall_response_reason_cb(http_parser *p, const char *buf, size_t len)
int pause_chunk_header_cb(http_parser *p)
int pause_request_url_cb(http_parser *p, const char *buf, size_t len)
static http_parser_settings settings_null
size_t count_parsed_messages(const size_t nmsgs,...)
int pause_response_reason_cb(http_parser *p, const char *buf, size_t len)
int request_url_cb(http_parser *p, const char *buf, size_t len)
const struct message requests[]
int pause_message_complete_cb(http_parser *p)
const char * http_errno_name(enum http_errno err)
int dontcall_chunk_header_cb(http_parser *p)
void parser_init(enum http_parser_type type)
const struct message responses[]
size_t parse_pause(const char *buf, size_t len)
unsigned short http_minor
int body_cb(http_parser *p, const char *buf, size_t len)
void test_simple(const char *buf, enum http_errno err_expected)
int headers_complete_cb_called
#define QUERY_URL_WITH_QUESTION_MARK_GET
int pause_body_cb(http_parser *p, const char *buf, size_t len)
int pause_header_field_cb(http_parser *p, const char *buf, size_t len)
enum message::@3 last_header_element
unsigned short http_major
static uint64_t test(std::string name, bool fc_, bool dedicated_, bool tc_, bool syncops_, uint64_t base)
size_t http_parser_execute(http_parser *parser, const http_parser_settings *settings, const char *data, size_t len)
int count_body_cb(http_parser *p, const char *buf, size_t len)
#define GET_ONE_HEADER_NO_BODY
void test_message(const struct message *message)
#define HTTP_PARSER_ERRNO_LINE(p)
void test_on_message_begin_cb(const struct message *message)
static http_parser_settings settings
#define MESSAGE_CHECK_NUM_EQ(expected, found, prop)
void test_scan(const struct message *r1, const struct message *r2, const struct message *r3)
int message_complete_cb_called
static http_parser * parser
void test_message_count_body(const struct message *message)
requires And< SemiMovable< VN >... > &&SemiMovable< E > auto error(E e)
#define TRAILING_SPACE_ON_CHUNKED_BODY
char * create_large_chunked_message(int body_size_in_kb, const char *headers)
int header_value_cb(http_parser *p, const char *buf, size_t len)
int pause_message_begin_cb(http_parser *p)
void test_parse_url(void)
int message_begin_cb(http_parser *p)
unsigned short status_code
int dontcall_header_field_cb(http_parser *p, const char *buf, size_t len)
enum http_parser_type type
int message_complete_on_eof
void http_parser_pause(http_parser *parser, int paused)
void test_message_pause(const struct message *msg)
int dontcall_message_begin_cb(http_parser *p)
void dump_url(const char *url, const struct http_parser_url *u)
#define HTTP_PARSER_ERRNO(p)
#define BONJOUR_MADAME_FR
int http_parser_parse_url(const char *buf, size_t buflen, int is_connect, struct http_parser_url *u)
int message_complete_cb(http_parser *p)
size_t read(T &out, folly::io::Cursor &cursor)
#define CHUNKED_W_TRAILING_HEADERS
const char * http_errno_description(enum http_errno err)
unsigned short http_major
int dontcall_headers_complete_cb(http_parser *p, const char *buf, size_t len)
static int check_num_eq(const struct message *m, const char *prop, int expected, int found)
#define TWO_CHUNKS_MULT_ZERO_END
static map< string, int > m
int dontcall_request_url_cb(http_parser *p, const char *buf, size_t len)
static void print_error(const char *raw, size_t error_location)
int pause_header_value_cb(http_parser *p, const char *buf, size_t len)
unsigned short http_minor
int message_begin_cb_called
static int check_str_eq(const struct message *m, const char *prop, const char *expected, const char *found)
int dontcall_chunk_complete_cb(http_parser *p)
int chunk_header_cb(http_parser *p)
void http_parser_init(http_parser *parser, enum http_parser_type t)
static int currently_parsing_eof
static http_parser_settings settings_pause
int dontcall_body_cb(http_parser *p, const char *buf, size_t len)
static http_parser_settings settings_count_body
size_t response_reason_size
int pause_headers_complete_cb(http_parser *p, const char *buf, size_t len)
int headers_complete_cb(http_parser *p, const char *buf, size_t len)
#define POST_IDENTITY_BODY_WORLD
int message_eq(int index, const struct message *expected)
int dontcall_header_value_cb(http_parser *p, const char *buf, size_t len)
int response_reason_cb(http_parser *p, const char *buf, size_t len)
#define CHUNKED_W_BULLSHIT_AFTER_LENGTH
int pause_chunk_complete_cb(http_parser *p)
#define GET_NO_HEADERS_NO_BODY
const struct url_test url_tests[]
#define NO_HEADERS_NO_BODY_404
static http_parser_settings * current_pause_parser
char response_reason[500]
void upgrade_message_fix(char *body, const size_t nread, const size_t nmsgs,...)
const struct message on_message_begin_cb_test[]
static http_parser_settings settings_dontcall
int chunk_complete_cb(http_parser *p)
void test_header_overflow_error(int req)
int empty_data_cb(http_parser *p, const char *buf, size_t len)
#define UNDERSTORE_HEADER_KEY
int header_field_cb(http_parser *p, const char *buf, size_t len)
int dontcall_message_complete_cb(http_parser *p)
struct http_parser_url::@1 field_data[UF_MAX]
#define PREFIX_NEWLINE_GET
#define POST_CHUNKED_ALL_YOUR_BASE
void test_no_overflow_long_body(int req, size_t length)
size_t parse_count_body(const char *buf, size_t len)
#define MESSAGE_CHECK_STR_EQ(expected, found, prop)
int empty_cb(http_parser *p)