From: Ilya Markov <imarkov@tarantool.org> To: georgy@tarantool.org Cc: tarantool-patches@freelists.org Subject: [tarantool-patches] [http.client 1/2] http: Remove parsed status line from headers Date: Fri, 15 Jun 2018 17:24:10 +0300 [thread overview] Message-ID: <02e9c328f4c895dec7655e91ab62004988ff0575.1529072604.git.imarkov@tarantool.org> (raw) In-Reply-To: <cover.1529072604.git.imarkov@tarantool.org> In-Reply-To: <cover.1529072604.git.imarkov@tarantool.org> Bug: Header parser validates http status line and besides saving http status, saves valid characters to header name, which is wrong. Fix this with skipping status line after validation without saving it as a header. In scope of #3451 --- src/http_parser.c | 30 +++++++++++++++++++++++++++++- src/http_parser.h | 1 + src/lua/httpc.c | 3 +-- test/app-tap/http_client.test.lua | 3 ++- 4 files changed, 33 insertions(+), 4 deletions(-) diff --git a/src/http_parser.c b/src/http_parser.c index 7166903..64f20e5 100644 --- a/src/http_parser.c +++ b/src/http_parser.c @@ -220,6 +220,8 @@ http_parse_header_line(struct http_parser *parser, char **bufp, enum { sw_start = 0, + skip_status_line, + skipped_status_line_almost_done, sw_name, sw_space_before_value, sw_value, @@ -271,6 +273,25 @@ http_parse_header_line(struct http_parser *parser, char **bufp, break; } break; + case skip_status_line: + switch (ch) { + case LF: + goto skipped_status; + case CR: + state = skipped_status_line_almost_done; + default: + break; + } + break; + case skipped_status_line_almost_done: + switch (ch) { + case LF: + goto skipped_status; + case CR: + break; + default: + return HTTP_PARSE_INVALID; + } /* http_header name */ case sw_name: c = lowcase[ch]; @@ -304,8 +325,11 @@ http_parse_header_line(struct http_parser *parser, char **bufp, if (rc == HTTP_PARSE_INVALID) { parser->http_minor = -1; parser->http_major = -1; + state = sw_start; + } else { + /* Skip it till end of line. */ + state = skip_status_line; } - state = sw_start; break; } if (ch == '\0') @@ -389,6 +413,10 @@ http_parse_header_line(struct http_parser *parser, char **bufp, } } +skipped_status: + *bufp = p + 1; + return HTTP_PARSE_CONTINUE; + done: *bufp = p + 1; return HTTP_PARSE_OK; diff --git a/src/http_parser.h b/src/http_parser.h index 5e20f53..c4d59a9 100644 --- a/src/http_parser.h +++ b/src/http_parser.h @@ -36,6 +36,7 @@ enum { HTTP_PARSE_OK, + HTTP_PARSE_CONTINUE, HTTP_PARSE_DONE, HTTP_PARSE_INVALID }; diff --git a/src/lua/httpc.c b/src/lua/httpc.c index 45abb98..0fe27d4 100644 --- a/src/lua/httpc.c +++ b/src/lua/httpc.c @@ -69,13 +69,12 @@ parse_headers(lua_State *L, char *buffer, size_t len) lua_newtable(L); while (true) { int rc = http_parse_header_line(&parser, &buffer, end_buf); - if (rc == HTTP_PARSE_INVALID) { + if (rc == HTTP_PARSE_INVALID || rc == HTTP_PARSE_CONTINUE) { continue; } if (rc == HTTP_PARSE_DONE) { break; } - if (rc == HTTP_PARSE_OK) { lua_pushlstring(L, parser.header_name, parser.header_name_idx); diff --git a/test/app-tap/http_client.test.lua b/test/app-tap/http_client.test.lua index 887395d..d9380c0 100755 --- a/test/app-tap/http_client.test.lua +++ b/test/app-tap/http_client.test.lua @@ -197,7 +197,7 @@ local function test_errors(test) end local function test_headers(test, url, opts) - test:plan(15) + test:plan(16) local http = client:new() local r = http:get(url .. 'headers', opts) test:is(type(r.headers["set-cookie"]), 'string', "set-cookie check") @@ -205,6 +205,7 @@ local function test_headers(test, url, opts) test:ok(r.headers["set-cookie"]:match("age = 17"), "set-cookie check") test:is(r.headers["content-type"], "application/json", "content-type check") test:is(r.headers["my_header"], "value1,value2", "other header check") + test:isnil(r.headers["11200ok"], "http status line not included in headers") test:is(r.cookies["likes"][1], "cheese", "cookie value check") test:ok(r.cookies["likes"][2][1]:match("Expires"), "cookie option check") test:ok(r.cookies["likes"][2][3]:match("HttpOnly"), "cookie option check") -- 2.7.4
next prev parent reply other threads:[~2018-06-15 14:24 UTC|newest] Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-06-15 14:24 [tarantool-patches] [http.client 0/2] Fix parsing headers Ilya Markov 2018-06-15 14:24 ` Ilya Markov [this message] 2018-06-15 14:24 ` [tarantool-patches] [http.client 2/2] http: Fix parse long headers names Ilya Markov
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=02e9c328f4c895dec7655e91ab62004988ff0575.1529072604.git.imarkov@tarantool.org \ --to=imarkov@tarantool.org \ --cc=georgy@tarantool.org \ --cc=tarantool-patches@freelists.org \ --subject='Re: [tarantool-patches] [http.client 1/2] http: Remove parsed status line from headers' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox