]> git.kaiwu.me - nginx.git/commitdiff
Fixed handling of already closed connections.
authorMaxim Dounin <mdounin@mdounin.ru>
Sun, 28 Mar 2021 14:45:39 +0000 (17:45 +0300)
committerMaxim Dounin <mdounin@mdounin.ru>
Sun, 28 Mar 2021 14:45:39 +0000 (17:45 +0300)
In limit_req, auth_delay, and upstream code to check for broken
connections, tests for possible connection close by the client
did not work if the connection was already closed when relevant
event handler was set.  This happened because there were no additional
events in case of edge-triggered event methods, and read events
were disabled in case of level-triggered ones.

Fix is to explicitly post a read event if the c->read->ready flag
is set.

src/http/modules/ngx_http_limit_req_module.c
src/http/ngx_http_core_module.c
src/http/ngx_http_upstream.c

index dad5edb934c3b21bb21a25bebf657a97195c9b5f..2b062a3052f73bb7e1c6177aed9d1bb627302c74 100644 (file)
@@ -310,8 +310,13 @@ ngx_http_limit_req_handler(ngx_http_request_t *r)
 
     r->main->limit_req_status = NGX_HTTP_LIMIT_REQ_DELAYED;
 
-    if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) {
-        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+    if (r->connection->read->ready) {
+        ngx_post_event(r->connection->read, &ngx_posted_events);
+
+    } else {
+        if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) {
+            return NGX_HTTP_INTERNAL_SERVER_ERROR;
+        }
     }
 
     r->read_event_handler = ngx_http_test_reading;
index 67476e7d7ccf35e7b732e373a244882cb1dc584c..9b94b328e9d8708854c07ab413ce9f4310ac89f6 100644 (file)
@@ -1190,8 +1190,13 @@ ngx_http_core_auth_delay(ngx_http_request_t *r)
     ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
                   "delaying unauthorized request");
 
-    if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) {
-        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+    if (r->connection->read->ready) {
+        ngx_post_event(r->connection->read, &ngx_posted_events);
+
+    } else {
+        if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) {
+            return NGX_HTTP_INTERNAL_SERVER_ERROR;
+        }
     }
 
     r->read_event_handler = ngx_http_test_reading;
index bd1627c091fa0c8c8edbfdf67465e2815151b881..1016afa5b4803e498373e2e1cbad43b5f4688492 100644 (file)
@@ -608,9 +608,14 @@ ngx_http_upstream_init_request(ngx_http_request_t *r)
 
     if (!u->store && !r->post_action && !u->conf->ignore_client_abort) {
 
-        if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) {
-            ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
-            return;
+        if (r->connection->read->ready) {
+            ngx_post_event(r->connection->read, &ngx_posted_events);
+
+        } else {
+            if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) {
+                ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+                return;
+            }
         }
 
         r->read_event_handler = ngx_http_upstream_rd_check_broken_connection;