Merge branch 'nginx' (nginx-1.15.4).
Change-Id: I70e09ea945468bfc6aab18f4331369d377ff03c7
Signed-off-by: Piotr Sikora <piotrsikora@google.com>
diff --git a/.hgtags b/.hgtags
index a4f1a21..6b97c0f 100644
--- a/.hgtags
+++ b/.hgtags
@@ -429,3 +429,4 @@
4189160cb946bb38d0bc0a452b5eb4cdd8979fb5 release-1.15.1
b234199c7ed8a156a6bb98f7ff58302c857c954f release-1.15.2
28b3e17ca7eba1e6a0891afde0e4bc5bcc99c861 release-1.15.3
+49d49835653857daa418e68d6cbfed4958c78fca release-1.15.4
diff --git a/BUILD b/BUILD
index 9253e79..8026b48 100644
--- a/BUILD
+++ b/BUILD
@@ -1535,5 +1535,5 @@
preinst = "@nginx_pkgoss//:debian_preinst",
prerm = "@nginx_pkgoss//:debian_prerm",
section = "httpd",
- version = "1.15.3",
+ version = "1.15.4",
)
diff --git a/build.bzl b/build.bzl
index 79f36a8..4906869 100644
--- a/build.bzl
+++ b/build.bzl
@@ -663,7 +663,7 @@
name = "nginx_pkgoss",
build_file_content = _PKGOSS_BUILD_FILE.format(nginx = nginx) +
_PKGOSS_BUILD_FILE_TAIL,
- commit = "7f82ec785633480de508d4e61f47f4b62e93760c", # nginx-1.15.3
+ commit = "6dad8e159e768fd3b0940fe089cc09c6ac135f19", # nginx-1.15.4
remote = "https://nginx.googlesource.com/nginx-pkgoss",
)
diff --git a/docs/xml/nginx/changes.xml b/docs/xml/nginx/changes.xml
index d1e37e8..02c4b3c 100644
--- a/docs/xml/nginx/changes.xml
+++ b/docs/xml/nginx/changes.xml
@@ -5,6 +5,96 @@
<change_log title="nginx">
+<changes ver="1.15.4" date="2018-09-25">
+
+<change type="feature">
+<para lang="ru">
+теперь директиву ssl_early_data можно использовать с OpenSSL.
+</para>
+<para lang="en">
+now the "ssl_early_data" directive can be used with OpenSSL.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+в модуле ngx_http_uwsgi_module.<br/>
+Спасибо Chris Caputo.
+</para>
+<para lang="en">
+in the ngx_http_uwsgi_module.<br/>
+Thanks to Chris Caputo.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+соединения к некоторым gRPC-бэкендам могли не кэшироваться
+при использовании директивы keepalive.
+</para>
+<para lang="en">
+connections with some gRPC backends might not be cached
+when using the "keepalive" directive.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+при использовании директивы error_page для перенаправления ошибок,
+возникающих на ранних этапах обработки запроса,
+в частности ошибок с кодом 400,
+могла происходить утечка сокетов.
+</para>
+<para lang="en">
+a socket leak might occur
+when using the "error_page" directive
+to redirect early request processing errors,
+notably errors with code 400.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+директива return при возврате ошибок не изменяла код ответа,
+если запрос был перенаправлен с помощью директивы error_page.
+</para>
+<para lang="en">
+the "return" directive did not change the response code when returning errors
+if the request was redirected by the "error_page" directive.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+стандартные сообщения об ошибках и ответы модуля ngx_http_autoindex_module
+содержали атрибут bgcolor, что могло приводить к их некорректному отображению
+при использовании пользовательских настроек цветов в браузерах.<br/>
+Спасибо Nova DasSarma.
+</para>
+<para lang="en">
+standard error pages and responses of the ngx_http_autoindex_module module
+used the "bgcolor" attribute, and might be displayed incorrectly when using
+custom color settings in browsers.<br/>
+Thanks to Nova DasSarma.
+</para>
+</change>
+
+<change type="change">
+<para lang="ru">
+уровень логгирования ошибок SSL "no suitable key share" и
+"no suitable signature algorithm"
+понижен с уровня crit до info.
+</para>
+<para lang="en">
+the logging level of the "no suitable key share" and
+"no suitable signature algorithm" SSL errors
+has been lowered from "crit" to "info".
+</para>
+</change>
+
+</changes>
+
+
<changes ver="1.15.3" date="2018-08-28">
<change type="feature">
diff --git a/src/core/nginx.h b/src/core/nginx.h
index dadcda6..3294ab5 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -13,8 +13,8 @@
#define NGINX_NAME "nginx"
#endif
-#define nginx_version 1015003
-#define NGINX_VERSION "1.15.3"
+#define nginx_version 1015004
+#define NGINX_VERSION "1.15.4"
#define NGINX_VER NGINX_NAME "/" NGINX_VERSION
#ifdef NGX_BUILD
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index 9525c36..6b63601 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -26,9 +26,23 @@
static void ngx_ssl_passwords_cleanup(void *data);
static int ngx_ssl_new_client_session(ngx_ssl_conn_t *ssl_conn,
ngx_ssl_session_t *sess);
+#ifdef SSL_READ_EARLY_DATA_SUCCESS
+static ngx_int_t ngx_ssl_try_early_data(ngx_connection_t *c);
+#endif
+#if (NGX_DEBUG)
+static void ngx_ssl_handshake_log(ngx_connection_t *c);
+#endif
static void ngx_ssl_handshake_handler(ngx_event_t *ev);
+#ifdef SSL_READ_EARLY_DATA_SUCCESS
+static ssize_t ngx_ssl_recv_early(ngx_connection_t *c, u_char *buf,
+ size_t size);
+#endif
static ngx_int_t ngx_ssl_handle_recv(ngx_connection_t *c, int n);
static void ngx_ssl_write_handler(ngx_event_t *wev);
+#ifdef SSL_READ_EARLY_DATA_SUCCESS
+static ssize_t ngx_ssl_write_early(ngx_connection_t *c, u_char *data,
+ size_t size);
+#endif
static void ngx_ssl_read_handler(ngx_event_t *rev);
static void ngx_ssl_shutdown_handler(ngx_event_t *ev);
static void ngx_ssl_connection_error(ngx_connection_t *c, int sslerr,
@@ -340,6 +354,10 @@
SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_COMPRESSION);
#endif
+#ifdef SSL_OP_NO_ANTI_REPLAY
+ SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_ANTI_REPLAY);
+#endif
+
#ifdef SSL_MODE_RELEASE_BUFFERS
SSL_CTX_set_mode(ssl->ctx, SSL_MODE_RELEASE_BUFFERS);
#endif
@@ -866,6 +884,8 @@
BIO *rbio, *wbio;
ngx_connection_t *c;
+#ifndef SSL_OP_NO_RENEGOTIATION
+
if ((where & SSL_CB_HANDSHAKE_START)
&& SSL_is_server((ngx_ssl_conn_t *) ssl_conn))
{
@@ -877,6 +897,8 @@
}
}
+#endif
+
if ((where & SSL_CB_ACCEPT_LOOP) == SSL_CB_ACCEPT_LOOP) {
c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn);
@@ -1204,6 +1226,12 @@
SSL_CTX_set_early_data_enabled(ssl->ctx, 1);
+#elif defined SSL_READ_EARLY_DATA_SUCCESS
+
+ /* OpenSSL */
+
+ SSL_CTX_set_max_early_data(ssl->ctx, NGX_SSL_BUFSIZE);
+
#else
ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
"\"ssl_early_data\" is not supported on this platform, "
@@ -1265,6 +1293,12 @@
sc->session_ctx = ssl->ctx;
+#ifdef SSL_READ_EARLY_DATA_SUCCESS
+ if (SSL_CTX_get_max_early_data(ssl->ctx)) {
+ sc->try_early_data = 1;
+ }
+#endif
+
sc->connection = SSL_new(ssl->ctx);
if (sc->connection == NULL) {
@@ -1344,6 +1378,12 @@
int n, sslerr;
ngx_err_t err;
+#ifdef SSL_READ_EARLY_DATA_SUCCESS
+ if (c->ssl->try_early_data) {
+ return ngx_ssl_try_early_data(c);
+ }
+#endif
+
ngx_ssl_clear_error(c->log);
n = SSL_do_handshake(c->ssl->connection);
@@ -1361,50 +1401,7 @@
}
#if (NGX_DEBUG)
- {
- char buf[129], *s, *d;
-#if OPENSSL_VERSION_NUMBER >= 0x10000000L
- const
-#endif
- SSL_CIPHER *cipher;
-
- cipher = SSL_get_current_cipher(c->ssl->connection);
-
- if (cipher) {
- SSL_CIPHER_description(cipher, &buf[1], 128);
-
- for (s = &buf[1], d = buf; *s; s++) {
- if (*s == ' ' && *d == ' ') {
- continue;
- }
-
- if (*s == LF || *s == CR) {
- continue;
- }
-
- *++d = *s;
- }
-
- if (*d != ' ') {
- d++;
- }
-
- *d = '\0';
-
- ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "SSL: %s, cipher: \"%s\"",
- SSL_get_version(c->ssl->connection), &buf[1]);
-
- if (SSL_session_reused(c->ssl->connection)) {
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "SSL reused session");
- }
-
- } else {
- ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
- "SSL no shared ciphers");
- }
- }
+ ngx_ssl_handshake_log(c);
#endif
c->ssl->handshaked = 1;
@@ -1414,6 +1411,7 @@
c->recv_chain = ngx_ssl_recv_chain;
c->send_chain = ngx_ssl_send_chain;
+#ifndef SSL_OP_NO_RENEGOTIATION
#if OPENSSL_VERSION_NUMBER < 0x10100000L
#ifdef SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS
@@ -1424,6 +1422,7 @@
#endif
#endif
+#endif
return NGX_OK;
}
@@ -1485,6 +1484,173 @@
}
+#ifdef SSL_READ_EARLY_DATA_SUCCESS
+
+static ngx_int_t
+ngx_ssl_try_early_data(ngx_connection_t *c)
+{
+ int n, sslerr;
+ u_char buf;
+ size_t readbytes;
+ ngx_err_t err;
+
+ ngx_ssl_clear_error(c->log);
+
+ readbytes = 0;
+
+ n = SSL_read_early_data(c->ssl->connection, &buf, 1, &readbytes);
+
+ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "SSL_read_early_data: %d, %uz", n, readbytes);
+
+ if (n == SSL_READ_EARLY_DATA_FINISH) {
+ c->ssl->try_early_data = 0;
+ return ngx_ssl_handshake(c);
+ }
+
+ if (n == SSL_READ_EARLY_DATA_SUCCESS) {
+
+ if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+#if (NGX_DEBUG)
+ ngx_ssl_handshake_log(c);
+#endif
+
+ c->ssl->try_early_data = 0;
+
+ c->ssl->early_buf = buf;
+ c->ssl->early_preread = 1;
+
+ c->ssl->handshaked = 1;
+ c->ssl->in_early = 1;
+
+ c->recv = ngx_ssl_recv;
+ c->send = ngx_ssl_write;
+ c->recv_chain = ngx_ssl_recv_chain;
+ c->send_chain = ngx_ssl_send_chain;
+
+ return NGX_OK;
+ }
+
+ /* SSL_READ_EARLY_DATA_ERROR */
+
+ sslerr = SSL_get_error(c->ssl->connection, n);
+
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr);
+
+ if (sslerr == SSL_ERROR_WANT_READ) {
+ c->read->ready = 0;
+ c->read->handler = ngx_ssl_handshake_handler;
+ c->write->handler = ngx_ssl_handshake_handler;
+
+ if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ return NGX_AGAIN;
+ }
+
+ if (sslerr == SSL_ERROR_WANT_WRITE) {
+ c->write->ready = 0;
+ c->read->handler = ngx_ssl_handshake_handler;
+ c->write->handler = ngx_ssl_handshake_handler;
+
+ if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ return NGX_AGAIN;
+ }
+
+ err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
+
+ c->ssl->no_wait_shutdown = 1;
+ c->ssl->no_send_shutdown = 1;
+ c->read->eof = 1;
+
+ if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) {
+ ngx_connection_error(c, err,
+ "peer closed connection in SSL handshake");
+
+ return NGX_ERROR;
+ }
+
+ c->read->error = 1;
+
+ ngx_ssl_connection_error(c, sslerr, err, "SSL_read_early_data() failed");
+
+ return NGX_ERROR;
+}
+
+#endif
+
+
+#if (NGX_DEBUG)
+
+static void
+ngx_ssl_handshake_log(ngx_connection_t *c)
+{
+ char buf[129], *s, *d;
+#if OPENSSL_VERSION_NUMBER >= 0x10000000L
+ const
+#endif
+ SSL_CIPHER *cipher;
+
+ cipher = SSL_get_current_cipher(c->ssl->connection);
+
+ if (cipher) {
+ SSL_CIPHER_description(cipher, &buf[1], 128);
+
+ for (s = &buf[1], d = buf; *s; s++) {
+ if (*s == ' ' && *d == ' ') {
+ continue;
+ }
+
+ if (*s == LF || *s == CR) {
+ continue;
+ }
+
+ *++d = *s;
+ }
+
+ if (*d != ' ') {
+ d++;
+ }
+
+ *d = '\0';
+
+ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "SSL: %s, cipher: \"%s\"",
+ SSL_get_version(c->ssl->connection), &buf[1]);
+
+ if (SSL_session_reused(c->ssl->connection)) {
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "SSL reused session");
+ }
+
+ } else {
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "SSL no shared ciphers");
+ }
+}
+
+#endif
+
+
static void
ngx_ssl_handshake_handler(ngx_event_t *ev)
{
@@ -1572,6 +1738,12 @@
{
int n, bytes;
+#ifdef SSL_READ_EARLY_DATA_SUCCESS
+ if (c->ssl->in_early) {
+ return ngx_ssl_recv_early(c, buf, size);
+ }
+#endif
+
if (c->ssl->last == NGX_ERROR) {
c->read->error = 1;
return NGX_ERROR;
@@ -1645,12 +1817,131 @@
}
+#ifdef SSL_READ_EARLY_DATA_SUCCESS
+
+static ssize_t
+ngx_ssl_recv_early(ngx_connection_t *c, u_char *buf, size_t size)
+{
+ int n, bytes;
+ size_t readbytes;
+
+ if (c->ssl->last == NGX_ERROR) {
+ c->read->error = 1;
+ return NGX_ERROR;
+ }
+
+ if (c->ssl->last == NGX_DONE) {
+ c->read->ready = 0;
+ c->read->eof = 1;
+ return 0;
+ }
+
+ bytes = 0;
+
+ ngx_ssl_clear_error(c->log);
+
+ if (c->ssl->early_preread) {
+
+ if (size == 0) {
+ c->read->ready = 0;
+ c->read->eof = 1;
+ return 0;
+ }
+
+ *buf = c->ssl->early_buf;
+
+ c->ssl->early_preread = 0;
+
+ bytes = 1;
+ size -= 1;
+ buf += 1;
+ }
+
+ /*
+ * SSL_read_early_data() may return data in parts, so try to read
+ * until SSL_read_early_data() would return no data
+ */
+
+ for ( ;; ) {
+
+ readbytes = 0;
+
+ n = SSL_read_early_data(c->ssl->connection, buf, size, &readbytes);
+
+ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "SSL_read_early_data: %d, %uz", n, readbytes);
+
+ if (n == SSL_READ_EARLY_DATA_SUCCESS) {
+
+ c->ssl->last = ngx_ssl_handle_recv(c, 1);
+
+ bytes += readbytes;
+ size -= readbytes;
+
+ if (size == 0) {
+ c->read->ready = 1;
+ return bytes;
+ }
+
+ buf += readbytes;
+
+ continue;
+ }
+
+ if (n == SSL_READ_EARLY_DATA_FINISH) {
+
+ c->ssl->last = ngx_ssl_handle_recv(c, 1);
+ c->ssl->in_early = 0;
+
+ if (bytes) {
+ c->read->ready = 1;
+ return bytes;
+ }
+
+ return ngx_ssl_recv(c, buf, size);
+ }
+
+ /* SSL_READ_EARLY_DATA_ERROR */
+
+ c->ssl->last = ngx_ssl_handle_recv(c, 0);
+
+ if (bytes) {
+ if (c->ssl->last != NGX_AGAIN) {
+ c->read->ready = 1;
+ }
+
+ return bytes;
+ }
+
+ switch (c->ssl->last) {
+
+ case NGX_DONE:
+ c->read->ready = 0;
+ c->read->eof = 1;
+ return 0;
+
+ case NGX_ERROR:
+ c->read->error = 1;
+
+ /* fall through */
+
+ case NGX_AGAIN:
+ return c->ssl->last;
+ }
+ }
+}
+
+#endif
+
+
static ngx_int_t
ngx_ssl_handle_recv(ngx_connection_t *c, int n)
{
int sslerr;
ngx_err_t err;
+#ifndef SSL_OP_NO_RENEGOTIATION
+
if (c->ssl->renegotiation) {
/*
* disable renegotiation (CVE-2009-3555):
@@ -1673,6 +1964,8 @@
return NGX_ERROR;
}
+#endif
+
if (n > 0) {
if (c->ssl->saved_write_handler) {
@@ -1698,14 +1991,28 @@
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr);
if (sslerr == SSL_ERROR_WANT_READ) {
+
+ if (c->ssl->saved_write_handler) {
+
+ c->write->handler = c->ssl->saved_write_handler;
+ c->ssl->saved_write_handler = NULL;
+ c->write->ready = 1;
+
+ if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ ngx_post_event(c->write, &ngx_posted_events);
+ }
+
c->read->ready = 0;
return NGX_AGAIN;
}
if (sslerr == SSL_ERROR_WANT_WRITE) {
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
- "peer started SSL renegotiation");
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "SSL_read: want write");
c->write->ready = 0;
@@ -1747,6 +2054,8 @@
c = wev->data;
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL write handler");
+
c->read->handler(c->read);
}
@@ -1920,6 +2229,12 @@
int n, sslerr;
ngx_err_t err;
+#ifdef SSL_READ_EARLY_DATA_SUCCESS
+ if (c->ssl->in_early) {
+ return ngx_ssl_write_early(c, data, size);
+ }
+#endif
+
ngx_ssl_clear_error(c->log);
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL to write: %uz", size);
@@ -1955,14 +2270,28 @@
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr);
if (sslerr == SSL_ERROR_WANT_WRITE) {
+
+ if (c->ssl->saved_read_handler) {
+
+ c->read->handler = c->ssl->saved_read_handler;
+ c->ssl->saved_read_handler = NULL;
+ c->read->ready = 1;
+
+ if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ ngx_post_event(c->read, &ngx_posted_events);
+ }
+
c->write->ready = 0;
return NGX_AGAIN;
}
if (sslerr == SSL_ERROR_WANT_READ) {
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
- "peer started SSL renegotiation");
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "SSL_write: want read");
c->read->ready = 0;
@@ -1993,6 +2322,107 @@
}
+#ifdef SSL_READ_EARLY_DATA_SUCCESS
+
+ssize_t
+ngx_ssl_write_early(ngx_connection_t *c, u_char *data, size_t size)
+{
+ int n, sslerr;
+ size_t written;
+ ngx_err_t err;
+
+ ngx_ssl_clear_error(c->log);
+
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL to write: %uz", size);
+
+ written = 0;
+
+ n = SSL_write_early_data(c->ssl->connection, data, size, &written);
+
+ ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "SSL_write_early_data: %d, %uz", n, written);
+
+ if (n > 0) {
+
+ if (c->ssl->saved_read_handler) {
+
+ c->read->handler = c->ssl->saved_read_handler;
+ c->ssl->saved_read_handler = NULL;
+ c->read->ready = 1;
+
+ if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ ngx_post_event(c->read, &ngx_posted_events);
+ }
+
+ c->sent += written;
+
+ return written;
+ }
+
+ sslerr = SSL_get_error(c->ssl->connection, n);
+
+ err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
+
+ ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_get_error: %d", sslerr);
+
+ if (sslerr == SSL_ERROR_WANT_WRITE) {
+
+ if (c->ssl->saved_read_handler) {
+
+ c->read->handler = c->ssl->saved_read_handler;
+ c->ssl->saved_read_handler = NULL;
+ c->read->ready = 1;
+
+ if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ ngx_post_event(c->read, &ngx_posted_events);
+ }
+
+ c->write->ready = 0;
+ return NGX_AGAIN;
+ }
+
+ if (sslerr == SSL_ERROR_WANT_READ) {
+
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
+ "SSL_write_early_data: want read");
+
+ c->read->ready = 0;
+
+ if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ /*
+ * we do not set the timer because there is already
+ * the write event timer
+ */
+
+ if (c->ssl->saved_read_handler == NULL) {
+ c->ssl->saved_read_handler = c->read->handler;
+ c->read->handler = ngx_ssl_read_handler;
+ }
+
+ return NGX_AGAIN;
+ }
+
+ c->ssl->no_wait_shutdown = 1;
+ c->ssl->no_send_shutdown = 1;
+ c->write->error = 1;
+
+ ngx_ssl_connection_error(c, sslerr, err, "SSL_write_early_data() failed");
+
+ return NGX_ERROR;
+}
+
+#endif
+
+
static void
ngx_ssl_read_handler(ngx_event_t *rev)
{
@@ -2000,6 +2430,8 @@
c = rev->data;
+ ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL read handler");
+
c->write->handler(c->write);
}
@@ -2176,6 +2608,12 @@
/* handshake failures */
if (n == SSL_R_BAD_CHANGE_CIPHER_SPEC /* 103 */
+#ifdef SSL_R_NO_SUITABLE_KEY_SHARE
+ || n == SSL_R_NO_SUITABLE_KEY_SHARE /* 101 */
+#endif
+#ifdef SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM
+ || n == SSL_R_NO_SUITABLE_SIGNATURE_ALGORITHM /* 118 */
+#endif
|| n == SSL_R_BLOCK_CIPHER_PAD_IS_WRONG /* 129 */
|| n == SSL_R_DIGEST_CHECK_FAILED /* 149 */
|| n == SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST /* 151 */
@@ -2197,7 +2635,13 @@
|| n == SSL_R_UNEXPECTED_RECORD /* 245 */
|| n == SSL_R_UNKNOWN_ALERT_TYPE /* 246 */
|| n == SSL_R_UNKNOWN_PROTOCOL /* 252 */
+#ifdef SSL_R_NO_COMMON_SIGNATURE_ALGORITHMS
+ || n == SSL_R_NO_COMMON_SIGNATURE_ALGORITHMS /* 253 */
+#endif
|| n == SSL_R_UNSUPPORTED_PROTOCOL /* 258 */
+#ifdef SSL_R_NO_SHARED_GROUP
+ || n == SSL_R_NO_SHARED_GROUP /* 266 */
+#endif
|| n == SSL_R_WRONG_VERSION_NUMBER /* 267 */
|| n == SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC /* 281 */
#ifdef SSL_R_RENEGOTIATE_EXT_TOO_LONG
@@ -3678,9 +4122,21 @@
s->len = 0;
#ifdef SSL_ERROR_EARLY_DATA_REJECTED
+
+ /* BoringSSL */
+
if (SSL_in_early_data(c->ssl->connection)) {
ngx_str_set(s, "1");
}
+
+#elif defined SSL_READ_EARLY_DATA_SUCCESS
+
+ /* OpenSSL */
+
+ if (!SSL_is_init_finished(c->ssl->connection)) {
+ ngx_str_set(s, "1");
+ }
+
#endif
return NGX_OK;
diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h
index c9524ad..3d87c4d 100644
--- a/src/event/ngx_event_openssl.h
+++ b/src/event/ngx_event_openssl.h
@@ -87,12 +87,17 @@
ngx_event_handler_pt saved_read_handler;
ngx_event_handler_pt saved_write_handler;
+ u_char early_buf;
+
unsigned handshaked:1;
unsigned renegotiation:1;
unsigned buffer:1;
unsigned no_wait_shutdown:1;
unsigned no_send_shutdown:1;
unsigned handshake_buffer_set:1;
+ unsigned try_early_data:1;
+ unsigned in_early:1;
+ unsigned early_preread:1;
};
diff --git a/src/http/modules/ngx_http_autoindex_module.c b/src/http/modules/ngx_http_autoindex_module.c
index 94b91db..d59fba2 100644
--- a/src/http/modules/ngx_http_autoindex_module.c
+++ b/src/http/modules/ngx_http_autoindex_module.c
@@ -452,7 +452,7 @@
static u_char header[] =
"</title></head>" CRLF
- "<body bgcolor=\"white\">" CRLF
+ "<body>" CRLF
"<h1>Index of "
;
diff --git a/src/http/modules/ngx_http_grpc_module.c b/src/http/modules/ngx_http_grpc_module.c
index 7fbf736..17b0a26 100644
--- a/src/http/modules/ngx_http_grpc_module.c
+++ b/src/http/modules/ngx_http_grpc_module.c
@@ -109,8 +109,10 @@
unsigned header_sent:1;
unsigned output_closed:1;
+ unsigned output_blocked:1;
unsigned parsing_headers:1;
unsigned end_stream:1;
+ unsigned done:1;
unsigned status:1;
ngx_http_request_t *request;
@@ -1072,8 +1074,10 @@
ctx->state = 0;
ctx->header_sent = 0;
ctx->output_closed = 0;
+ ctx->output_blocked = 0;
ctx->parsing_headers = 0;
ctx->end_stream = 0;
+ ctx->done = 0;
ctx->status = 0;
ctx->connection = NULL;
@@ -1093,6 +1097,7 @@
ngx_int_t rc;
ngx_uint_t next, last;
ngx_chain_t *cl, *out, **ll;
+ ngx_http_upstream_t *u;
ngx_http_grpc_ctx_t *ctx;
ngx_http_grpc_frame_t *f;
@@ -1407,6 +1412,36 @@
rc = NGX_AGAIN;
}
+ if (rc == NGX_AGAIN) {
+ ctx->output_blocked = 1;
+
+ } else {
+ ctx->output_blocked = 0;
+ }
+
+ if (ctx->done) {
+
+ /*
+ * We have already got the response and were sending some additional
+ * control frames. Even if there is still something unsent, stop
+ * here anyway.
+ */
+
+ u = r->upstream;
+ u->length = 0;
+
+ if (ctx->in == NULL
+ && ctx->out == NULL
+ && ctx->output_closed
+ && !ctx->output_blocked
+ && ctx->state == ngx_http_grpc_st_start)
+ {
+ u->keepalive = 1;
+ }
+
+ ngx_post_event(u->peer.connection->read, &ngx_posted_events);
+ }
+
return rc;
}
@@ -1749,6 +1784,7 @@
if (ctx->in == NULL
&& ctx->out == NULL
&& ctx->output_closed
+ && !ctx->output_blocked
&& b->last == b->pos)
{
u->keepalive = 1;
@@ -1832,6 +1868,34 @@
rc = ngx_http_grpc_parse_frame(r, ctx, b);
if (rc == NGX_AGAIN) {
+
+ if (ctx->done) {
+
+ /*
+ * We have finished parsing the response and the
+ * remaining control frames. If there are unsent
+ * control frames, post a write event to send them.
+ */
+
+ if (ctx->out) {
+ ngx_post_event(u->peer.connection->write,
+ &ngx_posted_events);
+ return NGX_AGAIN;
+ }
+
+ u->length = 0;
+
+ if (ctx->in == NULL
+ && ctx->output_closed
+ && !ctx->output_blocked
+ && ctx->state == ngx_http_grpc_st_start)
+ {
+ u->keepalive = 1;
+ }
+
+ break;
+ }
+
return NGX_AGAIN;
}
@@ -1898,6 +1962,13 @@
return NGX_ERROR;
}
+ if (ctx->stream_id && ctx->done) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "upstream sent frame for closed stream %ui",
+ ctx->stream_id);
+ return NGX_ERROR;
+ }
+
ctx->padding = 0;
}
@@ -1914,17 +1985,7 @@
ctx->state = ngx_http_grpc_st_start;
if (ctx->flags & NGX_HTTP_V2_END_STREAM_FLAG) {
- u->length = 0;
-
- if (ctx->in == NULL
- && ctx->out == NULL
- && ctx->output_closed
- && b->last == b->pos)
- {
- u->keepalive = 1;
- }
-
- break;
+ ctx->done = 1;
}
continue;
@@ -2094,17 +2155,8 @@
"grpc trailer done");
if (ctx->end_stream) {
- u->length = 0;
-
- if (ctx->in == NULL
- && ctx->out == NULL
- && ctx->output_closed
- && b->last == b->pos)
- {
- u->keepalive = 1;
- }
-
- return NGX_OK;
+ ctx->done = 1;
+ break;
}
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
@@ -2121,6 +2173,10 @@
return NGX_ERROR;
}
+ if (rc == NGX_HTTP_PARSE_HEADER_DONE) {
+ continue;
+ }
+
/* rc == NGX_AGAIN */
if (ctx->rest == 0) {
@@ -2237,17 +2293,7 @@
ctx->state = ngx_http_grpc_st_start;
if (ctx->flags & NGX_HTTP_V2_END_STREAM_FLAG) {
- u->length = 0;
-
- if (ctx->in == NULL
- && ctx->out == NULL
- && ctx->output_closed
- && b->last == b->pos)
- {
- u->keepalive = 1;
- }
-
- break;
+ ctx->done = 1;
}
}
diff --git a/src/http/modules/ngx_http_rewrite_module.c b/src/http/modules/ngx_http_rewrite_module.c
index a6f1fc8..3b49c45 100644
--- a/src/http/modules/ngx_http_rewrite_module.c
+++ b/src/http/modules/ngx_http_rewrite_module.c
@@ -180,15 +180,7 @@
code(e);
}
- if (e->status < NGX_HTTP_BAD_REQUEST) {
- return e->status;
- }
-
- if (r->err_status == 0) {
- return e->status;
- }
-
- return r->err_status;
+ return e->status;
}
diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c
index 0959133..d0adbdb 100644
--- a/src/http/modules/ngx_http_uwsgi_module.c
+++ b/src/http/modules/ngx_http_uwsgi_module.c
@@ -954,12 +954,18 @@
#if 0
/* allow custom uwsgi packet */
if (len > 0 && len < 2) {
- ngx_log_error (NGX_LOG_ALERT, r->connection->log, 0,
- "uwsgi request is too little: %uz", len);
+ ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+ "uwsgi request is too little: %uz", len);
return NGX_ERROR;
}
#endif
+ if (len > 65535) {
+ ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+ "uwsgi request is too big: %uz", len);
+ return NGX_ERROR;
+ }
+
b = ngx_create_temp_buf(r->pool, len + 4);
if (b == NULL) {
return NGX_ERROR;
diff --git a/src/http/ngx_http_file_cache.c b/src/http/ngx_http_file_cache.c
index 56866fa..330833d 100644
--- a/src/http/ngx_http_file_cache.c
+++ b/src/http/ngx_http_file_cache.c
@@ -2669,7 +2669,7 @@
} else {
status = ngx_atoi(value[i].data, value[i].len);
- if (status < 100) {
+ if (status < 100 || status > 599) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid status \"%V\"", &value[i]);
return NGX_CONF_ERROR;
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index 02a5075..d7da788 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -1114,7 +1114,7 @@
n = ngx_http_read_request_header(r);
if (n == NGX_AGAIN || n == NGX_ERROR) {
- return;
+ break;
}
}
@@ -1139,7 +1139,7 @@
}
if (ngx_http_process_request_uri(r) != NGX_OK) {
- return;
+ break;
}
if (r->schema_end) {
@@ -1158,16 +1158,16 @@
ngx_log_error(NGX_LOG_INFO, c->log, 0,
"client sent invalid host in request line");
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
- return;
+ break;
}
if (rc == NGX_ERROR) {
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
+ break;
}
if (ngx_http_set_virtual_server(r, &host) == NGX_ERROR) {
- return;
+ break;
}
r->headers_in.server = host;
@@ -1179,11 +1179,11 @@
&& ngx_http_set_virtual_server(r, &r->headers_in.server)
== NGX_ERROR)
{
- return;
+ break;
}
ngx_http_process_request(r);
- return;
+ break;
}
@@ -1192,7 +1192,7 @@
!= NGX_OK)
{
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
+ break;
}
c->log->action = "reading client request headers";
@@ -1200,7 +1200,7 @@
rev->handler = ngx_http_process_request_headers;
ngx_http_process_request_headers(rev);
- return;
+ break;
}
if (rc != NGX_AGAIN) {
@@ -1217,7 +1217,7 @@
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
}
- return;
+ break;
}
/* NGX_AGAIN: a request line parsing is still incomplete */
@@ -1228,7 +1228,7 @@
if (rv == NGX_ERROR) {
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
+ break;
}
if (rv == NGX_DECLINED) {
@@ -1238,10 +1238,12 @@
ngx_log_error(NGX_LOG_INFO, c->log, 0,
"client sent too long URI");
ngx_http_finalize_request(r, NGX_HTTP_REQUEST_URI_TOO_LARGE);
- return;
+ break;
}
}
}
+
+ ngx_http_run_posted_requests(c);
}
@@ -1403,7 +1405,7 @@
if (rv == NGX_ERROR) {
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
+ break;
}
if (rv == NGX_DECLINED) {
@@ -1416,7 +1418,7 @@
"client sent too large request");
ngx_http_finalize_request(r,
NGX_HTTP_REQUEST_HEADER_TOO_LARGE);
- return;
+ break;
}
len = r->header_in->end - p;
@@ -1431,14 +1433,14 @@
ngx_http_finalize_request(r,
NGX_HTTP_REQUEST_HEADER_TOO_LARGE);
- return;
+ break;
}
}
n = ngx_http_read_request_header(r);
if (n == NGX_AGAIN || n == NGX_ERROR) {
- return;
+ break;
}
}
@@ -1468,7 +1470,7 @@
h = ngx_list_push(&r->headers_in.headers);
if (h == NULL) {
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
+ break;
}
h->hash = r->header_hash;
@@ -1484,7 +1486,7 @@
h->lowcase_key = ngx_pnalloc(r->pool, h->key.len);
if (h->lowcase_key == NULL) {
ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
- return;
+ break;
}
if (h->key.len == r->lowcase_index) {
@@ -1498,7 +1500,7 @@
h->lowcase_key, h->key.len);
if (hh && hh->handler(r, h, hh->offset) != NGX_OK) {
- return;
+ break;
}
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@@ -1522,12 +1524,12 @@
rc = ngx_http_process_request_header(r);
if (rc != NGX_OK) {
- return;
+ break;
}
ngx_http_process_request(r);
- return;
+ break;
}
if (rc == NGX_AGAIN) {
@@ -1543,8 +1545,10 @@
"client sent invalid header line");
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
- return;
+ break;
}
+
+ ngx_http_run_posted_requests(c);
}
@@ -2115,8 +2119,6 @@
r->read_event_handler = ngx_http_block_reading;
ngx_http_handler(r);
-
- ngx_http_run_posted_requests(c);
}
@@ -3482,6 +3484,10 @@
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "lingering read: %z", n);
+ if (n == NGX_AGAIN) {
+ break;
+ }
+
if (n == NGX_ERROR || n == 0) {
ngx_http_close_request(r, 0);
return;
diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c
index a19318b..17511c2 100644
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -60,7 +60,7 @@
static char ngx_http_error_301_page[] =
"<html>" CRLF
"<head><title>301 Moved Permanently</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>301 Moved Permanently</h1></center>" CRLF
;
@@ -68,7 +68,7 @@
static char ngx_http_error_302_page[] =
"<html>" CRLF
"<head><title>302 Found</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>302 Found</h1></center>" CRLF
;
@@ -76,7 +76,7 @@
static char ngx_http_error_303_page[] =
"<html>" CRLF
"<head><title>303 See Other</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>303 See Other</h1></center>" CRLF
;
@@ -84,7 +84,7 @@
static char ngx_http_error_307_page[] =
"<html>" CRLF
"<head><title>307 Temporary Redirect</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>307 Temporary Redirect</h1></center>" CRLF
;
@@ -92,7 +92,7 @@
static char ngx_http_error_308_page[] =
"<html>" CRLF
"<head><title>308 Permanent Redirect</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>308 Permanent Redirect</h1></center>" CRLF
;
@@ -100,7 +100,7 @@
static char ngx_http_error_400_page[] =
"<html>" CRLF
"<head><title>400 Bad Request</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>400 Bad Request</h1></center>" CRLF
;
@@ -108,7 +108,7 @@
static char ngx_http_error_401_page[] =
"<html>" CRLF
"<head><title>401 Authorization Required</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>401 Authorization Required</h1></center>" CRLF
;
@@ -116,7 +116,7 @@
static char ngx_http_error_402_page[] =
"<html>" CRLF
"<head><title>402 Payment Required</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>402 Payment Required</h1></center>" CRLF
;
@@ -124,7 +124,7 @@
static char ngx_http_error_403_page[] =
"<html>" CRLF
"<head><title>403 Forbidden</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>403 Forbidden</h1></center>" CRLF
;
@@ -132,7 +132,7 @@
static char ngx_http_error_404_page[] =
"<html>" CRLF
"<head><title>404 Not Found</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>404 Not Found</h1></center>" CRLF
;
@@ -140,7 +140,7 @@
static char ngx_http_error_405_page[] =
"<html>" CRLF
"<head><title>405 Not Allowed</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>405 Not Allowed</h1></center>" CRLF
;
@@ -148,7 +148,7 @@
static char ngx_http_error_406_page[] =
"<html>" CRLF
"<head><title>406 Not Acceptable</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>406 Not Acceptable</h1></center>" CRLF
;
@@ -156,7 +156,7 @@
static char ngx_http_error_408_page[] =
"<html>" CRLF
"<head><title>408 Request Time-out</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>408 Request Time-out</h1></center>" CRLF
;
@@ -164,7 +164,7 @@
static char ngx_http_error_409_page[] =
"<html>" CRLF
"<head><title>409 Conflict</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>409 Conflict</h1></center>" CRLF
;
@@ -172,7 +172,7 @@
static char ngx_http_error_410_page[] =
"<html>" CRLF
"<head><title>410 Gone</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>410 Gone</h1></center>" CRLF
;
@@ -180,7 +180,7 @@
static char ngx_http_error_411_page[] =
"<html>" CRLF
"<head><title>411 Length Required</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>411 Length Required</h1></center>" CRLF
;
@@ -188,7 +188,7 @@
static char ngx_http_error_412_page[] =
"<html>" CRLF
"<head><title>412 Precondition Failed</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>412 Precondition Failed</h1></center>" CRLF
;
@@ -196,7 +196,7 @@
static char ngx_http_error_413_page[] =
"<html>" CRLF
"<head><title>413 Request Entity Too Large</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>413 Request Entity Too Large</h1></center>" CRLF
;
@@ -204,7 +204,7 @@
static char ngx_http_error_414_page[] =
"<html>" CRLF
"<head><title>414 Request-URI Too Large</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>414 Request-URI Too Large</h1></center>" CRLF
;
@@ -212,7 +212,7 @@
static char ngx_http_error_415_page[] =
"<html>" CRLF
"<head><title>415 Unsupported Media Type</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>415 Unsupported Media Type</h1></center>" CRLF
;
@@ -220,7 +220,7 @@
static char ngx_http_error_416_page[] =
"<html>" CRLF
"<head><title>416 Requested Range Not Satisfiable</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>416 Requested Range Not Satisfiable</h1></center>" CRLF
;
@@ -228,7 +228,7 @@
static char ngx_http_error_421_page[] =
"<html>" CRLF
"<head><title>421 Misdirected Request</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>421 Misdirected Request</h1></center>" CRLF
;
@@ -236,7 +236,7 @@
static char ngx_http_error_429_page[] =
"<html>" CRLF
"<head><title>429 Too Many Requests</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>429 Too Many Requests</h1></center>" CRLF
;
@@ -245,7 +245,7 @@
"<html>" CRLF
"<head><title>400 Request Header Or Cookie Too Large</title></head>"
CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>400 Bad Request</h1></center>" CRLF
"<center>Request Header Or Cookie Too Large</center>" CRLF
;
@@ -255,7 +255,7 @@
"<html>" CRLF
"<head><title>400 The SSL certificate error</title></head>"
CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>400 Bad Request</h1></center>" CRLF
"<center>The SSL certificate error</center>" CRLF
;
@@ -265,7 +265,7 @@
"<html>" CRLF
"<head><title>400 No required SSL certificate was sent</title></head>"
CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>400 Bad Request</h1></center>" CRLF
"<center>No required SSL certificate was sent</center>" CRLF
;
@@ -275,7 +275,7 @@
"<html>" CRLF
"<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>"
CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>400 Bad Request</h1></center>" CRLF
"<center>The plain HTTP request was sent to HTTPS port</center>" CRLF
;
@@ -284,7 +284,7 @@
static char ngx_http_error_500_page[] =
"<html>" CRLF
"<head><title>500 Internal Server Error</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>500 Internal Server Error</h1></center>" CRLF
;
@@ -292,7 +292,7 @@
static char ngx_http_error_501_page[] =
"<html>" CRLF
"<head><title>501 Not Implemented</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>501 Not Implemented</h1></center>" CRLF
;
@@ -300,7 +300,7 @@
static char ngx_http_error_502_page[] =
"<html>" CRLF
"<head><title>502 Bad Gateway</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>502 Bad Gateway</h1></center>" CRLF
;
@@ -308,7 +308,7 @@
static char ngx_http_error_503_page[] =
"<html>" CRLF
"<head><title>503 Service Temporarily Unavailable</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>503 Service Temporarily Unavailable</h1></center>" CRLF
;
@@ -316,7 +316,7 @@
static char ngx_http_error_504_page[] =
"<html>" CRLF
"<head><title>504 Gateway Time-out</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>504 Gateway Time-out</h1></center>" CRLF
;
@@ -324,7 +324,7 @@
static char ngx_http_error_505_page[] =
"<html>" CRLF
"<head><title>505 HTTP Version Not Supported</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>505 HTTP Version Not Supported</h1></center>" CRLF
;
@@ -332,7 +332,7 @@
static char ngx_http_error_507_page[] =
"<html>" CRLF
"<head><title>507 Insufficient Storage</title></head>" CRLF
-"<body bgcolor=\"white\">" CRLF
+"<body>" CRLF
"<center><h1>507 Insufficient Storage</h1></center>" CRLF
;
diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c
index 7b0b6e1..80520ee 100644
--- a/src/http/v2/ngx_http_v2.c
+++ b/src/http/v2/ngx_http_v2.c
@@ -2703,11 +2703,13 @@
if (rc == NGX_ABORT) {
/* header handler has already finalized request */
+ ngx_http_run_posted_requests(fc);
return NULL;
}
if (rc == NGX_DECLINED) {
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
+ ngx_http_run_posted_requests(fc);
return NULL;
}
@@ -3785,18 +3787,22 @@
static void
ngx_http_v2_run_request(ngx_http_request_t *r)
{
+ ngx_connection_t *fc;
+
+ fc = r->connection;
+
if (ngx_http_v2_construct_request_line(r) != NGX_OK) {
- return;
+ goto failed;
}
if (ngx_http_v2_construct_cookie_header(r) != NGX_OK) {
- return;
+ goto failed;
}
r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE;
if (ngx_http_process_request_header(r) != NGX_OK) {
- return;
+ goto failed;
}
if (r->headers_in.content_length_n > 0 && r->stream->in_closed) {
@@ -3806,7 +3812,7 @@
r->stream->skip_data = 1;
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
- return;
+ goto failed;
}
if (r->headers_in.content_length_n == -1 && !r->stream->in_closed) {
@@ -3814,6 +3820,10 @@
}
ngx_http_process_request(r);
+
+failed:
+
+ ngx_http_run_posted_requests(fc);
}
diff --git a/src/stream/ngx_stream_core_module.c b/src/stream/ngx_stream_core_module.c
index 96e7c9a..3c4027b 100644
--- a/src/stream/ngx_stream_core_module.c
+++ b/src/stream/ngx_stream_core_module.c
@@ -249,34 +249,40 @@
}
if (!c->read->ready) {
- if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
- rc = NGX_ERROR;
- break;
- }
-
- if (!c->read->timer_set) {
- ngx_add_timer(c->read, cscf->preread_timeout);
- }
-
- c->read->handler = ngx_stream_session_handler;
-
- return NGX_OK;
+ break;
}
n = c->recv(c, c->buffer->last, size);
- if (n == NGX_ERROR) {
+ if (n == NGX_ERROR || n == 0) {
rc = NGX_STREAM_OK;
break;
}
- if (n > 0) {
- c->buffer->last += n;
+ if (n == NGX_AGAIN) {
+ break;
}
+ c->buffer->last += n;
+
rc = ph->handler(s);
}
+ if (rc == NGX_AGAIN) {
+ if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
+ ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
+ return NGX_OK;
+ }
+
+ if (!c->read->timer_set) {
+ ngx_add_timer(c->read, cscf->preread_timeout);
+ }
+
+ c->read->handler = ngx_stream_session_handler;
+
+ return NGX_OK;
+ }
+
if (c->read->timer_set) {
ngx_del_timer(c->read);
}