diff options
author | Roman Arutyunyan <arut@nginx.com> | 2021-01-22 16:34:06 +0300 |
---|---|---|
committer | Roman Arutyunyan <arut@nginx.com> | 2021-01-22 16:34:06 +0300 |
commit | 9e489d208fff35c490b43980a064c38cc8dc4f2c (patch) | |
tree | 13434e205541c72867fff50bcd2c05662078d611 /src/http/ngx_http_request.c | |
parent | f3c9e9f9616066c6f1d16b9b1e01b7a3d0e2503a (diff) | |
download | nginx-9e489d208fff35c490b43980a064c38cc8dc4f2c.tar.gz nginx-9e489d208fff35c490b43980a064c38cc8dc4f2c.zip |
HTTP/3: refactored request parser.
The change reduces diff to the default branch for
src/http/ngx_http_request.c and src/http/ngx_http_parse.c.
Diffstat (limited to 'src/http/ngx_http_request.c')
-rw-r--r-- | src/http/ngx_http_request.c | 197 |
1 files changed, 35 insertions, 162 deletions
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c index 0ce4dacec..abcc1bba8 100644 --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -31,10 +31,6 @@ static ngx_int_t ngx_http_process_connection(ngx_http_request_t *r, static ngx_int_t ngx_http_process_user_agent(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset); -static ngx_int_t ngx_http_validate_host(ngx_str_t *host, ngx_pool_t *pool, - ngx_uint_t alloc); -static ngx_int_t ngx_http_set_virtual_server(ngx_http_request_t *r, - ngx_str_t *host); static ngx_int_t ngx_http_find_virtual_server(ngx_connection_t *c, ngx_http_virtual_names_t *virtual_names, ngx_str_t *host, ngx_http_request_t *r, ngx_http_core_srv_conf_t **cscfp); @@ -52,7 +48,6 @@ static void ngx_http_keepalive_handler(ngx_event_t *ev); static void ngx_http_set_lingering_close(ngx_connection_t *c); static void ngx_http_lingering_close_handler(ngx_event_t *ev); static ngx_int_t ngx_http_post_action(ngx_http_request_t *r); -static void ngx_http_close_request(ngx_http_request_t *r, ngx_int_t error); static void ngx_http_log_request(ngx_http_request_t *r); static u_char *ngx_http_log_error_handler(ngx_http_request_t *r, @@ -303,54 +298,11 @@ ngx_http_init_connection(ngx_connection_t *c) hc->conf_ctx = hc->addr_conf->default_server->ctx; #if (NGX_HTTP_QUIC) - if (hc->addr_conf->quic) { - ngx_quic_conf_t *qcf; - ngx_http_connection_t *phc; - ngx_http_core_loc_conf_t *clcf; - - hc->ssl = 1; - -#if (NGX_HTTP_V3) - - if (hc->addr_conf->http3) { - ngx_int_t rc; - - rc = ngx_http_v3_init_connection(c); - - if (rc == NGX_ERROR) { - ngx_http_close_connection(c); - return; - } - - if (rc == NGX_DONE) { - return; - } - } - -#endif - - if (c->quic == NULL) { - c->log->connection = c->number; - - qcf = ngx_http_get_module_srv_conf(hc->conf_ctx, - ngx_http_quic_module); - ngx_quic_run(c, qcf); + if (ngx_http_quic_init(c) == NGX_DONE) { return; } - - phc = c->quic->parent->data; - - if (phc->ssl_servername) { - hc->ssl_servername = phc->ssl_servername; - hc->conf_ctx = phc->conf_ctx; - - clcf = ngx_http_get_module_loc_conf(hc->conf_ctx, - ngx_http_core_module); - ngx_set_connection_log(c, clcf->error_log); - } } - #endif ctx = ngx_palloc(c->pool, sizeof(ngx_http_log_ctx_t)); @@ -380,6 +332,13 @@ ngx_http_init_connection(ngx_connection_t *c) } #endif +#if (NGX_HTTP_V3) + if (hc->addr_conf->http3) { + ngx_http_v3_init(c); + return; + } +#endif + #if (NGX_HTTP_SSL) { ngx_http_ssl_srv_conf_t *sscf; @@ -669,12 +628,6 @@ ngx_http_alloc_request(ngx_connection_t *c) r->method = NGX_HTTP_UNKNOWN; r->http_version = NGX_HTTP_VERSION_10; -#if (NGX_HTTP_V3) - if (hc->addr_conf->http3) { - r->http_version = NGX_HTTP_VERSION_30; - } -#endif - r->headers_in.content_length_n = -1; r->headers_in.keep_alive_n = -1; r->headers_out.content_length_n = -1; @@ -1140,16 +1093,7 @@ ngx_http_process_request_line(ngx_event_t *rev) } } - switch (r->http_version) { -#if (NGX_HTTP_V3) - case NGX_HTTP_VERSION_30: - rc = ngx_http_v3_parse_request(r, r->header_in); - break; -#endif - - default: /* HTTP/1.x */ - rc = ngx_http_parse_request_line(r, r->header_in); - } + rc = ngx_http_parse_request_line(r, r->header_in); if (rc == NGX_OK) { @@ -1157,7 +1101,7 @@ ngx_http_process_request_line(ngx_event_t *rev) r->request_line.len = r->request_end - r->request_start; r->request_line.data = r->request_start; - r->request_length = r->header_in->pos - r->parse_start; + r->request_length = r->header_in->pos - r->request_start; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http request line: \"%V\"", &r->request_line); @@ -1234,15 +1178,6 @@ ngx_http_process_request_line(ngx_event_t *rev) break; } - if (rc == NGX_BUSY) { - if (ngx_handle_read_event(rev, 0) != NGX_OK) { - ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); - return; - } - - break; - } - if (rc != NGX_AGAIN) { /* there was error while a request line parsing */ @@ -1272,8 +1207,8 @@ ngx_http_process_request_line(ngx_event_t *rev) } if (rv == NGX_DECLINED) { - r->request_line.len = r->header_in->end - r->parse_start; - r->request_line.data = r->parse_start; + r->request_line.len = r->header_in->end - r->request_start; + r->request_line.data = r->request_start; ngx_log_error(NGX_LOG_INFO, c->log, 0, "client sent too long URI"); @@ -1437,7 +1372,7 @@ ngx_http_process_request_headers(ngx_event_t *rev) cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); - rc = NGX_OK; + rc = NGX_AGAIN; for ( ;; ) { @@ -1453,7 +1388,7 @@ ngx_http_process_request_headers(ngx_event_t *rev) } if (rv == NGX_DECLINED) { - p = r->parse_start; + p = r->header_name_start; r->lingering_close = 1; @@ -1473,7 +1408,7 @@ ngx_http_process_request_headers(ngx_event_t *rev) ngx_log_error(NGX_LOG_INFO, c->log, 0, "client sent too long header line: \"%*s...\"", - len, r->parse_start); + len, r->header_name_start); ngx_http_finalize_request(r, NGX_HTTP_REQUEST_HEADER_TOO_LARGE); @@ -1491,32 +1426,21 @@ ngx_http_process_request_headers(ngx_event_t *rev) /* the host header could change the server configuration context */ cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); - switch (r->http_version) { -#if (NGX_HTTP_V3) - case NGX_HTTP_VERSION_30: - rc = ngx_http_v3_parse_header(r, r->header_in, - cscf->underscores_in_headers); - break; -#endif - - default: /* HTTP/1.x */ - rc = ngx_http_parse_header_line(r, r->header_in, - cscf->underscores_in_headers); - } + rc = ngx_http_parse_header_line(r, r->header_in, + cscf->underscores_in_headers); if (rc == NGX_OK) { - r->request_length += r->header_in->pos - r->parse_start; + r->request_length += r->header_in->pos - r->header_name_start; if (r->invalid_header && cscf->ignore_invalid_headers) { /* there was error while a header line parsing */ ngx_log_error(NGX_LOG_INFO, c->log, 0, - "client sent invalid header line: \"%*s: %*s\"", - r->header_name_end - r->header_name_start, - r->header_name_start, - r->header_end - r->header_start, r->header_start); + "client sent invalid header line: \"%*s\"", + r->header_end - r->header_name_start, + r->header_name_start); continue; } @@ -1532,17 +1456,11 @@ ngx_http_process_request_headers(ngx_event_t *rev) h->key.len = r->header_name_end - r->header_name_start; h->key.data = r->header_name_start; - - if (h->key.data[h->key.len]) { - h->key.data[h->key.len] = '\0'; - } + h->key.data[h->key.len] = '\0'; h->value.len = r->header_end - r->header_start; h->value.data = r->header_start; - - if (h->value.data[h->value.len]) { - h->value.data[h->value.len] = '\0'; - } + h->value.data[h->value.len] = '\0'; h->lowcase_key = ngx_pnalloc(r->pool, h->key.len); if (h->lowcase_key == NULL) { @@ -1578,7 +1496,7 @@ ngx_http_process_request_headers(ngx_event_t *rev) ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http header done"); - r->request_length += r->header_in->pos - r->parse_start; + r->request_length += r->header_in->pos - r->header_name_start; r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE; @@ -1693,7 +1611,7 @@ ngx_http_alloc_large_header_buffer(ngx_http_request_t *r, return NGX_OK; } - old = r->parse_start; + old = request_line ? r->request_start : r->header_name_start; cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); @@ -1771,14 +1689,6 @@ ngx_http_alloc_large_header_buffer(ngx_http_request_t *r, b->pos = new + (r->header_in->pos - old); b->last = new + (r->header_in->pos - old); - r->parse_start = new; - - r->header_in = b; - - if (r->http_version > NGX_HTTP_VERSION_11) { - return NGX_OK; - } - if (request_line) { r->request_start = new; @@ -1827,6 +1737,8 @@ ngx_http_alloc_large_header_buffer(ngx_http_request_t *r, r->header_end = new + (r->header_end - old); } + r->header_in = b; + return NGX_OK; } @@ -2047,46 +1959,13 @@ ngx_http_process_request_header(ngx_http_request_t *r) return NGX_ERROR; } - if (r->headers_in.host == NULL && r->http_version == NGX_HTTP_VERSION_11) { + if (r->headers_in.host == NULL && r->http_version > NGX_HTTP_VERSION_10) { ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "client sent HTTP/1.1 request without \"Host\" header"); ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); return NGX_ERROR; } - if (r->headers_in.host == NULL && r->http_version == NGX_HTTP_VERSION_20) { - ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, - "client sent HTTP/2 request without " - "\":authority\" or \"Host\" header"); - ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); - return NGX_ERROR; - } - - if (r->http_version == NGX_HTTP_VERSION_30) { - if (r->headers_in.server.len == 0) { - ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, - "client sent HTTP/3 request without " - "\":authority\" or \"Host\" header"); - ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); - return NGX_ERROR; - } - - if (r->headers_in.host) { - if (r->headers_in.host->value.len != r->headers_in.server.len - || ngx_memcmp(r->headers_in.host->value.data, - r->headers_in.server.data, - r->headers_in.server.len) - != 0) - { - ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, - "client sent HTTP/3 request with different " - "values of \":authority\" and \"Host\" headers"); - ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); - return NGX_ERROR; - } - } - } - if (r->headers_in.content_length) { r->headers_in.content_length_n = ngx_atoof(r->headers_in.content_length->value.data, @@ -2125,12 +2004,6 @@ ngx_http_process_request_header(ngx_http_request_t *r) } } -#if (NGX_HTTP_V3) - if (r->http_version == NGX_HTTP_VERSION_30) { - r->headers_in.chunked = 1; - } -#endif - if (r->headers_in.connection_type == NGX_HTTP_CONNECTION_KEEP_ALIVE) { if (r->headers_in.keep_alive) { r->headers_in.keep_alive_n = @@ -2235,7 +2108,7 @@ ngx_http_process_request(ngx_http_request_t *r) } -static ngx_int_t +ngx_int_t ngx_http_validate_host(ngx_str_t *host, ngx_pool_t *pool, ngx_uint_t alloc) { u_char *h, ch; @@ -2326,7 +2199,7 @@ ngx_http_validate_host(ngx_str_t *host, ngx_pool_t *pool, ngx_uint_t alloc) } -static ngx_int_t +ngx_int_t ngx_http_set_virtual_server(ngx_http_request_t *r, ngx_str_t *host) { ngx_int_t rc; @@ -3744,7 +3617,7 @@ ngx_http_post_action(ngx_http_request_t *r) } -static void +void ngx_http_close_request(ngx_http_request_t *r, ngx_int_t rc) { ngx_connection_t *c; @@ -3965,15 +3838,15 @@ ngx_http_log_error_handler(ngx_http_request_t *r, ngx_http_request_t *sr, len -= p - buf; buf = p; - if (r->request_line.data == NULL && r->parse_start) { - for (p = r->parse_start; p < r->header_in->last; p++) { + if (r->request_line.data == NULL && r->request_start) { + for (p = r->request_start; p < r->header_in->last; p++) { if (*p == CR || *p == LF) { break; } } - r->request_line.len = p - r->parse_start; - r->request_line.data = r->parse_start; + r->request_line.len = p - r->request_start; + r->request_line.data = r->request_start; } if (r->request_line.len) { |