[tarantool-patches] [http.client 1/2] http: Remove parsed status line from headers
Ilya Markov
imarkov at tarantool.org
Fri Jun 15 17:24:10 MSK 2018
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
More information about the Tarantool-patches
mailing list