From 4c81d7a5fab293c6836342cdefea531a6230e127 Mon Sep 17 00:00:00 2001 From: Hakase Date: Fri, 8 Jun 2018 18:54:51 +0900 Subject: [PATCH] Latest update - 7296 --- src/http/ngx_http_core_module.c | 1 + src/http/ngx_http_parse.c | 5 +++ src/http/ngx_http_request.c | 7 +++- src/http/ngx_http_request.h | 1 + src/http/v2/ngx_http_v2.c | 47 +++++++++++++++++-------- src/http/v2/ngx_http_v2_filter_module.c | 25 ++++++------- 6 files changed, 58 insertions(+), 28 deletions(-) diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c index 89bf282..f60b809 100644 --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -2328,6 +2328,7 @@ ngx_http_subrequest(ngx_http_request_t *r, sr->unparsed_uri = r->unparsed_uri; sr->method_name = ngx_http_core_get_method; sr->http_protocol = r->http_protocol; + sr->schema = r->schema; ngx_http_set_exten(sr); diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c index 844054c..d9a1dbe 100644 --- a/src/http/ngx_http_parse.c +++ b/src/http/ngx_http_parse.c @@ -307,6 +307,11 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b) break; } + if ((ch >= '0' && ch <= '9') || ch == '+' || ch == '-' || ch == '.') + { + break; + } + switch (ch) { case ':': r->schema_end = p; diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c index ad84800..f864476 100644 --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -1020,7 +1020,12 @@ ngx_http_process_request_line(ngx_event_t *rev) return; } - if (r->host_start && r->host_end) { + if (r->schema_end) { + r->schema.len = r->schema_end - r->schema_start; + r->schema.data = r->schema_start; + } + + if (r->host_end) { host.len = r->host_end - r->host_start; host.data = r->host_start; diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h index e49158f..be0a569 100644 --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -412,6 +412,7 @@ struct ngx_http_request_s { ngx_str_t method_name; ngx_str_t http_protocol; + ngx_str_t schema; ngx_chain_t *out; ngx_http_request_t *main; diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c index 303d157..642d918 100644 --- a/src/http/v2/ngx_http_v2.c +++ b/src/http/v2/ngx_http_v2.c @@ -2629,18 +2629,13 @@ ngx_http_v2_push_stream(ngx_http_v2_stream_t *parent, ngx_str_t *path) r->method_name = ngx_http_core_get_method; r->method = NGX_HTTP_GET; - r->schema_start = (u_char *) "https"; - -#if (NGX_HTTP_SSL) - if (fc->ssl) { - r->schema_end = r->schema_start + 5; - - } else -#endif - { - r->schema_end = r->schema_start + 4; + r->schema.data = ngx_pstrdup(pool, &parent->request->schema); + if (r->schema.data == NULL) { + goto close; } + r->schema.len = parent->request->schema.len; + value.data = ngx_pstrdup(pool, path); if (value.data == NULL) { goto close; @@ -3487,7 +3482,10 @@ ngx_http_v2_parse_method(ngx_http_request_t *r, ngx_str_t *value) static ngx_int_t ngx_http_v2_parse_scheme(ngx_http_request_t *r, ngx_str_t *value) { - if (r->schema_start) { + u_char c, ch; + ngx_uint_t i; + + if (r->schema.len) { ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "client sent duplicate :scheme header"); @@ -3501,8 +3499,27 @@ ngx_http_v2_parse_scheme(ngx_http_request_t *r, ngx_str_t *value) return NGX_DECLINED; } - r->schema_start = value->data; - r->schema_end = value->data + value->len; + for (i = 0; i < value->len; i++) { + ch = value->data[i]; + + c = (u_char) (ch | 0x20); + if (c >= 'a' && c <= 'z') { + continue; + } + + if (((ch >= '0' && ch <= '9') || ch == '+' || ch == '-' || ch == '.') + && i > 0) + { + continue; + } + + ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, + "client sent invalid :scheme header: \"%V\"", value); + + return NGX_DECLINED; + } + + r->schema = *value; return NGX_OK; } @@ -3565,14 +3582,14 @@ ngx_http_v2_construct_request_line(ngx_http_request_t *r) static const u_char ending[] = " HTTP/2.0"; if (r->method_name.len == 0 - || r->schema_start == NULL + || r->schema.len == 0 || r->unparsed_uri.len == 0) { if (r->method_name.len == 0) { ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "client sent no :method header"); - } else if (r->schema_start == NULL) { + } else if (r->schema.len == 0) { ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "client sent no :scheme header"); diff --git a/src/http/v2/ngx_http_v2_filter_module.c b/src/http/v2/ngx_http_v2_filter_module.c index 9d6cfdd..51750b0 100644 --- a/src/http/v2/ngx_http_v2_filter_module.c +++ b/src/http/v2/ngx_http_v2_filter_module.c @@ -912,15 +912,15 @@ ngx_http_v2_push_resource(ngx_http_request_t *r, ngx_str_t *path, ph = ngx_http_v2_push_headers; + len = ngx_max(r->schema.len, path->len); + if (binary[0].len) { - tmp = ngx_palloc(r->pool, path->len); + tmp = ngx_palloc(r->pool, len); if (tmp == NULL) { return NGX_ERROR; } } else { - len = path->len; - for (i = 0; i < NGX_HTTP_V2_PUSH_HEADERS; i++) { h = (ngx_table_elt_t **) ((char *) &r->headers_in + ph[i].offset); @@ -962,7 +962,7 @@ ngx_http_v2_push_resource(ngx_http_request_t *r, ngx_str_t *path, len = (h2c->table_update ? 1 : 0) + 1 + 1 + NGX_HTTP_V2_INT_OCTETS + path->len - + 1; + + 1 + NGX_HTTP_V2_INT_OCTETS + r->schema.len; for (i = 0; i < NGX_HTTP_V2_PUSH_HEADERS; i++) { len += binary[i].len; @@ -998,18 +998,19 @@ ngx_http_v2_push_resource(ngx_http_request_t *r, ngx_str_t *path, pos = ngx_http_v2_write_header_pot(":path", path); -#if (NGX_HTTP_SSL) - if (fc->ssl) { - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0, - "http2 push header: \":scheme: https\""); + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0, + "http2 push header: \":scheme: %V\"", &r->schema); + + if (r->schema.len == 5 && ngx_strncmp(r->schema.data, "https", 5) == 0) { *pos++ = ngx_http_v2_indexed(NGX_HTTP_V2_SCHEME_HTTPS_INDEX); - } else -#endif + } else if (r->schema.len == 4 + && ngx_strncmp(r->schema.data, "http", 4) == 0) { - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0, - "http2 push header: \":scheme: http\""); *pos++ = ngx_http_v2_indexed(NGX_HTTP_V2_SCHEME_HTTP_INDEX); + + } else { + pos = ngx_http_v2_write_header_tbl(":scheme", r->schema); } for (i = 0; i < NGX_HTTP_V2_PUSH_HEADERS; i++) {