Extra data from upstream and keepalive connections

Awdhesh Mathpal mathpal_n at fastmail.com
Fri Oct 8 18:19:29 UTC 2021


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 <mathpal at amazon.com>
# 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





More information about the nginx-devel mailing list