aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxim Dounin <mdounin@mdounin.ru>2017-04-02 14:32:26 +0300
committerMaxim Dounin <mdounin@mdounin.ru>2017-04-02 14:32:26 +0300
commitfae6878f202b13f0ffe39f75fe19fa15e179e9d5 (patch)
tree35e8d9641b7b244c4ba861501c42d36647146007
parent679bd07b42f6abde6ab0554653585d8e153e5c02 (diff)
downloadnginx-fae6878f202b13f0ffe39f75fe19fa15e179e9d5.tar.gz
nginx-fae6878f202b13f0ffe39f75fe19fa15e179e9d5.zip
Limit req: fixed delaying subrequests.
Since limit_req uses connection's write event to delay request processing, it can conflict with timers in other subrequests. In particular, even if applied to an active subrequest, it can break things if wev->delayed is already set (due to limit_rate or sendfile_max_chunk), since after limit_req finishes the wev->delayed flag will be set and no timer will be active. Fix is to use the wev->delayed flag in limit_req as well. This ensures that wev->delayed won't be set after limit_req finishes, and also ensures that limit_req's timers will be properly handled by other subrequests if the one delayed by limit_req is not active.
-rw-r--r--src/http/modules/ngx_http_limit_req_module.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/src/http/modules/ngx_http_limit_req_module.c b/src/http/modules/ngx_http_limit_req_module.c
index 2f695f212..4a79b479b 100644
--- a/src/http/modules/ngx_http_limit_req_module.c
+++ b/src/http/modules/ngx_http_limit_req_module.c
@@ -276,6 +276,8 @@ ngx_http_limit_req_handler(ngx_http_request_t *r)
r->read_event_handler = ngx_http_test_reading;
r->write_event_handler = ngx_http_limit_req_delay;
+
+ r->connection->write->delayed = 1;
ngx_add_timer(r->connection->write, delay);
return NGX_AGAIN;
@@ -292,7 +294,7 @@ ngx_http_limit_req_delay(ngx_http_request_t *r)
wev = r->connection->write;
- if (!wev->timedout) {
+ if (wev->delayed && !wev->timedout) {
if (ngx_handle_write_event(wev, 0) != NGX_OK) {
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
@@ -301,6 +303,7 @@ ngx_http_limit_req_delay(ngx_http_request_t *r)
return;
}
+ wev->delayed = 0;
wev->timedout = 0;
if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) {