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); }