Opened 3 months ago

Last modified 3 months ago

#1811 new defect

proxy server,slice+limit_rate,keepalived connection will be delayed to receive

Reported by: kuninchengdu@… Owned by:
Priority: critical Milestone: nginx-1.17
Component: nginx-module Version: 1.13.x
Keywords: slice+limit_rate Cc: gcc
uname -a: 3.0.76-0.11-default #1 SMP Fri Jun 14 08:21:43 UTC 2013 (ccab990) x86_64 x86_64 x86_64 GNU/Linux
nginx -V: nginx version: openresty/1.13.6.1 built by gcc 4.3.4 [gcc-4_3-branch revision 152973] (SUSE Linux) built with OpenSSL 1.1.0f 25 May 2017 TLS SNI support enabled configure arguments: --prefix=/git/NginxPlatform/tmp/nginx --with-debug --with-cc-opt='-DNGX_LUA_USE_ASSERT -DNGX_LUA_ABORT_AT_PANIC -O2 -I/git/NginxPlatform/include -O0 -Werror -DNGX_HTTP_HEADERS -fstack-protector' --add-module=../ngx_devel_kit-0.3.0 --add-module=../echo-nginx-module-0.61 --add-module=../xss-nginx-module-0.05 --add-module=../ngx_coolkit-0.2rc3 --add-module=../set-misc-nginx-module-0.31 --add-module=../form-input-nginx-module-0.12 --add-module=../encrypted-session-nginx-module-0.07 --add-module=../srcache-nginx-module-0.31 --add-module=../ngx_lua-0.10.11 --add-module=../ngx_lua_upstream-0.07 --add-module=../headers-more-nginx-module-0.33 --add-module=../array-var-nginx-module-0.05 --add-module=../memc-nginx-module-0.18 --add-module=../redis2-nginx-module-0.14 --add-module=../redis-nginx-module-0.3.7 --add-module=../rds-json-nginx-module-0.15 --add-module=../rds-csv-nginx-module-0.08 --add-module=../ngx_stream_lua-0.0.3 --with-ld-opt='-L/git/NginxPlatform/lib -luuid -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-free -Wl,-z,relro -Wl,-z,noexecstack -Wl,--disable-new-dtags,-rpath,${origin_path}' --with-compat --with-redis --with-ipv6 --with-http_worker_info_module --with-http_plugin_log_module --with-http_slice_module --with-http_v2_module --with-http_stub_status_module --add-module=/git/NginxPlatform/src/modules/ngx_http_online_config_module --add-module=/git/NginxPlatform/src/modules/ngx_upstream_check_module --add-module=/git/NginxPlatform/src/modules/ngx_http_upstream_select_server_module --add-dynamic-module=/git/NginxPlatform/nginx-http-flv-module --add-dynamic-module=/git/NginxPlatform/src/modules/ngx_http_was_filter_module --add-dynamic-module=/git/NginxPlatform/src/modules/ngx_http_slice_ats_module --add-dynamic-module=/git/NginxPlatform/src/modules/ngx_http_was_adapter_module --add-dynamic-module=/git/NginxPlatform/src/modules/ngx_http_ott_kpi_module --add-dynamic-module=/git/NginxPlatform/src/modules/ngx_http_fast_forward_filter_module --add-module=/git/NginxPlatform/src/modules/ngx_http_sysguard_module --add-dynamic-module=/git/NginxPlatform/src/modules/ngx_http_geoblocking_module --add-dynamic-module=/git/NginxPlatform/src/modules/ngx_http_cache_purge_module --add-module=/git/NginxPlatform/src/modules/ngx_http_custom_log_variables_module --add-module=/git/NginxPlatform/src/modules/ngx_http_stream_log_module --with-stream --with-stream_ssl_module --with-http_ssl_module

Description

slice 512k;
limit_rate 512k;
proxy_pass ...

above configuration,ngx_http_write_filter will delay when sending last data,but request is main request which calling by ngx_http_writer as subrequest has finished before sending all the data,then ngx_http_slice_body_filter will exec ‘ngx_http_send_special(r, NGX_HTTP_LAST)’,and
ngx_http_write_filter will exec as following:

if (c->write->delayed) {
c->buffered |= NGX_HTTP_WRITE_BUFFERED;
return NGX_AGAIN;
}

then ngx_http_writer will return because c->buffered is not zero

if (r->buffered
r->postponed (r == r->main && c->buffered)) {

if (!wev->delayed) {
ngx_add_timer(wev, clcf->send_timeout);
}
if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
ngx_http_close_request(r, 0);
}
return;
}

now, client reuse this connection to send a new request,but
r->read_event_handler is ngx_http_test_reading,it only peek, after delay ms,old request will close, and exec
ngx_http_set_keepalive and ngx_http_process_request_line,then new request can be recived

Change History (2)

comment:1 follow-up: Changed 3 months ago by mdounin

It looks like you are using a 3rd party fork of an outdated nginx version. Please make sure you are able to reproduce the issue with latest nginx version - nginx 1.17.1. If you are able to, please provide a self-contained configuration which demonstrates the issue.

comment:2 in reply to: ↑ 1 Changed 3 months ago by kuninchengdu@…

although I use a 3rd module, but the process as above never enter it,I only use slice and limit_rate,
the result which I analysis is:
subrequest finilize firstly(set c->data to r->main),but data does not send completely.
this is a common process in nginx.
then ngx_http_writer will exec, but limit_rate will delay after sending all the data,
normally, ngx_http_finilize_request will delete timer and c->write->delay, but slice is a
subrequet, slice module will exec ngx_http_send_special(r, NGX_HTTP_LAST) in slice body filter, but
it will be delayed in ngx_http_write_filter becase c->write->delay is true, then
c->buffered |= NGX_HTTP_WRITE_BUFFERED;

then ngx_http_writer will abort not to exec ngx_http_finilize_request!

Replying to mdounin:

It looks like you are using a 3rd party fork of an outdated nginx version. Please make sure you are able to reproduce the issue with latest nginx version - nginx 1.17.1. If you are able to, please provide a self-contained configuration which demonstrates the issue.

Note: See TracTickets for help on using tickets.