]> git.kaiwu.me - nginx.git/commitdiff
Fixed client buffer reallocation for HTTP/3.
authorRoman Arutyunyan <arut@nginx.com>
Tue, 19 May 2020 13:20:33 +0000 (16:20 +0300)
committerRoman Arutyunyan <arut@nginx.com>
Tue, 19 May 2020 13:20:33 +0000 (16:20 +0300)
Preserving pointers within the client buffer is not needed for HTTP/3 because
all data is either allocated from pool or static.  Unlike with HTTP/1, data
typically cannot be referenced directly within the client buffer.  Trying to
preserve NULLs or external pointers lead to broken pointers.

Also, reverted changes in ngx_http_alloc_large_header_buffer() not relevant
for HTTP/3 to minimize diff to mainstream.

src/http/ngx_http_request.c
src/http/v3/ngx_http_v3_request.c

index baef5f44423b66eaff525e3dd8bbcc5066e27fbd..1b3573598348ef73b4273123226262c0858468e8 100644 (file)
@@ -1784,6 +1784,12 @@ ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
 
     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;
 
@@ -1791,63 +1797,47 @@ ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
             r->request_end = new + (r->request_end - old);
         }
 
-        if (r->method_start >= old && r->method_start < r->header_in->pos) {
-            r->method_start = new + (r->method_start - old);
-            r->method_end = new + (r->method_end - old);
-        }
+        r->method_end = new + (r->method_end - old);
 
-        if (r->uri_start >= old && r->uri_start < r->header_in->pos) {
-            r->uri_start = new + (r->uri_start - old);
-            r->uri_end = new + (r->uri_end - old);
-        }
+        r->uri_start = new + (r->uri_start - old);
+        r->uri_end = new + (r->uri_end - old);
 
-        if (r->schema_start >= old && r->schema_start < r->header_in->pos) {
+        if (r->schema_start) {
             r->schema_start = new + (r->schema_start - old);
             r->schema_end = new + (r->schema_end - old);
         }
 
-        if (r->host_start >= old && r->host_start < r->header_in->pos) {
+        if (r->host_start) {
             r->host_start = new + (r->host_start - old);
             if (r->host_end) {
                 r->host_end = new + (r->host_end - old);
             }
         }
 
-        if (r->port_start >= old && r->port_start < r->header_in->pos) {
+        if (r->port_start) {
             r->port_start = new + (r->port_start - old);
             r->port_end = new + (r->port_end - old);
         }
 
-        if (r->uri_ext >= old && r->uri_ext < r->header_in->pos) {
+        if (r->uri_ext) {
             r->uri_ext = new + (r->uri_ext - old);
         }
 
-        if (r->args_start >= old && r->args_start < r->header_in->pos) {
+        if (r->args_start) {
             r->args_start = new + (r->args_start - old);
         }
 
-        if (r->http_protocol.data >= old
-            && r->http_protocol.data < r->header_in->pos)
-        {
+        if (r->http_protocol.data) {
             r->http_protocol.data = new + (r->http_protocol.data - old);
         }
 
     } else {
-        if (r->header_name_start >= old
-            && r->header_name_start < r->header_in->pos)
-        {
-            r->header_name_start = new;
-            r->header_name_end = new + (r->header_name_end - old);
-        }
-
-        if (r->header_start >= old && r->header_start < r->header_in->pos) {
-            r->header_start = new + (r->header_start - old);
-            r->header_end = new + (r->header_end - old);
-        }
+        r->header_name_start = new;
+        r->header_name_end = new + (r->header_name_end - old);
+        r->header_start = new + (r->header_start - old);
+        r->header_end = new + (r->header_end - old);
     }
 
-    r->header_in = b;
-
     return NGX_OK;
 }
 
index 432bc8711e8bde17bebe64916788f8fdda02106d..7fb297728064676b0ed359c37447ed4593b5d10b 100644 (file)
@@ -60,6 +60,7 @@ ngx_http_v3_parse_request(ngx_http_request_t *r, ngx_buf_t *b)
 
         r->h3_parse = st;
         r->parse_start = b->pos;
+        r->state = 1;
     }
 
     while (b->pos < b->last) {