changeset 8407:d6feece1288a quic

Fixed $request_length for HTTP/3. New field r->parse_start is introduced to substitute r->request_start and r->header_name_start for request length accounting. These fields only work for this purpose in HTTP/1 because HTTP/1 request line and header line start with these values. Also, error logging is now fixed to output the right part of the request.
author Roman Arutyunyan <arut@nginx.com>
date Tue, 19 May 2020 15:47:37 +0300
parents 66feab03d9b7
children 5b367070cc9c
files src/http/ngx_http_parse.c src/http/ngx_http_request.c src/http/ngx_http_request.h src/http/v3/ngx_http_v3_request.c
diffstat 4 files changed, 19 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/src/http/ngx_http_parse.c
+++ b/src/http/ngx_http_parse.c
@@ -143,6 +143,7 @@ ngx_http_parse_request_line(ngx_http_req
 
         /* HTTP methods: GET, HEAD, POST */
         case sw_start:
+            r->parse_start = p;
             r->request_start = p;
             r->method_start = p;
 
@@ -883,6 +884,7 @@ ngx_http_parse_header_line(ngx_http_requ
 
         /* first char */
         case sw_start:
+            r->parse_start = p;
             r->header_name_start = p;
             r->invalid_header = 0;
 
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -1178,7 +1178,7 @@ ngx_http_process_request_line(ngx_event_
 
             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->request_start; /* XXX */
+            r->request_length = r->header_in->pos - r->parse_start;
 
             ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
                            "http request line: \"%V\"", &r->request_line);
@@ -1293,8 +1293,8 @@ ngx_http_process_request_line(ngx_event_
             }
 
             if (rv == NGX_DECLINED) {
-                r->request_line.len = r->header_in->end - r->request_start;
-                r->request_line.data = r->request_start;
+                r->request_line.len = r->header_in->end - r->parse_start;
+                r->request_line.data = r->parse_start;
 
                 ngx_log_error(NGX_LOG_INFO, c->log, 0,
                               "client sent too long URI");
@@ -1470,7 +1470,7 @@ ngx_http_process_request_headers(ngx_eve
                 }
 
                 if (rv == NGX_DECLINED) {
-                    p = r->header_name_start;
+                    p = r->parse_start;
 
                     r->lingering_close = 1;
 
@@ -1490,7 +1490,7 @@ ngx_http_process_request_headers(ngx_eve
 
                     ngx_log_error(NGX_LOG_INFO, c->log, 0,
                                 "client sent too long header line: \"%*s...\"",
-                                len, r->header_name_start);
+                                len, r->parse_start);
 
                     ngx_http_finalize_request(r,
                                             NGX_HTTP_REQUEST_HEADER_TOO_LARGE);
@@ -1523,8 +1523,7 @@ ngx_http_process_request_headers(ngx_eve
 
         if (rc == NGX_OK) {
 
-            /* XXX */
-            r->request_length += r->header_in->pos - r->header_name_start;
+            r->request_length += r->header_in->pos - r->parse_start;
 
             if (r->invalid_header && cscf->ignore_invalid_headers) {
 
@@ -1596,7 +1595,7 @@ ngx_http_process_request_headers(ngx_eve
             ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                            "http header done");
 
-            r->request_length += r->header_in->pos - r->header_name_start; /* XXX */
+            r->request_length += r->header_in->pos - r->parse_start;
 
             r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE;
 
@@ -1711,7 +1710,7 @@ ngx_http_alloc_large_header_buffer(ngx_h
         return NGX_OK;
     }
 
-    old = request_line ? r->request_start : r->header_name_start; /* XXX */
+    old = r->parse_start;
 
     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
 
@@ -1783,6 +1782,8 @@ ngx_http_alloc_large_header_buffer(ngx_h
     b->pos = new + (r->header_in->pos - old);
     b->last = new + (r->header_in->pos - old);
 
+    r->parse_start = new;
+
     if (request_line) {
         r->request_start = new;
 
@@ -3892,15 +3893,15 @@ ngx_http_log_error_handler(ngx_http_requ
     len -= p - buf;
     buf = p;
 
-    if (r->request_line.data == NULL && r->request_start) {
-        for (p = r->request_start; p < r->header_in->last; p++) {
+    if (r->request_line.data == NULL && r->parse_start) {
+        for (p = r->parse_start; p < r->header_in->last; p++) {
             if (*p == CR || *p == LF) {
                 break;
             }
         }
 
-        r->request_line.len = p - r->request_start;
-        r->request_line.data = r->request_start;
+        r->request_line.len = p - r->parse_start;
+        r->request_line.data = r->parse_start;
     }
 
     if (r->request_line.len) {
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -579,6 +579,7 @@ struct ngx_http_request_s {
      * via ngx_http_ephemeral_t
      */
 
+    u_char                           *parse_start;
     u_char                           *uri_start;
     u_char                           *uri_end;
     u_char                           *uri_ext;
--- a/src/http/v3/ngx_http_v3_request.c
+++ b/src/http/v3/ngx_http_v3_request.c
@@ -59,6 +59,7 @@ ngx_http_v3_parse_request(ngx_http_reque
         }
 
         r->h3_parse = st;
+        r->parse_start = b->pos;
     }
 
     while (b->pos < b->last) {
@@ -130,6 +131,7 @@ ngx_http_v3_parse_header(ngx_http_reques
     st = r->h3_parse;
 
     if (st->header_rep.state == 0) {
+        r->parse_start = b->pos;
         r->invalid_header = 0;
     }