Compare commits

...

30 Commits

Author SHA1 Message Date
Maxim Dounin c04971f65c release-1.20.2 tag 2021-11-16 17:44:02 +03:00
Maxim Dounin 11a9f6c929 nginx-1.20.2-RELEASE 2021-11-16 17:44:02 +03:00
Maxim Dounin bede588761 Changed ngx_chain_update_chains() to test tag first (ticket #2248).
Without this change, aio used with HTTP/2 can result in connection hang,
as observed with "aio threads; aio_write on;" and proxying (ticket #2248).

The problem is that HTTP/2 updates buffers outside of the output filters
(notably, marks them as sent), and then posts a write event to call
output filters.  If a filter does not call the next one for some reason
(for example, because of an AIO operation in progress), this might
result in a state when the owner of a buffer already called
ngx_chain_update_chains() and can reuse the buffer, while the same buffer
is still sitting in the busy chain of some other filter.

In the particular case a buffer was sitting in output chain's ctx->busy,
and was reused by event pipe.  Output chain's ctx->busy was permanently
blocked by it, and this resulted in connection hang.

Fix is to change ngx_chain_update_chains() to skip buffers from other
modules unconditionally, without trying to wait for these buffers to
become empty.
2021-10-30 02:39:19 +03:00
Maxim Dounin 19a9a22ffc Fixed $content_length cacheability with chunked (ticket #2252). 2021-10-06 18:01:42 +03:00
Maxim Dounin 4bdba693ef Updated OpenSSL used for win32 builds. 2021-08-31 17:54:54 +03:00
Maxim Dounin 9c57f54d54 Upstream: fixed timeouts with gRPC, SSL and select (ticket #2229).
With SSL it is possible that an established connection is ready for
reading after the handshake.  Further, events might be already disabled
in case of level-triggered event methods.  If this happens and
ngx_http_upstream_send_request() blocks waiting for some data from
the upstream, such as flow control in case of gRPC, the connection
will time out due to no read events on the upstream connection.

Fix is to explicitly check the c->read->ready flag if sending request
blocks and post a read event if it is set.

Note that while it is possible to modify ngx_ssl_handshake() to keep
read events active, this won't completely resolve the issue, since
there can be data already received during the SSL handshake
(see 573bd30e46b4).
2021-08-20 03:53:56 +03:00
Sergey Kandaurov aa59acf058 SSL: use of the SSL_OP_IGNORE_UNEXPECTED_EOF option.
A new behaviour was introduced in OpenSSL 1.1.1e, when a peer does not send
close_notify before closing the connection.  Previously, it was to return
SSL_ERROR_SYSCALL with errno 0, known since at least OpenSSL 0.9.7, and is
handled gracefully in nginx.  Now it returns SSL_ERROR_SSL with a distinct
reason SSL_R_UNEXPECTED_EOF_WHILE_READING ("unexpected eof while reading").
This leads to critical errors seen in nginx within various routines such as
SSL_do_handshake(), SSL_read(), SSL_shutdown().  The behaviour was restored
in OpenSSL 1.1.1f, but presents in OpenSSL 3.0 by default.

Use of the SSL_OP_IGNORE_UNEXPECTED_EOF option added in OpenSSL 3.0 allows
to set a compatible behaviour to return SSL_ERROR_ZERO_RETURN:
https://git.openssl.org/?p=openssl.git;a=commitdiff;h=09b90e0

See for additional details: https://github.com/openssl/openssl/issues/11381
2021-08-10 23:43:17 +03:00
Sergey Kandaurov 2b5c9bf17e SSL: silenced warnings when building with OpenSSL 3.0.
The OPENSSL_SUPPRESS_DEPRECATED macro is used to suppress deprecation warnings.
This covers Session Tickets keys, SSL Engine, DH low level API for DHE ciphers.

Unlike OPENSSL_API_COMPAT, it works well with OpenSSL built with no-deprecated.
In particular, it doesn't unhide various macros in OpenSSL includes, which are
meant to be hidden under OPENSSL_NO_DEPRECATED.
2021-08-10 23:43:16 +03:00
Sergey Kandaurov c44c7169b0 SSL: ERR_peek_error_line_data() compatibility with OpenSSL 3.0.
ERR_peek_error_line_data() was deprecated in favour of ERR_peek_error_all().
Here we use the ERR_peek_error_data() helper to pass only used arguments.
2021-08-10 23:43:16 +03:00
Sergey Kandaurov b150852b65 SSL: using SSL_CTX_set0_tmp_dh_pkey() with OpenSSL 3.0 in dhparam.
Using PEM_read_bio_DHparams() and SSL_CTX_set_tmp_dh() is deprecated
as part of deprecating the low level DH functions in favor of EVP_PKEY:
https://git.openssl.org/?p=openssl.git;a=commitdiff;h=163f6dc
2021-08-10 23:43:16 +03:00
Sergey Kandaurov 092dbcea1a SSL: SSL_get_peer_certificate() is deprecated in OpenSSL 3.0.
Switch to SSL_get1_peer_certificate() when building with OpenSSL 3.0
and OPENSSL_NO_DEPRECATED defined.
2021-08-10 23:43:16 +03:00
Sergey Kandaurov 6ae41a4c76 SSL: RSA data type is deprecated in OpenSSL 3.0.
The only consumer is a callback function for SSL_CTX_set_tmp_rsa_callback()
deprecated in OpenSSL 1.1.0.  Now the function is conditionally compiled too.
2021-08-10 23:42:59 +03:00
Sergey Kandaurov ebadd603ee SSL: SSL_CTX_set_tmp_dh() error handling.
For example, it can fail due to weak DH parameters.
2021-08-04 21:27:51 +03:00
Maxim Dounin fbd0eb08b0 SSL: set events ready flags after handshake.
The c->read->ready and c->write->ready flags might be reset during
the handshake, and not set again if the handshake was finished on
the other event.  At the same time, some data might be read from
the socket during the handshake, so missing c->read->ready flag might
result in a connection hang, for example, when waiting for an SMTP
greeting (which was already received during the handshake).

Found by Sergey Kandaurov.
2021-08-03 20:50:30 +03:00
Sergey Kandaurov 95d439345b gRPC: handling GOAWAY with a higher last stream identifier.
Previously, once received from upstream, it couldn't limit
opening additional streams in a cached keepalive connection.
2021-06-17 11:43:55 +03:00
Maxim Dounin b53023e0e5 Fixed SSL logging with lingering close.
Recent fixes to SSL shutdown with lingering close (554c6ae25ffc, 1.19.5)
broke logging of SSL variables.  To make sure logging of SSL variables
works properly, avoid freeing c->ssl when doing an SSL shutdown before
lingering close.

Reported by Reinis Rozitis
(http://mailman.nginx.org/pipermail/nginx/2021-May/060670.html).
2021-06-01 17:37:51 +03:00
Maxim Dounin 2b215d01f2 SSL: ngx_ssl_shutdown() rework.
Instead of calling SSL_free() with each return point, introduced a single
place where cleanup happens.  As a positive side effect, this fixes two
potential memory leaks on ngx_handle_read_event() and ngx_handle_write_event()
errors where there were no SSL_free() calls (though unlikely practical,
as errors there are only expected to happen due to bugs or kernel issues).
2021-06-01 17:37:49 +03:00
Maxim Dounin 88c3088474 Version bump. 2021-11-16 16:57:52 +03:00
Maxim Dounin acc9ee614f release-1.20.1 tag 2021-05-25 15:35:38 +03:00
Maxim Dounin dbbb8fda3f nginx-1.20.1-RELEASE 2021-05-25 15:35:38 +03:00
Maxim Dounin cda4356a47 Resolver: explicit check for compression pointers in question.
Since nginx always uses exactly one entry in the question section of
a DNS query, and never uses compression pointers in this entry, parsing
of a DNS response in ngx_resolver_process_response() does not expect
compression pointers to appear in the question section of the DNS
response.  Indeed, compression pointers in the first name of a DNS response
hardly make sense, do not seem to be allowed by RFC 1035 (which says
"a pointer to a prior occurance of the same name", note "prior"), and
were never observed in practice.

Added an explicit check to ngx_resolver_process_response()'s parsing
of the question section to properly report an error if compression pointers
nevertheless appear in the question section.
2021-05-25 15:17:50 +03:00
Maxim Dounin c76b6027aa Resolver: simplified ngx_resolver_copy().
Instead of checking on each label if we need to place a dot or not,
now it always adds a dot after a label, and reduces the resulting
length afterwards.
2021-05-25 15:17:45 +03:00
Maxim Dounin c7b4ba76f6 Resolver: reworked ngx_resolver_copy() copy loop.
To make the code easier to read, reworked the ngx_resolver_copy()
copy loop to match the one used to calculate length.  No functional
changes.
2021-05-25 15:17:43 +03:00
Maxim Dounin f9c3f85f7b Resolver: fixed label types handling in ngx_resolver_copy().
Previously, anything with any of the two high bits set were interpreted
as compression pointers.  This is incorrect, as RFC 1035 clearly states
that "The 10 and 01 combinations are reserved for future use".  Further,
the 01 combination is actually allocated for EDNS extended label type
(see RFC 2671 and RFC 6891), not really used though.

Fix is to reject unrecognized label types rather than misinterpreting
them as compression pointers.
2021-05-25 15:17:41 +03:00
Maxim Dounin dc8f286940 Resolver: fixed off-by-one read in ngx_resolver_copy().
It is believed to be harmless, and in the worst case it uses some
uninitialized memory as a part of the compression pointer length,
eventually leading to the "name is out of DNS response" error.
2021-05-25 15:17:38 +03:00
Maxim Dounin aeb088ebab Resolver: fixed off-by-one write in ngx_resolver_copy().
Reported by Luis Merino, Markus Vervier, Eric Sesterhenn, X41 D-Sec GmbH.
2021-05-25 15:17:36 +03:00
Maxim Dounin 597d509a1c Version bump. 2021-05-25 15:29:54 +03:00
Maxim Dounin e95a38cf48 release-1.20.0 tag 2021-04-20 16:35:47 +03:00
Maxim Dounin 646752ddd9 nginx-1.20.0-RELEASE 2021-04-20 16:35:46 +03:00
Maxim Dounin f471ce1ff5 Stable branch. 2021-04-20 16:06:58 +03:00
11 changed files with 267 additions and 51 deletions

View File

@ -5,6 +5,124 @@
<change_log title="nginx">
<changes ver="1.20.2" date="2021-11-16">
<change type="feature">
<para lang="ru">
совместимость с OpenSSL 3.0.
</para>
<para lang="en">
OpenSSL 3.0 compatibility.
</para>
</change>
<change type="bugfix">
<para lang="ru">
SSL-переменные могли быть пустыми при записи в лог;
ошибка появилась в 1.19.5.
</para>
<para lang="en">
SSL variables might be empty when used in logs;
the bug had appeared in 1.19.5.
</para>
</change>
<change type="bugfix">
<para lang="ru">
keepalive-соединения с gRPC-бэкендами могли не закрываться
после получения GOAWAY-фрейма.
</para>
<para lang="en">
keepalive connections with gRPC backends might not be closed
after receiving a GOAWAY frame.
</para>
</change>
<change type="bugfix">
<para lang="ru">
SSL-соединения к бэкендам в модуле stream
могли зависать после SSL handshake.
</para>
<para lang="en">
backend SSL connections in the stream module
might hang after an SSL handshake.
</para>
</change>
<change type="bugfix">
<para lang="ru">
SSL-соединения с gRPC-бэкендами могли зависать,
если использовались методы select, poll или /dev/poll.
</para>
<para lang="en">
SSL connections with gRPC backends might hang
if select, poll, or /dev/poll methods were used.
</para>
</change>
<change type="bugfix">
<para lang="ru">
в переменной $content_length при использовании chunked transfer encoding.
</para>
<para lang="en">
in the $content_length variable when using chunked transfer encoding.
</para>
</change>
<change type="bugfix">
<para lang="ru">
при использовании HTTP/2 и директивы aio_write
запросы могли зависать.
</para>
<para lang="en">
requests might hang
when using HTTP/2 and the "aio_write" directive.
</para>
</change>
</changes>
<changes ver="1.20.1" date="2021-05-25">
<change type="security">
<para lang="ru">
при использовании директивы resolver
во время обработки ответа DNS-сервера
могла происходить перезапись одного байта памяти,
что позволяло атакующему,
имеющему возможность подделывать UDP-пакеты от DNS-сервера,
вызвать падение рабочего процесса
или, потенциально, выполнение произвольного кода (CVE-2021-23017).
</para>
<para lang="en">
1-byte memory overwrite might occur
during DNS server response processing
if the "resolver" directive was used,
allowing an attacker
who is able to forge UDP packets from the DNS server
to cause worker process crash
or, potentially, arbitrary code execution (CVE-2021-23017).
</para>
</change>
</changes>
<changes ver="1.20.0" date="2021-04-20">
<change>
<para lang="ru">
Стабильная ветка 1.20.x.
</para>
<para lang="en">
1.20.x stable branch.
</para>
</change>
</changes>
<changes ver="1.19.10" date="2021-04-13">
<change type="change">

View File

@ -6,7 +6,7 @@ TEMP = tmp
CC = cl
OBJS = objs.msvc8
OPENSSL = openssl-1.1.1k
OPENSSL = openssl-1.1.1l
ZLIB = zlib-1.2.11
PCRE = pcre-8.44

View File

@ -9,8 +9,8 @@
#define _NGINX_H_INCLUDED_
#define nginx_version 1019010
#define NGINX_VERSION "1.19.10"
#define nginx_version 1020002
#define NGINX_VERSION "1.20.2"
#define NGINX_VER "nginx/" NGINX_VERSION
#ifdef NGX_BUILD

View File

@ -203,16 +203,16 @@ ngx_chain_update_chains(ngx_pool_t *p, ngx_chain_t **free, ngx_chain_t **busy,
while (*busy) {
cl = *busy;
if (ngx_buf_size(cl->buf) != 0) {
break;
}
if (cl->buf->tag != tag) {
*busy = cl->next;
ngx_free_chain(p, cl);
continue;
}
if (ngx_buf_size(cl->buf) != 0) {
break;
}
cl->buf->pos = cl->buf->start;
cl->buf->last = cl->buf->start;

View File

@ -1798,6 +1798,12 @@ ngx_resolver_process_response(ngx_resolver_t *r, u_char *buf, size_t n,
i = sizeof(ngx_resolver_hdr_t);
while (i < (ngx_uint_t) n) {
if (buf[i] & 0xc0) {
err = "unexpected compression pointer in DNS response";
goto done;
}
if (buf[i] == '\0') {
goto found;
}
@ -3939,11 +3945,11 @@ ngx_resolver_copy(ngx_resolver_t *r, ngx_str_t *name, u_char *buf, u_char *src,
{
char *err;
u_char *p, *dst;
ssize_t len;
size_t len;
ngx_uint_t i, n;
p = src;
len = -1;
len = 0;
/*
* compression pointers allow to create endless loop, so we set limit;
@ -3958,6 +3964,16 @@ ngx_resolver_copy(ngx_resolver_t *r, ngx_str_t *name, u_char *buf, u_char *src,
}
if (n & 0xc0) {
if ((n & 0xc0) != 0xc0) {
err = "invalid label type in DNS response";
goto invalid;
}
if (p >= last) {
err = "name is out of DNS response";
goto invalid;
}
n = ((n & 0x3f) << 8) + *p;
p = &buf[n];
@ -3986,7 +4002,7 @@ done:
return NGX_OK;
}
if (len == -1) {
if (len == 0) {
ngx_str_null(name);
return NGX_OK;
}
@ -3998,30 +4014,23 @@ done:
name->data = dst;
n = *src++;
for ( ;; ) {
n = *src++;
if (n == 0) {
name->len = dst - name->data - 1;
return NGX_OK;
}
if (n & 0xc0) {
n = ((n & 0x3f) << 8) + *src;
src = &buf[n];
n = *src++;
} else {
ngx_strlow(dst, src, n);
dst += n;
src += n;
n = *src++;
if (n != 0) {
*dst++ = '.';
}
}
if (n == 0) {
name->len = dst - name->data;
return NGX_OK;
*dst++ = '.';
}
}
}

View File

@ -378,6 +378,10 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data)
SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_CLIENT_RENEGOTIATION);
#endif
#ifdef SSL_OP_IGNORE_UNEXPECTED_EOF
SSL_CTX_set_options(ssl->ctx, SSL_OP_IGNORE_UNEXPECTED_EOF);
#endif
#ifdef SSL_MODE_RELEASE_BUFFERS
SSL_CTX_set_mode(ssl->ctx, SSL_MODE_RELEASE_BUFFERS);
#endif
@ -1116,6 +1120,8 @@ ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where, int ret)
}
#if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER)
RSA *
ngx_ssl_rsa512_key_callback(ngx_ssl_conn_t *ssl_conn, int is_export,
int key_length)
@ -1126,7 +1132,7 @@ ngx_ssl_rsa512_key_callback(ngx_ssl_conn_t *ssl_conn, int is_export,
return NULL;
}
#if (OPENSSL_VERSION_NUMBER < 0x10100003L && !defined OPENSSL_NO_DEPRECATED)
#ifndef OPENSSL_NO_DEPRECATED
if (key == NULL) {
key = RSA_generate_key(512, RSA_F4, NULL, NULL);
@ -1137,6 +1143,8 @@ ngx_ssl_rsa512_key_callback(ngx_ssl_conn_t *ssl_conn, int is_export,
return key;
}
#endif
ngx_array_t *
ngx_ssl_read_password_file(ngx_conf_t *cf, ngx_str_t *file)
@ -1350,7 +1358,6 @@ ngx_ssl_passwords_cleanup(void *data)
ngx_int_t
ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file)
{
DH *dh;
BIO *bio;
if (file->len == 0) {
@ -1368,6 +1375,10 @@ ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file)
return NGX_ERROR;
}
#ifdef SSL_CTX_set_tmp_dh
{
DH *dh;
dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
if (dh == NULL) {
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
@ -1376,9 +1387,42 @@ ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file)
return NGX_ERROR;
}
SSL_CTX_set_tmp_dh(ssl->ctx, dh);
if (SSL_CTX_set_tmp_dh(ssl->ctx, dh) != 1) {
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
"SSL_CTX_set_tmp_dh(\"%s\") failed", file->data);
DH_free(dh);
BIO_free(bio);
return NGX_ERROR;
}
DH_free(dh);
}
#else
{
EVP_PKEY *dh;
/*
* PEM_read_bio_DHparams() and SSL_CTX_set_tmp_dh()
* are deprecated in OpenSSL 3.0
*/
dh = PEM_read_bio_Parameters(bio, NULL);
if (dh == NULL) {
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
"PEM_read_bio_Parameters(\"%s\") failed", file->data);
BIO_free(bio);
return NGX_ERROR;
}
if (SSL_CTX_set0_tmp_dh_pkey(ssl->ctx, dh) != 1) {
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
"SSL_CTX_set0_tmp_dh_pkey(\%s\") failed", file->data);
BIO_free(bio);
return NGX_ERROR;
}
}
#endif
BIO_free(bio);
return NGX_OK;
@ -1740,6 +1784,9 @@ ngx_ssl_handshake(ngx_connection_t *c)
c->recv_chain = ngx_ssl_recv_chain;
c->send_chain = ngx_ssl_send_chain;
c->read->ready = 1;
c->write->ready = 1;
#ifndef SSL_OP_NO_RENEGOTIATION
#if OPENSSL_VERSION_NUMBER < 0x10100000L
#ifdef SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS
@ -1885,6 +1932,9 @@ ngx_ssl_try_early_data(ngx_connection_t *c)
c->recv_chain = ngx_ssl_recv_chain;
c->send_chain = ngx_ssl_send_chain;
c->read->ready = 1;
c->write->ready = 1;
rc = ngx_ssl_ocsp_validate(c);
if (rc == NGX_ERROR) {
@ -2896,9 +2946,12 @@ ngx_int_t
ngx_ssl_shutdown(ngx_connection_t *c)
{
int n, sslerr, mode;
ngx_int_t rc;
ngx_err_t err;
ngx_uint_t tries;
rc = NGX_OK;
ngx_ssl_ocsp_cleanup(c);
if (SSL_in_init(c->ssl->connection)) {
@ -2908,11 +2961,7 @@ ngx_ssl_shutdown(ngx_connection_t *c)
* Avoid calling SSL_shutdown() if handshake wasn't completed.
*/
SSL_free(c->ssl->connection);
c->ssl = NULL;
c->recv = ngx_recv;
return NGX_OK;
goto done;
}
if (c->timedout || c->error || c->buffered) {
@ -2954,11 +3003,7 @@ ngx_ssl_shutdown(ngx_connection_t *c)
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n);
if (n == 1) {
SSL_free(c->ssl->connection);
c->ssl = NULL;
c->recv = ngx_recv;
return NGX_OK;
goto done;
}
if (n == 0 && tries-- > 1) {
@ -2984,11 +3029,11 @@ ngx_ssl_shutdown(ngx_connection_t *c)
}
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
return NGX_ERROR;
goto failed;
}
if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
return NGX_ERROR;
goto failed;
}
ngx_add_timer(c->read, 3000);
@ -2997,23 +3042,33 @@ ngx_ssl_shutdown(ngx_connection_t *c)
}
if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) {
SSL_free(c->ssl->connection);
c->ssl = NULL;
c->recv = ngx_recv;
return NGX_OK;
goto done;
}
err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
ngx_ssl_connection_error(c, sslerr, err, "SSL_shutdown() failed");
SSL_free(c->ssl->connection);
c->ssl = NULL;
c->recv = ngx_recv;
return NGX_ERROR;
break;
}
failed:
rc = NGX_ERROR;
done:
if (c->ssl->shutdown_without_free) {
c->ssl->shutdown_without_free = 0;
c->recv = ngx_recv;
return rc;
}
SSL_free(c->ssl->connection);
c->ssl = NULL;
c->recv = ngx_recv;
return rc;
}
@ -3229,7 +3284,7 @@ ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
for ( ;; ) {
n = ERR_peek_error_line_data(NULL, NULL, &data, &flags);
n = ERR_peek_error_data(&data, &flags);
if (n == 0) {
break;

View File

@ -12,6 +12,8 @@
#include <ngx_config.h>
#include <ngx_core.h>
#define OPENSSL_SUPPRESS_DEPRECATED
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/bn.h>
@ -64,6 +66,16 @@
#endif
#if (OPENSSL_VERSION_NUMBER >= 0x30000000L && !defined SSL_get_peer_certificate)
#define SSL_get_peer_certificate(s) SSL_get1_peer_certificate(s)
#endif
#if (OPENSSL_VERSION_NUMBER < 0x30000000L && !defined ERR_peek_error_data)
#define ERR_peek_error_data(d, f) ERR_peek_error_line_data(NULL, NULL, d, f)
#endif
typedef struct ngx_ssl_ocsp_s ngx_ssl_ocsp_t;
@ -100,6 +112,7 @@ struct ngx_ssl_connection_s {
unsigned buffer:1;
unsigned no_wait_shutdown:1;
unsigned no_send_shutdown:1;
unsigned shutdown_without_free:1;
unsigned handshake_buffer_set:1;
unsigned try_early_data:1;
unsigned in_early:1;
@ -195,8 +208,10 @@ ngx_int_t ngx_ssl_ocsp_validate(ngx_connection_t *c);
ngx_int_t ngx_ssl_ocsp_get_status(ngx_connection_t *c, const char **s);
void ngx_ssl_ocsp_cleanup(ngx_connection_t *c);
ngx_int_t ngx_ssl_ocsp_cache_init(ngx_shm_zone_t *shm_zone, void *data);
#if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER)
RSA *ngx_ssl_rsa512_key_callback(ngx_ssl_conn_t *ssl_conn, int is_export,
int key_length);
#endif
ngx_array_t *ngx_ssl_read_password_file(ngx_conf_t *cf, ngx_str_t *file);
ngx_array_t *ngx_ssl_preserve_passwords(ngx_conf_t *cf,
ngx_array_t *passwords);

View File

@ -124,6 +124,7 @@ typedef struct {
unsigned done:1;
unsigned status:1;
unsigned rst:1;
unsigned goaway:1;
ngx_http_request_t *request;
@ -1213,6 +1214,7 @@ ngx_http_grpc_reinit_request(ngx_http_request_t *r)
ctx->done = 0;
ctx->status = 0;
ctx->rst = 0;
ctx->goaway = 0;
ctx->connection = NULL;
return NGX_OK;
@ -1568,6 +1570,7 @@ ngx_http_grpc_body_output_filter(void *data, ngx_chain_t *in)
&& ctx->out == NULL
&& ctx->output_closed
&& !ctx->output_blocked
&& !ctx->goaway
&& ctx->state == ngx_http_grpc_st_start)
{
u->keepalive = 1;
@ -1717,6 +1720,8 @@ ngx_http_grpc_process_header(ngx_http_request_t *r)
return NGX_HTTP_UPSTREAM_INVALID_HEADER;
}
ctx->goaway = 1;
continue;
}
@ -1910,6 +1915,7 @@ ngx_http_grpc_process_header(ngx_http_request_t *r)
&& ctx->out == NULL
&& ctx->output_closed
&& !ctx->output_blocked
&& !ctx->goaway
&& b->last == b->pos)
{
u->keepalive = 1;
@ -2038,6 +2044,7 @@ ngx_http_grpc_filter(void *data, ssize_t bytes)
if (ctx->in == NULL
&& ctx->output_closed
&& !ctx->output_blocked
&& !ctx->goaway
&& ctx->state == ngx_http_grpc_st_start)
{
u->keepalive = 1;
@ -2207,6 +2214,8 @@ ngx_http_grpc_filter(void *data, ssize_t bytes)
return NGX_ERROR;
}
ctx->goaway = 1;
continue;
}

View File

@ -3398,6 +3398,8 @@ ngx_http_set_lingering_close(ngx_connection_t *c)
if (c->ssl) {
ngx_int_t rc;
c->ssl->shutdown_without_free = 1;
rc = ngx_ssl_shutdown(c);
if (rc == NGX_ERROR) {

View File

@ -2062,6 +2062,10 @@ ngx_http_upstream_send_request(ngx_http_request_t *r, ngx_http_upstream_t *u,
c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
}
if (c->read->ready) {
ngx_post_event(c->read, &ngx_posted_events);
}
return;
}

View File

@ -1179,6 +1179,10 @@ ngx_http_variable_content_length(ngx_http_request_t *r,
v->no_cacheable = 0;
v->not_found = 0;
} else if (r->headers_in.chunked) {
v->not_found = 1;
v->no_cacheable = 1;
} else {
v->not_found = 1;
}