Opened 21 months ago
Closed 21 months ago
#2456 closed defect (invalid)
Does not discard request body for unnormal close
Reported by: | Owned by: | ||
---|---|---|---|
Priority: | minor | Milestone: | |
Component: | documentation | Version: | 1.18.x |
Keywords: | Cc: | ||
uname -a: | |||
nginx -V: |
nginx version: nginx/1.18.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) built with OpenSSL 1.1.1r-dev xx XXX xxxx TLS SNI support enabled configure arguments: --prefix=/usr/local/nginx --with-http_ssl_module --with-http_v2_module --with-openssl=/home/fangjian/openssl |
Description
For the case where the origin is closed without reading the complete request, nginx does not normally discard the request body,call ngx_http_upstream_finalize_request with rc == 0
if (u->length == 0
(upstream->read->eof && u->length == -1))
{
ngx_http_upstream_finalize_request(r, u, 0);
return;
}
This may cause Nginx to send RST to downstream, causing downstream to finish the request abnormally。How to solve this problem elegantly? Thank you.
Change History (7)
follow-up: 4 comment:1 by , 21 months ago
follow-up: 3 comment:2 by , 21 months ago
This may cause Nginx to send RST to downstream, causing downstream to finish the request abnormally
If the request is finalized before the whole request body was received from the client, nginx will trigger lingering_close to prevent RST (assuming lingering_close on;
, which is the default), see ngx_http_finalize_connection().
If you are nevertheless seeing RST being sent, please provide more details. In particular, full nginx configuration, a debug log, and a network dump showing the RST would be helpful.
follow-up: 5 comment:3 by , 21 months ago
This can indeed be solved, but it will strongly depend on this configurationReplying to Maxim Dounin:
This may cause Nginx to send RST to downstream, causing downstream to finish the request abnormally
If the request is finalized before the whole request body was received from the client, nginx will trigger lingering_close to prevent RST (assuming
lingering_close on;
, which is the default), see ngx_http_finalize_connection().
If you are nevertheless seeing RST being sent, please provide more details. In particular, full nginx configuration, a debug log, and a network dump showing the RST would be helpful.
comment:4 by , 21 months ago
yes,bug this will affect performance and memory/disk space Replying to Roman Arutyunyan:
With buffered proxying (the default setting) there's no such problem. The request body is read first, and then upstream peers are tried until one of them succeeds.
With unbuffered proxying, things are different. NGINX behaves exactly as the upstream does, like there's no proxy at all.
follow-up: 6 comment:5 by , 21 months ago
Replying to fangjian.routon@…:
This can indeed be solved, but it will strongly depend on this configuration
Please elaborate. It is expected to work fine with lingering close enabled, which is the default. If you've disabled lingering close for some reason (and/or tuned timeouts so these are not enough for some clients), it's your informed decision and RSTs are expected to appear in many practical cases.
comment:6 by , 21 months ago
Replying to Maxim Dounin:
Replying to fangjian.routon@…:
This can indeed be solved, but it will strongly depend on this configuration
Please elaborate. It is expected to work fine with lingering close enabled, which is the default. If you've disabled lingering close for some reason (and/or tuned timeouts so these are not enough for some clients), it's your informed decision and RSTs are expected to appear in many practical cases.
OK,Thank you for your reply
comment:7 by , 21 months ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
Closing this. As explained in comment:2, the particular upstream behaviour triggers lingering close in nginx, and RSTs shouldn't appear on the wire.
With buffered proxying (the default setting) there's no such problem. The request body is read first, and then upstream peers are tried until one of them succeeds.
With unbuffered proxying, things are different. NGINX behaves exactly as the upstream does, like there's no proxy at all.