summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorValentin Bartenev <vbart@nginx.com>2018-03-15 21:07:57 +0300
committerValentin Bartenev <vbart@nginx.com>2018-03-15 21:07:57 +0300
commit0b628bfe484d1262d37e5043cad9f7a326d0d5e4 (patch)
treea0265b06d8e503c75cf8e672e779c2ca174616c7
parent3d2f85d9ca66aecaf1c46a818998a27f99f755e2 (diff)
downloadunit-0b628bfe484d1262d37e5043cad9f7a326d0d5e4.tar.gz
unit-0b628bfe484d1262d37e5043cad9f7a326d0d5e4.tar.bz2
HTTP parser: allowing tabs in field values as per RFC 7230.
-rw-r--r--src/nxt_http_parse.c34
-rw-r--r--src/test/nxt_http_parse_test.c24
2 files changed, 45 insertions, 13 deletions
diff --git a/src/nxt_http_parse.c b/src/nxt_http_parse.c
index 95127569..2bd821b8 100644
--- a/src/nxt_http_parse.c
+++ b/src/nxt_http_parse.c
@@ -629,26 +629,34 @@ nxt_http_parse_field_value(nxt_http_request_parse_t *rp, u_char **pos,
p += rp->field_value.length;
- p = nxt_http_lookup_field_end(p, end);
+ for ( ;; ) {
+ p = nxt_http_lookup_field_end(p, end);
- if (nxt_slow_path(p == end)) {
- *pos = start;
+ if (nxt_slow_path(p == end)) {
+ *pos = start;
- len = p - start;
+ len = p - start;
- if (nxt_slow_path(len > NXT_HTTP_MAX_FIELD_VALUE)) {
- return NXT_HTTP_PARSE_TOO_LARGE_FIELD;
+ if (nxt_slow_path(len > NXT_HTTP_MAX_FIELD_VALUE)) {
+ return NXT_HTTP_PARSE_TOO_LARGE_FIELD;
+ }
+
+ rp->field_value.length = len;
+ rp->handler = &nxt_http_parse_field_value;
+ return NXT_AGAIN;
}
- rp->field_value.length = len;
- rp->handler = &nxt_http_parse_field_value;
- return NXT_AGAIN;
- }
+ ch = *p;
- ch = *p;
+ if (nxt_fast_path(ch == '\r' || ch == '\n')) {
+ break;
+ }
- if (nxt_slow_path(ch != '\r' && ch != '\n')) {
- return NXT_HTTP_PARSE_INVALID;
+ if (ch != '\t') {
+ return NXT_HTTP_PARSE_INVALID;
+ }
+
+ p++;
}
*pos = p;
diff --git a/src/test/nxt_http_parse_test.c b/src/test/nxt_http_parse_test.c
index bc2e3a42..a23f27c3 100644
--- a/src/test/nxt_http_parse_test.c
+++ b/src/test/nxt_http_parse_test.c
@@ -270,6 +270,18 @@ static nxt_http_parse_test_case_t nxt_http_test_cases[] = {
},
{
nxt_string("GET / HTTP/1.1\r\n"
+ "Ho\nst: example.com\r\n\r\n"),
+ NXT_HTTP_PARSE_INVALID,
+ NULL, { NULL }
+ },
+ {
+ nxt_string("GET / HTTP/1.1\r\n"
+ "Host : example.com\r\n\r\n"),
+ NXT_HTTP_PARSE_INVALID,
+ NULL, { NULL }
+ },
+ {
+ nxt_string("GET / HTTP/1.1\r\n"
"Host: exa\0mple.com\r\n\r\n"),
NXT_HTTP_PARSE_INVALID,
NULL, { NULL }
@@ -300,6 +312,18 @@ static nxt_http_parse_test_case_t nxt_http_test_cases[] = {
},
{
nxt_string("GET / HTTP/1.1\r\n"
+ "Host: exa\nmple.com\r\n\r\n"),
+ NXT_HTTP_PARSE_INVALID,
+ NULL, { NULL }
+ },
+ {
+ nxt_string("GET / HTTP/1.1\r\n"
+ "Host: exa\tmple.com\r\n\r\n"),
+ NXT_DONE,
+ NULL, { NULL }
+ },
+ {
+ nxt_string("GET / HTTP/1.1\r\n"
"X-Unknown-Header: value\r\n"
"X-Good-Header: value\r\n\r\n"),
NXT_DONE,