diff options
author | Maxim Dounin <mdounin@mdounin.ru> | 2021-03-28 17:45:39 +0300 |
---|---|---|
committer | Maxim Dounin <mdounin@mdounin.ru> | 2021-03-28 17:45:39 +0300 |
commit | 179c79ce8afd459acffa50e6dabc60b0b7d9a014 (patch) | |
tree | fc91c504be21a6c5c593d85b4e3323d503a71018 | |
parent | 8885c45e1ead18c1fc9325e372069ec9c55e5938 (diff) | |
download | nginx-179c79ce8afd459acffa50e6dabc60b0b7d9a014.tar.gz nginx-179c79ce8afd459acffa50e6dabc60b0b7d9a014.zip |
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.
-rw-r--r-- | src/http/modules/ngx_http_limit_req_module.c | 9 | ||||
-rw-r--r-- | src/http/ngx_http_core_module.c | 9 | ||||
-rw-r--r-- | src/http/ngx_http_upstream.c | 11 |
3 files changed, 22 insertions, 7 deletions
diff --git a/src/http/modules/ngx_http_limit_req_module.c b/src/http/modules/ngx_http_limit_req_module.c index dad5edb93..2b062a305 100644 --- a/src/http/modules/ngx_http_limit_req_module.c +++ b/src/http/modules/ngx_http_limit_req_module.c @@ -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; diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c index 67476e7d7..9b94b328e 100644 --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -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; diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c index bd1627c09..1016afa5b 100644 --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -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; |