@@ -58,13 +58,19 @@ struct message {
5858 int message_begin_cb_called ;
5959 int headers_complete_cb_called ;
6060 int message_complete_cb_called ;
61+ int message_complete_on_eof ;
6162};
6263
63- #define parse (t , buf , len ) \
64- (t == REQUEST ? http_parse_requests(&parser, buf, len) \
65- : http_parse_responses(&parser, buf, len))
66-
64+ static int currently_parsing_eof ;
6765
66+ inline size_t parse (enum message_type t , const char * buf , size_t len )
67+ {
68+ size_t nparsed ;
69+ currently_parsing_eof = (len == 0 );
70+ nparsed = (t == REQUEST ? http_parse_requests (& parser , buf , len )
71+ : http_parse_responses (& parser , buf , len ));
72+ return nparsed ;
73+ }
6874
6975static struct message messages [5 ];
7076static int num_messages ;
@@ -80,6 +86,7 @@ const struct message requests[] =
8086 "Accept: */*\r\n"
8187 "\r\n"
8288 ,.should_keep_alive = TRUE
89+ ,.message_complete_on_eof = FALSE
8390 ,.http_major = 1
8491 ,.http_minor = 1
8592 ,.method = HTTP_GET
@@ -110,6 +117,7 @@ const struct message requests[] =
110117 "Connection: keep-alive\r\n"
111118 "\r\n"
112119 ,.should_keep_alive = TRUE
120+ ,.message_complete_on_eof = FALSE
113121 ,.http_major = 1
114122 ,.http_minor = 1
115123 ,.method = HTTP_GET
@@ -138,6 +146,7 @@ const struct message requests[] =
138146 "aaaaaaaaaaaaa:++++++++++\r\n"
139147 "\r\n"
140148 ,.should_keep_alive = TRUE
149+ ,.message_complete_on_eof = FALSE
141150 ,.http_major = 1
142151 ,.http_minor = 1
143152 ,.method = HTTP_GET
@@ -158,6 +167,7 @@ const struct message requests[] =
158167 ,.raw = "GET /forums/1/topics/2375?page=1#posts-17408 HTTP/1.1\r\n"
159168 "\r\n"
160169 ,.should_keep_alive = TRUE
170+ ,.message_complete_on_eof = FALSE
161171 ,.http_major = 1
162172 ,.http_minor = 1
163173 ,.method = HTTP_GET
@@ -176,6 +186,7 @@ const struct message requests[] =
176186 ,.raw = "GET /get_no_headers_no_body/world HTTP/1.1\r\n"
177187 "\r\n"
178188 ,.should_keep_alive = TRUE
189+ ,.message_complete_on_eof = FALSE /* would need Connection: close */
179190 ,.http_major = 1
180191 ,.http_minor = 1
181192 ,.method = HTTP_GET
@@ -194,6 +205,7 @@ const struct message requests[] =
194205 "Accept: */*\r\n"
195206 "\r\n"
196207 ,.should_keep_alive = TRUE
208+ ,.message_complete_on_eof = FALSE /* would need Connection: close */
197209 ,.http_major = 1
198210 ,.http_minor = 1
199211 ,.method = HTTP_GET
@@ -216,6 +228,7 @@ const struct message requests[] =
216228 "\r\n"
217229 "HELLO"
218230 ,.should_keep_alive = FALSE
231+ ,.message_complete_on_eof = FALSE
219232 ,.http_major = 1
220233 ,.http_minor = 0
221234 ,.method = HTTP_GET
@@ -240,6 +253,7 @@ const struct message requests[] =
240253 "\r\n"
241254 "World"
242255 ,.should_keep_alive = TRUE
256+ ,.message_complete_on_eof = FALSE
243257 ,.http_major = 1
244258 ,.http_minor = 1
245259 ,.method = HTTP_POST
@@ -266,6 +280,7 @@ const struct message requests[] =
266280 "0\r\n"
267281 "\r\n"
268282 ,.should_keep_alive = TRUE
283+ ,.message_complete_on_eof = FALSE
269284 ,.http_major = 1
270285 ,.http_minor = 1
271286 ,.method = HTTP_POST
@@ -291,6 +306,7 @@ const struct message requests[] =
291306 "000\r\n"
292307 "\r\n"
293308 ,.should_keep_alive = TRUE
309+ ,.message_complete_on_eof = FALSE
294310 ,.http_major = 1
295311 ,.http_minor = 1
296312 ,.method = HTTP_POST
@@ -318,6 +334,7 @@ const struct message requests[] =
318334 "Content-Type: text/plain\r\n"
319335 "\r\n"
320336 ,.should_keep_alive = TRUE
337+ ,.message_complete_on_eof = FALSE
321338 ,.http_major = 1
322339 ,.http_minor = 1
323340 ,.method = HTTP_POST
@@ -345,6 +362,7 @@ const struct message requests[] =
345362 "0\r\n"
346363 "\r\n"
347364 ,.should_keep_alive = TRUE
365+ ,.message_complete_on_eof = FALSE
348366 ,.http_major = 1
349367 ,.http_minor = 1
350368 ,.method = HTTP_POST
@@ -364,6 +382,7 @@ const struct message requests[] =
364382 ,.type = REQUEST
365383 ,.raw = "GET /with_\"stupid\"_quotes?foo=\"bar\" HTTP/1.1\r\n\r\n"
366384 ,.should_keep_alive = TRUE
385+ ,.message_complete_on_eof = FALSE
367386 ,.http_major = 1
368387 ,.http_minor = 1
369388 ,.method = HTTP_GET
@@ -377,13 +396,19 @@ const struct message requests[] =
377396 }
378397
379398#define APACHEBENCH_GET 13
399+ /* The server receiving this request SHOULD NOT wait for EOF
400+ * to know that content-length == 0.
401+ * How to represent this in a unit test? message_complete_on_eof
402+ * Compare with NO_CONTENT_LENGTH_RESPONSE.
403+ */
380404, {.name = "apachebench get"
381405 ,.type = REQUEST
382406 ,.raw = "GET /test HTTP/1.0\r\n"
383407 "Host: 0.0.0.0:5000\r\n"
384408 "User-Agent: ApacheBench/2.3\r\n"
385409 "Accept: */*\r\n\r\n"
386410 ,.should_keep_alive = FALSE
411+ ,.message_complete_on_eof = FALSE
387412 ,.http_major = 1
388413 ,.http_minor = 0
389414 ,.method = HTTP_GET
@@ -423,6 +448,7 @@ const struct message responses[] =
423448 "<A HREF=\"http://www.google.com/\">here</A>.\r\n"
424449 "</BODY></HTML>\r\n"
425450 ,.should_keep_alive = TRUE
451+ ,.message_complete_on_eof = FALSE
426452 ,.http_major = 1
427453 ,.http_minor = 1
428454 ,.status_code = 301
@@ -445,6 +471,11 @@ const struct message responses[] =
445471 }
446472
447473#define NO_CONTENT_LENGTH_RESPONSE 1
474+ /* The client should wait for the server's EOF. That is, when content-length
475+ * is not specified, and "Connection: close", the end of body is specified
476+ * by the EOF.
477+ * Compare with APACHEBENCH_GET
478+ */
448479, {.name = "no content-length response"
449480 ,.type = RESPONSE
450481 ,.raw = "HTTP/1.1 200 OK\r\n"
@@ -464,6 +495,7 @@ const struct message responses[] =
464495 " </SOAP-ENV:Body>\n"
465496 "</SOAP-ENV:Envelope>"
466497 ,.should_keep_alive = FALSE
498+ ,.message_complete_on_eof = TRUE
467499 ,.http_major = 1
468500 ,.http_minor = 1
469501 ,.status_code = 200
@@ -491,6 +523,7 @@ const struct message responses[] =
491523 ,.type = RESPONSE
492524 ,.raw = "HTTP/1.1 404 Not Found\r\n\r\n"
493525 ,.should_keep_alive = TRUE
526+ ,.message_complete_on_eof = FALSE
494527 ,.http_major = 1
495528 ,.http_minor = 1
496529 ,.status_code = 404
@@ -504,6 +537,7 @@ const struct message responses[] =
504537 ,.type = RESPONSE
505538 ,.raw = "HTTP/1.1 301\r\n\r\n"
506539 ,.should_keep_alive = TRUE
540+ ,.message_complete_on_eof = FALSE
507541 ,.http_major = 1
508542 ,.http_minor = 1
509543 ,.status_code = 301
@@ -528,6 +562,7 @@ const struct message responses[] =
528562 "0 \r\n"
529563 "\r\n"
530564 ,.should_keep_alive = TRUE
565+ ,.message_complete_on_eof = FALSE
531566 ,.http_major = 1
532567 ,.http_minor = 1
533568 ,.status_code = 200
@@ -648,6 +683,9 @@ message_complete_cb (http_parser *parser)
648683 exit (1 );
649684 }
650685 messages [num_messages ].message_complete_cb_called = TRUE;
686+
687+ messages [num_messages ].message_complete_on_eof = currently_parsing_eof ;
688+
651689 num_messages ++ ;
652690 return 0 ;
653691}
@@ -724,11 +762,13 @@ message_eq (int index, const struct message *expected)
724762 }
725763
726764 MESSAGE_CHECK_NUM_EQ (expected , m , should_keep_alive );
765+ MESSAGE_CHECK_NUM_EQ (expected , m , message_complete_on_eof );
727766
728767 assert (m -> message_begin_cb_called );
729768 assert (m -> headers_complete_cb_called );
730769 assert (m -> message_complete_cb_called );
731770
771+
732772 MESSAGE_CHECK_STR_EQ (expected , m , request_path );
733773 MESSAGE_CHECK_STR_EQ (expected , m , query_string );
734774 MESSAGE_CHECK_STR_EQ (expected , m , fragment );
0 commit comments