From a74eb9053f740469bfc5936063a5bd25344af26f Mon Sep 17 00:00:00 2001 From: Kjell Schubert Date: Fri, 17 Apr 2015 16:25:11 -0700 Subject: [PATCH 1/3] Closes #234: No immediate onMessageComplete cb for upgrade w/body (D1364677 + D1380182 orig author afrind@fb.com) --- http_parser.c | 12 +++++++++--- test.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/http_parser.c b/http_parser.c index aa6310f7..0135e320 100644 --- a/http_parser.c +++ b/http_parser.c @@ -123,7 +123,7 @@ do { \ FOR##_mark = NULL; \ } \ } while (0) - + /* Run the data callback FOR and consume the current byte */ #define CALLBACK_DATA(FOR) \ CALLBACK_DATA_(FOR, p - FOR##_mark, p - data + 1) @@ -1832,8 +1832,10 @@ size_t http_parser_execute (http_parser *parser, parser->nread = 0; - /* Exit, the rest of the connect is in a different protocol. */ - if (parser->upgrade) { + int hasBody = parser->flags & F_CHUNKED || parser->content_length > 0; + if (parser->upgrade && (parser->method == HTTP_CONNECT || + (parser->flags & F_SKIPBODY) || !hasBody)) { + /* Exit, the rest of the message is in a different protocol. */ UPDATE_STATE(NEW_MESSAGE()); CALLBACK_NOTIFY(message_complete); RETURN((p - data) + 1); @@ -1915,6 +1917,10 @@ size_t http_parser_execute (http_parser *parser, case s_message_done: UPDATE_STATE(NEW_MESSAGE()); CALLBACK_NOTIFY(message_complete); + if (parser->upgrade) { + /* Exit, the rest of the message is in a different protocol. */ + RETURN((p - data) + 1); + } break; case s_chunk_size_start: diff --git a/test.c b/test.c index 58c1955a..a9978f1a 100644 --- a/test.c +++ b/test.c @@ -1036,6 +1036,57 @@ const struct message requests[] = ,.body= "" } +#define UPGRADE_POST_REQUEST 38 +, {.name = "upgrade post request" + ,.type= HTTP_REQUEST + ,.raw= "POST /demo HTTP/1.1\r\n" + "Host: example.com\r\n" + "Connection: Upgrade\r\n" + "Upgrade: HTTP/2.0\r\n" + "Content-Length: 15\r\n" + "\r\n" + "sweet post body" + "Hot diggity dogg" + ,.should_keep_alive= TRUE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 1 + ,.method= HTTP_POST + ,.request_url= "/demo" + ,.num_headers= 4 + ,.upgrade="Hot diggity dogg" + ,.headers= { { "Host", "example.com" } + , { "Connection", "Upgrade" } + , { "Upgrade", "HTTP/2.0" } + , { "Content-Length", "15" } + } + ,.body= "sweet post body" + } + +#define CONNECT_WITH_BODY_REQUEST 39 +, {.name = "connect with body request" + ,.type= HTTP_REQUEST + ,.raw= "CONNECT foo.bar.com:443 HTTP/1.0\r\n" + "User-agent: Mozilla/1.1N\r\n" + "Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n" + "Content-Length: 10\r\n" + "\r\n" + "blarfcicle" + ,.should_keep_alive= FALSE + ,.message_complete_on_eof= FALSE + ,.http_major= 1 + ,.http_minor= 0 + ,.method= HTTP_CONNECT + ,.request_url= "foo.bar.com:443" + ,.num_headers= 3 + ,.upgrade="blarfcicle" + ,.headers= { { "User-agent", "Mozilla/1.1N" } + , { "Proxy-authorization", "basic aGVsbG86d29ybGQ=" } + , { "Content-Length", "10" } + } + ,.body= "" + } + , {.name= NULL } /* sentinel */ }; @@ -2909,7 +2960,7 @@ test_message (const struct message *message) if (msg1len) { read = parse(msg1, msg1len); - if (message->upgrade && parser->upgrade) { + if (message->upgrade && parser->upgrade && num_messages > 0) { messages[num_messages - 1].upgrade = msg1 + read; goto test; } From 7b48104963670244df1ede3ed1162b44a01f35ee Mon Sep 17 00:00:00 2001 From: Kjell Schubert Date: Mon, 20 Apr 2015 15:52:13 -0700 Subject: [PATCH 2/3] these are changes needed on top of the original proxygen changesets --- http_parser.c | 3 ++- test.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/http_parser.c b/http_parser.c index 0135e320..35d8b343 100644 --- a/http_parser.c +++ b/http_parser.c @@ -1832,7 +1832,8 @@ size_t http_parser_execute (http_parser *parser, parser->nread = 0; - int hasBody = parser->flags & F_CHUNKED || parser->content_length > 0; + int hasBody = parser->flags & F_CHUNKED || + (parser->content_length > 0 && parser->content_length != ULLONG_MAX); if (parser->upgrade && (parser->method == HTTP_CONNECT || (parser->flags & F_SKIPBODY) || !hasBody)) { /* Exit, the rest of the message is in a different protocol. */ diff --git a/test.c b/test.c index a9978f1a..558f7719 100644 --- a/test.c +++ b/test.c @@ -1052,6 +1052,7 @@ const struct message requests[] = ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_POST + ,.request_path= "/demo" ,.request_url= "/demo" ,.num_headers= 4 ,.upgrade="Hot diggity dogg" @@ -2294,7 +2295,7 @@ upgrade_message_fix(char *body, const size_t nread, const size_t nmsgs, ...) { va_list ap; size_t i; size_t off = 0; - + va_start(ap, nmsgs); for (i = 0; i < nmsgs; i++) { From 0446abacae5890b636b9614a1d31294eb346ce52 Mon Sep 17 00:00:00 2001 From: Kjell Schubert Date: Wed, 22 Apr 2015 09:45:13 -0700 Subject: [PATCH 3/3] restore line-trailing whitespace to minimize diff --- http_parser.c | 2 +- test.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/http_parser.c b/http_parser.c index 35d8b343..fb4c1565 100644 --- a/http_parser.c +++ b/http_parser.c @@ -123,7 +123,7 @@ do { \ FOR##_mark = NULL; \ } \ } while (0) - + /* Run the data callback FOR and consume the current byte */ #define CALLBACK_DATA(FOR) \ CALLBACK_DATA_(FOR, p - FOR##_mark, p - data + 1) diff --git a/test.c b/test.c index 558f7719..a9c4225d 100644 --- a/test.c +++ b/test.c @@ -2295,7 +2295,7 @@ upgrade_message_fix(char *body, const size_t nread, const size_t nmsgs, ...) { va_list ap; size_t i; size_t off = 0; - + va_start(ap, nmsgs); for (i = 0; i < nmsgs; i++) {