New upstream version 1.13.10
This commit is contained in:
parent
0490248e0f
commit
55e1981acb
36 changed files with 5497 additions and 382 deletions
25
CHANGES
25
CHANGES
|
|
@ -1,4 +1,29 @@
|
|||
|
||||
Changes with nginx 1.13.10 20 Mar 2018
|
||||
|
||||
*) Feature: the "set" parameter of the "include" SSI directive now
|
||||
allows writing arbitrary responses to a variable; the
|
||||
"subrequest_output_buffer_size" directive defines maximum response
|
||||
size.
|
||||
|
||||
*) Feature: now nginx uses clock_gettime(CLOCK_MONOTONIC) if available,
|
||||
to avoid timeouts being incorrectly triggered on system time changes.
|
||||
|
||||
*) Feature: the "escape=none" parameter of the "log_format" directive.
|
||||
Thanks to Johannes Baiter and Calin Don.
|
||||
|
||||
*) Feature: the $ssl_preread_alpn_protocols variable in the
|
||||
ngx_stream_ssl_preread_module.
|
||||
|
||||
*) Feature: the ngx_http_grpc_module.
|
||||
|
||||
*) Bugfix: in memory allocation error handling in the "geo" directive.
|
||||
|
||||
*) Bugfix: when using variables in the "auth_basic_user_file" directive
|
||||
a null character might appear in logs.
|
||||
Thanks to Vadim Filimonov.
|
||||
|
||||
|
||||
Changes with nginx 1.13.9 20 Feb 2018
|
||||
|
||||
*) Feature: HTTP/2 server push support; the "http2_push" and
|
||||
|
|
|
|||
26
CHANGES.ru
26
CHANGES.ru
|
|
@ -1,4 +1,30 @@
|
|||
|
||||
Изменения в nginx 1.13.10 20.03.2018
|
||||
|
||||
*) Добавление: теперь параметр set в SSI-директиве include позволяет
|
||||
сохранять в переменную любые ответы; максимальный размер ответа
|
||||
задаётся директивой subrequest_output_buffer_size.
|
||||
|
||||
*) Добавление: теперь nginx использует вызов
|
||||
clock_gettime(CLOCK_MONOTONIC), если он доступен, что позволяет
|
||||
избежать некорректного срабатывания таймаутов при изменениях
|
||||
системного времени.
|
||||
|
||||
*) Добавление: параметр "escape=none" директивы log_format.
|
||||
Спасибо Johannes Baiter и Calin Don.
|
||||
|
||||
*) Добавление: переменная $ssl_preread_alpn_protocols в модуле
|
||||
ngx_stream_ssl_preread_module.
|
||||
|
||||
*) Добавление: модуль ngx_http_grpc_module.
|
||||
|
||||
*) Исправление: в обработке ошибок выделения памяти в директиве geo.
|
||||
|
||||
*) Исправление: при использовании переменных в директиве
|
||||
auth_basic_user_file в лог мог выводиться символ '\0'.
|
||||
Спасибо Вадиму Филимонову.
|
||||
|
||||
|
||||
Изменения в nginx 1.13.9 20.02.2018
|
||||
|
||||
*) Добавление: поддержка HTTP/2 server push; директивы http2_push и
|
||||
|
|
|
|||
12
auto/modules
12
auto/modules
|
|
@ -428,6 +428,7 @@ if [ $HTTP = YES ]; then
|
|||
src/http/v2/ngx_http_v2_module.h"
|
||||
ngx_module_srcs="src/http/v2/ngx_http_v2.c \
|
||||
src/http/v2/ngx_http_v2_table.c \
|
||||
src/http/v2/ngx_http_v2_encode.c \
|
||||
src/http/v2/ngx_http_v2_huff_decode.c \
|
||||
src/http/v2/ngx_http_v2_huff_encode.c \
|
||||
src/http/v2/ngx_http_v2_module.c"
|
||||
|
|
@ -743,6 +744,17 @@ if [ $HTTP = YES ]; then
|
|||
. auto/module
|
||||
fi
|
||||
|
||||
if [ $HTTP_GRPC = YES -a $HTTP_V2 = YES ]; then
|
||||
ngx_module_name=ngx_http_grpc_module
|
||||
ngx_module_incs=
|
||||
ngx_module_deps=
|
||||
ngx_module_srcs=src/http/modules/ngx_http_grpc_module.c
|
||||
ngx_module_libs=
|
||||
ngx_module_link=$HTTP_GRPC
|
||||
|
||||
. auto/module
|
||||
fi
|
||||
|
||||
if [ $HTTP_PERL != NO ]; then
|
||||
ngx_module_name=ngx_http_perl_module
|
||||
ngx_module_incs=src/http/modules/perl
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@ HTTP_PROXY=YES
|
|||
HTTP_FASTCGI=YES
|
||||
HTTP_UWSGI=YES
|
||||
HTTP_SCGI=YES
|
||||
HTTP_GRPC=YES
|
||||
HTTP_PERL=NO
|
||||
HTTP_MEMCACHED=YES
|
||||
HTTP_LIMIT_CONN=YES
|
||||
|
|
@ -262,6 +263,7 @@ $0: warning: the \"--with-ipv6\" option is deprecated"
|
|||
--without-http_fastcgi_module) HTTP_FASTCGI=NO ;;
|
||||
--without-http_uwsgi_module) HTTP_UWSGI=NO ;;
|
||||
--without-http_scgi_module) HTTP_SCGI=NO ;;
|
||||
--without-http_grpc_module) HTTP_GRPC=NO ;;
|
||||
--without-http_memcached_module) HTTP_MEMCACHED=NO ;;
|
||||
--without-http_limit_conn_module) HTTP_LIMIT_CONN=NO ;;
|
||||
--without-http_limit_req_module) HTTP_LIMIT_REQ=NO ;;
|
||||
|
|
@ -471,6 +473,7 @@ cat << END
|
|||
--without-http_fastcgi_module disable ngx_http_fastcgi_module
|
||||
--without-http_uwsgi_module disable ngx_http_uwsgi_module
|
||||
--without-http_scgi_module disable ngx_http_scgi_module
|
||||
--without-http_grpc_module disable ngx_http_grpc_module
|
||||
--without-http_memcached_module disable ngx_http_memcached_module
|
||||
--without-http_limit_conn_module disable ngx_http_limit_conn_module
|
||||
--without-http_limit_req_module disable ngx_http_limit_req_module
|
||||
|
|
|
|||
24
auto/unix
24
auto/unix
|
|
@ -791,6 +791,30 @@ ngx_feature_test="struct tm t; time_t c=0; localtime_r(&c, &t)"
|
|||
. auto/feature
|
||||
|
||||
|
||||
ngx_feature="clock_gettime(CLOCK_MONOTONIC)"
|
||||
ngx_feature_name="NGX_HAVE_CLOCK_MONOTONIC"
|
||||
ngx_feature_run=no
|
||||
ngx_feature_incs="#include <time.h>"
|
||||
ngx_feature_path=
|
||||
ngx_feature_libs=
|
||||
ngx_feature_test="struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts)"
|
||||
. auto/feature
|
||||
|
||||
|
||||
if [ $ngx_found = no ]; then
|
||||
|
||||
# Linux before glibc 2.17, notably CentOS 6
|
||||
|
||||
ngx_feature="clock_gettime(CLOCK_MONOTONIC) in librt"
|
||||
ngx_feature_libs="-lrt"
|
||||
. auto/feature
|
||||
|
||||
if [ $ngx_found = yes ]; then
|
||||
CORE_LIBS="$CORE_LIBS -lrt"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
ngx_feature="posix_memalign()"
|
||||
ngx_feature_name="NGX_HAVE_POSIX_MEMALIGN"
|
||||
ngx_feature_run=no
|
||||
|
|
|
|||
|
|
@ -241,6 +241,32 @@ syn keyword ngxDirective contained geoip_org
|
|||
syn keyword ngxDirective contained geoip_proxy
|
||||
syn keyword ngxDirective contained geoip_proxy_recursive
|
||||
syn keyword ngxDirective contained google_perftools_profiles
|
||||
syn keyword ngxDirective contained grpc_bind
|
||||
syn keyword ngxDirective contained grpc_buffer_size
|
||||
syn keyword ngxDirective contained grpc_connect_timeout
|
||||
syn keyword ngxDirective contained grpc_hide_header
|
||||
syn keyword ngxDirective contained grpc_ignore_headers
|
||||
syn keyword ngxDirective contained grpc_intercept_errors
|
||||
syn keyword ngxDirective contained grpc_next_upstream
|
||||
syn keyword ngxDirective contained grpc_next_upstream_timeout
|
||||
syn keyword ngxDirective contained grpc_next_upstream_tries
|
||||
syn keyword ngxDirective contained grpc_pass
|
||||
syn keyword ngxDirective contained grpc_pass_header
|
||||
syn keyword ngxDirective contained grpc_read_timeout
|
||||
syn keyword ngxDirective contained grpc_send_timeout
|
||||
syn keyword ngxDirective contained grpc_set_header
|
||||
syn keyword ngxDirective contained grpc_ssl_certificate
|
||||
syn keyword ngxDirective contained grpc_ssl_certificate_key
|
||||
syn keyword ngxDirective contained grpc_ssl_ciphers
|
||||
syn keyword ngxDirective contained grpc_ssl_crl
|
||||
syn keyword ngxDirective contained grpc_ssl_name
|
||||
syn keyword ngxDirective contained grpc_ssl_password_file
|
||||
syn keyword ngxDirective contained grpc_ssl_protocols
|
||||
syn keyword ngxDirective contained grpc_ssl_server_name
|
||||
syn keyword ngxDirective contained grpc_ssl_session_reuse
|
||||
syn keyword ngxDirective contained grpc_ssl_trusted_certificate
|
||||
syn keyword ngxDirective contained grpc_ssl_verify
|
||||
syn keyword ngxDirective contained grpc_ssl_verify_depth
|
||||
syn keyword ngxDirective contained gunzip
|
||||
syn keyword ngxDirective contained gunzip_buffers
|
||||
syn keyword ngxDirective contained gzip
|
||||
|
|
@ -268,11 +294,14 @@ syn keyword ngxDirective contained hls_mp4_max_buffer_size
|
|||
syn keyword ngxDirective contained http2_body_preread_size
|
||||
syn keyword ngxDirective contained http2_chunk_size
|
||||
syn keyword ngxDirective contained http2_idle_timeout
|
||||
syn keyword ngxDirective contained http2_max_concurrent_pushes
|
||||
syn keyword ngxDirective contained http2_max_concurrent_streams
|
||||
syn keyword ngxDirective contained http2_max_field_size
|
||||
syn keyword ngxDirective contained http2_max_header_size
|
||||
syn keyword ngxDirective contained http2_max_requests
|
||||
syn keyword ngxDirective contained http2_pool_size
|
||||
syn keyword ngxDirective contained http2_push
|
||||
syn keyword ngxDirective contained http2_push_preload
|
||||
syn keyword ngxDirective contained http2_recv_buffer_size
|
||||
syn keyword ngxDirective contained http2_recv_timeout
|
||||
syn keyword ngxDirective contained http2_streams_index_size
|
||||
|
|
@ -574,6 +603,7 @@ syn keyword ngxDirective contained sub_filter
|
|||
syn keyword ngxDirective contained sub_filter_last_modified
|
||||
syn keyword ngxDirective contained sub_filter_once
|
||||
syn keyword ngxDirective contained sub_filter_types
|
||||
syn keyword ngxDirective contained subrequest_output_buffer_size
|
||||
syn keyword ngxDirective contained tcp_nodelay
|
||||
syn keyword ngxDirective contained tcp_nopush
|
||||
syn keyword ngxDirective contained thread_pool
|
||||
|
|
@ -1323,11 +1353,8 @@ syn keyword ngxDirectiveThirdParty contained rules_enabled
|
|||
|
||||
" Phusion Passenger
|
||||
" https://www.phusionpassenger.com/library/config/nginx/reference/
|
||||
syn keyword ngxDirectiveThirdParty contained disable_security_update_check
|
||||
syn keyword ngxDirectiveThirdParty contained passenger_abort_on_startup_error
|
||||
syn keyword ngxDirectiveThirdParty contained passenger_abort_websockets_on_process_shutdown
|
||||
syn keyword ngxDirectiveThirdParty contained passenger_analytics_log_group
|
||||
syn keyword ngxDirectiveThirdParty contained passenger_analytics_log_user
|
||||
syn keyword ngxDirectiveThirdParty contained passenger_app_env
|
||||
syn keyword ngxDirectiveThirdParty contained passenger_app_file_descriptor_ulimit
|
||||
syn keyword ngxDirectiveThirdParty contained passenger_app_group_name
|
||||
|
|
@ -1369,6 +1396,7 @@ syn keyword ngxDirectiveThirdParty contained passenger_max_instances_per_app
|
|||
syn keyword ngxDirectiveThirdParty contained passenger_max_pool_size
|
||||
syn keyword ngxDirectiveThirdParty contained passenger_max_preloader_idle_time
|
||||
syn keyword ngxDirectiveThirdParty contained passenger_max_request_queue_size
|
||||
syn keyword ngxDirectiveThirdParty contained passenger_max_request_queue_time
|
||||
syn keyword ngxDirectiveThirdParty contained passenger_max_request_time
|
||||
syn keyword ngxDirectiveThirdParty contained passenger_max_requests
|
||||
syn keyword ngxDirectiveThirdParty contained passenger_memory_limit
|
||||
|
|
@ -1402,21 +1430,22 @@ syn keyword ngxDirectiveThirdParty contained passenger_turbocaching
|
|||
syn keyword ngxDirectiveThirdParty contained passenger_user
|
||||
syn keyword ngxDirectiveThirdParty contained passenger_user_switching
|
||||
syn keyword ngxDirectiveThirdParty contained passenger_vary_turbocache_by_cookie
|
||||
syn keyword ngxDirectiveThirdParty contained rack_env
|
||||
syn keyword ngxDirectiveThirdParty contained rails_app_spawner_idle_time
|
||||
syn keyword ngxDirectiveThirdParty contained rails_env
|
||||
syn keyword ngxDirectiveThirdParty contained security_update_check_proxy
|
||||
syn keyword ngxDirectiveThirdParty contained union_station_filter
|
||||
syn keyword ngxDirectiveThirdParty contained union_station_gateway_address
|
||||
syn keyword ngxDirectiveThirdParty contained union_station_gateway_cert
|
||||
syn keyword ngxDirectiveThirdParty contained union_station_gateway_port
|
||||
syn keyword ngxDirectiveThirdParty contained union_station_key
|
||||
syn keyword ngxDirectiveThirdParty contained union_station_proxy_address
|
||||
syn keyword ngxDirectiveThirdParty contained union_station_support
|
||||
syn keyword ngxDirectiveThirdPartyDeprecated contained passenger_analytics_log_group
|
||||
syn keyword ngxDirectiveThirdPartyDeprecated contained passenger_analytics_log_user
|
||||
syn keyword ngxDirectiveThirdPartyDeprecated contained passenger_debug_log_file
|
||||
syn keyword ngxDirectiveThirdPartyDeprecated contained passenger_use_global_queue
|
||||
syn keyword ngxDirectiveThirdPartyDeprecated contained rack_env
|
||||
syn keyword ngxDirectiveThirdPartyDeprecated contained rails_app_spawner_idle_time
|
||||
syn keyword ngxDirectiveThirdPartyDeprecated contained rails_env
|
||||
syn keyword ngxDirectiveThirdPartyDeprecated contained rails_framework_spawner_idle_time
|
||||
syn keyword ngxDirectiveThirdPartyDeprecated contained rails_spawn_method
|
||||
syn keyword ngxDirectiveThirdPartyDeprecated contained union_station_filter
|
||||
syn keyword ngxDirectiveThirdPartyDeprecated contained union_station_gateway_address
|
||||
syn keyword ngxDirectiveThirdPartyDeprecated contained union_station_gateway_cert
|
||||
syn keyword ngxDirectiveThirdPartyDeprecated contained union_station_gateway_port
|
||||
syn keyword ngxDirectiveThirdPartyDeprecated contained union_station_key
|
||||
syn keyword ngxDirectiveThirdPartyDeprecated contained union_station_proxy_address
|
||||
syn keyword ngxDirectiveThirdPartyDeprecated contained union_station_support
|
||||
|
||||
" ngx_postgres is an upstream module that allows nginx to communicate directly with PostgreSQL database
|
||||
" https://github.com/FRiCKLE/ngx_postgres
|
||||
|
|
@ -2028,6 +2057,7 @@ syn keyword ngxDirectiveThirdParty contained sass_source_map_embed
|
|||
syn keyword ngxDirectiveThirdParty contained selective_cache_purge_query
|
||||
syn keyword ngxDirectiveThirdParty contained selective_cache_purge_redis_database
|
||||
syn keyword ngxDirectiveThirdParty contained selective_cache_purge_redis_host
|
||||
syn keyword ngxDirectiveThirdParty contained selective_cache_purge_redis_password
|
||||
syn keyword ngxDirectiveThirdParty contained selective_cache_purge_redis_port
|
||||
syn keyword ngxDirectiveThirdParty contained selective_cache_purge_redis_unix_socket
|
||||
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@
|
|||
#define _NGINX_H_INCLUDED_
|
||||
|
||||
|
||||
#define nginx_version 1013009
|
||||
#define NGINX_VERSION "1.13.9"
|
||||
#define nginx_version 1013010
|
||||
#define NGINX_VERSION "1.13.10"
|
||||
#define NGINX_VER "nginx/" NGINX_VERSION
|
||||
|
||||
#ifdef NGX_BUILD
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@
|
|||
#include <ngx_core.h>
|
||||
|
||||
|
||||
static ngx_msec_t ngx_monotonic_time(time_t sec, ngx_uint_t msec);
|
||||
|
||||
|
||||
/*
|
||||
* The time may be updated by signal handler or by several threads.
|
||||
* The time update operations are rare and require to hold the ngx_time_lock.
|
||||
|
|
@ -93,7 +96,7 @@ ngx_time_update(void)
|
|||
sec = tv.tv_sec;
|
||||
msec = tv.tv_usec / 1000;
|
||||
|
||||
ngx_current_msec = (ngx_msec_t) sec * 1000 + msec;
|
||||
ngx_current_msec = ngx_monotonic_time(sec, msec);
|
||||
|
||||
tp = &cached_time[slot];
|
||||
|
||||
|
|
@ -189,6 +192,31 @@ ngx_time_update(void)
|
|||
}
|
||||
|
||||
|
||||
static ngx_msec_t
|
||||
ngx_monotonic_time(time_t sec, ngx_uint_t msec)
|
||||
{
|
||||
#if (NGX_HAVE_CLOCK_MONOTONIC)
|
||||
struct timespec ts;
|
||||
|
||||
#if defined(CLOCK_MONOTONIC_FAST)
|
||||
clock_gettime(CLOCK_MONOTONIC_FAST, &ts);
|
||||
|
||||
#elif defined(CLOCK_MONOTONIC_COARSE)
|
||||
clock_gettime(CLOCK_MONOTONIC_COARSE, &ts);
|
||||
|
||||
#else
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
#endif
|
||||
|
||||
sec = ts.tv_sec;
|
||||
msec = ts.tv_nsec / 1000000;
|
||||
|
||||
#endif
|
||||
|
||||
return (ngx_msec_t) sec * 1000 + msec;
|
||||
}
|
||||
|
||||
|
||||
#if !(NGX_WIN32)
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -388,7 +388,16 @@ ngx_event_connect_set_transparent(ngx_peer_connection_t *pc, ngx_socket_t s)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
ngx_log_error(NGX_LOG_ALERT, pc->log, 0,
|
||||
"could not enable transparent proxying for IPv6 "
|
||||
"on this platform");
|
||||
|
||||
return NGX_ERROR;
|
||||
|
||||
#endif
|
||||
|
||||
break;
|
||||
|
||||
#endif /* NGX_HAVE_INET6 */
|
||||
|
|
|
|||
|
|
@ -266,8 +266,8 @@ ngx_http_auth_basic_handler(ngx_http_request_t *r)
|
|||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"user \"%V\" was not found in \"%V\"",
|
||||
&r->headers_in.user, &user_file);
|
||||
"user \"%V\" was not found in \"%s\"",
|
||||
&r->headers_in.user, user_file.data);
|
||||
|
||||
return ngx_http_auth_basic_set_realm(r, &realm);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2512,36 +2512,6 @@ ngx_http_fastcgi_non_buffered_filter(void *data, ssize_t bytes)
|
|||
break;
|
||||
}
|
||||
|
||||
/* provide continuous buffer for subrequests in memory */
|
||||
|
||||
if (r->subrequest_in_memory) {
|
||||
|
||||
cl = u->out_bufs;
|
||||
|
||||
if (cl) {
|
||||
buf->pos = cl->buf->pos;
|
||||
}
|
||||
|
||||
buf->last = buf->pos;
|
||||
|
||||
for (cl = u->out_bufs; cl; cl = cl->next) {
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http fastcgi in memory %p-%p %O",
|
||||
cl->buf->pos, cl->buf->last, ngx_buf_size(cl->buf));
|
||||
|
||||
if (buf->last == cl->buf->pos) {
|
||||
buf->last = cl->buf->last;
|
||||
continue;
|
||||
}
|
||||
|
||||
buf->last = ngx_movemem(buf->last, cl->buf->pos,
|
||||
cl->buf->last - cl->buf->pos);
|
||||
|
||||
cl->buf->pos = buf->last - (cl->buf->last - cl->buf->pos);
|
||||
cl->buf->last = buf->last;
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
|
@ -2736,8 +2706,6 @@ ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf)
|
|||
* conf->upstream.cache_methods = 0;
|
||||
* conf->upstream.temp_path = NULL;
|
||||
* conf->upstream.hide_headers_hash = { NULL, 0 };
|
||||
* conf->upstream.uri = { 0, NULL };
|
||||
* conf->upstream.location = NULL;
|
||||
* conf->upstream.store_lengths = NULL;
|
||||
* conf->upstream.store_values = NULL;
|
||||
*
|
||||
|
|
|
|||
|
|
@ -439,6 +439,7 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
ctx.temp_pool = ngx_create_pool(NGX_DEFAULT_POOL_SIZE, cf->log);
|
||||
if (ctx.temp_pool == NULL) {
|
||||
ngx_destroy_pool(pool);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
|
|
@ -460,6 +461,10 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
*cf = save;
|
||||
|
||||
if (rv != NGX_CONF_OK) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
geo->proxies = ctx.proxies;
|
||||
geo->proxy_recursive = ctx.proxy_recursive;
|
||||
|
||||
|
|
@ -482,7 +487,7 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
ctx.high.low[i] = ngx_palloc(cf->pool, len + sizeof(void *));
|
||||
if (ctx.high.low[i] == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
ngx_memcpy(ctx.high.low[i], a->elts, len);
|
||||
|
|
@ -508,14 +513,11 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
var->get_handler = ngx_http_geo_range_variable;
|
||||
var->data = (uintptr_t) geo;
|
||||
|
||||
ngx_destroy_pool(ctx.temp_pool);
|
||||
ngx_destroy_pool(pool);
|
||||
|
||||
} else {
|
||||
if (ctx.tree == NULL) {
|
||||
ctx.tree = ngx_radix_tree_create(cf->pool, -1);
|
||||
if (ctx.tree == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -525,7 +527,7 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
if (ctx.tree6 == NULL) {
|
||||
ctx.tree6 = ngx_radix_tree_create(cf->pool, -1);
|
||||
if (ctx.tree6 == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -535,14 +537,11 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
var->get_handler = ngx_http_geo_cidr_variable;
|
||||
var->data = (uintptr_t) geo;
|
||||
|
||||
ngx_destroy_pool(ctx.temp_pool);
|
||||
ngx_destroy_pool(pool);
|
||||
|
||||
if (ngx_radix32tree_insert(ctx.tree, 0, 0,
|
||||
(uintptr_t) &ngx_http_variable_null_value)
|
||||
== NGX_ERROR)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* NGX_BUSY is okay (default was set explicitly) */
|
||||
|
|
@ -552,12 +551,22 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
(uintptr_t) &ngx_http_variable_null_value)
|
||||
== NGX_ERROR)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
goto failed;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return rv;
|
||||
ngx_destroy_pool(ctx.temp_pool);
|
||||
ngx_destroy_pool(pool);
|
||||
|
||||
return NGX_CONF_OK;
|
||||
|
||||
failed:
|
||||
|
||||
ngx_destroy_pool(ctx.temp_pool);
|
||||
ngx_destroy_pool(pool);
|
||||
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
4640
src/http/modules/ngx_http_grpc_module.c
Normal file
4640
src/http/modules/ngx_http_grpc_module.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -90,6 +90,11 @@ typedef struct {
|
|||
} ngx_http_log_var_t;
|
||||
|
||||
|
||||
#define NGX_HTTP_LOG_ESCAPE_DEFAULT 0
|
||||
#define NGX_HTTP_LOG_ESCAPE_JSON 1
|
||||
#define NGX_HTTP_LOG_ESCAPE_NONE 2
|
||||
|
||||
|
||||
static void ngx_http_log_write(ngx_http_request_t *r, ngx_http_log_t *log,
|
||||
u_char *buf, size_t len);
|
||||
static ssize_t ngx_http_log_script_write(ngx_http_request_t *r,
|
||||
|
|
@ -126,7 +131,7 @@ static u_char *ngx_http_log_request_length(ngx_http_request_t *r, u_char *buf,
|
|||
ngx_http_log_op_t *op);
|
||||
|
||||
static ngx_int_t ngx_http_log_variable_compile(ngx_conf_t *cf,
|
||||
ngx_http_log_op_t *op, ngx_str_t *value, ngx_uint_t json);
|
||||
ngx_http_log_op_t *op, ngx_str_t *value, ngx_uint_t escape);
|
||||
static size_t ngx_http_log_variable_getlen(ngx_http_request_t *r,
|
||||
uintptr_t data);
|
||||
static u_char *ngx_http_log_variable(ngx_http_request_t *r, u_char *buf,
|
||||
|
|
@ -136,6 +141,10 @@ static size_t ngx_http_log_json_variable_getlen(ngx_http_request_t *r,
|
|||
uintptr_t data);
|
||||
static u_char *ngx_http_log_json_variable(ngx_http_request_t *r, u_char *buf,
|
||||
ngx_http_log_op_t *op);
|
||||
static size_t ngx_http_log_unescaped_variable_getlen(ngx_http_request_t *r,
|
||||
uintptr_t data);
|
||||
static u_char *ngx_http_log_unescaped_variable(ngx_http_request_t *r,
|
||||
u_char *buf, ngx_http_log_op_t *op);
|
||||
|
||||
|
||||
static void *ngx_http_log_create_main_conf(ngx_conf_t *cf);
|
||||
|
|
@ -905,7 +914,7 @@ ngx_http_log_request_length(ngx_http_request_t *r, u_char *buf,
|
|||
|
||||
static ngx_int_t
|
||||
ngx_http_log_variable_compile(ngx_conf_t *cf, ngx_http_log_op_t *op,
|
||||
ngx_str_t *value, ngx_uint_t json)
|
||||
ngx_str_t *value, ngx_uint_t escape)
|
||||
{
|
||||
ngx_int_t index;
|
||||
|
||||
|
|
@ -916,11 +925,18 @@ ngx_http_log_variable_compile(ngx_conf_t *cf, ngx_http_log_op_t *op,
|
|||
|
||||
op->len = 0;
|
||||
|
||||
if (json) {
|
||||
switch (escape) {
|
||||
case NGX_HTTP_LOG_ESCAPE_JSON:
|
||||
op->getlen = ngx_http_log_json_variable_getlen;
|
||||
op->run = ngx_http_log_json_variable;
|
||||
break;
|
||||
|
||||
} else {
|
||||
case NGX_HTTP_LOG_ESCAPE_NONE:
|
||||
op->getlen = ngx_http_log_unescaped_variable_getlen;
|
||||
op->run = ngx_http_log_unescaped_variable;
|
||||
break;
|
||||
|
||||
default: /* NGX_HTTP_LOG_ESCAPE_DEFAULT */
|
||||
op->getlen = ngx_http_log_variable_getlen;
|
||||
op->run = ngx_http_log_variable;
|
||||
}
|
||||
|
|
@ -1073,6 +1089,39 @@ ngx_http_log_json_variable(ngx_http_request_t *r, u_char *buf,
|
|||
}
|
||||
|
||||
|
||||
static size_t
|
||||
ngx_http_log_unescaped_variable_getlen(ngx_http_request_t *r, uintptr_t data)
|
||||
{
|
||||
ngx_http_variable_value_t *value;
|
||||
|
||||
value = ngx_http_get_indexed_variable(r, data);
|
||||
|
||||
if (value == NULL || value->not_found) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
value->escape = 0;
|
||||
|
||||
return value->len;
|
||||
}
|
||||
|
||||
|
||||
static u_char *
|
||||
ngx_http_log_unescaped_variable(ngx_http_request_t *r, u_char *buf,
|
||||
ngx_http_log_op_t *op)
|
||||
{
|
||||
ngx_http_variable_value_t *value;
|
||||
|
||||
value = ngx_http_get_indexed_variable(r, op->data);
|
||||
|
||||
if (value == NULL || value->not_found) {
|
||||
return buf;
|
||||
}
|
||||
|
||||
return ngx_cpymem(buf, value->data, value->len);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ngx_http_log_create_main_conf(ngx_conf_t *cf)
|
||||
{
|
||||
|
|
@ -1536,18 +1585,21 @@ ngx_http_log_compile_format(ngx_conf_t *cf, ngx_array_t *flushes,
|
|||
size_t i, len;
|
||||
ngx_str_t *value, var;
|
||||
ngx_int_t *flush;
|
||||
ngx_uint_t bracket, json;
|
||||
ngx_uint_t bracket, escape;
|
||||
ngx_http_log_op_t *op;
|
||||
ngx_http_log_var_t *v;
|
||||
|
||||
json = 0;
|
||||
escape = NGX_HTTP_LOG_ESCAPE_DEFAULT;
|
||||
value = args->elts;
|
||||
|
||||
if (s < args->nelts && ngx_strncmp(value[s].data, "escape=", 7) == 0) {
|
||||
data = value[s].data + 7;
|
||||
|
||||
if (ngx_strcmp(data, "json") == 0) {
|
||||
json = 1;
|
||||
escape = NGX_HTTP_LOG_ESCAPE_JSON;
|
||||
|
||||
} else if (ngx_strcmp(data, "none") == 0) {
|
||||
escape = NGX_HTTP_LOG_ESCAPE_NONE;
|
||||
|
||||
} else if (ngx_strcmp(data, "default") != 0) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
|
|
@ -1636,7 +1688,7 @@ ngx_http_log_compile_format(ngx_conf_t *cf, ngx_array_t *flushes,
|
|||
}
|
||||
}
|
||||
|
||||
if (ngx_http_log_variable_compile(cf, op, &var, json)
|
||||
if (ngx_http_log_variable_compile(cf, op, &var, escape)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
|
|
|
|||
|
|
@ -592,8 +592,6 @@ ngx_http_memcached_create_loc_conf(ngx_conf_t *cf)
|
|||
* conf->upstream.bufs.num = 0;
|
||||
* conf->upstream.next_upstream = 0;
|
||||
* conf->upstream.temp_path = NULL;
|
||||
* conf->upstream.uri = { 0, NULL };
|
||||
* conf->upstream.location = NULL;
|
||||
*/
|
||||
|
||||
conf->upstream.local = NGX_CONF_UNSET_PTR;
|
||||
|
|
|
|||
|
|
@ -2321,36 +2321,6 @@ ngx_http_proxy_non_buffered_chunked_filter(void *data, ssize_t bytes)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
/* provide continuous buffer for subrequests in memory */
|
||||
|
||||
if (r->subrequest_in_memory) {
|
||||
|
||||
cl = u->out_bufs;
|
||||
|
||||
if (cl) {
|
||||
buf->pos = cl->buf->pos;
|
||||
}
|
||||
|
||||
buf->last = buf->pos;
|
||||
|
||||
for (cl = u->out_bufs; cl; cl = cl->next) {
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http proxy in memory %p-%p %O",
|
||||
cl->buf->pos, cl->buf->last, ngx_buf_size(cl->buf));
|
||||
|
||||
if (buf->last == cl->buf->pos) {
|
||||
buf->last = cl->buf->last;
|
||||
continue;
|
||||
}
|
||||
|
||||
buf->last = ngx_movemem(buf->last, cl->buf->pos,
|
||||
cl->buf->last - cl->buf->pos);
|
||||
|
||||
cl->buf->pos = buf->last - (cl->buf->last - cl->buf->pos);
|
||||
cl->buf->last = buf->last;
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
|
@ -2827,13 +2797,13 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
|
|||
* conf->upstream.cache_methods = 0;
|
||||
* conf->upstream.temp_path = NULL;
|
||||
* conf->upstream.hide_headers_hash = { NULL, 0 };
|
||||
* conf->upstream.uri = { 0, NULL };
|
||||
* conf->upstream.location = NULL;
|
||||
* conf->upstream.store_lengths = NULL;
|
||||
* conf->upstream.store_values = NULL;
|
||||
* conf->upstream.ssl_name = NULL;
|
||||
*
|
||||
* conf->method = NULL;
|
||||
* conf->location = NULL;
|
||||
* conf->url = { 0, NULL };
|
||||
* conf->headers_source = NULL;
|
||||
* conf->headers.lengths = NULL;
|
||||
* conf->headers.values = NULL;
|
||||
|
|
|
|||
|
|
@ -2231,9 +2231,11 @@ ngx_http_ssi_set_variable(ngx_http_request_t *r, void *data, ngx_int_t rc)
|
|||
{
|
||||
ngx_str_t *value = data;
|
||||
|
||||
if (r->upstream) {
|
||||
value->len = r->upstream->buffer.last - r->upstream->buffer.pos;
|
||||
value->data = r->upstream->buffer.pos;
|
||||
if (r->headers_out.status < NGX_HTTP_SPECIAL_RESPONSE
|
||||
&& r->out && r->out->buf)
|
||||
{
|
||||
value->len = r->out->buf->last - r->out->buf->pos;
|
||||
value->data = r->out->buf->pos;
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
|
|
|||
|
|
@ -399,6 +399,13 @@ static ngx_command_t ngx_http_core_commands[] = {
|
|||
offsetof(ngx_http_core_loc_conf_t, sendfile_max_chunk),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("subrequest_output_buffer_size"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_size_slot,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
offsetof(ngx_http_core_loc_conf_t, subrequest_output_buffer_size),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("aio"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||
ngx_http_core_set_aio,
|
||||
|
|
@ -2237,6 +2244,12 @@ ngx_http_subrequest(ngx_http_request_t *r,
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (r->subrequest_in_memory) {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"nested in-memory subrequest \"%V\"", uri);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
sr = ngx_pcalloc(r->pool, sizeof(ngx_http_request_t));
|
||||
if (sr == NULL) {
|
||||
return NGX_ERROR;
|
||||
|
|
@ -2318,6 +2331,10 @@ ngx_http_subrequest(ngx_http_request_t *r,
|
|||
|
||||
sr->log_handler = r->log_handler;
|
||||
|
||||
if (sr->subrequest_in_memory) {
|
||||
sr->filter_need_in_memory = 1;
|
||||
}
|
||||
|
||||
if (!sr->background) {
|
||||
if (c->data == r && r->postponed == NULL) {
|
||||
c->data = sr;
|
||||
|
|
@ -3356,6 +3373,7 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf)
|
|||
clcf->internal = NGX_CONF_UNSET;
|
||||
clcf->sendfile = NGX_CONF_UNSET;
|
||||
clcf->sendfile_max_chunk = NGX_CONF_UNSET_SIZE;
|
||||
clcf->subrequest_output_buffer_size = NGX_CONF_UNSET_SIZE;
|
||||
clcf->aio = NGX_CONF_UNSET;
|
||||
clcf->aio_write = NGX_CONF_UNSET;
|
||||
#if (NGX_THREADS)
|
||||
|
|
@ -3578,6 +3596,9 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
|||
ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0);
|
||||
ngx_conf_merge_size_value(conf->sendfile_max_chunk,
|
||||
prev->sendfile_max_chunk, 0);
|
||||
ngx_conf_merge_size_value(conf->subrequest_output_buffer_size,
|
||||
prev->subrequest_output_buffer_size,
|
||||
(size_t) ngx_pagesize);
|
||||
ngx_conf_merge_value(conf->aio, prev->aio, NGX_HTTP_AIO_OFF);
|
||||
ngx_conf_merge_value(conf->aio_write, prev->aio_write, 0);
|
||||
#if (NGX_THREADS)
|
||||
|
|
|
|||
|
|
@ -351,6 +351,8 @@ struct ngx_http_core_loc_conf_s {
|
|||
size_t limit_rate_after; /* limit_rate_after */
|
||||
size_t sendfile_max_chunk; /* sendfile_max_chunk */
|
||||
size_t read_ahead; /* read_ahead */
|
||||
size_t subrequest_output_buffer_size;
|
||||
/* subrequest_output_buffer_size */
|
||||
|
||||
ngx_msec_t client_body_timeout; /* client_body_timeout */
|
||||
ngx_msec_t send_timeout; /* send_timeout */
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@
|
|||
|
||||
static ngx_int_t ngx_http_postpone_filter_add(ngx_http_request_t *r,
|
||||
ngx_chain_t *in);
|
||||
static ngx_int_t ngx_http_postpone_filter_in_memory(ngx_http_request_t *r,
|
||||
ngx_chain_t *in);
|
||||
static ngx_int_t ngx_http_postpone_filter_init(ngx_conf_t *cf);
|
||||
|
||||
|
||||
|
|
@ -60,6 +62,10 @@ ngx_http_postpone_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||
"http postpone filter \"%V?%V\" %p", &r->uri, &r->args, in);
|
||||
|
||||
if (r->subrequest_in_memory) {
|
||||
return ngx_http_postpone_filter_in_memory(r, in);
|
||||
}
|
||||
|
||||
if (r != c->data) {
|
||||
|
||||
if (in) {
|
||||
|
|
@ -171,6 +177,78 @@ found:
|
|||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_postpone_filter_in_memory(ngx_http_request_t *r, ngx_chain_t *in)
|
||||
{
|
||||
size_t len;
|
||||
ngx_buf_t *b;
|
||||
ngx_connection_t *c;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
|
||||
c = r->connection;
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||
"http postpone filter in memory");
|
||||
|
||||
if (r->out == NULL) {
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
|
||||
if (r->headers_out.content_length_n != -1) {
|
||||
len = r->headers_out.content_length_n;
|
||||
|
||||
if (len > clcf->subrequest_output_buffer_size) {
|
||||
ngx_log_error(NGX_LOG_ERR, c->log, 0,
|
||||
"too big subrequest response: %uz", len);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
} else {
|
||||
len = clcf->subrequest_output_buffer_size;
|
||||
}
|
||||
|
||||
b = ngx_create_temp_buf(r->pool, len);
|
||||
if (b == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
b->last_buf = 1;
|
||||
|
||||
r->out = ngx_alloc_chain_link(r->pool);
|
||||
if (r->out == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
r->out->buf = b;
|
||||
r->out->next = NULL;
|
||||
}
|
||||
|
||||
b = r->out->buf;
|
||||
|
||||
for ( /* void */ ; in; in = in->next) {
|
||||
|
||||
if (ngx_buf_special(in->buf)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
len = in->buf->last - in->buf->pos;
|
||||
|
||||
if (len > (size_t) (b->end - b->last)) {
|
||||
ngx_log_error(NGX_LOG_ERR, c->log, 0,
|
||||
"too big subrequest response");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||
"http postpone filter in memory %uz bytes", len);
|
||||
|
||||
b->last = ngx_cpymem(b->last, in->buf->pos, len);
|
||||
in->buf->pos = in->buf->last;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_postpone_filter_init(ngx_conf_t *cf)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -132,6 +132,10 @@ ngx_http_header_t ngx_http_headers_in[] = {
|
|||
offsetof(ngx_http_headers_in_t, transfer_encoding),
|
||||
ngx_http_process_header_line },
|
||||
|
||||
{ ngx_string("TE"),
|
||||
offsetof(ngx_http_headers_in_t, te),
|
||||
ngx_http_process_header_line },
|
||||
|
||||
{ ngx_string("Expect"),
|
||||
offsetof(ngx_http_headers_in_t, expect),
|
||||
ngx_http_process_unique_header_line },
|
||||
|
|
|
|||
|
|
@ -197,6 +197,7 @@ typedef struct {
|
|||
ngx_table_elt_t *if_range;
|
||||
|
||||
ngx_table_elt_t *transfer_encoding;
|
||||
ngx_table_elt_t *te;
|
||||
ngx_table_elt_t *expect;
|
||||
ngx_table_elt_t *upgrade;
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ static ngx_int_t ngx_http_upstream_intercept_errors(ngx_http_request_t *r,
|
|||
static ngx_int_t ngx_http_upstream_test_connect(ngx_connection_t *c);
|
||||
static ngx_int_t ngx_http_upstream_process_headers(ngx_http_request_t *r,
|
||||
ngx_http_upstream_t *u);
|
||||
static void ngx_http_upstream_process_body_in_memory(ngx_http_request_t *r,
|
||||
static ngx_int_t ngx_http_upstream_process_trailers(ngx_http_request_t *r,
|
||||
ngx_http_upstream_t *u);
|
||||
static void ngx_http_upstream_send_response(ngx_http_request_t *r,
|
||||
ngx_http_upstream_t *u);
|
||||
|
|
@ -166,6 +166,8 @@ static ngx_int_t ngx_http_upstream_response_length_variable(
|
|||
ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_upstream_header_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_upstream_trailer_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_upstream_cookie_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
|
||||
|
|
@ -425,6 +427,9 @@ static ngx_http_variable_t ngx_http_upstream_vars[] = {
|
|||
{ ngx_string("upstream_http_"), NULL, ngx_http_upstream_header_variable,
|
||||
0, NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_PREFIX, 0 },
|
||||
|
||||
{ ngx_string("upstream_trailer_"), NULL, ngx_http_upstream_trailer_variable,
|
||||
0, NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_PREFIX, 0 },
|
||||
|
||||
{ ngx_string("upstream_cookie_"), NULL, ngx_http_upstream_cookie_variable,
|
||||
0, NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_PREFIX, 0 },
|
||||
|
||||
|
|
@ -1048,6 +1053,13 @@ ngx_http_upstream_cache_send(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_list_init(&u->headers_in.trailers, r->pool, 2,
|
||||
sizeof(ngx_table_elt_t))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
rc = u->process_header(r);
|
||||
|
||||
if (rc == NGX_OK) {
|
||||
|
|
@ -1604,6 +1616,7 @@ ngx_http_upstream_connect(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
|||
|
||||
u->request_sent = 0;
|
||||
u->request_body_sent = 0;
|
||||
u->request_body_blocked = 0;
|
||||
|
||||
if (rc == NGX_AGAIN) {
|
||||
ngx_add_timer(c->write, u->conf->connect_timeout);
|
||||
|
|
@ -1885,6 +1898,13 @@ ngx_http_upstream_reinit(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
|||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_list_init(&u->headers_in.trailers, r->pool, 2,
|
||||
sizeof(ngx_table_elt_t))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
/* reinit the request chain */
|
||||
|
||||
file_pos = 0;
|
||||
|
|
@ -1975,7 +1995,7 @@ ngx_http_upstream_send_request(ngx_http_request_t *r, ngx_http_upstream_t *u,
|
|||
}
|
||||
|
||||
if (rc == NGX_AGAIN) {
|
||||
if (!c->write->ready) {
|
||||
if (!c->write->ready || u->request_body_blocked) {
|
||||
ngx_add_timer(c->write, u->conf->send_timeout);
|
||||
|
||||
} else if (c->write->timer_set) {
|
||||
|
|
@ -2000,7 +2020,7 @@ ngx_http_upstream_send_request(ngx_http_request_t *r, ngx_http_upstream_t *u,
|
|||
}
|
||||
|
||||
if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
|
||||
if (ngx_tcp_push(c->fd) == NGX_ERROR) {
|
||||
if (ngx_tcp_push(c->fd) == -1) {
|
||||
ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno,
|
||||
ngx_tcp_push_n " failed");
|
||||
ngx_http_upstream_finalize_request(r, u,
|
||||
|
|
@ -2011,7 +2031,9 @@ ngx_http_upstream_send_request(ngx_http_request_t *r, ngx_http_upstream_t *u,
|
|||
c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
|
||||
}
|
||||
|
||||
u->write_event_handler = ngx_http_upstream_dummy_handler;
|
||||
if (!u->conf->preserve_output) {
|
||||
u->write_event_handler = ngx_http_upstream_dummy_handler;
|
||||
}
|
||||
|
||||
if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
|
||||
ngx_http_upstream_finalize_request(r, u,
|
||||
|
|
@ -2052,7 +2074,16 @@ ngx_http_upstream_send_request_body(ngx_http_request_t *r,
|
|||
out = NULL;
|
||||
}
|
||||
|
||||
return ngx_output_chain(&u->output, out);
|
||||
rc = ngx_output_chain(&u->output, out);
|
||||
|
||||
if (rc == NGX_AGAIN) {
|
||||
u->request_body_blocked = 1;
|
||||
|
||||
} else {
|
||||
u->request_body_blocked = 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (!u->request_sent) {
|
||||
|
|
@ -2093,6 +2124,13 @@ ngx_http_upstream_send_request_body(ngx_http_request_t *r,
|
|||
ngx_free_chain(r->pool, ln);
|
||||
}
|
||||
|
||||
if (rc == NGX_AGAIN) {
|
||||
u->request_body_blocked = 1;
|
||||
|
||||
} else {
|
||||
u->request_body_blocked = 0;
|
||||
}
|
||||
|
||||
if (rc == NGX_OK && !r->reading_body) {
|
||||
break;
|
||||
}
|
||||
|
|
@ -2157,7 +2195,7 @@ ngx_http_upstream_send_request_handler(ngx_http_request_t *r,
|
|||
|
||||
#endif
|
||||
|
||||
if (u->header_sent) {
|
||||
if (u->header_sent && !u->conf->preserve_output) {
|
||||
u->write_event_handler = ngx_http_upstream_dummy_handler;
|
||||
|
||||
(void) ngx_handle_write_event(c->write, 0);
|
||||
|
|
@ -2239,6 +2277,15 @@ ngx_http_upstream_process_header(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
|||
return;
|
||||
}
|
||||
|
||||
if (ngx_list_init(&u->headers_in.trailers, r->pool, 2,
|
||||
sizeof(ngx_table_elt_t))
|
||||
!= NGX_OK)
|
||||
{
|
||||
ngx_http_upstream_finalize_request(r, u,
|
||||
NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
#if (NGX_HTTP_CACHE)
|
||||
|
||||
if (r->cache) {
|
||||
|
|
@ -2335,45 +2382,7 @@ ngx_http_upstream_process_header(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!r->subrequest_in_memory) {
|
||||
ngx_http_upstream_send_response(r, u);
|
||||
return;
|
||||
}
|
||||
|
||||
/* subrequest content in memory */
|
||||
|
||||
if (u->input_filter == NULL) {
|
||||
u->input_filter_init = ngx_http_upstream_non_buffered_filter_init;
|
||||
u->input_filter = ngx_http_upstream_non_buffered_filter;
|
||||
u->input_filter_ctx = r;
|
||||
}
|
||||
|
||||
if (u->input_filter_init(u->input_filter_ctx) == NGX_ERROR) {
|
||||
ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
n = u->buffer.last - u->buffer.pos;
|
||||
|
||||
if (n) {
|
||||
u->buffer.last = u->buffer.pos;
|
||||
|
||||
u->state->response_length += n;
|
||||
|
||||
if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) {
|
||||
ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (u->length == 0) {
|
||||
ngx_http_upstream_finalize_request(r, u, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
u->read_event_handler = ngx_http_upstream_process_body_in_memory;
|
||||
|
||||
ngx_http_upstream_process_body_in_memory(r, u);
|
||||
ngx_http_upstream_send_response(r, u);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -2775,81 +2784,48 @@ ngx_http_upstream_process_headers(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_http_upstream_process_body_in_memory(ngx_http_request_t *r,
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_process_trailers(ngx_http_request_t *r,
|
||||
ngx_http_upstream_t *u)
|
||||
{
|
||||
size_t size;
|
||||
ssize_t n;
|
||||
ngx_buf_t *b;
|
||||
ngx_event_t *rev;
|
||||
ngx_connection_t *c;
|
||||
ngx_uint_t i;
|
||||
ngx_list_part_t *part;
|
||||
ngx_table_elt_t *h, *ho;
|
||||
|
||||
c = u->peer.connection;
|
||||
rev = c->read;
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||
"http upstream process body in memory");
|
||||
|
||||
if (rev->timedout) {
|
||||
ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
|
||||
ngx_http_upstream_finalize_request(r, u, NGX_HTTP_GATEWAY_TIME_OUT);
|
||||
return;
|
||||
if (!u->conf->pass_trailers) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
b = &u->buffer;
|
||||
part = &u->headers_in.trailers.part;
|
||||
h = part->elts;
|
||||
|
||||
for ( ;; ) {
|
||||
for (i = 0; /* void */; i++) {
|
||||
|
||||
size = b->end - b->last;
|
||||
if (i >= part->nelts) {
|
||||
if (part->next == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (size == 0) {
|
||||
ngx_log_error(NGX_LOG_ALERT, c->log, 0,
|
||||
"upstream buffer is too small to read response");
|
||||
ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
|
||||
return;
|
||||
part = part->next;
|
||||
h = part->elts;
|
||||
i = 0;
|
||||
}
|
||||
|
||||
n = c->recv(c, b->last, size);
|
||||
|
||||
if (n == NGX_AGAIN) {
|
||||
break;
|
||||
if (ngx_hash_find(&u->conf->hide_headers_hash, h[i].hash,
|
||||
h[i].lowcase_key, h[i].key.len))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (n == 0 || n == NGX_ERROR) {
|
||||
ngx_http_upstream_finalize_request(r, u, n);
|
||||
return;
|
||||
ho = ngx_list_push(&r->headers_out.trailers);
|
||||
if (ho == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
u->state->bytes_received += n;
|
||||
u->state->response_length += n;
|
||||
|
||||
if (u->input_filter(u->input_filter_ctx, n) == NGX_ERROR) {
|
||||
ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!rev->ready) {
|
||||
break;
|
||||
}
|
||||
*ho = h[i];
|
||||
}
|
||||
|
||||
if (u->length == 0) {
|
||||
ngx_http_upstream_finalize_request(r, u, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ngx_handle_read_event(rev, 0) != NGX_OK) {
|
||||
ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rev->active) {
|
||||
ngx_add_timer(rev, u->conf->read_timeout);
|
||||
|
||||
} else if (rev->timer_set) {
|
||||
ngx_del_timer(rev);
|
||||
}
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -4359,12 +4335,6 @@ ngx_http_upstream_finalize_request(ngx_http_request_t *r,
|
|||
|
||||
#endif
|
||||
|
||||
if (r->subrequest_in_memory
|
||||
&& u->headers_in.status_n >= NGX_HTTP_SPECIAL_RESPONSE)
|
||||
{
|
||||
u->buffer.last = u->buffer.pos;
|
||||
}
|
||||
|
||||
r->read_event_handler = ngx_http_block_reading;
|
||||
|
||||
if (rc == NGX_DECLINED) {
|
||||
|
|
@ -4396,6 +4366,12 @@ ngx_http_upstream_finalize_request(ngx_http_request_t *r,
|
|||
}
|
||||
|
||||
if (rc == 0) {
|
||||
|
||||
if (ngx_http_upstream_process_trailers(r, u) != NGX_OK) {
|
||||
ngx_http_finalize_request(r, NGX_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
rc = ngx_http_send_special(r, NGX_HTTP_LAST);
|
||||
|
||||
} else if (flush) {
|
||||
|
|
@ -5505,6 +5481,21 @@ ngx_http_upstream_header_variable(ngx_http_request_t *r,
|
|||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_trailer_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
if (r->upstream == NULL) {
|
||||
v->not_found = 1;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
return ngx_http_variable_unknown_header(v, (ngx_str_t *) data,
|
||||
&r->upstream->headers_in.trailers.part,
|
||||
sizeof("upstream_trailer_") - 1);
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_cookie_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ typedef struct {
|
|||
ngx_msec_t response_time;
|
||||
ngx_msec_t connect_time;
|
||||
ngx_msec_t header_time;
|
||||
ngx_msec_t queue_time;
|
||||
off_t response_length;
|
||||
off_t bytes_received;
|
||||
|
||||
|
|
@ -221,6 +222,8 @@ 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)
|
||||
ngx_ssl_t *ssl;
|
||||
|
|
@ -250,6 +253,7 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
ngx_list_t headers;
|
||||
ngx_list_t trailers;
|
||||
|
||||
ngx_uint_t status_n;
|
||||
ngx_str_t status_line;
|
||||
|
|
@ -388,6 +392,7 @@ struct ngx_http_upstream_s {
|
|||
|
||||
unsigned request_sent:1;
|
||||
unsigned request_body_sent:1;
|
||||
unsigned request_body_blocked:1;
|
||||
unsigned header_sent:1;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -429,7 +429,9 @@ ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
v->flags &= flags | ~NGX_HTTP_VAR_WEAK;
|
||||
if (!(flags & NGX_HTTP_VAR_WEAK)) {
|
||||
v->flags &= ~NGX_HTTP_VAR_WEAK;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
|
@ -494,7 +496,9 @@ ngx_http_add_prefix_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
v->flags &= flags | ~NGX_HTTP_VAR_WEAK;
|
||||
if (!(flags & NGX_HTTP_VAR_WEAK)) {
|
||||
v->flags &= ~NGX_HTTP_VAR_WEAK;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,8 +54,6 @@ typedef struct {
|
|||
|
||||
#define NGX_HTTP_V2_FRAME_BUFFER_SIZE 24
|
||||
|
||||
#define NGX_HTTP_V2_DEFAULT_FRAME_SIZE (1 << 14)
|
||||
|
||||
#define NGX_HTTP_V2_ROOT (void *) -1
|
||||
|
||||
|
||||
|
|
@ -783,8 +781,8 @@ ngx_http_v2_state_head(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end)
|
|||
type, h2c->state.flags, h2c->state.length, h2c->state.sid);
|
||||
|
||||
if (type >= NGX_HTTP_V2_FRAME_STATES) {
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
|
||||
"http2 frame with unknown type %ui", type);
|
||||
ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
|
||||
"client sent frame with unknown type %ui", type);
|
||||
return ngx_http_v2_state_skip(h2c, pos, end);
|
||||
}
|
||||
|
||||
|
|
@ -1992,6 +1990,9 @@ ngx_http_v2_state_settings(ngx_http_v2_connection_t *h2c, u_char *pos,
|
|||
return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
|
||||
}
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
|
||||
"http2 SETTINGS frame");
|
||||
|
||||
return ngx_http_v2_state_settings_params(h2c, pos, end);
|
||||
}
|
||||
|
||||
|
|
@ -2132,8 +2133,8 @@ ngx_http_v2_state_ping(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end)
|
|||
return ngx_http_v2_state_save(h2c, pos, end, ngx_http_v2_state_ping);
|
||||
}
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
|
||||
"http2 PING frame, flags: %ud", h2c->state.flags);
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
|
||||
"http2 PING frame");
|
||||
|
||||
if (h2c->state.flags & NGX_HTTP_V2_ACK_FLAG) {
|
||||
return ngx_http_v2_state_skip(h2c, pos, end);
|
||||
|
|
@ -3257,19 +3258,9 @@ ngx_http_v2_validate_header(ngx_http_request_t *r, ngx_http_v2_header_t *header)
|
|||
continue;
|
||||
}
|
||||
|
||||
switch (ch) {
|
||||
case '\0':
|
||||
case LF:
|
||||
case CR:
|
||||
case ':':
|
||||
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||
"client sent invalid header name: \"%V\"",
|
||||
&header->name);
|
||||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (ch >= 'A' && ch <= 'Z') {
|
||||
if (ch == '\0' || ch == LF || ch == CR || ch == ':'
|
||||
|| (ch >= 'A' && ch <= 'Z'))
|
||||
{
|
||||
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||
"client sent invalid header name: \"%V\"",
|
||||
&header->name);
|
||||
|
|
@ -3283,10 +3274,7 @@ ngx_http_v2_validate_header(ngx_http_request_t *r, ngx_http_v2_header_t *header)
|
|||
for (i = 0; i != header->value.len; i++) {
|
||||
ch = header->value.data[i];
|
||||
|
||||
switch (ch) {
|
||||
case '\0':
|
||||
case LF:
|
||||
case CR:
|
||||
if (ch == '\0' || ch == LF || ch == CR) {
|
||||
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||
"client sent header \"%V\" with "
|
||||
"invalid value: \"%V\"",
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#define NGX_HTTP_V2_STATE_BUFFER_SIZE 16
|
||||
|
||||
#define NGX_HTTP_V2_DEFAULT_FRAME_SIZE (1 << 14)
|
||||
#define NGX_HTTP_V2_MAX_FRAME_SIZE ((1 << 24) - 1)
|
||||
|
||||
#define NGX_HTTP_V2_INT_OCTETS 4
|
||||
|
|
@ -291,6 +292,9 @@ void ngx_http_v2_close_stream(ngx_http_v2_stream_t *stream, ngx_int_t rc);
|
|||
ngx_int_t ngx_http_v2_send_output_queue(ngx_http_v2_connection_t *h2c);
|
||||
|
||||
|
||||
ngx_str_t *ngx_http_v2_get_static_name(ngx_uint_t index);
|
||||
ngx_str_t *ngx_http_v2_get_static_value(ngx_uint_t index);
|
||||
|
||||
ngx_int_t ngx_http_v2_get_indexed_header(ngx_http_v2_connection_t *h2c,
|
||||
ngx_uint_t index, ngx_uint_t name_only);
|
||||
ngx_int_t ngx_http_v2_add_header(ngx_http_v2_connection_t *h2c,
|
||||
|
|
@ -357,4 +361,53 @@ size_t ngx_http_v2_huff_encode(u_char *src, size_t len, u_char *dst,
|
|||
|
||||
#define ngx_http_v2_write_sid ngx_http_v2_write_uint32
|
||||
|
||||
|
||||
#define ngx_http_v2_indexed(i) (128 + (i))
|
||||
#define ngx_http_v2_inc_indexed(i) (64 + (i))
|
||||
|
||||
#define ngx_http_v2_write_name(dst, src, len, tmp) \
|
||||
ngx_http_v2_string_encode(dst, src, len, tmp, 1)
|
||||
#define ngx_http_v2_write_value(dst, src, len, tmp) \
|
||||
ngx_http_v2_string_encode(dst, src, len, tmp, 0)
|
||||
|
||||
#define NGX_HTTP_V2_ENCODE_RAW 0
|
||||
#define NGX_HTTP_V2_ENCODE_HUFF 0x80
|
||||
|
||||
#define NGX_HTTP_V2_AUTHORITY_INDEX 1
|
||||
|
||||
#define NGX_HTTP_V2_METHOD_INDEX 2
|
||||
#define NGX_HTTP_V2_METHOD_GET_INDEX 2
|
||||
#define NGX_HTTP_V2_METHOD_POST_INDEX 3
|
||||
|
||||
#define NGX_HTTP_V2_PATH_INDEX 4
|
||||
#define NGX_HTTP_V2_PATH_ROOT_INDEX 4
|
||||
|
||||
#define NGX_HTTP_V2_SCHEME_HTTP_INDEX 6
|
||||
#define NGX_HTTP_V2_SCHEME_HTTPS_INDEX 7
|
||||
|
||||
#define NGX_HTTP_V2_STATUS_INDEX 8
|
||||
#define NGX_HTTP_V2_STATUS_200_INDEX 8
|
||||
#define NGX_HTTP_V2_STATUS_204_INDEX 9
|
||||
#define NGX_HTTP_V2_STATUS_206_INDEX 10
|
||||
#define NGX_HTTP_V2_STATUS_304_INDEX 11
|
||||
#define NGX_HTTP_V2_STATUS_400_INDEX 12
|
||||
#define NGX_HTTP_V2_STATUS_404_INDEX 13
|
||||
#define NGX_HTTP_V2_STATUS_500_INDEX 14
|
||||
|
||||
#define NGX_HTTP_V2_ACCEPT_ENCODING_INDEX 16
|
||||
#define NGX_HTTP_V2_ACCEPT_LANGUAGE_INDEX 17
|
||||
#define NGX_HTTP_V2_CONTENT_LENGTH_INDEX 28
|
||||
#define NGX_HTTP_V2_CONTENT_TYPE_INDEX 31
|
||||
#define NGX_HTTP_V2_DATE_INDEX 33
|
||||
#define NGX_HTTP_V2_LAST_MODIFIED_INDEX 44
|
||||
#define NGX_HTTP_V2_LOCATION_INDEX 46
|
||||
#define NGX_HTTP_V2_SERVER_INDEX 54
|
||||
#define NGX_HTTP_V2_USER_AGENT_INDEX 58
|
||||
#define NGX_HTTP_V2_VARY_INDEX 59
|
||||
|
||||
|
||||
u_char *ngx_http_v2_string_encode(u_char *dst, u_char *src, size_t len,
|
||||
u_char *tmp, ngx_uint_t lower);
|
||||
|
||||
|
||||
#endif /* _NGX_HTTP_V2_H_INCLUDED_ */
|
||||
|
|
|
|||
62
src/http/v2/ngx_http_v2_encode.c
Normal file
62
src/http/v2/ngx_http_v2_encode.c
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
|
||||
/*
|
||||
* Copyright (C) Nginx, Inc.
|
||||
* Copyright (C) Valentin V. Bartenev
|
||||
*/
|
||||
|
||||
|
||||
#include <ngx_config.h>
|
||||
#include <ngx_core.h>
|
||||
#include <ngx_http.h>
|
||||
|
||||
|
||||
static u_char *ngx_http_v2_write_int(u_char *pos, ngx_uint_t prefix,
|
||||
ngx_uint_t value);
|
||||
|
||||
|
||||
u_char *
|
||||
ngx_http_v2_string_encode(u_char *dst, u_char *src, size_t len, u_char *tmp,
|
||||
ngx_uint_t lower)
|
||||
{
|
||||
size_t hlen;
|
||||
|
||||
hlen = ngx_http_v2_huff_encode(src, len, tmp, lower);
|
||||
|
||||
if (hlen > 0) {
|
||||
*dst = NGX_HTTP_V2_ENCODE_HUFF;
|
||||
dst = ngx_http_v2_write_int(dst, ngx_http_v2_prefix(7), hlen);
|
||||
return ngx_cpymem(dst, tmp, hlen);
|
||||
}
|
||||
|
||||
*dst = NGX_HTTP_V2_ENCODE_RAW;
|
||||
dst = ngx_http_v2_write_int(dst, ngx_http_v2_prefix(7), len);
|
||||
|
||||
if (lower) {
|
||||
ngx_strlow(dst, src, len);
|
||||
return dst + len;
|
||||
}
|
||||
|
||||
return ngx_cpymem(dst, src, len);
|
||||
}
|
||||
|
||||
|
||||
static u_char *
|
||||
ngx_http_v2_write_int(u_char *pos, ngx_uint_t prefix, ngx_uint_t value)
|
||||
{
|
||||
if (value < prefix) {
|
||||
*pos++ |= value;
|
||||
return pos;
|
||||
}
|
||||
|
||||
*pos++ |= prefix;
|
||||
value -= prefix;
|
||||
|
||||
while (value >= 128) {
|
||||
*pos++ = value % 128 + 128;
|
||||
value /= 128;
|
||||
}
|
||||
|
||||
*pos++ = (u_char) value;
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
|
@ -23,43 +23,6 @@
|
|||
#define ngx_http_v2_literal_size(h) \
|
||||
(ngx_http_v2_integer_octets(sizeof(h) - 1) + sizeof(h) - 1)
|
||||
|
||||
#define ngx_http_v2_indexed(i) (128 + (i))
|
||||
#define ngx_http_v2_inc_indexed(i) (64 + (i))
|
||||
|
||||
#define ngx_http_v2_write_name(dst, src, len, tmp) \
|
||||
ngx_http_v2_string_encode(dst, src, len, tmp, 1)
|
||||
#define ngx_http_v2_write_value(dst, src, len, tmp) \
|
||||
ngx_http_v2_string_encode(dst, src, len, tmp, 0)
|
||||
|
||||
#define NGX_HTTP_V2_ENCODE_RAW 0
|
||||
#define NGX_HTTP_V2_ENCODE_HUFF 0x80
|
||||
|
||||
#define NGX_HTTP_V2_AUTHORITY_INDEX 1
|
||||
#define NGX_HTTP_V2_METHOD_GET_INDEX 2
|
||||
#define NGX_HTTP_V2_PATH_INDEX 4
|
||||
|
||||
#define NGX_HTTP_V2_SCHEME_HTTP_INDEX 6
|
||||
#define NGX_HTTP_V2_SCHEME_HTTPS_INDEX 7
|
||||
|
||||
#define NGX_HTTP_V2_STATUS_INDEX 8
|
||||
#define NGX_HTTP_V2_STATUS_200_INDEX 8
|
||||
#define NGX_HTTP_V2_STATUS_204_INDEX 9
|
||||
#define NGX_HTTP_V2_STATUS_206_INDEX 10
|
||||
#define NGX_HTTP_V2_STATUS_304_INDEX 11
|
||||
#define NGX_HTTP_V2_STATUS_400_INDEX 12
|
||||
#define NGX_HTTP_V2_STATUS_404_INDEX 13
|
||||
#define NGX_HTTP_V2_STATUS_500_INDEX 14
|
||||
|
||||
#define NGX_HTTP_V2_ACCEPT_ENCODING_INDEX 16
|
||||
#define NGX_HTTP_V2_ACCEPT_LANGUAGE_INDEX 17
|
||||
#define NGX_HTTP_V2_CONTENT_LENGTH_INDEX 28
|
||||
#define NGX_HTTP_V2_CONTENT_TYPE_INDEX 31
|
||||
#define NGX_HTTP_V2_DATE_INDEX 33
|
||||
#define NGX_HTTP_V2_LAST_MODIFIED_INDEX 44
|
||||
#define NGX_HTTP_V2_LOCATION_INDEX 46
|
||||
#define NGX_HTTP_V2_SERVER_INDEX 54
|
||||
#define NGX_HTTP_V2_USER_AGENT_INDEX 58
|
||||
#define NGX_HTTP_V2_VARY_INDEX 59
|
||||
|
||||
#define NGX_HTTP_V2_NO_TRAILERS (ngx_http_v2_out_frame_t *) -1
|
||||
|
||||
|
|
@ -93,10 +56,6 @@ static ngx_int_t ngx_http_v2_push_resources(ngx_http_request_t *r);
|
|||
static ngx_int_t ngx_http_v2_push_resource(ngx_http_request_t *r,
|
||||
ngx_str_t *path, ngx_str_t *binary);
|
||||
|
||||
static u_char *ngx_http_v2_string_encode(u_char *dst, u_char *src, size_t len,
|
||||
u_char *tmp, ngx_uint_t lower);
|
||||
static u_char *ngx_http_v2_write_int(u_char *pos, ngx_uint_t prefix,
|
||||
ngx_uint_t value);
|
||||
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);
|
||||
static ngx_http_v2_out_frame_t *ngx_http_v2_create_push_frame(
|
||||
|
|
@ -177,7 +136,7 @@ ngx_http_v2_header_filter(ngx_http_request_t *r)
|
|||
u_char status, *pos, *start, *p, *tmp;
|
||||
size_t len, tmp_len;
|
||||
ngx_str_t host, location;
|
||||
ngx_uint_t i, port;
|
||||
ngx_uint_t i, port, fin;
|
||||
ngx_list_part_t *part;
|
||||
ngx_table_elt_t *header;
|
||||
ngx_connection_t *fc;
|
||||
|
|
@ -684,7 +643,10 @@ ngx_http_v2_header_filter(ngx_http_request_t *r)
|
|||
header[i].value.len, tmp);
|
||||
}
|
||||
|
||||
frame = ngx_http_v2_create_headers_frame(r, start, pos, r->header_only);
|
||||
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);
|
||||
if (frame == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
|
@ -1111,54 +1073,6 @@ ngx_http_v2_push_resource(ngx_http_request_t *r, ngx_str_t *path,
|
|||
}
|
||||
|
||||
|
||||
static u_char *
|
||||
ngx_http_v2_string_encode(u_char *dst, u_char *src, size_t len, u_char *tmp,
|
||||
ngx_uint_t lower)
|
||||
{
|
||||
size_t hlen;
|
||||
|
||||
hlen = ngx_http_v2_huff_encode(src, len, tmp, lower);
|
||||
|
||||
if (hlen > 0) {
|
||||
*dst = NGX_HTTP_V2_ENCODE_HUFF;
|
||||
dst = ngx_http_v2_write_int(dst, ngx_http_v2_prefix(7), hlen);
|
||||
return ngx_cpymem(dst, tmp, hlen);
|
||||
}
|
||||
|
||||
*dst = NGX_HTTP_V2_ENCODE_RAW;
|
||||
dst = ngx_http_v2_write_int(dst, ngx_http_v2_prefix(7), len);
|
||||
|
||||
if (lower) {
|
||||
ngx_strlow(dst, src, len);
|
||||
return dst + len;
|
||||
}
|
||||
|
||||
return ngx_cpymem(dst, src, len);
|
||||
}
|
||||
|
||||
|
||||
static u_char *
|
||||
ngx_http_v2_write_int(u_char *pos, ngx_uint_t prefix, ngx_uint_t value)
|
||||
{
|
||||
if (value < prefix) {
|
||||
*pos++ |= value;
|
||||
return pos;
|
||||
}
|
||||
|
||||
*pos++ |= prefix;
|
||||
value -= prefix;
|
||||
|
||||
while (value >= 128) {
|
||||
*pos++ = value % 128 + 128;
|
||||
value /= 128;
|
||||
}
|
||||
|
||||
*pos++ = (u_char) value;
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
|
|
@ -1255,9 +1169,9 @@ ngx_http_v2_create_headers_frame(ngx_http_request_t *r, u_char *pos,
|
|||
cl->next = NULL;
|
||||
frame->last = cl;
|
||||
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http2:%ui create HEADERS frame %p: len:%uz",
|
||||
stream->node->id, frame, frame->length);
|
||||
ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http2:%ui create HEADERS frame %p: len:%uz fin:%ui",
|
||||
stream->node->id, frame, frame->length, fin);
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
|
@ -1526,7 +1440,7 @@ ngx_http_v2_send_chain(ngx_connection_t *fc, ngx_chain_t *in, off_t limit)
|
|||
in = in->next;
|
||||
}
|
||||
|
||||
if (in == NULL) {
|
||||
if (in == NULL || stream->out_closed) {
|
||||
|
||||
if (stream->queued) {
|
||||
fc->write->active = 1;
|
||||
|
|
|
|||
|
|
@ -86,6 +86,20 @@ static ngx_http_v2_header_t ngx_http_v2_static_table[] = {
|
|||
/ sizeof(ngx_http_v2_header_t))
|
||||
|
||||
|
||||
ngx_str_t *
|
||||
ngx_http_v2_get_static_name(ngx_uint_t index)
|
||||
{
|
||||
return &ngx_http_v2_static_table[index - 1].name;
|
||||
}
|
||||
|
||||
|
||||
ngx_str_t *
|
||||
ngx_http_v2_get_static_value(ngx_uint_t index)
|
||||
{
|
||||
return &ngx_http_v2_static_table[index - 1].value;
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_v2_get_indexed_header(ngx_http_v2_connection_t *h2c, ngx_uint_t index,
|
||||
ngx_uint_t name_only)
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ ngx_freebsd_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
|
|||
if (ngx_freebsd_use_tcp_nopush
|
||||
&& c->tcp_nopush == NGX_TCP_NOPUSH_UNSET)
|
||||
{
|
||||
if (ngx_tcp_nopush(c->fd) == NGX_ERROR) {
|
||||
if (ngx_tcp_nopush(c->fd) == -1) {
|
||||
err = ngx_socket_errno;
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
|
|||
|
||||
if (c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) {
|
||||
|
||||
if (ngx_tcp_nopush(c->fd) == NGX_ERROR) {
|
||||
if (ngx_tcp_nopush(c->fd) == -1) {
|
||||
err = ngx_socket_errno;
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -341,18 +341,18 @@ ngx_stream_geo_addr(ngx_stream_session_t *s, ngx_stream_geo_ctx_t *ctx,
|
|||
static char *
|
||||
ngx_stream_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
char *rv;
|
||||
size_t len;
|
||||
ngx_str_t *value, name;
|
||||
ngx_uint_t i;
|
||||
ngx_conf_t save;
|
||||
ngx_pool_t *pool;
|
||||
ngx_array_t *a;
|
||||
ngx_stream_variable_t *var;
|
||||
ngx_stream_geo_ctx_t *geo;
|
||||
ngx_stream_geo_conf_ctx_t ctx;
|
||||
char *rv;
|
||||
size_t len;
|
||||
ngx_str_t *value, name;
|
||||
ngx_uint_t i;
|
||||
ngx_conf_t save;
|
||||
ngx_pool_t *pool;
|
||||
ngx_array_t *a;
|
||||
ngx_stream_variable_t *var;
|
||||
ngx_stream_geo_ctx_t *geo;
|
||||
ngx_stream_geo_conf_ctx_t ctx;
|
||||
#if (NGX_HAVE_INET6)
|
||||
static struct in6_addr zero;
|
||||
static struct in6_addr zero;
|
||||
#endif
|
||||
|
||||
value = cf->args->elts;
|
||||
|
|
@ -409,6 +409,7 @@ ngx_stream_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
ctx.temp_pool = ngx_create_pool(NGX_DEFAULT_POOL_SIZE, cf->log);
|
||||
if (ctx.temp_pool == NULL) {
|
||||
ngx_destroy_pool(pool);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
|
|
@ -430,6 +431,10 @@ ngx_stream_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
*cf = save;
|
||||
|
||||
if (rv != NGX_CONF_OK) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (ctx.ranges) {
|
||||
|
||||
if (ctx.high.low && !ctx.binary_include) {
|
||||
|
|
@ -449,7 +454,7 @@ ngx_stream_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
|
||||
ctx.high.low[i] = ngx_palloc(cf->pool, len + sizeof(void *));
|
||||
if (ctx.high.low[i] == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
ngx_memcpy(ctx.high.low[i], a->elts, len);
|
||||
|
|
@ -475,14 +480,11 @@ ngx_stream_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
var->get_handler = ngx_stream_geo_range_variable;
|
||||
var->data = (uintptr_t) geo;
|
||||
|
||||
ngx_destroy_pool(ctx.temp_pool);
|
||||
ngx_destroy_pool(pool);
|
||||
|
||||
} else {
|
||||
if (ctx.tree == NULL) {
|
||||
ctx.tree = ngx_radix_tree_create(cf->pool, -1);
|
||||
if (ctx.tree == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -492,7 +494,7 @@ ngx_stream_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
if (ctx.tree6 == NULL) {
|
||||
ctx.tree6 = ngx_radix_tree_create(cf->pool, -1);
|
||||
if (ctx.tree6 == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -502,14 +504,11 @@ ngx_stream_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
var->get_handler = ngx_stream_geo_cidr_variable;
|
||||
var->data = (uintptr_t) geo;
|
||||
|
||||
ngx_destroy_pool(ctx.temp_pool);
|
||||
ngx_destroy_pool(pool);
|
||||
|
||||
if (ngx_radix32tree_insert(ctx.tree, 0, 0,
|
||||
(uintptr_t) &ngx_stream_variable_null_value)
|
||||
== NGX_ERROR)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* NGX_BUSY is okay (default was set explicitly) */
|
||||
|
|
@ -519,12 +518,22 @@ ngx_stream_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||
(uintptr_t) &ngx_stream_variable_null_value)
|
||||
== NGX_ERROR)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
goto failed;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return rv;
|
||||
ngx_destroy_pool(ctx.temp_pool);
|
||||
ngx_destroy_pool(pool);
|
||||
|
||||
return NGX_CONF_OK;
|
||||
|
||||
failed:
|
||||
|
||||
ngx_destroy_pool(ctx.temp_pool);
|
||||
ngx_destroy_pool(pool);
|
||||
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -89,6 +89,11 @@ typedef struct {
|
|||
} ngx_stream_log_var_t;
|
||||
|
||||
|
||||
#define NGX_STREAM_LOG_ESCAPE_DEFAULT 0
|
||||
#define NGX_STREAM_LOG_ESCAPE_JSON 1
|
||||
#define NGX_STREAM_LOG_ESCAPE_NONE 2
|
||||
|
||||
|
||||
static void ngx_stream_log_write(ngx_stream_session_t *s, ngx_stream_log_t *log,
|
||||
u_char *buf, size_t len);
|
||||
static ssize_t ngx_stream_log_script_write(ngx_stream_session_t *s,
|
||||
|
|
@ -106,7 +111,7 @@ static void ngx_stream_log_flush(ngx_open_file_t *file, ngx_log_t *log);
|
|||
static void ngx_stream_log_flush_handler(ngx_event_t *ev);
|
||||
|
||||
static ngx_int_t ngx_stream_log_variable_compile(ngx_conf_t *cf,
|
||||
ngx_stream_log_op_t *op, ngx_str_t *value, ngx_uint_t json);
|
||||
ngx_stream_log_op_t *op, ngx_str_t *value, ngx_uint_t escape);
|
||||
static size_t ngx_stream_log_variable_getlen(ngx_stream_session_t *s,
|
||||
uintptr_t data);
|
||||
static u_char *ngx_stream_log_variable(ngx_stream_session_t *s, u_char *buf,
|
||||
|
|
@ -116,6 +121,10 @@ static size_t ngx_stream_log_json_variable_getlen(ngx_stream_session_t *s,
|
|||
uintptr_t data);
|
||||
static u_char *ngx_stream_log_json_variable(ngx_stream_session_t *s,
|
||||
u_char *buf, ngx_stream_log_op_t *op);
|
||||
static size_t ngx_stream_log_unescaped_variable_getlen(ngx_stream_session_t *s,
|
||||
uintptr_t data);
|
||||
static u_char *ngx_stream_log_unescaped_variable(ngx_stream_session_t *s,
|
||||
u_char *buf, ngx_stream_log_op_t *op);
|
||||
|
||||
|
||||
static void *ngx_stream_log_create_main_conf(ngx_conf_t *cf);
|
||||
|
|
@ -682,7 +691,7 @@ ngx_stream_log_copy_long(ngx_stream_session_t *s, u_char *buf,
|
|||
|
||||
static ngx_int_t
|
||||
ngx_stream_log_variable_compile(ngx_conf_t *cf, ngx_stream_log_op_t *op,
|
||||
ngx_str_t *value, ngx_uint_t json)
|
||||
ngx_str_t *value, ngx_uint_t escape)
|
||||
{
|
||||
ngx_int_t index;
|
||||
|
||||
|
|
@ -693,11 +702,18 @@ ngx_stream_log_variable_compile(ngx_conf_t *cf, ngx_stream_log_op_t *op,
|
|||
|
||||
op->len = 0;
|
||||
|
||||
if (json) {
|
||||
switch (escape) {
|
||||
case NGX_STREAM_LOG_ESCAPE_JSON:
|
||||
op->getlen = ngx_stream_log_json_variable_getlen;
|
||||
op->run = ngx_stream_log_json_variable;
|
||||
break;
|
||||
|
||||
} else {
|
||||
case NGX_STREAM_LOG_ESCAPE_NONE:
|
||||
op->getlen = ngx_stream_log_unescaped_variable_getlen;
|
||||
op->run = ngx_stream_log_unescaped_variable;
|
||||
break;
|
||||
|
||||
default: /* NGX_STREAM_LOG_ESCAPE_DEFAULT */
|
||||
op->getlen = ngx_stream_log_variable_getlen;
|
||||
op->run = ngx_stream_log_variable;
|
||||
}
|
||||
|
|
@ -851,6 +867,40 @@ ngx_stream_log_json_variable(ngx_stream_session_t *s, u_char *buf,
|
|||
}
|
||||
|
||||
|
||||
static size_t
|
||||
ngx_stream_log_unescaped_variable_getlen(ngx_stream_session_t *s,
|
||||
uintptr_t data)
|
||||
{
|
||||
ngx_stream_variable_value_t *value;
|
||||
|
||||
value = ngx_stream_get_indexed_variable(s, data);
|
||||
|
||||
if (value == NULL || value->not_found) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
value->escape = 0;
|
||||
|
||||
return value->len;
|
||||
}
|
||||
|
||||
|
||||
static u_char *
|
||||
ngx_stream_log_unescaped_variable(ngx_stream_session_t *s, u_char *buf,
|
||||
ngx_stream_log_op_t *op)
|
||||
{
|
||||
ngx_stream_variable_value_t *value;
|
||||
|
||||
value = ngx_stream_get_indexed_variable(s, op->data);
|
||||
|
||||
if (value == NULL || value->not_found) {
|
||||
return buf;
|
||||
}
|
||||
|
||||
return ngx_cpymem(buf, value->data, value->len);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ngx_stream_log_create_main_conf(ngx_conf_t *cf)
|
||||
{
|
||||
|
|
@ -1265,17 +1315,20 @@ ngx_stream_log_compile_format(ngx_conf_t *cf, ngx_array_t *flushes,
|
|||
size_t i, len;
|
||||
ngx_str_t *value, var;
|
||||
ngx_int_t *flush;
|
||||
ngx_uint_t bracket, json;
|
||||
ngx_uint_t bracket, escape;
|
||||
ngx_stream_log_op_t *op;
|
||||
|
||||
json = 0;
|
||||
escape = NGX_STREAM_LOG_ESCAPE_DEFAULT;
|
||||
value = args->elts;
|
||||
|
||||
if (s < args->nelts && ngx_strncmp(value[s].data, "escape=", 7) == 0) {
|
||||
data = value[s].data + 7;
|
||||
|
||||
if (ngx_strcmp(data, "json") == 0) {
|
||||
json = 1;
|
||||
escape = NGX_STREAM_LOG_ESCAPE_JSON;
|
||||
|
||||
} else if (ngx_strcmp(data, "none") == 0) {
|
||||
escape = NGX_STREAM_LOG_ESCAPE_NONE;
|
||||
|
||||
} else if (ngx_strcmp(data, "default") != 0) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
|
|
@ -1350,7 +1403,7 @@ ngx_stream_log_compile_format(ngx_conf_t *cf, ngx_array_t *flushes,
|
|||
goto invalid;
|
||||
}
|
||||
|
||||
if (ngx_stream_log_variable_compile(cf, op, &var, json)
|
||||
if (ngx_stream_log_variable_compile(cf, op, &var, escape)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_CONF_ERROR;
|
||||
|
|
|
|||
|
|
@ -17,10 +17,12 @@ typedef struct {
|
|||
typedef struct {
|
||||
size_t left;
|
||||
size_t size;
|
||||
size_t ext;
|
||||
u_char *pos;
|
||||
u_char *dst;
|
||||
u_char buf[4];
|
||||
ngx_str_t host;
|
||||
ngx_str_t alpn;
|
||||
ngx_log_t *log;
|
||||
ngx_pool_t *pool;
|
||||
ngx_uint_t state;
|
||||
|
|
@ -32,6 +34,8 @@ static ngx_int_t ngx_stream_ssl_preread_parse_record(
|
|||
ngx_stream_ssl_preread_ctx_t *ctx, u_char *pos, u_char *last);
|
||||
static ngx_int_t ngx_stream_ssl_preread_server_name_variable(
|
||||
ngx_stream_session_t *s, ngx_stream_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_stream_ssl_preread_alpn_protocols_variable(
|
||||
ngx_stream_session_t *s, ngx_stream_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_stream_ssl_preread_add_variables(ngx_conf_t *cf);
|
||||
static void *ngx_stream_ssl_preread_create_srv_conf(ngx_conf_t *cf);
|
||||
static char *ngx_stream_ssl_preread_merge_srv_conf(ngx_conf_t *cf, void *parent,
|
||||
|
|
@ -85,6 +89,9 @@ static ngx_stream_variable_t ngx_stream_ssl_preread_vars[] = {
|
|||
{ ngx_string("ssl_preread_server_name"), NULL,
|
||||
ngx_stream_ssl_preread_server_name_variable, 0, 0, 0 },
|
||||
|
||||
{ ngx_string("ssl_preread_alpn_protocols"), NULL,
|
||||
ngx_stream_ssl_preread_alpn_protocols_variable, 0, 0, 0 },
|
||||
|
||||
ngx_stream_null_variable
|
||||
};
|
||||
|
||||
|
|
@ -139,12 +146,14 @@ ngx_stream_ssl_preread_handler(ngx_stream_session_t *s)
|
|||
if (p[0] != 0x16) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_STREAM, ctx->log, 0,
|
||||
"ssl preread: not a handshake");
|
||||
ngx_stream_set_ctx(s, NULL, ngx_stream_ssl_preread_module);
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
if (p[1] != 3) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_STREAM, ctx->log, 0,
|
||||
"ssl preread: unsupported SSL version");
|
||||
ngx_stream_set_ctx(s, NULL, ngx_stream_ssl_preread_module);
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
|
|
@ -158,6 +167,12 @@ ngx_stream_ssl_preread_handler(ngx_stream_session_t *s)
|
|||
p += 5;
|
||||
|
||||
rc = ngx_stream_ssl_preread_parse_record(ctx, p, p + len);
|
||||
|
||||
if (rc == NGX_DECLINED) {
|
||||
ngx_stream_set_ctx(s, NULL, ngx_stream_ssl_preread_module);
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
if (rc != NGX_AGAIN) {
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -175,7 +190,7 @@ static ngx_int_t
|
|||
ngx_stream_ssl_preread_parse_record(ngx_stream_ssl_preread_ctx_t *ctx,
|
||||
u_char *pos, u_char *last)
|
||||
{
|
||||
size_t left, n, size;
|
||||
size_t left, n, size, ext;
|
||||
u_char *dst, *p;
|
||||
|
||||
enum {
|
||||
|
|
@ -192,7 +207,10 @@ ngx_stream_ssl_preread_parse_record(ngx_stream_ssl_preread_ctx_t *ctx,
|
|||
sw_ext_header, /* extension_type, extension_data length */
|
||||
sw_sni_len, /* SNI length */
|
||||
sw_sni_host_head, /* SNI name_type, host_name length */
|
||||
sw_sni_host /* SNI host_name */
|
||||
sw_sni_host, /* SNI host_name */
|
||||
sw_alpn_len, /* ALPN length */
|
||||
sw_alpn_proto_len, /* ALPN protocol_name length */
|
||||
sw_alpn_proto_data /* ALPN protocol_name */
|
||||
} state;
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_STREAM, ctx->log, 0,
|
||||
|
|
@ -201,6 +219,7 @@ ngx_stream_ssl_preread_parse_record(ngx_stream_ssl_preread_ctx_t *ctx,
|
|||
state = ctx->state;
|
||||
size = ctx->size;
|
||||
left = ctx->left;
|
||||
ext = ctx->ext;
|
||||
dst = ctx->dst;
|
||||
p = ctx->buf;
|
||||
|
||||
|
|
@ -299,10 +318,18 @@ ngx_stream_ssl_preread_parse_record(ngx_stream_ssl_preread_ctx_t *ctx,
|
|||
break;
|
||||
|
||||
case sw_ext_header:
|
||||
if (p[0] == 0 && p[1] == 0) {
|
||||
if (p[0] == 0 && p[1] == 0 && ctx->host.data == NULL) {
|
||||
/* SNI extension */
|
||||
state = sw_sni_len;
|
||||
dst = NULL;
|
||||
dst = p;
|
||||
size = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (p[0] == 0 && p[1] == 16 && ctx->alpn.data == NULL) {
|
||||
/* ALPN extension */
|
||||
state = sw_alpn_len;
|
||||
dst = p;
|
||||
size = 2;
|
||||
break;
|
||||
}
|
||||
|
|
@ -313,6 +340,7 @@ ngx_stream_ssl_preread_parse_record(ngx_stream_ssl_preread_ctx_t *ctx,
|
|||
break;
|
||||
|
||||
case sw_sni_len:
|
||||
ext = (p[0] << 8) + p[1];
|
||||
state = sw_sni_host_head;
|
||||
dst = p;
|
||||
size = 3;
|
||||
|
|
@ -325,14 +353,21 @@ ngx_stream_ssl_preread_parse_record(ngx_stream_ssl_preread_ctx_t *ctx,
|
|||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
state = sw_sni_host;
|
||||
size = (p[1] << 8) + p[2];
|
||||
|
||||
if (ext < 3 + size) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_STREAM, ctx->log, 0,
|
||||
"ssl preread: SNI format error");
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
ext -= 3 + size;
|
||||
|
||||
ctx->host.data = ngx_pnalloc(ctx->pool, size);
|
||||
if (ctx->host.data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
state = sw_sni_host;
|
||||
dst = ctx->host.data;
|
||||
break;
|
||||
|
||||
|
|
@ -341,19 +376,77 @@ ngx_stream_ssl_preread_parse_record(ngx_stream_ssl_preread_ctx_t *ctx,
|
|||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_STREAM, ctx->log, 0,
|
||||
"ssl preread: SNI hostname \"%V\"", &ctx->host);
|
||||
return NGX_OK;
|
||||
|
||||
state = sw_ext;
|
||||
dst = NULL;
|
||||
size = ext;
|
||||
break;
|
||||
|
||||
case sw_alpn_len:
|
||||
ext = (p[0] << 8) + p[1];
|
||||
|
||||
ctx->alpn.data = ngx_pnalloc(ctx->pool, ext);
|
||||
if (ctx->alpn.data == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
state = sw_alpn_proto_len;
|
||||
dst = p;
|
||||
size = 1;
|
||||
break;
|
||||
|
||||
case sw_alpn_proto_len:
|
||||
size = p[0];
|
||||
|
||||
if (size == 0) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_STREAM, ctx->log, 0,
|
||||
"ssl preread: ALPN empty protocol");
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
if (ext < 1 + size) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_STREAM, ctx->log, 0,
|
||||
"ssl preread: ALPN format error");
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
ext -= 1 + size;
|
||||
|
||||
state = sw_alpn_proto_data;
|
||||
dst = ctx->alpn.data + ctx->alpn.len;
|
||||
break;
|
||||
|
||||
case sw_alpn_proto_data:
|
||||
ctx->alpn.len += p[0];
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_STREAM, ctx->log, 0,
|
||||
"ssl preread: ALPN protocols \"%V\"", &ctx->alpn);
|
||||
|
||||
if (ext) {
|
||||
ctx->alpn.data[ctx->alpn.len++] = ',';
|
||||
|
||||
state = sw_alpn_proto_len;
|
||||
dst = p;
|
||||
size = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
state = sw_ext;
|
||||
dst = NULL;
|
||||
size = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (left < size) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_STREAM, ctx->log, 0,
|
||||
"ssl preread: failed to parse handshake");
|
||||
return NGX_DECLINED;
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_STREAM, ctx->log, 0,
|
||||
"ssl preread: failed to parse handshake");
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
}
|
||||
|
||||
ctx->state = state;
|
||||
ctx->size = size;
|
||||
ctx->left = left;
|
||||
ctx->ext = ext;
|
||||
ctx->dst = dst;
|
||||
|
||||
return NGX_AGAIN;
|
||||
|
|
@ -383,6 +476,29 @@ ngx_stream_ssl_preread_server_name_variable(ngx_stream_session_t *s,
|
|||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_stream_ssl_preread_alpn_protocols_variable(ngx_stream_session_t *s,
|
||||
ngx_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
ngx_stream_ssl_preread_ctx_t *ctx;
|
||||
|
||||
ctx = ngx_stream_get_module_ctx(s, ngx_stream_ssl_preread_module);
|
||||
|
||||
if (ctx == NULL) {
|
||||
v->not_found = 1;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
v->valid = 1;
|
||||
v->no_cacheable = 0;
|
||||
v->not_found = 0;
|
||||
v->len = ctx->alpn.len;
|
||||
v->data = ctx->alpn.data;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_stream_ssl_preread_add_variables(ngx_conf_t *cf)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -161,7 +161,9 @@ ngx_stream_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
v->flags &= flags | ~NGX_STREAM_VAR_WEAK;
|
||||
if (!(flags & NGX_STREAM_VAR_WEAK)) {
|
||||
v->flags &= ~NGX_STREAM_VAR_WEAK;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
|
@ -227,7 +229,9 @@ ngx_stream_add_prefix_variable(ngx_conf_t *cf, ngx_str_t *name,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
v->flags &= flags | ~NGX_STREAM_VAR_WEAK;
|
||||
if (!(flags & NGX_STREAM_VAR_WEAK)) {
|
||||
v->flags &= ~NGX_STREAM_VAR_WEAK;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue