Merge branch 'nginx' (nginx-1.19.9).

Change-Id: I3cb5a688a03938c58ae238efa79ea3ac4f20dfa9
Signed-off-by: Piotr Sikora <piotrsikora@google.com>
diff --git a/.hgtags b/.hgtags
index 316ef60..f5cb382 100644
--- a/.hgtags
+++ b/.hgtags
@@ -458,3 +458,4 @@
 f618488eb769e0ed74ef0d93cd118d2ad79ef94d release-1.19.6
 3fa6e2095a7a51acc630517e1c27a7b7ac41f7b3 release-1.19.7
 8c65d21464aaa5923775f80c32474adc7a320068 release-1.19.8
+da571b8eaf8f30f36c43b3c9b25e01e31f47149c release-1.19.9
diff --git a/BUILD b/BUILD
index 55ed1ac..608034a 100644
--- a/BUILD
+++ b/BUILD
@@ -1537,5 +1537,5 @@
     preinst = "@nginx_pkgoss//:debian_preinst",
     prerm = "@nginx_pkgoss//:debian_prerm",
     section = "httpd",
-    version = "1.19.8",
+    version = "1.19.9",
 )
diff --git a/build.bzl b/build.bzl
index 9618982..4800a24 100644
--- a/build.bzl
+++ b/build.bzl
@@ -673,9 +673,9 @@
         name = "nginx_pkgoss",
         build_file_content = _PKGOSS_BUILD_FILE.format(nginx = nginx) +
                              _PKGOSS_BUILD_FILE_TAIL,
-        commit = "f6674ffb8cbba3096aea8ad52951ce0eb71a0f31",  # nginx-1.19.8
+        commit = "319a336633b034c798b26e23a15fda1b54545fc9",  # nginx-1.19.9
         remote = "https://nginx.googlesource.com/nginx-pkgoss",
-        shallow_since = "1615305446 +0300",
+        shallow_since = "1617121567 +0300",
     )
 
 def nginx_repositories_zlib(bind):
diff --git a/docs/xml/nginx/changes.xml b/docs/xml/nginx/changes.xml
index 1c7fb26..8a0220e 100644
--- 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">
diff --git a/misc/GNUmakefile b/misc/GNUmakefile
index 3a2ef5b..c5fde1f 100644
--- a/misc/GNUmakefile
+++ b/misc/GNUmakefile
@@ -6,7 +6,7 @@
 
 CC =		cl
 OBJS =		objs.msvc8
-OPENSSL =	openssl-1.1.1j
+OPENSSL =	openssl-1.1.1k
 ZLIB =		zlib-1.2.11
 PCRE =		pcre-8.44
 
diff --git a/src/core/nginx.h b/src/core/nginx.h
index 0b9c56f..2d2a96a 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -13,8 +13,8 @@
 #define NGINX_NAME         "nginx"
 #endif
 
-#define nginx_version      1019008
-#define NGINX_VERSION      "1.19.8"
+#define nginx_version      1019009
+#define NGINX_VERSION      "1.19.9"
 #define NGINX_VER          NGINX_NAME "/" NGINX_VERSION
 
 #ifdef NGX_BUILD
diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c
index 5b716ee..49616b7 100644
--- a/src/core/ngx_resolver.c
+++ b/src/core/ngx_resolver.c
@@ -1563,13 +1563,28 @@
     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;
 }
 
 
diff --git a/src/event/modules/ngx_eventport_module.c b/src/event/modules/ngx_eventport_module.c
index ffc98e1..287d69c 100644
--- a/src/event/modules/ngx_eventport_module.c
+++ b/src/event/modules/ngx_eventport_module.c
@@ -399,7 +399,7 @@
             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);
 
diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c
index b97ddee..49dca57 100644
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -257,9 +257,7 @@
         ngx_shmtx_unlock(&ngx_accept_mutex);
     }
 
-    if (delta) {
-        ngx_event_expire_timers();
-    }
+    ngx_event_expire_timers();
 
     ngx_event_process_posted(cycle, &ngx_posted_events);
 }
diff --git a/src/http/modules/ngx_http_grpc_module.c b/src/http/modules/ngx_http_grpc_module.c
index f5bf575..53bc547 100644
--- a/src/http/modules/ngx_http_grpc_module.c
+++ b/src/http/modules/ngx_http_grpc_module.c
@@ -2074,17 +2074,6 @@
                     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 @@
             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 @@
         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) {
diff --git a/src/http/modules/ngx_http_limit_req_module.c b/src/http/modules/ngx_http_limit_req_module.c
index dad5edb..2b062a3 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 @@
 
     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 cdfe6d7..e43255b 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -1190,8 +1190,13 @@
     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_request.c b/src/http/ngx_http_request.c
index 566c1c7..4fe51b7 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -2823,11 +2823,6 @@
         ngx_del_timer(c->write);
     }
 
-    if (c->read->eof) {
-        ngx_http_close_request(r, 0);
-        return;
-    }
-
     ngx_http_finalize_connection(r);
 }
 
@@ -2926,6 +2921,11 @@
 
     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;
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index 1fa02e7..e2e6930 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -607,6 +607,17 @@
     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;
     }
@@ -3015,9 +3026,7 @@
                 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;
diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c
index ac3e869..9df6bcb 100644
--- a/src/http/v2/ngx_http_v2.c
+++ b/src/http/v2/ngx_http_v2.c
@@ -1369,7 +1369,9 @@
     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) {
diff --git a/src/mail/ngx_mail_auth_http_module.c b/src/mail/ngx_mail_auth_http_module.c
index 06ded47..2a198f4 100644
--- a/src/mail/ngx_mail_auth_http_module.c
+++ b/src/mail/ngx_mail_auth_http_module.c
@@ -1135,10 +1135,10 @@
     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 @@
         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) {
diff --git a/src/mail/ngx_mail_handler.c b/src/mail/ngx_mail_handler.c
index b901053..0aaa0e7 100644
--- a/src/mail/ngx_mail_handler.c
+++ b/src/mail/ngx_mail_handler.c
@@ -272,16 +272,17 @@
 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) {
diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c
index f87e009..b31485f 100644
--- a/src/os/unix/ngx_process_cycle.c
+++ b/src/os/unix/ngx_process_cycle.c
@@ -15,7 +15,7 @@
     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 @@
 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 @@
 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_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,19 +388,20 @@
                       &ngx_cache_loader_ctx, "cache loader process",
                       respawn ? NGX_PROCESS_JUST_SPAWN : NGX_PROCESS_NORESPAWN);
 
-    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);
 }
 
 
 static void
-ngx_pass_open_channel(ngx_cycle_t *cycle, ngx_channel_t *ch)
+ngx_pass_open_channel(ngx_cycle_t *cycle)
 {
-    ngx_int_t  i;
+    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];
 
     for (i = 0; i < ngx_last_process; i++) {
 
@@ -430,14 +414,14 @@
 
         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 @@
                 }
 
 
-                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;