[nginx] Fixed handling of already closed connections.

Maxim Dounin mdounin at mdounin.ru
Sun Mar 28 14:47:20 UTC 2021


details:   https://hg.nginx.org/nginx/rev/1ebd78df4ce7
branches:  
changeset: 7811:1ebd78df4ce7
user:      Maxim Dounin <mdounin at mdounin.ru>
date:      Sun Mar 28 17:45:39 2021 +0300
description:
Fixed handling of already closed connections.

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.

diffstat:

 src/http/modules/ngx_http_limit_req_module.c |   9 +++++++--
 src/http/ngx_http_core_module.c              |   9 +++++++--
 src/http/ngx_http_upstream.c                 |  11 ++++++++---
 3 files changed, 22 insertions(+), 7 deletions(-)

diffs (59 lines):

diff -r 1bf8ab7063de -r 1ebd78df4ce7 src/http/modules/ngx_http_limit_req_module.c
--- a/src/http/modules/ngx_http_limit_req_module.c	Sun Mar 28 17:45:37 2021 +0300
+++ b/src/http/modules/ngx_http_limit_req_module.c	Sun Mar 28 17:45:39 2021 +0300
@@ -310,8 +310,13 @@ ngx_http_limit_req_handler(ngx_http_requ
 
     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;
diff -r 1bf8ab7063de -r 1ebd78df4ce7 src/http/ngx_http_core_module.c
--- a/src/http/ngx_http_core_module.c	Sun Mar 28 17:45:37 2021 +0300
+++ b/src/http/ngx_http_core_module.c	Sun Mar 28 17:45:39 2021 +0300
@@ -1190,8 +1190,13 @@ ngx_http_core_auth_delay(ngx_http_reques
     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;
diff -r 1bf8ab7063de -r 1ebd78df4ce7 src/http/ngx_http_upstream.c
--- a/src/http/ngx_http_upstream.c	Sun Mar 28 17:45:37 2021 +0300
+++ b/src/http/ngx_http_upstream.c	Sun Mar 28 17:45:39 2021 +0300
@@ -608,9 +608,14 @@ ngx_http_upstream_init_request(ngx_http_
 
     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;


More information about the nginx-devel mailing list