Skip to content

Commit a8f7a3c

Browse files
committed
add message_complete_on_eof test
1 parent 357d7c2 commit a8f7a3c

File tree

2 files changed

+45
-5
lines changed

2 files changed

+45
-5
lines changed

http_parser.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1269,7 +1269,7 @@ size_t parse (http_parser *parser, const char *data, size_t len, int start_state
12691269
/* Content-Length header given and non-zero */
12701270
state = s_body_identity;
12711271
} else {
1272-
if (http_should_keep_alive(parser)) {
1272+
if (start_state == s_start_req || http_should_keep_alive(parser)) {
12731273
/* Assume content-length 0 - read the next */
12741274
CALLBACK2(message_complete);
12751275
state = start_state;

test.c

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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

6975
static struct message messages[5];
7076
static 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

Comments
 (0)