Latest update - GitHub 446ce03

This commit is contained in:
2025-08-30 23:11:04 +09:00
parent 45064635e8
commit b65b2d1663
50 changed files with 1239 additions and 149 deletions
-20
View File
@@ -129,26 +129,6 @@ if test -z "$NGX_KQUEUE_CHECKED"; then
fi
if [ "$NGX_SYSTEM" = "NetBSD" ]; then
# NetBSD 2.0 incompatibly defines kevent.udata as "intptr_t"
cat << END >> $NGX_AUTO_CONFIG_H
#define NGX_KQUEUE_UDATA_T
END
else
cat << END >> $NGX_AUTO_CONFIG_H
#define NGX_KQUEUE_UDATA_T (void *)
END
fi
ngx_feature="crypt()"
ngx_feature_name="NGX_HAVE_CRYPT"
ngx_feature_run=no
-2
View File
@@ -36,8 +36,6 @@ http {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
+193
View File
@@ -5,6 +5,199 @@
<change_log title="nginx">
<changes ver="1.29.1" date="2025-08-13">
<change type="security">
<para lang="ru">
обработка специально созданного логина/пароля при использовании
метода аутентификации "none" в модуле ngx_mail_smtp_module
могла приводить к отправке серверу аутентификации
части содержимого памяти рабочего процесса (CVE-2025-53859).
</para>
<para lang="en">
processing of a specially crafted login/password when using
the "none" authentication method in the ngx_mail_smtp_module
might cause worker process memory disclosure
to the authentication server (CVE-2025-53859).
</para>
</change>
<change type="change">
<para lang="ru">
теперь сжатие сертификатов в протоколе TLSv1.3 по умолчанию запрещено.
</para>
<para lang="en">
now TLSv1.3 certificate compression is disabled by default.
</para>
</change>
<change type="feature">
<para lang="ru">
директива ssl_certificate_compression.
</para>
<para lang="en">
the "ssl_certificate_compression" directive.
</para>
</change>
<change type="feature">
<para lang="ru">
поддержка 0-RTT в QUIC при использовании OpenSSL 3.5.1 и новее.
</para>
<para lang="en">
support for 0-RTT in QUIC when using OpenSSL 3.5.1 or newer.
</para>
</change>
<change type="bugfix">
<para lang="ru">
при использовании HTTP/2 и директивы early_hints
ответ 103 мог буферизироваться.
</para>
<para lang="en">
the 103 response might be buffered
when using HTTP/2 and the "early_hints" directive.
</para>
</change>
<change type="bugfix">
<para lang="ru">
в обработке заголовков запроса "Host" и ":authority"
с одинаковыми значениями при использовании HTTP/2;
ошибка появилась в 1.17.9.
</para>
<para lang="en">
in handling "Host" and ":authority" header lines
with equal values when using HTTP/2;
the bug had appeared in 1.17.9.
</para>
</change>
<change type="bugfix">
<para lang="ru">
в обработке заголовка запроса "Host" с портом
при использовании HTTP/3.
</para>
<para lang="en">
in handling "Host" header lines with a port
when using HTTP/3.
</para>
</change>
<change type="bugfix">
<para lang="ru">
nginx не собирался под NetBSD 10.0.
</para>
<para lang="en">
nginx could not be built on NetBSD 10.0.
</para>
</change>
<change type="bugfix">
<para lang="ru">
в работе параметра none директивы smtp_auth.
</para>
<para lang="en">
in the "none" parameter of the "smtp_auth" directive.
</para>
</change>
</changes>
<changes ver="1.29.0" date="2025-06-24">
<change type="feature">
<para lang="ru">
поддержка ответа с кодом 103 от proxy- и gRPC-бэкендов;
директива early_hints.
</para>
<para lang="en">
support for response code 103 from proxy and gRPC backends;
the "early_hints" directive.
</para>
</change>
<change type="feature">
<para lang="ru">
возможность загрузки секретных ключей с аппаратных устройств
с помощью OpenSSL provider.
</para>
<para lang="en">
loading of secret keys from hardware tokens
with OpenSSL provider.
</para>
</change>
<change type="feature">
<para lang="ru">
поддержка параметра so_keepalive директивы listen на macOS.
</para>
<para lang="en">
support for the "so_keepalive" parameter of the "listen" directive on macOS.
</para>
</change>
<change type="change">
<para lang="ru">
уровень логгирования ошибок SSL в QUIC handshake
изменён с уровня error на crit для критических ошибок
и на info для всех остальных;
уровень логгирования неподдерживаемых транспортных параметров QUIC
понижен с уровня info до debug.
</para>
<para lang="en">
the logging level of SSL errors in a QUIC handshake
has been changed from "error" to "crit" for critical errors,
and to "info" for the rest;
the logging level of unsupported QUIC transport parameters
has been lowered from "info" to "debug".
</para>
</change>
<change type="change">
<para lang="ru">
бинарная версия nginx/Windows теперь использует для сборки Windows SDK 10.
</para>
<para lang="en">
the native nginx/Windows binary release is now built using Windows SDK 10.
</para>
</change>
<change type="bugfix">
<para lang="ru">
nginx не собирался gcc 15,
если использовались модули ngx_http_v2_module и ngx_http_v3_module.
</para>
<para lang="en">
nginx could not be built by gcc 15
if ngx_http_v2_module or ngx_http_v3_module modules were used.
</para>
</change>
<change type="bugfix">
<para lang="ru">
nginx мог не собираться gcc 14 и новее с оптимизацией -O3 -flto,
если использовался модуль ngx_http_v3_module.
</para>
<para lang="en">
nginx might not be built by gcc 14 or newer with -O3 -flto optimization
if ngx_http_v3_module was used.
</para>
</change>
<change>
<para lang="ru">
Исправления и улучшения в HTTP/3.
</para>
<para lang="en">
Bugfixes and improvements in HTTP/3.
</para>
</change>
</changes>
<changes ver="1.27.5" date="2025-04-16">
<change type="feature">
+5 -4
View File
@@ -6,9 +6,9 @@ TEMP = tmp
CC = cl
OBJS = objs.msvc8
OPENSSL = openssl-3.0.15
OPENSSL = openssl-3.5.2
ZLIB = zlib-1.3.1
PCRE = pcre2-10.39
PCRE = pcre2-10.45
release: export
@@ -76,7 +76,8 @@ win32:
--with-stream_realip_module \
--with-stream_ssl_preread_module \
--with-openssl=$(OBJS)/lib/$(OPENSSL) \
--with-openssl-opt="no-asm no-tests -D_WIN32_WINNT=0x0501" \
--with-openssl-opt="no-asm no-tests no-makedepend \
-D_WIN32_WINNT=0x0501" \
--with-http_ssl_module \
--with-mail_ssl_module \
--with-stream_ssl_module
@@ -109,7 +110,7 @@ zip: export
cp -p $(OBJS)/lib/$(OPENSSL)/LICENSE.txt \
$(TEMP)/$(NGINX)/docs/OpenSSL.LICENSE
cp -p $(OBJS)/lib/$(PCRE)/LICENCE \
cp -p $(OBJS)/lib/$(PCRE)/LICENCE.md \
$(TEMP)/$(NGINX)/docs/PCRE.LICENCE
sed -ne '/^ (C) 1995-20/,/^ jloup@gzip\.org/p' \
+2 -2
View File
@@ -9,8 +9,8 @@
#define _NGINX_H_INCLUDED_
#define nginx_version 1027006
#define NGINX_VERSION "1.27.6"
#define nginx_version 1029002
#define NGINX_VERSION "1.29.2"
#define NGINX_VER "nginx/" NGINX_VERSION " by Hakase"
#ifndef NGINX_SERVER
+1 -1
View File
@@ -207,7 +207,7 @@ ngx_thread_pool_exit_handler(void *data, ngx_log_t *log)
*lock = 0;
pthread_exit(0);
pthread_exit(NULL);
}
+11 -2
View File
@@ -10,6 +10,15 @@
#include <ngx_event.h>
/* NetBSD up to 10.0 incompatibly defines kevent.udata as "intptr_t" */
#if (__NetBSD__ && __NetBSD_Version__ < 1000000000)
#define NGX_KQUEUE_UDATA_T
#else
#define NGX_KQUEUE_UDATA_T (void *)
#endif
typedef struct {
ngx_uint_t changes;
ngx_uint_t events;
@@ -191,7 +200,7 @@ ngx_kqueue_init(ngx_cycle_t *cycle, ngx_msec_t timer)
kev.flags = EV_ADD|EV_ENABLE;
kev.fflags = 0;
kev.data = timer;
kev.udata = 0;
kev.udata = NGX_KQUEUE_UDATA_T (uintptr_t) 0;
ts.tv_sec = 0;
ts.tv_nsec = 0;
@@ -237,7 +246,7 @@ ngx_kqueue_notify_init(ngx_log_t *log)
notify_kev.data = 0;
notify_kev.flags = EV_ADD|EV_CLEAR;
notify_kev.fflags = 0;
notify_kev.udata = 0;
notify_kev.udata = NGX_KQUEUE_UDATA_T (uintptr_t) 0;
if (kevent(ngx_kqueue, &notify_kev, 1, NULL, 0, NULL) == -1) {
ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+36 -13
View File
@@ -387,6 +387,11 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data)
SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_COMPRESSION);
#endif
#ifdef SSL_OP_NO_TX_CERTIFICATE_COMPRESSION
SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_TX_CERTIFICATE_COMPRESSION);
SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_RX_CERTIFICATE_COMPRESSION);
#endif
#ifdef SSL_OP_NO_ANTI_REPLAY
SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_ANTI_REPLAY);
#endif
@@ -659,6 +664,36 @@ retry:
}
ngx_int_t
ngx_ssl_certificate_compression(ngx_conf_t *cf, ngx_ssl_t *ssl,
ngx_uint_t enable)
{
if (!enable) {
return NGX_OK;
}
#ifdef SSL_OP_NO_TX_CERTIFICATE_COMPRESSION
if (SSL_CTX_compress_certs(ssl->ctx, 0) == 0) {
ngx_ssl_error(NGX_LOG_WARN, ssl->log, 0,
"SSL_CTX_compress_certs() failed, ignored");
return NGX_OK;
}
SSL_CTX_clear_options(ssl->ctx, SSL_OP_NO_TX_CERTIFICATE_COMPRESSION);
#else
ngx_log_error(NGX_LOG_WARN, ssl->log, 0,
"\"ssl_certificate_compression\" is not supported "
"on this platform, ignored");
#endif
return NGX_OK;
}
ngx_int_t
ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers,
ngx_uint_t prefer_server_ciphers)
@@ -1374,7 +1409,7 @@ ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file)
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);
#if (OPENSSL_VERSION_NUMBER >= 0x3000001fL)
#if (OPENSSL_VERSION_NUMBER >= 0x30000010L)
EVP_PKEY_free(dh);
#endif
BIO_free(bio);
@@ -5094,11 +5129,7 @@ ngx_ssl_get_curve(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
return NGX_OK;
}
#if (OPENSSL_VERSION_NUMBER >= 0x3000000fL)
name = SSL_group_to_name(c->ssl->connection, nid);
#else
name = NULL;
#endif
s->len = name ? ngx_strlen(name) : sizeof("0x0000") - 1;
s->data = ngx_pnalloc(pool, s->len);
@@ -5152,11 +5183,7 @@ ngx_ssl_get_curves(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
nid = curves[i];
if (nid & TLSEXT_nid_unknown) {
#if (OPENSSL_VERSION_NUMBER >= 0x3000000fL)
name = SSL_group_to_name(c->ssl->connection, nid);
#else
name = NULL;
#endif
len += name ? ngx_strlen(name) : sizeof("0x0000") - 1;
@@ -5178,11 +5205,7 @@ ngx_ssl_get_curves(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
nid = curves[i];
if (nid & TLSEXT_nid_unknown) {
#if (OPENSSL_VERSION_NUMBER >= 0x3000000fL)
name = SSL_group_to_name(c->ssl->connection, nid);
#else
name = NULL;
#endif
p = name ? ngx_cpymem(p, name, ngx_strlen(name))
: ngx_sprintf(p, "0x%04xd", nid & 0xffff);
+7
View File
@@ -96,6 +96,11 @@
#endif
#if (OPENSSL_VERSION_NUMBER < 0x30000000L)
#define SSL_group_to_name(s, nid) NULL
#endif
typedef struct ngx_ssl_ocsp_s ngx_ssl_ocsp_t;
@@ -245,6 +250,8 @@ ngx_int_t ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
ngx_int_t ngx_ssl_connection_certificate(ngx_connection_t *c, ngx_pool_t *pool,
ngx_str_t *cert, ngx_str_t *key, ngx_ssl_cache_t *cache,
ngx_array_t *passwords);
ngx_int_t ngx_ssl_certificate_compression(ngx_conf_t *cf, ngx_ssl_t *ssl,
ngx_uint_t enable);
ngx_int_t ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers,
ngx_uint_t prefer_server_ciphers);
+1 -1
View File
@@ -707,7 +707,7 @@ ngx_ssl_cache_pkey_create(ngx_ssl_cache_key_t *id, char **err, void *data)
return NULL;
}
pkey = ENGINE_load_private_key(engine, (char *) last, 0, 0);
pkey = ENGINE_load_private_key(engine, (char *) last, NULL, NULL);
if (pkey == NULL) {
*err = "ENGINE_load_private_key() failed";
+1 -1
View File
@@ -964,7 +964,7 @@ ngx_quic_handle_payload(ngx_connection_t *c, ngx_quic_header_t *pkt)
qc = ngx_quic_get_connection(c);
qc->error = 0;
qc->error_reason = 0;
qc->error_reason = NULL;
c->log->action = "decrypting packet";
+1 -1
View File
@@ -12,7 +12,7 @@
#include <ngx_core.h>
#ifdef OSSL_RECORD_PROTECTION_LEVEL_NONE
#if (OPENSSL_VERSION_NUMBER >= 0x30500010L)
#define NGX_QUIC_OPENSSL_API 1
#elif (defined SSL_R_MISSING_QUIC_TRANSPORT_PARAMETERS_EXTENSION)
@@ -245,7 +245,7 @@ ngx_http_addition_merge_conf(ngx_conf_t *cf, void *parent, void *child)
if (ngx_http_merge_types(cf, &conf->types_keys, &conf->types,
&prev->types_keys, &prev->types,
ngx_http_html_default_types)
!= NGX_OK)
!= NGX_CONF_OK)
{
return NGX_CONF_ERROR;
}
@@ -253,7 +253,8 @@ ngx_http_auth_basic_handler(ngx_http_request_t *r)
pwd.len = i - passwd;
pwd.data = ngx_pnalloc(r->pool, pwd.len + 1);
if (pwd.data == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
goto cleanup;
}
ngx_cpystrn(pwd.data, &buf[passwd], pwd.len + 1);
@@ -1564,7 +1564,7 @@ ngx_http_charset_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
if (ngx_http_merge_types(cf, &conf->types_keys, &conf->types,
&prev->types_keys, &prev->types,
ngx_http_charset_default_types)
!= NGX_OK)
!= NGX_CONF_OK)
{
return NGX_CONF_ERROR;
}
+1 -1
View File
@@ -3130,7 +3130,7 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
if (ngx_conf_merge_path_value(cf, &conf->upstream.temp_path,
prev->upstream.temp_path,
&ngx_http_fastcgi_temp_path)
!= NGX_OK)
!= NGX_CONF_OK)
{
return NGX_CONF_ERROR;
}
+18 -1
View File
@@ -1869,7 +1869,8 @@ ngx_http_grpc_process_header(ngx_http_request_t *r)
return NGX_HTTP_UPSTREAM_INVALID_HEADER;
}
if (status < NGX_HTTP_OK) {
if (status < NGX_HTTP_OK && status != NGX_HTTP_EARLY_HINTS)
{
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"upstream sent unexpected :status \"%V\"",
status_line);
@@ -1902,6 +1903,10 @@ ngx_http_grpc_process_header(ngx_http_request_t *r)
h->lowcase_key = h->key.data;
h->hash = ngx_hash_key(h->key.data, h->key.len);
if (u->headers_in.status_n == NGX_HTTP_EARLY_HINTS) {
continue;
}
hh = ngx_hash_find(&umcf->headers_in_hash, h->hash,
h->lowcase_key, h->key.len);
@@ -1923,6 +1928,17 @@ ngx_http_grpc_process_header(ngx_http_request_t *r)
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"grpc header done");
if (u->headers_in.status_n == NGX_HTTP_EARLY_HINTS) {
if (ctx->end_stream) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"upstream prematurely closed stream");
return NGX_HTTP_UPSTREAM_INVALID_HEADER;
}
ctx->status = 0;
return NGX_HTTP_UPSTREAM_EARLY_HINTS;
}
if (ctx->end_stream) {
u->headers_in.content_length_n = 0;
@@ -4413,6 +4429,7 @@ ngx_http_grpc_create_loc_conf(ngx_conf_t *cf)
conf->upstream.pass_request_body = 1;
conf->upstream.force_ranges = 0;
conf->upstream.pass_trailers = 1;
conf->upstream.pass_early_hints = 1;
conf->upstream.preserve_output = 1;
conf->headers_source = NGX_CONF_UNSET_PTR;
@@ -304,7 +304,7 @@ ngx_http_gunzip_filter_inflate_start(ngx_http_request_t *r,
{
int rc;
ctx->zstream.next_in = Z_NULL;
ctx->zstream.next_in = NULL;
ctx->zstream.avail_in = 0;
ctx->zstream.zalloc = ngx_http_gunzip_filter_alloc;
@@ -1115,7 +1115,7 @@ ngx_http_gzip_merge_conf(ngx_conf_t *cf, void *parent, void *child)
if (ngx_http_merge_types(cf, &conf->types_keys, &conf->types,
&prev->types_keys, &prev->types,
ngx_http_html_default_types)
!= NGX_OK)
!= NGX_CONF_OK)
{
return NGX_CONF_ERROR;
}
+32 -9
View File
@@ -1877,6 +1877,13 @@ ngx_http_proxy_process_status_line(ngx_http_request_t *r)
u->headers_in.status_n, &u->headers_in.status_line);
if (ctx->status.http_version < NGX_HTTP_VERSION_11) {
if (ctx->status.code == NGX_HTTP_EARLY_HINTS) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"upstream sent HTTP/1.0 response with early hints");
return NGX_HTTP_UPSTREAM_INVALID_HEADER;
}
u->headers_in.connection_close = 1;
}
@@ -1938,6 +1945,14 @@ ngx_http_proxy_process_header(ngx_http_request_t *r)
ngx_strlow(h->lowcase_key, h->key.data, h->key.len);
}
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http proxy header: \"%V: %V\"",
&h->key, &h->value);
if (r->upstream->headers_in.status_n == NGX_HTTP_EARLY_HINTS) {
continue;
}
hh = ngx_hash_find(&umcf->headers_in_hash, h->hash,
h->lowcase_key, h->key.len);
@@ -1949,10 +1964,6 @@ ngx_http_proxy_process_header(ngx_http_request_t *r)
}
}
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http proxy header: \"%V: %V\"",
&h->key, &h->value);
continue;
}
@@ -1963,6 +1974,20 @@ ngx_http_proxy_process_header(ngx_http_request_t *r)
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http proxy header done");
ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
if (r->upstream->headers_in.status_n == NGX_HTTP_EARLY_HINTS) {
ctx->status.code = 0;
ctx->status.count = 0;
ctx->status.start = NULL;
ctx->status.end = NULL;
r->upstream->process_header =
ngx_http_proxy_process_status_line;
r->state = 0;
return NGX_HTTP_UPSTREAM_EARLY_HINTS;
}
/*
* if no "Server" and "Date" in header line,
* then add the special empty headers
@@ -2010,8 +2035,6 @@ ngx_http_proxy_process_header(ngx_http_request_t *r)
* connections alive in case of r->header_only or X-Accel-Redirect
*/
ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module);
if (u->headers_in.status_n == NGX_HTTP_NO_CONTENT
|| u->headers_in.status_n == NGX_HTTP_NOT_MODIFIED
|| ctx->head
@@ -3422,10 +3445,10 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
conf->ssl_conf_commands = NGX_CONF_UNSET_PTR;
#endif
/* "proxy_cyclic_temp_file" is disabled */
/* the hardcoded values */
conf->upstream.cyclic_temp_file = 0;
conf->upstream.change_buffering = 1;
conf->upstream.pass_early_hints = 1;
conf->headers_source = NGX_CONF_UNSET_PTR;
@@ -3638,7 +3661,7 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
if (ngx_conf_merge_path_value(cf, &conf->upstream.temp_path,
prev->upstream.temp_path,
&ngx_http_proxy_temp_path)
!= NGX_OK)
!= NGX_CONF_OK)
{
return NGX_CONF_ERROR;
}
+1 -1
View File
@@ -1543,7 +1543,7 @@ ngx_http_scgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
if (ngx_conf_merge_path_value(cf, &conf->upstream.temp_path,
prev->upstream.temp_path,
&ngx_http_scgi_temp_path)
!= NGX_OK)
!= NGX_CONF_OK)
{
return NGX_CONF_ERROR;
}
@@ -820,7 +820,7 @@ ngx_http_ssi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
}
for (prm = cmd->params; prm->name.len; prm++) {
if (prm->mandatory && params[prm->index] == 0) {
if (prm->mandatory && params[prm->index] == NULL) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
"mandatory \"%V\" parameter is absent "
"in \"%V\" SSI command",
@@ -2942,7 +2942,7 @@ ngx_http_ssi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
if (ngx_http_merge_types(cf, &conf->types_keys, &conf->types,
&prev->types_keys, &prev->types,
ngx_http_html_default_types)
!= NGX_OK)
!= NGX_CONF_OK)
{
return NGX_CONF_ERROR;
}
+18
View File
@@ -124,6 +124,13 @@ static ngx_command_t ngx_http_ssl_commands[] = {
0,
NULL },
{ ngx_string("ssl_certificate_compression"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
NGX_HTTP_SRV_CONF_OFFSET,
offsetof(ngx_http_ssl_srv_conf_t, certificate_compression),
NULL },
{ ngx_string("ssl_dhparam"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
@@ -656,6 +663,7 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
*/
sscf->prefer_server_ciphers = NGX_CONF_UNSET;
sscf->certificate_compression = NGX_CONF_UNSET;
sscf->early_data = NGX_CONF_UNSET;
sscf->reject_handshake = NGX_CONF_UNSET;
sscf->buffer_size = NGX_CONF_UNSET_SIZE;
@@ -698,6 +706,9 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_value(conf->prefer_server_ciphers,
prev->prefer_server_ciphers, 1);
ngx_conf_merge_value(conf->certificate_compression,
prev->certificate_compression, 0);
ngx_conf_merge_value(conf->early_data, prev->early_data, 1);
ngx_conf_merge_value(conf->reject_handshake, prev->reject_handshake, 0);
@@ -846,6 +857,13 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
{
return NGX_CONF_ERROR;
}
if (ngx_ssl_certificate_compression(cf, &conf->ssl,
conf->certificate_compression)
!= NGX_OK)
{
return NGX_CONF_ERROR;
}
}
conf->ssl.buffer_size = conf->buffer_size;
+1
View File
@@ -18,6 +18,7 @@ typedef struct {
ngx_ssl_t ssl;
ngx_flag_t prefer_server_ciphers;
ngx_flag_t certificate_compression;
ngx_flag_t early_data;
ngx_flag_t reject_handshake;
@@ -901,7 +901,7 @@ ngx_http_sub_merge_conf(ngx_conf_t *cf, void *parent, void *child)
if (ngx_http_merge_types(cf, &conf->types_keys, &conf->types,
&prev->types_keys, &prev->types,
ngx_http_html_default_types)
!= NGX_OK)
!= NGX_CONF_OK)
{
return NGX_CONF_ERROR;
}
+1 -1
View File
@@ -1803,7 +1803,7 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
if (ngx_conf_merge_path_value(cf, &conf->upstream.temp_path,
prev->upstream.temp_path,
&ngx_http_uwsgi_temp_path)
!= NGX_OK)
!= NGX_CONF_OK)
{
return NGX_CONF_ERROR;
}
@@ -1112,7 +1112,7 @@ ngx_http_xslt_filter_merge_conf(ngx_conf_t *cf, void *parent, void *child)
if (ngx_http_merge_types(cf, &conf->types_keys, &conf->types,
&prev->types_keys, &prev->types,
ngx_http_xslt_default_types)
!= NGX_OK)
!= NGX_CONF_OK)
{
return NGX_CONF_ERROR;
}
+1
View File
@@ -72,6 +72,7 @@ ngx_uint_t ngx_http_max_module;
ngx_http_output_header_filter_pt ngx_http_top_header_filter;
ngx_http_output_header_filter_pt ngx_http_top_early_hints_filter;
ngx_http_output_body_filter_pt ngx_http_top_body_filter;
ngx_http_request_body_filter_pt ngx_http_top_request_body_filter;
+2 -1
View File
@@ -122,7 +122,6 @@ ngx_int_t ngx_http_parse_chunked(ngx_http_request_t *r, ngx_buf_t *b,
ngx_http_request_t *ngx_http_create_request(ngx_connection_t *c);
ngx_int_t ngx_http_process_request_uri(ngx_http_request_t *r);
ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r);
void ngx_http_process_request(ngx_http_request_t *r);
void ngx_http_update_location_config(ngx_http_request_t *r);
void ngx_http_handler(ngx_http_request_t *r);
@@ -152,6 +151,7 @@ ngx_int_t ngx_http_read_client_request_body(ngx_http_request_t *r,
ngx_int_t ngx_http_read_unbuffered_request_body(ngx_http_request_t *r);
ngx_int_t ngx_http_send_header(ngx_http_request_t *r);
ngx_int_t ngx_http_send_early_hints(ngx_http_request_t *r);
ngx_int_t ngx_http_special_response_handler(ngx_http_request_t *r,
ngx_int_t error);
ngx_int_t ngx_http_filter_finalize_request(ngx_http_request_t *r,
@@ -191,6 +191,7 @@ extern ngx_str_t ngx_http_html_default_types[];
extern ngx_http_output_header_filter_pt ngx_http_top_header_filter;
extern ngx_http_output_header_filter_pt ngx_http_top_early_hints_filter;
extern ngx_http_output_body_filter_pt ngx_http_top_body_filter;
extern ngx_http_request_body_filter_pt ngx_http_top_request_body_filter;
+42 -1
View File
@@ -670,6 +670,13 @@ static ngx_command_t ngx_http_core_commands[] = {
offsetof(ngx_http_core_loc_conf_t, etag),
NULL },
{ ngx_string("early_hints"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
ngx_http_set_predicate_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_core_loc_conf_t, early_hints),
NULL },
{ ngx_string("error_page"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|NGX_CONF_2MORE,
@@ -1857,6 +1864,37 @@ ngx_http_send_header(ngx_http_request_t *r)
}
ngx_int_t
ngx_http_send_early_hints(ngx_http_request_t *r)
{
ngx_int_t rc;
ngx_http_core_loc_conf_t *clcf;
if (r->post_action) {
return NGX_OK;
}
if (r->header_sent) {
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
"header already sent");
return NGX_ERROR;
}
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
rc = ngx_http_test_predicates(r, clcf->early_hints);
if (rc != NGX_DECLINED) {
return rc;
}
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http send early hints \"%V?%V\"", &r->uri, &r->args);
return ngx_http_top_early_hints_filter(r);
}
ngx_int_t
ngx_http_output_filter(ngx_http_request_t *r, ngx_chain_t *in)
{
@@ -3637,6 +3675,7 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf)
clcf->chunked_transfer_encoding = NGX_CONF_UNSET;
clcf->etag = NGX_CONF_UNSET;
clcf->server_tokens = NGX_CONF_UNSET_UINT;
clcf->early_hints = NGX_CONF_UNSET_PTR;
clcf->types_hash_max_size = NGX_CONF_UNSET_UINT;
clcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT;
@@ -3892,7 +3931,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
if (ngx_conf_merge_path_value(cf, &conf->client_body_temp_path,
prev->client_body_temp_path,
&ngx_http_client_temp_path)
!= NGX_OK)
!= NGX_CONF_OK)
{
return NGX_CONF_ERROR;
}
@@ -3917,6 +3956,8 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_uint_value(conf->server_tokens, prev->server_tokens,
NGX_HTTP_SERVER_TOKENS_ON);
ngx_conf_merge_ptr_value(conf->early_hints, prev->early_hints, NULL);
ngx_conf_merge_ptr_value(conf->open_file_cache,
prev->open_file_cache, NULL);
+2
View File
@@ -430,6 +430,8 @@ struct ngx_http_core_loc_conf_s {
ngx_http_complex_value_t *disable_symlinks_from;
#endif
ngx_array_t *early_hints; /* early_hints */
ngx_array_t *error_pages; /* error_page */
ngx_path_t *client_body_temp_path; /* client_body_temp_path */
+107
View File
@@ -13,6 +13,7 @@
static ngx_int_t ngx_http_header_filter_init(ngx_conf_t *cf);
static ngx_int_t ngx_http_header_filter(ngx_http_request_t *r);
static ngx_int_t ngx_http_early_hints_filter(ngx_http_request_t *r);
static ngx_http_module_t ngx_http_header_filter_module_ctx = {
@@ -50,6 +51,9 @@ static u_char ngx_http_server_string[] = "Server: " NGINX_SERVER CRLF;
static u_char ngx_http_server_full_string[] = "Server: " NGINX_SERVER_FULL CRLF;
static u_char ngx_http_server_build_string[] = "Server: " NGINX_SERVER_FULL_BUILD CRLF;
static ngx_str_t ngx_http_early_hints_status_line =
ngx_string("HTTP/1.1 103 Early Hints" CRLF);
static ngx_str_t ngx_http_status_lines[] = {
@@ -625,10 +629,113 @@ ngx_http_header_filter(ngx_http_request_t *r)
}
static ngx_int_t
ngx_http_early_hints_filter(ngx_http_request_t *r)
{
size_t len;
ngx_buf_t *b;
ngx_uint_t i;
ngx_chain_t out;
ngx_list_part_t *part;
ngx_table_elt_t *header;
if (r != r->main) {
return NGX_OK;
}
if (r->http_version < NGX_HTTP_VERSION_11) {
return NGX_OK;
}
len = 0;
part = &r->headers_out.headers.part;
header = part->elts;
for (i = 0; /* void */; i++) {
if (i >= part->nelts) {
if (part->next == NULL) {
break;
}
part = part->next;
header = part->elts;
i = 0;
}
if (header[i].hash == 0) {
continue;
}
len += header[i].key.len + sizeof(": ") - 1 + header[i].value.len
+ sizeof(CRLF) - 1;
}
if (len == 0) {
return NGX_OK;
}
len += ngx_http_early_hints_status_line.len
/* the end of the early hints */
+ sizeof(CRLF) - 1;
b = ngx_create_temp_buf(r->pool, len);
if (b == NULL) {
return NGX_ERROR;
}
b->last = ngx_copy(b->last, ngx_http_early_hints_status_line.data,
ngx_http_early_hints_status_line.len);
part = &r->headers_out.headers.part;
header = part->elts;
for (i = 0; /* void */; i++) {
if (i >= part->nelts) {
if (part->next == NULL) {
break;
}
part = part->next;
header = part->elts;
i = 0;
}
if (header[i].hash == 0) {
continue;
}
b->last = ngx_copy(b->last, header[i].key.data, header[i].key.len);
*b->last++ = ':'; *b->last++ = ' ';
b->last = ngx_copy(b->last, header[i].value.data, header[i].value.len);
*b->last++ = CR; *b->last++ = LF;
}
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"%*s", (size_t) (b->last - b->pos), b->pos);
/* the end of HTTP early hints */
*b->last++ = CR; *b->last++ = LF;
r->header_size = b->last - b->pos;
b->flush = 1;
out.buf = b;
out.next = NULL;
return ngx_http_write_filter(r, &out);
}
static ngx_int_t
ngx_http_header_filter_init(ngx_conf_t *cf)
{
ngx_http_top_header_filter = ngx_http_header_filter;
ngx_http_top_early_hints_filter = ngx_http_early_hints_filter;
return NGX_OK;
}
+2 -1
View File
@@ -29,6 +29,7 @@ static ngx_int_t ngx_http_process_connection(ngx_http_request_t *r,
static ngx_int_t ngx_http_process_user_agent(ngx_http_request_t *r,
ngx_table_elt_t *h, ngx_uint_t offset);
static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r);
static ngx_int_t ngx_http_find_virtual_server(ngx_connection_t *c,
ngx_http_virtual_names_t *virtual_names, ngx_str_t *host,
ngx_http_request_t *r, ngx_http_core_srv_conf_t **cscfp);
@@ -1984,7 +1985,7 @@ ngx_http_process_user_agent(ngx_http_request_t *r, ngx_table_elt_t *h,
}
ngx_int_t
static ngx_int_t
ngx_http_process_request_header(ngx_http_request_t *r)
{
if (r->headers_in.server.len == 0
+1
View File
@@ -74,6 +74,7 @@
#define NGX_HTTP_CONTINUE 100
#define NGX_HTTP_SWITCHING_PROTOCOLS 101
#define NGX_HTTP_PROCESSING 102
#define NGX_HTTP_EARLY_HINTS 103
#define NGX_HTTP_OK 200
#define NGX_HTTP_CREATED 201
+158 -1
View File
@@ -48,6 +48,9 @@ static void ngx_http_upstream_send_request_handler(ngx_http_request_t *r,
static void ngx_http_upstream_read_request_handler(ngx_http_request_t *r);
static void ngx_http_upstream_process_header(ngx_http_request_t *r,
ngx_http_upstream_t *u);
static ngx_int_t ngx_http_upstream_process_early_hints(ngx_http_request_t *r,
ngx_http_upstream_t *u);
static void ngx_http_upstream_early_hints_writer(ngx_http_request_t *r);
static ngx_int_t ngx_http_upstream_test_next(ngx_http_request_t *r,
ngx_http_upstream_t *u);
static ngx_int_t ngx_http_upstream_intercept_errors(ngx_http_request_t *r,
@@ -1120,7 +1123,7 @@ ngx_http_upstream_cache_send(ngx_http_request_t *r, ngx_http_upstream_t *u)
return NGX_ERROR;
}
if (rc == NGX_AGAIN) {
if (rc == NGX_AGAIN || rc == NGX_HTTP_UPSTREAM_EARLY_HINTS) {
rc = NGX_HTTP_UPSTREAM_INVALID_HEADER;
}
@@ -2530,6 +2533,18 @@ ngx_http_upstream_process_header(ngx_http_request_t *r, ngx_http_upstream_t *u)
continue;
}
if (rc == NGX_HTTP_UPSTREAM_EARLY_HINTS) {
rc = ngx_http_upstream_process_early_hints(r, u);
if (rc == NGX_OK) {
rc = u->process_header(r);
if (rc == NGX_AGAIN) {
continue;
}
}
}
break;
}
@@ -2567,6 +2582,148 @@ ngx_http_upstream_process_header(ngx_http_request_t *r, ngx_http_upstream_t *u)
}
static ngx_int_t
ngx_http_upstream_process_early_hints(ngx_http_request_t *r,
ngx_http_upstream_t *u)
{
u_char *p;
ngx_uint_t i;
ngx_list_part_t *part;
ngx_table_elt_t *h, *ho;
ngx_connection_t *c;
c = r->connection;
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http upstream early hints");
if (u->conf->pass_early_hints) {
u->early_hints_length += u->buffer.pos - u->buffer.start;
if (u->early_hints_length <= (off_t) u->conf->buffer_size) {
part = &u->headers_in.headers.part;
h = part->elts;
for (i = 0; /* void */; i++) {
if (i >= part->nelts) {
if (part->next == NULL) {
break;
}
part = part->next;
h = part->elts;
i = 0;
}
if (ngx_hash_find(&u->conf->hide_headers_hash, h[i].hash,
h[i].lowcase_key, h[i].key.len))
{
continue;
}
ho = ngx_list_push(&r->headers_out.headers);
if (ho == NULL) {
return NGX_ERROR;
}
*ho = h[i];
}
if (ngx_http_send_early_hints(r) == NGX_ERROR) {
return NGX_ERROR;
}
if (c->buffered) {
if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
return NGX_ERROR;
}
r->write_event_handler = ngx_http_upstream_early_hints_writer;
}
} else {
ngx_log_error(NGX_LOG_INFO, c->log, 0,
"upstream sent too big early hints");
}
}
ngx_http_clean_header(r);
ngx_memzero(&u->headers_in, sizeof(ngx_http_upstream_headers_in_t));
u->headers_in.content_length_n = -1;
u->headers_in.last_modified_time = -1;
if (ngx_list_init(&u->headers_in.headers, r->pool, 8,
sizeof(ngx_table_elt_t))
!= NGX_OK)
{
return NGX_ERROR;
}
if (ngx_list_init(&u->headers_in.trailers, r->pool, 2,
sizeof(ngx_table_elt_t))
!= NGX_OK)
{
return NGX_ERROR;
}
p = u->buffer.pos;
u->buffer.pos = u->buffer.start;
#if (NGX_HTTP_CACHE)
if (r->cache) {
u->buffer.pos += r->cache->header_start;
}
#endif
u->buffer.last = ngx_movemem(u->buffer.pos, p, u->buffer.last - p);
return NGX_OK;
}
static void
ngx_http_upstream_early_hints_writer(ngx_http_request_t *r)
{
ngx_connection_t *c;
ngx_http_upstream_t *u;
c = r->connection;
u = r->upstream;
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
"http upstream early hints writer");
c->log->action = "sending early hints to client";
if (ngx_http_write_filter(r, NULL) == NGX_ERROR) {
ngx_http_upstream_finalize_request(r, u,
NGX_HTTP_INTERNAL_SERVER_ERROR);
return;
}
if (!c->buffered) {
if (!u->store && !r->post_action && !u->conf->ignore_client_abort) {
r->write_event_handler =
ngx_http_upstream_wr_check_broken_connection;
} else {
r->write_event_handler = ngx_http_request_empty_handler;
}
}
if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
ngx_http_upstream_finalize_request(r, u,
NGX_HTTP_INTERNAL_SERVER_ERROR);
}
}
static ngx_int_t
ngx_http_upstream_test_next(ngx_http_request_t *r, ngx_http_upstream_t *u)
{
+4 -1
View File
@@ -43,6 +43,7 @@
|NGX_HTTP_UPSTREAM_FT_HTTP_429)
#define NGX_HTTP_UPSTREAM_INVALID_HEADER 40
#define NGX_HTTP_UPSTREAM_EARLY_HINTS 41
#define NGX_HTTP_UPSTREAM_IGN_XA_REDIRECT 0x00000002
@@ -184,6 +185,8 @@ typedef struct {
ngx_flag_t request_buffering;
ngx_flag_t pass_request_headers;
ngx_flag_t pass_request_body;
ngx_flag_t pass_trailers;
ngx_flag_t pass_early_hints;
ngx_flag_t ignore_client_abort;
ngx_flag_t intercept_errors;
@@ -232,7 +235,6 @@ typedef struct {
signed store:2;
unsigned intercept_404:1;
unsigned change_buffering:1;
unsigned pass_trailers:1;
unsigned preserve_output:1;
#if (NGX_HTTP_SSL || NGX_COMPAT)
@@ -354,6 +356,7 @@ struct ngx_http_upstream_s {
ngx_buf_t buffer;
off_t length;
off_t early_hints_length;
ngx_chain_t *out_bufs;
ngx_chain_t *busy_bufs;
+136 -37
View File
@@ -158,6 +158,7 @@ static ngx_int_t ngx_http_v2_construct_request_line(ngx_http_request_t *r);
static ngx_int_t ngx_http_v2_cookie(ngx_http_request_t *r,
ngx_http_v2_header_t *header);
static ngx_int_t ngx_http_v2_construct_cookie_header(ngx_http_request_t *r);
static ngx_int_t ngx_http_v2_construct_host_header(ngx_http_request_t *r);
static void ngx_http_v2_run_request(ngx_http_request_t *r);
static ngx_int_t ngx_http_v2_process_request_body(ngx_http_request_t *r,
u_char *pos, size_t size, ngx_uint_t last, ngx_uint_t flush);
@@ -3526,44 +3527,40 @@ ngx_http_v2_parse_scheme(ngx_http_request_t *r, ngx_str_t *value)
static ngx_int_t
ngx_http_v2_parse_authority(ngx_http_request_t *r, ngx_str_t *value)
{
ngx_table_elt_t *h;
ngx_http_header_t *hh;
ngx_http_core_main_conf_t *cmcf;
ngx_int_t rc;
static ngx_str_t host = ngx_string("host");
h = ngx_list_push(&r->headers_in.headers);
if (h == NULL) {
return NGX_ERROR;
if (r->host_start) {
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"client sent duplicate \":authority\" header");
return NGX_DECLINED;
}
h->hash = ngx_hash(ngx_hash(ngx_hash('h', 'o'), 's'), 't');
r->host_start = value->data;
r->host_end = value->data + value->len;
h->key.len = host.len;
h->key.data = host.data;
rc = ngx_http_validate_host(value, r->pool, 0);
h->value.len = value->len;
h->value.data = value->data;
h->lowcase_key = host.data;
cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
hh = ngx_hash_find(&cmcf->headers_in_hash, h->hash,
h->lowcase_key, h->key.len);
if (hh == NULL) {
return NGX_ERROR;
if (rc == NGX_DECLINED) {
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"client sent invalid \":authority\" header");
return NGX_DECLINED;
}
if (hh->handler(r, h, hh->offset) != NGX_OK) {
if (rc == NGX_ERROR) {
ngx_http_v2_close_stream(r->stream, NGX_HTTP_INTERNAL_SERVER_ERROR);
return NGX_ABORT;
}
if (ngx_http_set_virtual_server(r, value) == NGX_ERROR) {
/*
* request has been finalized already
* in ngx_http_process_host()
* in ngx_http_set_virtual_server()
*/
return NGX_ABORT;
}
r->headers_in.server = *value;
return NGX_OK;
}
@@ -3734,7 +3731,54 @@ ngx_http_v2_construct_cookie_header(ngx_http_request_t *r)
if (hh->handler(r, h, hh->offset) != NGX_OK) {
/*
* request has been finalized already
* in ngx_http_process_multi_header_lines()
* in ngx_http_process_header_line()
*/
return NGX_ERROR;
}
return NGX_OK;
}
static ngx_int_t
ngx_http_v2_construct_host_header(ngx_http_request_t *r)
{
ngx_table_elt_t *h;
ngx_http_header_t *hh;
ngx_http_core_main_conf_t *cmcf;
static ngx_str_t host = ngx_string("host");
h = ngx_list_push(&r->headers_in.headers);
if (h == NULL) {
ngx_http_v2_close_stream(r->stream, NGX_HTTP_INTERNAL_SERVER_ERROR);
return NGX_ERROR;
}
h->hash = ngx_hash(ngx_hash(ngx_hash('h', 'o'), 's'), 't');
h->key.len = host.len;
h->key.data = host.data;
h->value.len = r->host_end - r->host_start;
h->value.data = r->host_start;
h->lowcase_key = host.data;
cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
hh = ngx_hash_find(&cmcf->headers_in_hash, h->hash,
h->lowcase_key, h->key.len);
if (hh == NULL) {
ngx_http_v2_close_stream(r->stream, NGX_HTTP_INTERNAL_SERVER_ERROR);
return NGX_ERROR;
}
if (hh->handler(r, h, hh->offset) != NGX_OK) {
/*
* request has been finalized already
* in ngx_http_process_host()
*/
return NGX_ERROR;
}
@@ -3746,6 +3790,7 @@ ngx_http_v2_construct_cookie_header(ngx_http_request_t *r)
static void
ngx_http_v2_run_request(ngx_http_request_t *r)
{
ngx_str_t host;
ngx_connection_t *fc;
ngx_http_v2_srv_conf_t *h2scf;
ngx_http_v2_connection_t *h2c;
@@ -3773,24 +3818,78 @@ ngx_http_v2_run_request(ngx_http_request_t *r)
r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE;
if (ngx_http_process_request_header(r) != NGX_OK) {
goto failed;
}
if (r->headers_in.content_length_n > 0 && r->stream->in_closed) {
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"client prematurely closed stream");
r->stream->skip_data = 1;
if (r->headers_in.server.len == 0) {
ngx_log_error(NGX_LOG_INFO, fc->log, 0,
"client sent neither \":authority\" nor \"Host\" header");
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
goto failed;
}
if (r->headers_in.content_length_n == -1 && !r->stream->in_closed) {
if (r->host_end) {
host.len = r->host_end - r->host_start;
host.data = r->host_start;
if (r->headers_in.host) {
if (r->headers_in.host->value.len != host.len
|| ngx_memcmp(r->headers_in.host->value.data, host.data,
host.len)
!= 0)
{
ngx_log_error(NGX_LOG_INFO, fc->log, 0,
"client sent \":authority\" and \"Host\" headers "
"with different values");
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
goto failed;
}
} else {
/* compatibility for $http_host */
if (ngx_http_v2_construct_host_header(r) != NGX_OK) {
goto failed;
}
}
}
if (r->headers_in.content_length) {
r->headers_in.content_length_n =
ngx_atoof(r->headers_in.content_length->value.data,
r->headers_in.content_length->value.len);
if (r->headers_in.content_length_n == NGX_ERROR) {
ngx_log_error(NGX_LOG_INFO, fc->log, 0,
"client sent invalid \"Content-Length\" header");
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
goto failed;
}
if (r->headers_in.content_length_n > 0 && r->stream->in_closed) {
ngx_log_error(NGX_LOG_INFO, fc->log, 0,
"client prematurely closed stream");
r->stream->skip_data = 1;
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
goto failed;
}
} else if (!r->stream->in_closed) {
r->headers_in.chunked = 1;
}
if (r->method == NGX_HTTP_CONNECT) {
ngx_log_error(NGX_LOG_INFO, fc->log, 0, "client sent CONNECT method");
ngx_http_finalize_request(r, NGX_HTTP_NOT_ALLOWED);
goto failed;
}
if (r->method == NGX_HTTP_TRACE) {
ngx_log_error(NGX_LOG_INFO, fc->log, 0, "client sent TRACE method");
ngx_http_finalize_request(r, NGX_HTTP_NOT_ALLOWED);
goto failed;
}
h2c = r->stream->connection;
h2c->payload_bytes += r->request_length;
+1
View File
@@ -270,6 +270,7 @@ struct ngx_http_v2_stream_s {
ngx_pool_t *pool;
unsigned initialized:1;
unsigned waiting:1;
unsigned blocked:1;
unsigned exhausted:1;
+205 -7
View File
@@ -59,8 +59,13 @@
#define NGX_HTTP_V2_NO_TRAILERS (ngx_http_v2_out_frame_t *) -1
static ngx_int_t ngx_http_v2_header_filter(ngx_http_request_t *r);
static ngx_int_t ngx_http_v2_early_hints_filter(ngx_http_request_t *r);
static ngx_int_t ngx_http_v2_init_stream(ngx_http_request_t *r);
static ngx_http_v2_out_frame_t *ngx_http_v2_create_headers_frame(
ngx_http_request_t *r, u_char *pos, u_char *end, ngx_uint_t fin);
ngx_http_request_t *r, u_char *pos, u_char *end, ngx_uint_t fin,
ngx_uint_t flush);
static ngx_http_v2_out_frame_t *ngx_http_v2_create_trailers_frame(
ngx_http_request_t *r);
@@ -127,6 +132,7 @@ ngx_module_t ngx_http_v2_filter_module = {
static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
static ngx_http_output_header_filter_pt ngx_http_next_early_hints_filter;
static ngx_int_t
@@ -139,7 +145,6 @@ ngx_http_v2_header_filter(ngx_http_request_t *r)
ngx_list_part_t *part;
ngx_table_elt_t *header;
ngx_connection_t *fc;
ngx_http_cleanup_t *cln;
ngx_http_v2_stream_t *stream;
ngx_http_v2_out_frame_t *frame;
ngx_http_v2_connection_t *h2c;
@@ -582,14 +587,203 @@ ngx_http_v2_header_filter(ngx_http_request_t *r)
fin = r->header_only
|| (r->headers_out.content_length_n == 0 && !r->expect_trailers);
frame = ngx_http_v2_create_headers_frame(r, start, pos, fin);
frame = ngx_http_v2_create_headers_frame(r, start, pos, fin, 0);
if (frame == NULL) {
return NGX_ERROR;
}
ngx_http_v2_queue_blocked_frame(h2c, frame);
stream->queued = 1;
stream->queued++;
if (ngx_http_v2_init_stream(r) != NGX_OK) {
return NGX_ERROR;
}
return ngx_http_v2_filter_send(fc, stream);
}
static ngx_int_t
ngx_http_v2_early_hints_filter(ngx_http_request_t *r)
{
u_char *pos, *start, *tmp;
size_t len, tmp_len;
ngx_uint_t i;
ngx_list_part_t *part;
ngx_table_elt_t *header;
ngx_connection_t *fc;
ngx_http_v2_stream_t *stream;
ngx_http_v2_out_frame_t *frame;
ngx_http_v2_connection_t *h2c;
stream = r->stream;
if (!stream) {
return ngx_http_next_early_hints_filter(r);
}
if (r != r->main) {
return NGX_OK;
}
fc = r->connection;
if (fc->error) {
return NGX_ERROR;
}
len = 0;
tmp_len = 0;
part = &r->headers_out.headers.part;
header = part->elts;
for (i = 0; /* void */; i++) {
if (i >= part->nelts) {
if (part->next == NULL) {
break;
}
part = part->next;
header = part->elts;
i = 0;
}
if (header[i].hash == 0) {
continue;
}
if (header[i].key.len > NGX_HTTP_V2_MAX_FIELD) {
ngx_log_error(NGX_LOG_CRIT, fc->log, 0,
"too long response header name: \"%V\"",
&header[i].key);
return NGX_ERROR;
}
if (header[i].value.len > NGX_HTTP_V2_MAX_FIELD) {
ngx_log_error(NGX_LOG_CRIT, fc->log, 0,
"too long response header value: \"%V: %V\"",
&header[i].key, &header[i].value);
return NGX_ERROR;
}
len += 1 + NGX_HTTP_V2_INT_OCTETS + header[i].key.len
+ NGX_HTTP_V2_INT_OCTETS + header[i].value.len;
if (header[i].key.len > tmp_len) {
tmp_len = header[i].key.len;
}
if (header[i].value.len > tmp_len) {
tmp_len = header[i].value.len;
}
}
if (len == 0) {
return NGX_OK;
}
h2c = stream->connection;
len += h2c->table_update ? 1 : 0;
len += 1 + ngx_http_v2_literal_size("418");
tmp = ngx_palloc(r->pool, tmp_len);
pos = ngx_pnalloc(r->pool, len);
if (pos == NULL || tmp == NULL) {
return NGX_ERROR;
}
start = pos;
if (h2c->table_update) {
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0,
"http2 table size update: 0");
*pos++ = (1 << 5) | 0;
h2c->table_update = 0;
}
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
"http2 output header: \":status: %03ui\"",
(ngx_uint_t) NGX_HTTP_EARLY_HINTS);
*pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_STATUS_INDEX);
*pos++ = NGX_HTTP_V2_ENCODE_RAW | 3;
pos = ngx_sprintf(pos, "%03ui", (ngx_uint_t) NGX_HTTP_EARLY_HINTS);
part = &r->headers_out.headers.part;
header = part->elts;
for (i = 0; /* void */; i++) {
if (i >= part->nelts) {
if (part->next == NULL) {
break;
}
part = part->next;
header = part->elts;
i = 0;
}
if (header[i].hash == 0) {
continue;
}
#if (NGX_DEBUG)
if (fc->log->log_level & NGX_LOG_DEBUG_HTTP) {
ngx_strlow(tmp, header[i].key.data, header[i].key.len);
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, fc->log, 0,
"http2 output header: \"%*s: %V\"",
header[i].key.len, tmp, &header[i].value);
}
#endif
*pos++ = 0;
pos = ngx_http_v2_write_name(pos, header[i].key.data,
header[i].key.len, tmp);
pos = ngx_http_v2_write_value(pos, header[i].value.data,
header[i].value.len, tmp);
}
frame = ngx_http_v2_create_headers_frame(r, start, pos, 0, 1);
if (frame == NULL) {
return NGX_ERROR;
}
ngx_http_v2_queue_blocked_frame(h2c, frame);
stream->queued++;
if (ngx_http_v2_init_stream(r) != NGX_OK) {
return NGX_ERROR;
}
return ngx_http_v2_filter_send(fc, stream);
}
static ngx_int_t
ngx_http_v2_init_stream(ngx_http_request_t *r)
{
ngx_connection_t *fc;
ngx_http_cleanup_t *cln;
ngx_http_v2_stream_t *stream;
stream = r->stream;
fc = r->connection;
if (stream->initialized) {
return NGX_OK;
}
stream->initialized = 1;
cln = ngx_http_cleanup_add(r, 0);
if (cln == NULL) {
@@ -603,13 +797,13 @@ ngx_http_v2_header_filter(ngx_http_request_t *r)
fc->need_last_buf = 1;
fc->need_flush_buf = 1;
return ngx_http_v2_filter_send(fc, stream);
return NGX_OK;
}
static ngx_http_v2_out_frame_t *
ngx_http_v2_create_headers_frame(ngx_http_request_t *r, u_char *pos,
u_char *end, ngx_uint_t fin)
u_char *end, ngx_uint_t fin, ngx_uint_t flush)
{
u_char type, flags;
size_t rest, frame_size;
@@ -700,6 +894,7 @@ ngx_http_v2_create_headers_frame(ngx_http_request_t *r, u_char *pos,
}
b->last_buf = fin;
b->flush = flush;
cl->next = NULL;
frame->last = cl;
@@ -822,7 +1017,7 @@ ngx_http_v2_create_trailers_frame(ngx_http_request_t *r)
header[i].value.len, tmp);
}
return ngx_http_v2_create_headers_frame(r, start, pos, 1);
return ngx_http_v2_create_headers_frame(r, start, pos, 1, 0);
}
@@ -1544,5 +1739,8 @@ ngx_http_v2_filter_init(ngx_conf_t *cf)
ngx_http_next_header_filter = ngx_http_top_header_filter;
ngx_http_top_header_filter = ngx_http_v2_header_filter;
ngx_http_next_early_hints_filter = ngx_http_top_early_hints_filter;
ngx_http_top_early_hints_filter = ngx_http_v2_early_hints_filter;
return NGX_OK;
}
+150
View File
@@ -20,6 +20,7 @@
#define NGX_HTTP_V3_HEADER_METHOD_GET 17
#define NGX_HTTP_V3_HEADER_SCHEME_HTTP 22
#define NGX_HTTP_V3_HEADER_SCHEME_HTTPS 23
#define NGX_HTTP_V3_HEADER_STATUS_103 24
#define NGX_HTTP_V3_HEADER_STATUS_200 25
#define NGX_HTTP_V3_HEADER_ACCEPT_ENCODING 31
#define NGX_HTTP_V3_HEADER_CONTENT_TYPE_TEXT_PLAIN 53
@@ -36,6 +37,7 @@ typedef struct {
static ngx_int_t ngx_http_v3_header_filter(ngx_http_request_t *r);
static ngx_int_t ngx_http_v3_early_hints_filter(ngx_http_request_t *r);
static ngx_int_t ngx_http_v3_body_filter(ngx_http_request_t *r,
ngx_chain_t *in);
static ngx_chain_t *ngx_http_v3_create_trailers(ngx_http_request_t *r,
@@ -75,6 +77,7 @@ ngx_module_t ngx_http_v3_filter_module = {
static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
static ngx_http_output_header_filter_pt ngx_http_next_early_hints_filter;
static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
@@ -588,6 +591,150 @@ ngx_http_v3_header_filter(ngx_http_request_t *r)
}
static ngx_int_t
ngx_http_v3_early_hints_filter(ngx_http_request_t *r)
{
size_t len, n;
ngx_buf_t *b;
ngx_uint_t i;
ngx_chain_t *out, *hl, *cl;
ngx_list_part_t *part;
ngx_table_elt_t *header;
ngx_http_v3_session_t *h3c;
if (r->http_version != NGX_HTTP_VERSION_30) {
return ngx_http_next_early_hints_filter(r);
}
if (r != r->main) {
return NGX_OK;
}
len = 0;
part = &r->headers_out.headers.part;
header = part->elts;
for (i = 0; /* void */; i++) {
if (i >= part->nelts) {
if (part->next == NULL) {
break;
}
part = part->next;
header = part->elts;
i = 0;
}
if (header[i].hash == 0) {
continue;
}
len += ngx_http_v3_encode_field_l(NULL, &header[i].key,
&header[i].value);
}
if (len == 0) {
return NGX_OK;
}
len += ngx_http_v3_encode_field_section_prefix(NULL, 0, 0, 0);
len += ngx_http_v3_encode_field_ri(NULL, 0, NGX_HTTP_V3_HEADER_STATUS_103);
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http3 header len:%uz", len);
b = ngx_create_temp_buf(r->pool, len);
if (b == NULL) {
return NGX_ERROR;
}
b->last = (u_char *) ngx_http_v3_encode_field_section_prefix(b->last,
0, 0, 0);
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http3 output header: \":status: %03ui\"",
(ngx_uint_t) NGX_HTTP_EARLY_HINTS);
b->last = (u_char *) ngx_http_v3_encode_field_ri(b->last, 0,
NGX_HTTP_V3_HEADER_STATUS_103);
part = &r->headers_out.headers.part;
header = part->elts;
for (i = 0; /* void */; i++) {
if (i >= part->nelts) {
if (part->next == NULL) {
break;
}
part = part->next;
header = part->elts;
i = 0;
}
if (header[i].hash == 0) {
continue;
}
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http3 output header: \"%V: %V\"",
&header[i].key, &header[i].value);
b->last = (u_char *) ngx_http_v3_encode_field_l(b->last,
&header[i].key,
&header[i].value);
}
b->flush = 1;
cl = ngx_alloc_chain_link(r->pool);
if (cl == NULL) {
return NGX_ERROR;
}
cl->buf = b;
cl->next = NULL;
n = b->last - b->pos;
h3c = ngx_http_v3_get_session(r->connection);
h3c->payload_bytes += n;
len = ngx_http_v3_encode_varlen_int(NULL, NGX_HTTP_V3_FRAME_HEADERS)
+ ngx_http_v3_encode_varlen_int(NULL, n);
b = ngx_create_temp_buf(r->pool, len);
if (b == NULL) {
return NGX_ERROR;
}
b->last = (u_char *) ngx_http_v3_encode_varlen_int(b->last,
NGX_HTTP_V3_FRAME_HEADERS);
b->last = (u_char *) ngx_http_v3_encode_varlen_int(b->last, n);
hl = ngx_alloc_chain_link(r->pool);
if (hl == NULL) {
return NGX_ERROR;
}
hl->buf = b;
hl->next = cl;
out = hl;
for (cl = out; cl; cl = cl->next) {
h3c->total_bytes += cl->buf->last - cl->buf->pos;
r->header_size += cl->buf->last - cl->buf->pos;
}
return ngx_http_write_filter(r, out);
}
static ngx_int_t
ngx_http_v3_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
{
@@ -845,6 +992,9 @@ ngx_http_v3_filter_init(ngx_conf_t *cf)
ngx_http_next_header_filter = ngx_http_top_header_filter;
ngx_http_top_header_filter = ngx_http_v3_header_filter;
ngx_http_next_early_hints_filter = ngx_http_top_early_hints_filter;
ngx_http_top_early_hints_filter = ngx_http_v3_early_hints_filter;
ngx_http_next_body_filter = ngx_http_top_body_filter;
ngx_http_top_body_filter = ngx_http_v3_body_filter;
+6
View File
@@ -623,6 +623,12 @@ ngx_http_v3_parse_literal(ngx_connection_t *c, ngx_http_v3_parse_literal_t *st,
}
if (st->huffman) {
if (n > NGX_MAX_INT_T_VALUE / 8) {
ngx_log_error(NGX_LOG_INFO, c->log, 0,
"client sent too large field line");
return NGX_HTTP_V3_ERR_EXCESSIVE_LOAD;
}
n = n * 8 / 5;
st->huffstate = 0;
}
+10 -7
View File
@@ -965,7 +965,7 @@ ngx_http_v3_init_pseudo_headers(ngx_http_request_t *r)
if (rc == NGX_DECLINED) {
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"client sent invalid host in request line");
"client sent invalid \":authority\" header");
goto failed;
}
@@ -1003,6 +1003,7 @@ ngx_http_v3_process_request_header(ngx_http_request_t *r)
{
ssize_t n;
ngx_buf_t *b;
ngx_str_t host;
ngx_connection_t *c;
ngx_http_v3_session_t *h3c;
ngx_http_v3_srv_conf_t *h3scf;
@@ -1034,11 +1035,13 @@ ngx_http_v3_process_request_header(ngx_http_request_t *r)
goto failed;
}
if (r->headers_in.host) {
if (r->headers_in.host->value.len != r->headers_in.server.len
|| ngx_memcmp(r->headers_in.host->value.data,
r->headers_in.server.data,
r->headers_in.server.len)
if (r->headers_in.host && r->host_end) {
host.len = r->host_end - r->host_start;
host.data = r->host_start;
if (r->headers_in.host->value.len != host.len
|| ngx_memcmp(r->headers_in.host->value.data, host.data, host.len)
!= 0)
{
ngx_log_error(NGX_LOG_INFO, c->log, 0,
@@ -1213,7 +1216,7 @@ ngx_http_v3_construct_cookie_header(ngx_http_request_t *r)
if (hh->handler(r, h, hh->offset) != NGX_OK) {
/*
* request has been finalized already
* in ngx_http_process_multi_header_lines()
* in ngx_http_process_header_line()
*/
return NGX_ERROR;
}
+4 -1
View File
@@ -1321,7 +1321,10 @@ ngx_mail_auth_http_create_request(ngx_mail_session_t *s, ngx_pool_t *pool,
b->last = ngx_copy(b->last, passwd.data, passwd.len);
*b->last++ = CR; *b->last++ = LF;
if (s->auth_method != NGX_MAIL_AUTH_PLAIN && s->salt.len) {
if ((s->auth_method == NGX_MAIL_AUTH_APOP
|| s->auth_method == NGX_MAIL_AUTH_CRAM_MD5)
&& s->salt.len)
{
b->last = ngx_cpymem(b->last, "Auth-Salt: ", sizeof("Auth-Salt: ") - 1);
b->last = ngx_copy(b->last, s->salt.data, s->salt.len);
+26 -22
View File
@@ -523,7 +523,7 @@ ngx_mail_starttls_only(ngx_mail_session_t *s, ngx_connection_t *c)
ngx_int_t
ngx_mail_auth_plain(ngx_mail_session_t *s, ngx_connection_t *c, ngx_uint_t n)
{
u_char *p, *last;
u_char *p, *pos, *last;
ngx_str_t *arg, plain;
arg = s->args.elts;
@@ -555,7 +555,7 @@ ngx_mail_auth_plain(ngx_mail_session_t *s, ngx_connection_t *c, ngx_uint_t n)
return NGX_MAIL_PARSE_INVALID_COMMAND;
}
s->login.data = p;
pos = p;
while (p < last && *p) { p++; }
@@ -565,7 +565,8 @@ ngx_mail_auth_plain(ngx_mail_session_t *s, ngx_connection_t *c, ngx_uint_t n)
return NGX_MAIL_PARSE_INVALID_COMMAND;
}
s->login.len = p++ - s->login.data;
s->login.len = p++ - pos;
s->login.data = pos;
s->passwd.len = last - p;
s->passwd.data = p;
@@ -583,24 +584,26 @@ ngx_int_t
ngx_mail_auth_login_username(ngx_mail_session_t *s, ngx_connection_t *c,
ngx_uint_t n)
{
ngx_str_t *arg;
ngx_str_t *arg, login;
arg = s->args.elts;
ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
"mail auth login username: \"%V\"", &arg[n]);
s->login.data = ngx_pnalloc(c->pool, ngx_base64_decoded_length(arg[n].len));
if (s->login.data == NULL) {
login.data = ngx_pnalloc(c->pool, ngx_base64_decoded_length(arg[n].len));
if (login.data == NULL) {
return NGX_ERROR;
}
if (ngx_decode_base64(&s->login, &arg[n]) != NGX_OK) {
if (ngx_decode_base64(&login, &arg[n]) != NGX_OK) {
ngx_log_error(NGX_LOG_INFO, c->log, 0,
"client sent invalid base64 encoding in AUTH LOGIN command");
return NGX_MAIL_PARSE_INVALID_COMMAND;
}
s->login = login;
ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
"mail auth login username: \"%V\"", &s->login);
@@ -611,7 +614,7 @@ ngx_mail_auth_login_username(ngx_mail_session_t *s, ngx_connection_t *c,
ngx_int_t
ngx_mail_auth_login_password(ngx_mail_session_t *s, ngx_connection_t *c)
{
ngx_str_t *arg;
ngx_str_t *arg, passwd;
arg = s->args.elts;
@@ -620,18 +623,19 @@ ngx_mail_auth_login_password(ngx_mail_session_t *s, ngx_connection_t *c)
"mail auth login password: \"%V\"", &arg[0]);
#endif
s->passwd.data = ngx_pnalloc(c->pool,
ngx_base64_decoded_length(arg[0].len));
if (s->passwd.data == NULL) {
passwd.data = ngx_pnalloc(c->pool, ngx_base64_decoded_length(arg[0].len));
if (passwd.data == NULL) {
return NGX_ERROR;
}
if (ngx_decode_base64(&s->passwd, &arg[0]) != NGX_OK) {
if (ngx_decode_base64(&passwd, &arg[0]) != NGX_OK) {
ngx_log_error(NGX_LOG_INFO, c->log, 0,
"client sent invalid base64 encoding in AUTH LOGIN command");
return NGX_MAIL_PARSE_INVALID_COMMAND;
}
s->passwd = passwd;
#if (NGX_DEBUG_MAIL_PASSWD)
ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
"mail auth login password: \"%V\"", &s->passwd);
@@ -674,24 +678,26 @@ ngx_int_t
ngx_mail_auth_cram_md5(ngx_mail_session_t *s, ngx_connection_t *c)
{
u_char *p, *last;
ngx_str_t *arg;
ngx_str_t *arg, login;
arg = s->args.elts;
ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0,
"mail auth cram-md5: \"%V\"", &arg[0]);
s->login.data = ngx_pnalloc(c->pool, ngx_base64_decoded_length(arg[0].len));
if (s->login.data == NULL) {
login.data = ngx_pnalloc(c->pool, ngx_base64_decoded_length(arg[0].len));
if (login.data == NULL) {
return NGX_ERROR;
}
if (ngx_decode_base64(&s->login, &arg[0]) != NGX_OK) {
if (ngx_decode_base64(&login, &arg[0]) != NGX_OK) {
ngx_log_error(NGX_LOG_INFO, c->log, 0,
"client sent invalid base64 encoding in AUTH CRAM-MD5 command");
return NGX_MAIL_PARSE_INVALID_COMMAND;
}
s->login = login;
p = s->login.data;
last = p + s->login.len;
@@ -1000,14 +1006,12 @@ ngx_mail_log_error(ngx_log_t *log, u_char *buf, size_t len)
len -= p - buf;
buf = p;
if (s->login.len == 0) {
return p;
if (s->login.len) {
p = ngx_snprintf(buf, len, ", login: \"%V\"", &s->login);
len -= p - buf;
buf = p;
}
p = ngx_snprintf(buf, len, ", login: \"%V\"", &s->login);
len -= p - buf;
buf = p;
if (s->proxy == NULL) {
return p;
}
+3
View File
@@ -782,6 +782,9 @@ ngx_mail_smtp_mail(ngx_mail_session_t *s, ngx_connection_t *c)
ngx_str_set(&s->out, smtp_ok);
ngx_str_null(&s->login);
ngx_str_null(&s->passwd);
return NGX_OK;
}
+18
View File
@@ -98,6 +98,13 @@ static ngx_command_t ngx_mail_ssl_commands[] = {
0,
NULL },
{ ngx_string("ssl_certificate_compression"),
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
NGX_MAIL_SRV_CONF_OFFSET,
offsetof(ngx_mail_ssl_conf_t, certificate_compression),
NULL },
{ ngx_string("ssl_dhparam"),
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
@@ -315,6 +322,7 @@ ngx_mail_ssl_create_conf(ngx_conf_t *cf)
scf->passwords = NGX_CONF_UNSET_PTR;
scf->conf_commands = NGX_CONF_UNSET_PTR;
scf->prefer_server_ciphers = NGX_CONF_UNSET;
scf->certificate_compression = NGX_CONF_UNSET;
scf->verify = NGX_CONF_UNSET_UINT;
scf->verify_depth = NGX_CONF_UNSET_UINT;
scf->builtin_session_cache = NGX_CONF_UNSET;
@@ -344,6 +352,9 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_value(conf->prefer_server_ciphers,
prev->prefer_server_ciphers, 1);
ngx_conf_merge_value(conf->certificate_compression,
prev->certificate_compression, 0);
ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols,
(NGX_CONF_BITMASK_SET|NGX_SSL_DEFAULT_PROTOCOLS));
@@ -447,6 +458,13 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
return NGX_CONF_ERROR;
}
if (ngx_ssl_certificate_compression(cf, &conf->ssl,
conf->certificate_compression)
!= NGX_OK)
{
return NGX_CONF_ERROR;
}
if (conf->verify) {
if (conf->client_certificate.len == 0 && conf->verify != 3) {
+1
View File
@@ -21,6 +21,7 @@
typedef struct {
ngx_flag_t prefer_server_ciphers;
ngx_flag_t certificate_compression;
ngx_ssl_t ssl;
+1 -1
View File
@@ -43,7 +43,7 @@ ngx_timezone_update(void)
struct tm *t;
char buf[4];
s = time(0);
s = time(NULL);
t = localtime(&s);
+18
View File
@@ -133,6 +133,13 @@ static ngx_command_t ngx_stream_ssl_commands[] = {
0,
NULL },
{ ngx_string("ssl_certificate_compression"),
NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
NGX_STREAM_SRV_CONF_OFFSET,
offsetof(ngx_stream_ssl_srv_conf_t, certificate_compression),
NULL },
{ ngx_string("ssl_dhparam"),
NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_slot,
@@ -881,6 +888,7 @@ ngx_stream_ssl_create_srv_conf(ngx_conf_t *cf)
sscf->passwords = NGX_CONF_UNSET_PTR;
sscf->conf_commands = NGX_CONF_UNSET_PTR;
sscf->prefer_server_ciphers = NGX_CONF_UNSET;
sscf->certificate_compression = NGX_CONF_UNSET;
sscf->reject_handshake = NGX_CONF_UNSET;
sscf->verify = NGX_CONF_UNSET_UINT;
sscf->verify_depth = NGX_CONF_UNSET_UINT;
@@ -914,6 +922,9 @@ ngx_stream_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_value(conf->prefer_server_ciphers,
prev->prefer_server_ciphers, 1);
ngx_conf_merge_value(conf->certificate_compression,
prev->certificate_compression, 0);
ngx_conf_merge_value(conf->reject_handshake, prev->reject_handshake, 0);
ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols,
@@ -1039,6 +1050,13 @@ ngx_stream_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
{
return NGX_CONF_ERROR;
}
if (ngx_ssl_certificate_compression(cf, &conf->ssl,
conf->certificate_compression)
!= NGX_OK)
{
return NGX_CONF_ERROR;
}
}
if (conf->verify) {
+1
View File
@@ -18,6 +18,7 @@ typedef struct {
ngx_msec_t handshake_timeout;
ngx_flag_t prefer_server_ciphers;
ngx_flag_t certificate_compression;
ngx_flag_t reject_handshake;
ngx_ssl_t ssl;