[nginx] Limit req: fixed delaying subrequests.

Maxim Dounin mdounin at mdounin.ru
Sun Apr 2 13:28:03 UTC 2017


details:   http://hg.nginx.org/nginx/rev/7fcf209d40c8
branches:  
changeset: 6959:7fcf209d40c8
user:      Maxim Dounin <mdounin at mdounin.ru>
date:      Sun Apr 02 14:32:26 2017 +0300
description:
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.

diffstat:

 src/http/modules/ngx_http_limit_req_module.c |  5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diffs (29 lines):

diff --git a/src/http/modules/ngx_http_limit_req_module.c b/src/http/modules/ngx_http_limit_req_module.c
--- 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_requ
 
     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_reques
 
     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_reques
         return;
     }
 
+    wev->delayed = 0;
     wev->timedout = 0;
 
     if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) {


More information about the nginx-devel mailing list