summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/nxt_h1proto.c5
-rw-r--r--src/nxt_http.h1
-rw-r--r--src/nxt_http_parse.c36
-rw-r--r--src/nxt_http_parse.h1
-rw-r--r--src/test/nxt_http_parse_test.c5
5 files changed, 35 insertions, 13 deletions
diff --git a/src/nxt_h1proto.c b/src/nxt_h1proto.c
index ac60753d..e5141757 100644
--- a/src/nxt_h1proto.c
+++ b/src/nxt_h1proto.c
@@ -311,6 +311,10 @@ nxt_h1p_header_parse(nxt_task_t *task, void *obj, void *data)
status = NXT_HTTP_BAD_REQUEST;
break;
+ case NXT_HTTP_PARSE_UNSUPPORTED_VERSION:
+ status = NXT_HTTP_VERSION_NOT_SUPPORTED;
+ break;
+
case NXT_HTTP_PARSE_TOO_LARGE_FIELD:
status = NXT_HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE;
break;
@@ -594,6 +598,7 @@ static const nxt_str_t nxt_http_server_error[] = {
nxt_string("HTTP/1.1 502 Bad Gateway\r\n"),
nxt_string("HTTP/1.1 503 Service Unavailable\r\n"),
nxt_string("HTTP/1.1 504 Gateway Timeout\r\n"),
+ nxt_string("HTTP/1.1 505 HTTP Version Not Supported\r\n"),
};
diff --git a/src/nxt_http.h b/src/nxt_http.h
index f3143687..a8a28eca 100644
--- a/src/nxt_http.h
+++ b/src/nxt_http.h
@@ -30,6 +30,7 @@ typedef enum {
NXT_HTTP_BAD_GATEWAY = 502,
NXT_HTTP_SERVICE_UNAVAILABLE = 503,
NXT_HTTP_GATEWAY_TIMEOUT = 504,
+ NXT_HTTP_VERSION_NOT_SUPPORTED = 505,
} nxt_http_status_t;
diff --git a/src/nxt_http_parse.c b/src/nxt_http_parse.c
index ef9fee45..975fdd98 100644
--- a/src/nxt_http_parse.c
+++ b/src/nxt_http_parse.c
@@ -383,15 +383,24 @@ space_after_target:
/* " HTTP/1.1\r\n" or " HTTP/1.1\n" */
+ if (nxt_slow_path(p[9] != '\r' && p[9] != '\n')) {
+
+ if (p[1] == ' ') {
+ /* surplus space after tartet */
+ p++;
+ goto space_after_target;
+ }
+
+ rp->space_in_target = 1;
+ goto rest_of_target;
+ }
+
nxt_memcpy(ver.str, &p[1], 8);
- if (nxt_fast_path((ver.ui64 == http11.ui64
- || ver.ui64 == http10.ui64
- || (nxt_memcmp(ver.s.prefix, "HTTP/", 5) == 0
- && ver.s.major >= '0' && ver.s.major <= '9'
- && ver.s.point == '.'
- && ver.s.minor >= '0' && ver.s.minor <= '9'))
- && (p[9] == '\r' || p[9] == '\n')))
+ if (nxt_fast_path(ver.ui64 == http11.ui64
+ || ver.ui64 == http10.ui64
+ || (nxt_memcmp(ver.str, "HTTP/1.", 7) == 0
+ && ver.s.minor >= '0' && ver.s.minor <= '9')))
{
rp->version.ui64 = ver.ui64;
@@ -443,14 +452,15 @@ space_after_target:
return nxt_http_parse_field_name(rp, pos, end);
}
- if (p[1] == ' ') {
- /* surplus space after tartet */
- p++;
- goto space_after_target;
+ if (nxt_memcmp(ver.s.prefix, "HTTP/", 5) == 0
+ && ver.s.major >= '0' && ver.s.major <= '9'
+ && ver.s.point == '.'
+ && ver.s.minor >= '0' && ver.s.minor <= '9')
+ {
+ return NXT_HTTP_PARSE_UNSUPPORTED_VERSION;
}
- rp->space_in_target = 1;
- goto rest_of_target;
+ return NXT_HTTP_PARSE_INVALID;
}
diff --git a/src/nxt_http_parse.h b/src/nxt_http_parse.h
index 51c6809a..0326d45c 100644
--- a/src/nxt_http_parse.h
+++ b/src/nxt_http_parse.h
@@ -10,6 +10,7 @@
typedef enum {
NXT_HTTP_PARSE_INVALID = 1,
+ NXT_HTTP_PARSE_UNSUPPORTED_VERSION,
NXT_HTTP_PARSE_TOO_LARGE_FIELD,
} nxt_http_parse_error_t;
diff --git a/src/test/nxt_http_parse_test.c b/src/test/nxt_http_parse_test.c
index 637e9298..3da10766 100644
--- a/src/test/nxt_http_parse_test.c
+++ b/src/test/nxt_http_parse_test.c
@@ -125,6 +125,11 @@ static nxt_http_parse_test_case_t nxt_http_test_cases[] = {
NULL, { NULL }
},
{
+ nxt_string("GET / HTTP/2.0\r\n"),
+ NXT_HTTP_PARSE_UNSUPPORTED_VERSION,
+ NULL, { NULL }
+ },
+ {
nxt_string("GET /. HTTP/1.0\r\n\r\n"),
NXT_DONE,
&nxt_http_parse_test_request_line,