changeset 8728:f1986657fc26 quic

Merged with the default branch.
author Sergey Kandaurov <pluknet@nginx.com>
date Tue, 30 Mar 2021 23:34:51 +0300
parents a64255c01dab (current diff) eb23d58bfd6b (diff)
children 0f8565e0fc76
files src/event/ngx_event.c src/http/ngx_http_core_module.c src/http/ngx_http_request.c src/http/ngx_http_upstream.c
diffstat 16 files changed, 169 insertions(+), 78 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags
+++ b/.hgtags
@@ -458,3 +458,4 @@ 8e5b068f761cd512d10c9671fbde0b568c1fd08b
 f618488eb769e0ed74ef0d93cd118d2ad79ef94d release-1.19.6
 3fa6e2095a7a51acc630517e1c27a7b7ac41f7b3 release-1.19.7
 8c65d21464aaa5923775f80c32474adc7a320068 release-1.19.8
+da571b8eaf8f30f36c43b3c9b25e01e31f47149c release-1.19.9
--- a/docs/xml/nginx/changes.xml
+++ b/docs/xml/nginx/changes.xml
@@ -5,6 +5,68 @@
 <change_log title="nginx">
 
 
+<changes ver="1.19.9" date="2021-03-30">
+
+<change type="bugfix">
+<para lang="ru">
+nginx не собирался с почтовым прокси-сервером,
+но без модуля ngx_mail_ssl_module;
+ошибка появилась в 1.19.8.
+</para>
+<para lang="en">
+nginx could not be built with the mail proxy module,
+but without the ngx_mail_ssl_module;
+the bug had appeared in 1.19.8.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+при работе с gRPC-бэкендами могли возникать ошибки
+"upstream sent response body larger than indicated content length";
+ошибка появилась в 1.19.1.
+</para>
+<para lang="en">
+"upstream sent response body larger than indicated content length"
+errors might occur when working with gRPC backends;
+the bug had appeared in 1.19.1.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+если клиент закрывал соединение в момент отбрасывания тела запроса,
+nginx мог не закрыть соединение до истечения keepalive-таймаута.
+</para>
+<para lang="en">
+nginx might not close a connection till keepalive timeout expiration
+if the connection was closed by the client while discarding the request body.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+при ожидании задержки limit_req или auth_delay, а также при работе с бэкендами
+nginx мог не обнаружить, что соединение уже закрыто клиентом.
+</para>
+<para lang="en">
+nginx might not detect that a connection was already closed by the client
+when waiting for auth_delay or limit_req delay, or when working with backends.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+в методе обработки соединений eventport.
+</para>
+<para lang="en">
+in the eventport method.
+</para>
+</change>
+
+</changes>
+
+
 <changes ver="1.19.8" date="2021-03-09">
 
 <change type="feature">
--- a/misc/GNUmakefile
+++ b/misc/GNUmakefile
@@ -6,7 +6,7 @@ TEMP =		tmp
 
 CC =		cl
 OBJS =		objs.msvc8
-OPENSSL =	openssl-1.1.1j
+OPENSSL =	openssl-1.1.1k
 ZLIB =		zlib-1.2.11
 PCRE =		pcre-8.44
 
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -9,8 +9,8 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define nginx_version      1019008
-#define NGINX_VERSION      "1.19.8"
+#define nginx_version      1019009
+#define NGINX_VERSION      "1.19.9"
 #define NGINX_VER          "nginx/" NGINX_VERSION
 
 #ifdef NGX_BUILD
--- a/src/core/ngx_resolver.c
+++ b/src/core/ngx_resolver.c
@@ -1563,13 +1563,28 @@ ngx_resolver_udp_read(ngx_event_t *rev)
     do {
         n = ngx_udp_recv(c, buf, NGX_RESOLVER_UDP_SIZE);
 
-        if (n < 0) {
-            return;
+        if (n == NGX_AGAIN) {
+            break;
+        }
+
+        if (n == NGX_ERROR) {
+            goto failed;
         }
 
         ngx_resolver_process_response(rec->resolver, buf, n, 0);
 
     } while (rev->ready);
+
+    if (ngx_handle_read_event(rev, 0) != NGX_OK) {
+        goto failed;
+    }
+
+    return;
+
+failed:
+
+    ngx_close_connection(rec->udp);
+    rec->udp = NULL;
 }
 
 
--- a/src/event/modules/ngx_eventport_module.c
+++ b/src/event/modules/ngx_eventport_module.c
@@ -399,7 +399,7 @@ ngx_eventport_del_event(ngx_event_t *ev,
             return NGX_ERROR;
         }
 
-    } else {
+    } else if (ev->active) {
         ngx_log_debug1(NGX_LOG_DEBUG_EVENT, ev->log, 0,
                        "eventport del event: fd:%d", c->fd);
 
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -257,9 +257,7 @@ ngx_process_events_and_timers(ngx_cycle_
         ngx_shmtx_unlock(&ngx_accept_mutex);
     }
 
-    if (delta) {
-        ngx_event_expire_timers();
-    }
+    ngx_event_expire_timers();
 
     ngx_event_process_posted(cycle, &ngx_posted_events);
 }
--- a/src/http/modules/ngx_http_grpc_module.c
+++ b/src/http/modules/ngx_http_grpc_module.c
@@ -2074,17 +2074,6 @@ ngx_http_grpc_filter(void *data, ssize_t
                     return NGX_ERROR;
                 }
 
-                if (ctx->length != -1) {
-                    if ((off_t) ctx->rest > ctx->length) {
-                        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
-                                      "upstream sent response body larger "
-                                      "than indicated content length");
-                        return NGX_ERROR;
-                    }
-
-                    ctx->length -= ctx->rest;
-                }
-
                 if (ctx->rest > ctx->recv_window) {
                     ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                                   "upstream violated stream flow control, "
@@ -2450,6 +2439,18 @@ ngx_http_grpc_filter(void *data, ssize_t
             b->pos = b->last;
             buf->last = b->pos;
 
+            if (ctx->length != -1) {
+
+                if (buf->last - buf->pos > ctx->length) {
+                    ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+                                  "upstream sent response body larger "
+                                  "than indicated content length");
+                    return NGX_ERROR;
+                }
+
+                ctx->length -= buf->last - buf->pos;
+            }
+
             return NGX_AGAIN;
         }
 
@@ -2457,6 +2458,18 @@ ngx_http_grpc_filter(void *data, ssize_t
         buf->last = b->pos;
         ctx->rest = ctx->padding;
 
+        if (ctx->length != -1) {
+
+            if (buf->last - buf->pos > ctx->length) {
+                ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+                              "upstream sent response body larger "
+                              "than indicated content length");
+                return NGX_ERROR;
+            }
+
+            ctx->length -= buf->last - buf->pos;
+        }
+
     done:
 
         if (ctx->padding) {
--- 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_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;
--- 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_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;
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -2652,11 +2652,6 @@ ngx_http_finalize_request(ngx_http_reque
         ngx_del_timer(c->write);
     }
 
-    if (c->read->eof) {
-        ngx_http_close_request(r, 0);
-        return;
-    }
-
     ngx_http_finalize_connection(r);
 }
 
@@ -2762,6 +2757,11 @@ ngx_http_finalize_connection(ngx_http_re
 
     r = r->main;
 
+    if (r->connection->read->eof) {
+        ngx_http_close_request(r, 0);
+        return;
+    }
+
     if (r->reading_body) {
         r->keepalive = 0;
         r->lingering_close = 1;
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -614,6 +614,17 @@ ngx_http_upstream_init_request(ngx_http_
     u->store = u->conf->store;
 
     if (!u->store && !r->post_action && !u->conf->ignore_client_abort) {
+
+        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;
         r->write_event_handler = ngx_http_upstream_wr_check_broken_connection;
     }
@@ -3031,9 +3042,7 @@ ngx_http_upstream_send_response(ngx_http
                 return;
             }
 
-            if (u->peer.connection->read->ready || u->length == 0) {
-                ngx_http_upstream_process_non_buffered_upstream(r, u);
-            }
+            ngx_http_upstream_process_non_buffered_upstream(r, u);
         }
 
         return;
--- a/src/http/v2/ngx_http_v2.c
+++ b/src/http/v2/ngx_http_v2.c
@@ -1368,7 +1368,9 @@ ngx_http_v2_state_headers(ngx_http_v2_co
     clcf = ngx_http_get_module_loc_conf(h2c->http_connection->conf_ctx,
                                         ngx_http_core_module);
 
-    if (h2c->connection->requests >= clcf->keepalive_requests) {
+    if (clcf->keepalive_timeout == 0
+        || h2c->connection->requests >= clcf->keepalive_requests)
+    {
         h2c->goaway = 1;
 
         if (ngx_http_v2_send_goaway(h2c, NGX_HTTP_V2_NO_ERROR) == NGX_ERROR) {
--- a/src/mail/ngx_mail_auth_http_module.c
+++ b/src/mail/ngx_mail_auth_http_module.c
@@ -1135,10 +1135,10 @@ ngx_mail_auth_http_create_request(ngx_ma
     size_t                     len;
     ngx_buf_t                 *b;
     ngx_str_t                  login, passwd;
+    ngx_connection_t          *c;
 #if (NGX_MAIL_SSL)
     ngx_str_t                  verify, subject, issuer, serial, fingerprint,
                                raw_cert, cert;
-    ngx_connection_t          *c;
     ngx_mail_ssl_conf_t       *sslcf;
 #endif
     ngx_mail_core_srv_conf_t  *cscf;
@@ -1151,9 +1151,10 @@ ngx_mail_auth_http_create_request(ngx_ma
         return NULL;
     }
 
+    c = s->connection;
+
 #if (NGX_MAIL_SSL)
 
-    c = s->connection;
     sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
 
     if (c->ssl && sslcf->verify) {
--- a/src/mail/ngx_mail_handler.c
+++ b/src/mail/ngx_mail_handler.c
@@ -272,16 +272,17 @@ ngx_mail_proxy_protocol_handler(ngx_even
 static void
 ngx_mail_init_session_handler(ngx_event_t *rev)
 {
-    ngx_connection_t    *c;
-    ngx_mail_session_t  *s;
+    ngx_connection_t  *c;
 
     c = rev->data;
-    s = c->data;
 
 #if (NGX_MAIL_SSL)
     {
+    ngx_mail_session_t   *s;
     ngx_mail_ssl_conf_t  *sslcf;
 
+    s = c->data;
+
     sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module);
 
     if (sslcf->enable || s->ssl) {
--- a/src/os/unix/ngx_process_cycle.c
+++ b/src/os/unix/ngx_process_cycle.c
@@ -15,7 +15,7 @@ static void ngx_start_worker_processes(n
     ngx_int_t type);
 static void ngx_start_cache_manager_processes(ngx_cycle_t *cycle,
     ngx_uint_t respawn);
-static void ngx_pass_open_channel(ngx_cycle_t *cycle, ngx_channel_t *ch);
+static void ngx_pass_open_channel(ngx_cycle_t *cycle);
 static void ngx_signal_worker_processes(ngx_cycle_t *cycle, int signo);
 static ngx_uint_t ngx_reap_children(ngx_cycle_t *cycle);
 static void ngx_master_process_exit(ngx_cycle_t *cycle);
@@ -335,25 +335,16 @@ ngx_single_process_cycle(ngx_cycle_t *cy
 static void
 ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type)
 {
-    ngx_int_t      i;
-    ngx_channel_t  ch;
+    ngx_int_t  i;
 
     ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start worker processes");
 
-    ngx_memzero(&ch, sizeof(ngx_channel_t));
-
-    ch.command = NGX_CMD_OPEN_CHANNEL;
-
     for (i = 0; i < n; i++) {
 
         ngx_spawn_process(cycle, ngx_worker_process_cycle,
                           (void *) (intptr_t) i, "worker process", type);
 
-        ch.pid = ngx_processes[ngx_process_slot].pid;
-        ch.slot = ngx_process_slot;
-        ch.fd = ngx_processes[ngx_process_slot].channel[0];
-
-        ngx_pass_open_channel(cycle, &ch);
+        ngx_pass_open_channel(cycle);
     }
 }
 
@@ -361,9 +352,8 @@ ngx_start_worker_processes(ngx_cycle_t *
 static void
 ngx_start_cache_manager_processes(ngx_cycle_t *cycle, ngx_uint_t respawn)
 {
-    ngx_uint_t       i, manager, loader;
-    ngx_path_t     **path;
-    ngx_channel_t    ch;
+    ngx_uint_t    i, manager, loader;
+    ngx_path_t  **path;
 
     manager = 0;
     loader = 0;
@@ -388,14 +378,7 @@ ngx_start_cache_manager_processes(ngx_cy
                       &ngx_cache_manager_ctx, "cache manager process",
                       respawn ? NGX_PROCESS_JUST_RESPAWN : NGX_PROCESS_RESPAWN);
 
-    ngx_memzero(&ch, sizeof(ngx_channel_t));
-
-    ch.command = NGX_CMD_OPEN_CHANNEL;
-    ch.pid = ngx_processes[ngx_process_slot].pid;
-    ch.slot = ngx_process_slot;
-    ch.fd = ngx_processes[ngx_process_slot].channel[0];
-
-    ngx_pass_open_channel(cycle, &ch);
+    ngx_pass_open_channel(cycle);
 
     if (loader == 0) {
         return;
@@ -405,20 +388,21 @@ ngx_start_cache_manager_processes(ngx_cy
                       &ngx_cache_loader_ctx, "cache loader process",
                       respawn ? NGX_PROCESS_JUST_SPAWN : NGX_PROCESS_NORESPAWN);
 
+    ngx_pass_open_channel(cycle);
+}
+
+
+static void
+ngx_pass_open_channel(ngx_cycle_t *cycle)
+{
+    ngx_int_t      i;
+    ngx_channel_t  ch;
+
     ch.command = NGX_CMD_OPEN_CHANNEL;
     ch.pid = ngx_processes[ngx_process_slot].pid;
     ch.slot = ngx_process_slot;
     ch.fd = ngx_processes[ngx_process_slot].channel[0];
 
-    ngx_pass_open_channel(cycle, &ch);
-}
-
-
-static void
-ngx_pass_open_channel(ngx_cycle_t *cycle, ngx_channel_t *ch)
-{
-    ngx_int_t  i;
-
     for (i = 0; i < ngx_last_process; i++) {
 
         if (i == ngx_process_slot
@@ -430,14 +414,14 @@ ngx_pass_open_channel(ngx_cycle_t *cycle
 
         ngx_log_debug6(NGX_LOG_DEBUG_CORE, cycle->log, 0,
                       "pass channel s:%i pid:%P fd:%d to s:%i pid:%P fd:%d",
-                      ch->slot, ch->pid, ch->fd,
+                      ch.slot, ch.pid, ch.fd,
                       i, ngx_processes[i].pid,
                       ngx_processes[i].channel[0]);
 
         /* TODO: NGX_AGAIN */
 
         ngx_write_channel(ngx_processes[i].channel[0],
-                          ch, sizeof(ngx_channel_t), cycle->log);
+                          &ch, sizeof(ngx_channel_t), cycle->log);
     }
 }
 
@@ -621,12 +605,7 @@ ngx_reap_children(ngx_cycle_t *cycle)
                 }
 
 
-                ch.command = NGX_CMD_OPEN_CHANNEL;
-                ch.pid = ngx_processes[ngx_process_slot].pid;
-                ch.slot = ngx_process_slot;
-                ch.fd = ngx_processes[ngx_process_slot].channel[0];
-
-                ngx_pass_open_channel(cycle, &ch);
+                ngx_pass_open_channel(cycle);
 
                 live = 1;