From 229d8ae2d78b4a26858ef111e2a0711137bed5b4 Mon Sep 17 00:00:00 2001 From: Andrew Clayton Date: Fri, 6 Jun 2025 16:34:35 +0100 Subject: [PATCH] Upstream: Fix handling of malformed status lines. If an upstream returned a malformed status line, e.g. HTTP/1.1 404: Not Found (Note the extraneous ':') nginx would for HTTP 1.1 connections cause the client to hang until the proxy timeout was reached while nginx was waiting for more headers from the upstream that were never going to come. The client would then see an empty reply from the server. With HTTP 2 connections nginx would return a status of 000 to the client. E.g. ... < HTTP/2 000 < server: nginx/1.29.0 < date: Fri, 06 Jun 2025 15:31:08 GMT < * Unsupported response code in HTTP response * Connection #0 to host localhost left intact curl: (1) Unsupported response code in HTTP response Both cases would log a 499 status code to the access log. E.g. ::1 - - [06/Jun/2025:16:31:08 +0100] "GET / HTTP/2.0" 499 0 "-" "curl/8.11.1" This was due to returning NGX_OK from ngx_http_proxy_process_status_line() in ngx_http_proxy_module.c rather than NGX_HTTP_UPSTREAM_INVALID_HEADER. We also don't want to set r->http_version to NGX_HTTP_VERSION_9 as for HTTP 1.1 connections this would now result in > GET / HTTP/1.1 > Host: localhost:4000 > User-Agent: curl/8.11.1 > Accept: */* > * Request completely sent off * Received HTTP/0.9 when not allowed * closing connection #0 curl: (1) Received HTTP/0.9 when not allowed Which seems wrong. With this fix both the above cases return a 502 Bad Gateway, e.g. > GET / HTTP/2 > Host: localhost:4000 > User-Agent: curl/8.11.1 > Accept: */* > * Request completely sent off < HTTP/2 502 < server: nginx/1.29.0 < date: Fri, 06 Jun 2025 15:33:06 GMT < content-type: text/html < content-length: 157 ... A 502 is now logged to the access log, e.g. ::1 - - [06/Jun/2025:16:33:15 +0100] "GET / HTTP/1.1" 502 157 "-" "curl/8.11.1" For good measure we remove the setting of u->state->status to NGX_HTTP_OK which doesn't seem to have any effect here. Closes: https://github.com/nginx/nginx/issues/378 --- src/http/modules/ngx_http_proxy_module.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c index ff7460e44..5280ac4b9 100644 --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -1860,11 +1860,9 @@ ngx_http_proxy_process_status_line(ngx_http_request_t *r) } #endif - r->http_version = NGX_HTTP_VERSION_9; - u->state->status = NGX_HTTP_OK; u->headers_in.connection_close = 1; - return NGX_OK; + return NGX_HTTP_UPSTREAM_INVALID_HEADER; } if (u->state && u->state->status == 0) {