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