From 517e32785eec9333a93e1eb5f8bf3165ab7274ef Mon Sep 17 00:00:00 2001 From: Glenn Strauss Date: Thu, 30 Jul 2020 07:38:14 -0400 Subject: [PATCH] [core] HTTP2-Settings --- src/http-header-glue.c | 7 +++++++ src/http_header.c | 4 +++- src/http_header.h | 1 + src/request.c | 5 +++++ 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/http-header-glue.c b/src/http-header-glue.c index ce132d19..eadad268 100644 --- a/src/http-header-glue.c +++ b/src/http-header-glue.c @@ -1034,6 +1034,7 @@ static int http_response_process_headers(request_st * const r, http_response_opt && opts->backend != BACKEND_CGI) { id = HTTP_HEADER_OTHER; } + if (r->http_version >= HTTP_VERSION_2) continue; break; case HTTP_HEADER_CONNECTION: if (opts->backend == BACKEND_PROXY) continue; @@ -1041,6 +1042,7 @@ static int http_response_process_headers(request_st * const r, http_response_opt * but this is an imperfect though simplistic attempt to honor * backend request to close)*/ if (NULL != strstr(value, "lose")) r->keep_alive = 0; + if (r->http_version >= HTTP_VERSION_2) continue; break; case HTTP_HEADER_CONTENT_LENGTH: r->content_length = strtoul(value, NULL, 10); @@ -1054,6 +1056,11 @@ static int http_response_process_headers(request_st * const r, http_response_opt * and chunk_buffer_release() for r->gw_dechunk->b */ force_assert(r->gw_dechunk); continue; + case HTTP_HEADER_HTTP2_SETTINGS: + /* RFC7540 3.2.1 + * A server MUST NOT send this header field. */ + /* (not bothering to remove HTTP2-Settings from Connection) */ + continue; default: break; } diff --git a/src/http_header.c b/src/http_header.c index 238e2643..9a52a1b6 100644 --- a/src/http_header.c +++ b/src/http_header.c @@ -26,7 +26,7 @@ typedef struct keyvlenvalue { /* Note: must be kept in sync http_headers[] and http_headers_off[] */ /* http_headers_off lists first offset at which string of specific len occur */ int8_t http_headers_off[] = { - -1, -1, -1, -1, 0, 4, 5, 9, 10, 11, 12, -1, 15, 16, 20, 21, 23, 25 + -1, -1, -1, -1, 0, 4, 5, 9, 10, 11, 12, -1, 15, 16, 20, 22, 24, 26 }; static const keyvlenvalue http_headers[] = { { HTTP_HEADER_HOST, CONST_LEN_STR("Host") } @@ -50,6 +50,7 @@ static const keyvlenvalue http_headers[] = { ,{ HTTP_HEADER_IF_NONE_MATCH, CONST_LEN_STR("If-None-Match") } ,{ HTTP_HEADER_CACHE_CONTROL, CONST_LEN_STR("Cache-Control") } ,{ HTTP_HEADER_CONTENT_LENGTH, CONST_LEN_STR("Content-Length") } + ,{ HTTP_HEADER_HTTP2_SETTINGS, CONST_LEN_STR("HTTP2-Settings") } ,{ HTTP_HEADER_ACCEPT_ENCODING, CONST_LEN_STR("Accept-Encoding") } ,{ HTTP_HEADER_X_FORWARDED_FOR, CONST_LEN_STR("X-Forwarded-For") } ,{ HTTP_HEADER_CONTENT_ENCODING, CONST_LEN_STR("Content-Encoding") } @@ -85,6 +86,7 @@ int http_header_str_contains_token (const char * const s, const uint32_t slen, c { /*if (slen < mlen) return 0;*//*(possible optimizations for caller)*/ /*if (slen == mlen && buffer_eq_icase_ssn(s, m, mlen)) return 1;*/ + /*(note: does not handle quoted-string)*/ uint32_t i = 0; do { while (i < slen && (s[i]==' ' || s[i]=='\t' || s[i]==',')) ++i; diff --git a/src/http_header.h b/src/http_header.h index 45a18153..b302a23c 100644 --- a/src/http_header.h +++ b/src/http_header.h @@ -38,6 +38,7 @@ enum http_header_e { ,HTTP_HEADER_VARY = 0x02000000 ,HTTP_HEADER_X_FORWARDED_FOR = 0x04000000 ,HTTP_HEADER_X_FORWARDED_PROTO = 0x08000000 + ,HTTP_HEADER_HTTP2_SETTINGS = 0x10000000 }; __attribute_pure__ diff --git a/src/request.c b/src/request.c index 44b1c573..c9d5ebb4 100644 --- a/src/request.c +++ b/src/request.c @@ -449,6 +449,11 @@ static int http_request_parse_single_header(request_st * const restrict r, const return http_request_header_line_invalid(r, 400, "duplicate Content-Length header -> 400"); } break; + case HTTP_HEADER_HTTP2_SETTINGS: + if (r->rqst_htags & HTTP_HEADER_HTTP2_SETTINGS) { + return http_request_header_line_invalid(r, 400, "duplicate HTTP2-Settings header -> 400"); + } + break; case HTTP_HEADER_IF_MODIFIED_SINCE: if (r->rqst_htags & HTTP_HEADER_IF_MODIFIED_SINCE) { /* Proxies sometimes send dup headers