# HG changeset patch # User Roman Arutyunyan # Date 1589894433 -10800 # Node ID 5b367070cc9c4d0b1a0d82ec130c88a4881b7314 # Parent d6feece1288a52b7ace77a4bf0edf9e5b84e3d89 Fixed client buffer reallocation for HTTP/3. 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. diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -1784,6 +1784,12 @@ ngx_http_alloc_large_header_buffer(ngx_h 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_h 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); - } - - 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); - } - - if (r->schema_start >= old && r->schema_start < r->header_in->pos) { + r->method_end = new + (r->method_end - old); + + r->uri_start = new + (r->uri_start - old); + r->uri_end = new + (r->uri_end - old); + + 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; } diff --git a/src/http/v3/ngx_http_v3_request.c b/src/http/v3/ngx_http_v3_request.c --- a/src/http/v3/ngx_http_v3_request.c +++ b/src/http/v3/ngx_http_v3_request.c @@ -60,6 +60,7 @@ ngx_http_v3_parse_request(ngx_http_reque r->h3_parse = st; r->parse_start = b->pos; + r->state = 1; } while (b->pos < b->last) {