Hello,

Proxy module may not disable keepalive connection when upstream sends extra 
data with Content-Length:0 response header.

This happens because of an incorrect assumption on the state of the 
upstream->keepalive flag at 
https://github.com/nginx/nginx/blame/master/src/http/modules/ngx_http_proxy_module.c#L2336

When response content-length is 0,  then upstream->keepalive may get 
initialized to 1 depending on the Connection response header. 
https://github.com/nginx/nginx/blob/master/src/http/modules/ngx_http_proxy_module.c#L2002

To trigger this issue, nginx must be configured as follows:
-    proxy buffering is disabled
-    responses are processed by ngx_http_proxy_non_buffered_copy_filter (no 
nginx caching)
-    The upstream keepalive directive is enabled
-    The content-length response header from upstream is 0
-    Upstream sends a body/extra data

Under these conditions, the connection will be saved for next request.

Here is a patch that addresses this:

# HG changeset patch
# User Awdhesh Mathpal <[email protected]>
# Date 1633659791 25200
#      Thu Oct 07 19:23:11 2021 -0700
# Node ID ccf2ccd9724f7cff4363e81545b1af97aa881415
# Parent  ae7c767aa491fa55d3168dfc028a22f43ac8cf89
proxy: Disable keepalive on extra data

When an upstream sends Content-Length:0, upstream->keepalive
is initialized eagerly on the basis of Connection header. This
can lead to keepalive being enabled on the connection. If in such
a scenario upstream sends extra data, then the connection should
not be reused.

diff -r ae7c767aa491 -r ccf2ccd9724f src/http/modules/ngx_http_proxy_module.c
--- a/src/http/modules/ngx_http_proxy_module.c  Wed Oct 06 18:01:42 2021 +0300
+++ b/src/http/modules/ngx_http_proxy_module.c  Thu Oct 07 19:23:11 2021 -0700
@@ -2337,6 +2337,7 @@
         ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
                       "upstream sent more data than specified in "
                       "\"Content-Length\" header");
+        u->keepalive = 0;
         return NGX_OK;
     }

@@ -2370,7 +2371,7 @@
         ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
                       "upstream sent more data than specified in "
                       "\"Content-Length\" header");
-
+        u->keepalive = 0;
         cl->buf->last = cl->buf->pos + u->length;
         u->length = 0;



Awdhesh



_______________________________________________
nginx-devel mailing list
[email protected]
http://mailman.nginx.org/mailman/listinfo/nginx-devel

Reply via email to