From 004aff900156bcbc672300d23f65c7adafe37e81 Mon Sep 17 00:00:00 2001 From: Ryan Date: Thu, 20 Aug 2009 14:37:59 +0200 Subject: [PATCH] API Change: Demand that EOFs are passed to http_parser_execute(). --- README.md | 20 +++++++++++++++++--- test.c | 17 ++++++++++++++--- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index d59a12d..3b2d4eb 100644 --- a/README.md +++ b/README.md @@ -43,15 +43,29 @@ When data is received on the socket execute the parser and check for errors. char buf[len]; ssize_t recved; - recved = read(fd, buf, len); - if (recved != 0) // handle error + recved = recv(fd, buf, len, 0); + if (recved < 0) { + /* Handle error. */ + } + + /* Start up / continue the parser. + * Note we pass the recved==0 to http_parser_execute to signal + * that EOF has been recieved. + */ http_parser_execute(parser, buf, recved); if (http_parser_has_error(parser)) { - // handle error. usually just close the connection + /* Handle error. Usually just close the connection. */ } +HTTP needs to know where the end of the stream is. For example, sometimes +servers send responses without Content-Length and expect the client to +consume input (for the body) until EOF. To tell http_parser about EOF, give +`0` as the third parameter to `http_parser_execute()`. Callbacks and errors +can still be encountered during an EOF, so one must still be prepared +to receive them. + Scalar valued message information such as `status_code`, `method`, and the HTTP version are stored in the parser structure. This data is only temporarlly stored in `http_parser` and gets reset on each new message. If diff --git a/test.c b/test.c index 7c2fb83..db6ddf9 100644 --- a/test.c +++ b/test.c @@ -559,8 +559,11 @@ parse_messages (int message_count, const struct message *input_messages[]) parser_init(HTTP_REQUEST); traversed = http_parser_execute(&parser, total, length); + assert(!http_parser_has_error(&parser)); + traversed = http_parser_execute(&parser, NULL, 0); assert(!http_parser_has_error(&parser)); + assert(num_messages == message_count); for (i = 0; i < message_count; i++) { @@ -577,6 +580,10 @@ test_message (const struct message *message) traversed = http_parser_execute(&parser, message->raw, strlen(message->raw)); assert(!http_parser_has_error(&parser)); + + traversed = http_parser_execute(&parser, NULL, 0); + assert(!http_parser_has_error(&parser)); + assert(num_messages == 1); message_eq(0, message); @@ -589,6 +596,7 @@ test_error (const char *buf) parser_init(HTTP_REQUEST); traversed = http_parser_execute(&parser, buf, strlen(buf)); + traversed = http_parser_execute(&parser, NULL, 0); assert(http_parser_has_error(&parser)); } @@ -611,8 +619,11 @@ test_multiple3 (const struct message *r1, const struct message *r2, const struct parser_init(HTTP_REQUEST); traversed = http_parser_execute(&parser, total, strlen(total)); + assert(!http_parser_has_error(&parser) ); + + traversed = http_parser_execute(&parser, NULL, 0); + assert(!http_parser_has_error(&parser) ); - assert(! http_parser_has_error(&parser) ); assert(num_messages == 3); message_eq(0, r1); message_eq(1, r2); @@ -671,15 +682,15 @@ test_scan (const struct message *r1, const struct message *r2, const struct mess */ http_parser_execute(&parser, buf1, buf1_len); - assert(!http_parser_has_error(&parser)); http_parser_execute(&parser, buf2, buf2_len); - assert(!http_parser_has_error(&parser)); http_parser_execute(&parser, buf3, buf3_len); + assert(!http_parser_has_error(&parser)); + http_parser_execute(&parser, NULL, 0); assert(!http_parser_has_error(&parser)); assert(3 == num_messages);