Compare commits
14
Commits
da1c2b041b
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
008819315c
|
||
|
|
677450910d
|
||
|
|
d23cd2f0e0
|
||
|
|
72680e2bd2
|
||
|
|
10689fcf23
|
||
|
|
c8ca86a8d2
|
||
|
|
9b69c0a792
|
||
|
|
38112b0b03
|
||
|
|
8407b245de
|
||
|
|
cdf4d451e4
|
||
|
|
141b7448a4
|
||
|
|
b54c866079
|
||
|
|
f1c30863fd
|
||
|
|
d3a0c6f60b
|
@@ -450,3 +450,5 @@ fdacd273711ddf20f778c1fb91529ab53979a454 release-1.17.8
|
|||||||
5e8d52bca714d4b85284ddb649d1ba4a3ca978a8 release-1.17.9
|
5e8d52bca714d4b85284ddb649d1ba4a3ca978a8 release-1.17.9
|
||||||
c44970de01474f6f3e01b0adea85ec1d03e3a5f2 release-1.17.10
|
c44970de01474f6f3e01b0adea85ec1d03e3a5f2 release-1.17.10
|
||||||
cbe6ba650211541310618849168631ce0b788f35 release-1.19.0
|
cbe6ba650211541310618849168631ce0b788f35 release-1.19.0
|
||||||
|
062920e2f3bf871ef7a3d8496edec1b3065faf80 release-1.19.1
|
||||||
|
a7b46539f507e6c64efa0efda69ad60b6f4ffbce release-1.19.2
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
# Hakase-nginx
|
# Hakase-nginx
|
||||||
**My nginx build files.**
|
**My nginx build files.**
|
||||||
|
|
||||||
|
## This repository is no longer operational. Use an alternative such as tengine.
|
||||||
|
|
||||||
Example Web Server - [https://ssl.haka.se/](https://ssl.haka.se/)
|
Example Web Server - [https://ssl.haka.se/](https://ssl.haka.se/)
|
||||||
|
|
||||||
## Please install dependency library.
|
## Please install dependency library.
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ if [ "$VTS" = 1 ]; then BUILD_MODULES="${BUILD_MODULES} --add-module=./lib/nginx
|
|||||||
auto/configure \
|
auto/configure \
|
||||||
--with-cc-opt="-Wno-stringop-truncation -DTCP_FASTOPEN=23 ${BUILD_BIT}${BUILD_LTO} ${TEMP_OPT} -g -O3 -march=native -fstack-protector-strong -fuse-ld=gold -fuse-linker-plugin --param=ssp-buffer-size=4 -Wformat -Werror=format-security -Wno-strict-aliasing -Wp,-D_FORTIFY_SOURCE=2 -gsplit-dwarf -DNGX_HTTP_HEADERS" \
|
--with-cc-opt="-Wno-stringop-truncation -DTCP_FASTOPEN=23 ${BUILD_BIT}${BUILD_LTO} ${TEMP_OPT} -g -O3 -march=native -fstack-protector-strong -fuse-ld=gold -fuse-linker-plugin --param=ssp-buffer-size=4 -Wformat -Werror=format-security -Wno-strict-aliasing -Wp,-D_FORTIFY_SOURCE=2 -gsplit-dwarf -DNGX_HTTP_HEADERS" \
|
||||||
--with-ld-opt="${BUILD_LD} ${BUILD_LTO}" \
|
--with-ld-opt="${BUILD_LD} ${BUILD_LTO}" \
|
||||||
--with-openssl-opt="enable-weak-ssl-ciphers no-ssl3-method -march=native -ljemalloc ${BUILD_OPENSSL_LTO}" \
|
--with-openssl-opt="no-cmp enable-weak-ssl-ciphers no-ssl3-method -march=native -ljemalloc ${BUILD_OPENSSL_LTO}" \
|
||||||
--builddir=objs --prefix=${NGX_PREFIX} \
|
--builddir=objs --prefix=${NGX_PREFIX} \
|
||||||
--conf-path=${NGX_CONF} \
|
--conf-path=${NGX_CONF} \
|
||||||
--pid-path=${NGX_PID} \
|
--pid-path=${NGX_PID} \
|
||||||
|
|||||||
@@ -5,6 +5,232 @@
|
|||||||
<change_log title="nginx">
|
<change_log title="nginx">
|
||||||
|
|
||||||
|
|
||||||
|
<changes ver="1.19.2" date="2020-08-11">
|
||||||
|
|
||||||
|
<change type="change">
|
||||||
|
<para lang="ru">
|
||||||
|
теперь nginx начинает закрывать keepalive-соединения,
|
||||||
|
не дожидаясь исчерпания всех свободных соединений,
|
||||||
|
а также пишет об этом предупреждение в лог ошибок.
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
now nginx starts closing keepalive connections
|
||||||
|
before all free worker connections are exhausted,
|
||||||
|
and logs a warning about this to the error log.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
|
<change type="change">
|
||||||
|
<para lang="ru">
|
||||||
|
оптимизация чтения тела запроса
|
||||||
|
при использовании chunked transfer encoding.
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
optimization of client request body reading
|
||||||
|
when using chunked transfer encoding.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
|
<change type="bugfix">
|
||||||
|
<para lang="ru">
|
||||||
|
утечки памяти при использовании директивы ssl_ocsp.
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
memory leak if the "ssl_ocsp" directive was used.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
|
<change type="bugfix">
|
||||||
|
<para lang="ru">
|
||||||
|
в логах могли появляться сообщения "zero size buf in output",
|
||||||
|
если FastCGI-сервер возвращал некорректный ответ;
|
||||||
|
ошибка появилась в 1.19.1.
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
"zero size buf in output" alerts might appear in logs
|
||||||
|
if a FastCGI server returned an incorrect response;
|
||||||
|
the bug had appeared in 1.19.1.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
|
<change type="bugfix">
|
||||||
|
<para lang="ru">
|
||||||
|
в рабочем процессе мог произойти segmentation fault,
|
||||||
|
если размеры large_client_header_buffers отличались
|
||||||
|
в разных виртуальных серверах.
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
a segmentation fault might occur in a worker process
|
||||||
|
if different large_client_header_buffers sizes were used
|
||||||
|
in different virtual servers.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
|
<change type="bugfix">
|
||||||
|
<para lang="ru">
|
||||||
|
SSL shutdown мог не работать.
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
SSL shutdown might not work.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
|
<change type="bugfix">
|
||||||
|
<para lang="ru">
|
||||||
|
в логах могли появляться сообщения
|
||||||
|
"SSL_shutdown() failed (SSL: ... bad write retry)".
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
"SSL_shutdown() failed (SSL: ... bad write retry)"
|
||||||
|
messages might appear in logs.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
|
<change type="bugfix">
|
||||||
|
<para lang="ru">
|
||||||
|
в модуле ngx_http_slice_module.
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
in the ngx_http_slice_module.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
|
<change type="bugfix">
|
||||||
|
<para lang="ru">
|
||||||
|
в модуле ngx_http_xslt_filter_module.
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
in the ngx_http_xslt_filter_module.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
|
</changes>
|
||||||
|
|
||||||
|
|
||||||
|
<changes ver="1.19.1" date="2020-07-07">
|
||||||
|
|
||||||
|
<change type="change">
|
||||||
|
<para lang="ru">
|
||||||
|
директивы lingering_close, lingering_time и lingering_timeout
|
||||||
|
теперь работают при использовании HTTP/2.
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
the "lingering_close", "lingering_time", and "lingering_timeout" directives
|
||||||
|
now work when using HTTP/2.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
|
<change type="change">
|
||||||
|
<para lang="ru">
|
||||||
|
теперь лишние данные, присланные бэкендом, всегда отбрасываются.
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
now extra data sent by a backend are always discarded.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
|
<change type="change">
|
||||||
|
<para lang="ru">
|
||||||
|
теперь при получении слишком короткого ответа от FastCGI-сервера
|
||||||
|
nginx пытается отправить клиенту доступную часть ответа,
|
||||||
|
после чего закрывает соединение с клиентом.
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
now after receiving a too short response from a FastCGI server
|
||||||
|
nginx tries to send the available part of the response to the client,
|
||||||
|
and then closes the client connection.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
|
<change type="change">
|
||||||
|
<para lang="ru">
|
||||||
|
теперь при получении ответа некорректной длины от gRPC-бэкенда
|
||||||
|
nginx прекращает обработку ответа с ошибкой.
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
now after receiving a response with incorrect length from a gRPC backend
|
||||||
|
nginx stops response processing with an error.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
|
<change type="feature">
|
||||||
|
<para lang="ru">
|
||||||
|
параметр min_free в директивах proxy_cache_path, fastcgi_cache_path,
|
||||||
|
scgi_cache_path и uwsgi_cache_path.<br/>
|
||||||
|
Спасибо Adam Bambuch.
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
the "min_free" parameter of the "proxy_cache_path", "fastcgi_cache_path",
|
||||||
|
"scgi_cache_path", and "uwsgi_cache_path" directives.<br/>
|
||||||
|
Thanks to Adam Bambuch.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
|
<change type="bugfix">
|
||||||
|
<para lang="ru">
|
||||||
|
nginx не удалял unix domain listen-сокеты
|
||||||
|
при плавном завершении по сигналу SIGQUIT.
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
nginx did not delete unix domain listen sockets
|
||||||
|
during graceful shutdown on the SIGQUIT signal.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
|
<change type="bugfix">
|
||||||
|
<para lang="ru">
|
||||||
|
UDP-пакеты нулевого размера не проксировались.
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
zero length UDP datagrams were not proxied.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
|
<change type="bugfix">
|
||||||
|
<para lang="ru">
|
||||||
|
проксирование на uwsgi-бэкенды с использованием SSL могло не работать.<br/>
|
||||||
|
Спасибо Guanzhong Chen.
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
proxying to uwsgi backends using SSL might not work.<br/>
|
||||||
|
Thanks to Guanzhong Chen.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
|
<change type="bugfix">
|
||||||
|
<para lang="ru">
|
||||||
|
в обработке ошибок при использовании директивы ssl_ocsp.
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
in error handling when using the "ssl_ocsp" directive.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
|
<change type="bugfix">
|
||||||
|
<para lang="ru">
|
||||||
|
при использовании файловых систем XFS и NFS
|
||||||
|
размер кэша на диске мог считаться некорректно.
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
on XFS and NFS file systems
|
||||||
|
disk cache size might be calculated incorrectly.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
|
<change type="bugfix">
|
||||||
|
<para lang="ru">
|
||||||
|
если сервер memcached возвращал некорректный ответ,
|
||||||
|
в логах могли появляться сообщения "negative size buf in writer".
|
||||||
|
</para>
|
||||||
|
<para lang="en">
|
||||||
|
"negative size buf in writer" alerts might appear in logs
|
||||||
|
if a memcached server returned a malformed response.
|
||||||
|
</para>
|
||||||
|
</change>
|
||||||
|
|
||||||
|
</changes>
|
||||||
|
|
||||||
|
|
||||||
<changes ver="1.19.0" date="2020-05-26">
|
<changes ver="1.19.0" date="2020-05-26">
|
||||||
|
|
||||||
<change type="feature">
|
<change type="feature">
|
||||||
|
|||||||
Submodule lib/headers-more-nginx-module updated: 743a4bb1a2...d6d7ebab3c
+1
-1
Submodule lib/naxsi updated: 15e58c3385...312f912797
Submodule lib/nginx-http-flv-module updated: 34e8b7dfe9...13be96d72d
+1
-1
Submodule lib/ngx-fancyindex updated: 11101de198...56934db14c
+1
-1
Submodule lib/openssl updated: 3a6d64bb68...e85ee33eee
+1
-1
Submodule lib/zlib updated: 372bcd151c...ab50ae879a
@@ -492,6 +492,7 @@ ngx_add_inherited_sockets(ngx_cycle_t *cycle)
|
|||||||
ngx_memzero(ls, sizeof(ngx_listening_t));
|
ngx_memzero(ls, sizeof(ngx_listening_t));
|
||||||
|
|
||||||
ls->fd = (ngx_socket_t) s;
|
ls->fd = (ngx_socket_t) s;
|
||||||
|
ls->inherited = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -9,8 +9,8 @@
|
|||||||
#define _NGINX_H_INCLUDED_
|
#define _NGINX_H_INCLUDED_
|
||||||
|
|
||||||
|
|
||||||
#define nginx_version 1019001
|
#define nginx_version 1019003
|
||||||
#define NGINX_VERSION "1.19.1"
|
#define NGINX_VERSION "1.19.3"
|
||||||
#define NGINX_VER "nginx/" NGINX_VERSION " by Hakase"
|
#define NGINX_VER "nginx/" NGINX_VERSION " by Hakase"
|
||||||
|
|
||||||
#ifndef NGINX_SERVER
|
#ifndef NGINX_SERVER
|
||||||
|
|||||||
+10
-10
@@ -125,20 +125,20 @@ typedef struct {
|
|||||||
#define NGX_CHAIN_ERROR (ngx_chain_t *) NGX_ERROR
|
#define NGX_CHAIN_ERROR (ngx_chain_t *) NGX_ERROR
|
||||||
|
|
||||||
|
|
||||||
#define ngx_buf_in_memory(b) (b->temporary || b->memory || b->mmap)
|
#define ngx_buf_in_memory(b) ((b)->temporary || (b)->memory || (b)->mmap)
|
||||||
#define ngx_buf_in_memory_only(b) (ngx_buf_in_memory(b) && !b->in_file)
|
#define ngx_buf_in_memory_only(b) (ngx_buf_in_memory(b) && !(b)->in_file)
|
||||||
|
|
||||||
#define ngx_buf_special(b) \
|
#define ngx_buf_special(b) \
|
||||||
((b->flush || b->last_buf || b->sync) \
|
(((b)->flush || (b)->last_buf || (b)->sync) \
|
||||||
&& !ngx_buf_in_memory(b) && !b->in_file)
|
&& !ngx_buf_in_memory(b) && !(b)->in_file)
|
||||||
|
|
||||||
#define ngx_buf_sync_only(b) \
|
#define ngx_buf_sync_only(b) \
|
||||||
(b->sync \
|
((b)->sync && !ngx_buf_in_memory(b) \
|
||||||
&& !ngx_buf_in_memory(b) && !b->in_file && !b->flush && !b->last_buf)
|
&& !(b)->in_file && !(b)->flush && !(b)->last_buf)
|
||||||
|
|
||||||
#define ngx_buf_size(b) \
|
#define ngx_buf_size(b) \
|
||||||
(ngx_buf_in_memory(b) ? (off_t) (b->last - b->pos): \
|
(ngx_buf_in_memory(b) ? (off_t) ((b)->last - (b)->pos): \
|
||||||
(b->file_last - b->file_pos))
|
((b)->file_last - (b)->file_pos))
|
||||||
|
|
||||||
ngx_buf_t *ngx_create_temp_buf(ngx_pool_t *pool, size_t size);
|
ngx_buf_t *ngx_create_temp_buf(ngx_pool_t *pool, size_t size);
|
||||||
ngx_chain_t *ngx_create_chain_of_bufs(ngx_pool_t *pool, ngx_bufs_t *bufs);
|
ngx_chain_t *ngx_create_chain_of_bufs(ngx_pool_t *pool, ngx_bufs_t *bufs);
|
||||||
@@ -149,8 +149,8 @@ ngx_chain_t *ngx_create_chain_of_bufs(ngx_pool_t *pool, ngx_bufs_t *bufs);
|
|||||||
|
|
||||||
ngx_chain_t *ngx_alloc_chain_link(ngx_pool_t *pool);
|
ngx_chain_t *ngx_alloc_chain_link(ngx_pool_t *pool);
|
||||||
#define ngx_free_chain(pool, cl) \
|
#define ngx_free_chain(pool, cl) \
|
||||||
cl->next = pool->chain; \
|
(cl)->next = (pool)->chain; \
|
||||||
pool->chain = cl
|
(pool)->chain = (cl)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1070,7 +1070,8 @@ ngx_close_listening_sockets(ngx_cycle_t *cycle)
|
|||||||
|
|
||||||
if (ls[i].sockaddr->sa_family == AF_UNIX
|
if (ls[i].sockaddr->sa_family == AF_UNIX
|
||||||
&& ngx_process <= NGX_PROCESS_MASTER
|
&& ngx_process <= NGX_PROCESS_MASTER
|
||||||
&& ngx_new_binary == 0)
|
&& ngx_new_binary == 0
|
||||||
|
&& (!ls[i].inherited || ngx_getppid() != ngx_parent))
|
||||||
{
|
{
|
||||||
u_char *name = ls[i].addr_text.data + sizeof("unix:") - 1;
|
u_char *name = ls[i].addr_text.data + sizeof("unix:") - 1;
|
||||||
|
|
||||||
@@ -1106,12 +1107,9 @@ ngx_get_connection(ngx_socket_t s, ngx_log_t *log)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
c = ngx_cycle->free_connections;
|
ngx_drain_connections((ngx_cycle_t *) ngx_cycle);
|
||||||
|
|
||||||
if (c == NULL) {
|
c = ngx_cycle->free_connections;
|
||||||
ngx_drain_connections((ngx_cycle_t *) ngx_cycle);
|
|
||||||
c = ngx_cycle->free_connections;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c == NULL) {
|
if (c == NULL) {
|
||||||
ngx_log_error(NGX_LOG_ALERT, log, 0,
|
ngx_log_error(NGX_LOG_ALERT, log, 0,
|
||||||
@@ -1297,6 +1295,21 @@ ngx_drain_connections(ngx_cycle_t *cycle)
|
|||||||
ngx_queue_t *q;
|
ngx_queue_t *q;
|
||||||
ngx_connection_t *c;
|
ngx_connection_t *c;
|
||||||
|
|
||||||
|
if (cycle->free_connection_n > cycle->connection_n / 16
|
||||||
|
|| cycle->reusable_connections_n == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cycle->connections_reuse_time != ngx_time()) {
|
||||||
|
cycle->connections_reuse_time = ngx_time();
|
||||||
|
|
||||||
|
ngx_log_error(NGX_LOG_WARN, cycle->log, 0,
|
||||||
|
"%ui worker_connections are not enough, "
|
||||||
|
"reusing connections",
|
||||||
|
cycle->connection_n);
|
||||||
|
}
|
||||||
|
|
||||||
n = ngx_max(ngx_min(32, cycle->reusable_connections_n / 8), 1);
|
n = ngx_max(ngx_min(32, cycle->reusable_connections_n / 8), 1);
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
|
|||||||
@@ -520,6 +520,7 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
|
|||||||
== NGX_OK)
|
== NGX_OK)
|
||||||
{
|
{
|
||||||
nls[n].fd = ls[i].fd;
|
nls[n].fd = ls[i].fd;
|
||||||
|
nls[n].inherited = ls[i].inherited;
|
||||||
nls[n].previous = &ls[i];
|
nls[n].previous = &ls[i];
|
||||||
ls[i].remain = 1;
|
ls[i].remain = 1;
|
||||||
|
|
||||||
@@ -1008,6 +1009,7 @@ ngx_int_t
|
|||||||
ngx_create_pidfile(ngx_str_t *name, ngx_log_t *log)
|
ngx_create_pidfile(ngx_str_t *name, ngx_log_t *log)
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
|
ngx_int_t rc;
|
||||||
ngx_uint_t create;
|
ngx_uint_t create;
|
||||||
ngx_file_t file;
|
ngx_file_t file;
|
||||||
u_char pid[NGX_INT64_LEN + 2];
|
u_char pid[NGX_INT64_LEN + 2];
|
||||||
@@ -1032,11 +1034,13 @@ ngx_create_pidfile(ngx_str_t *name, ngx_log_t *log)
|
|||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rc = NGX_OK;
|
||||||
|
|
||||||
if (!ngx_test_config) {
|
if (!ngx_test_config) {
|
||||||
len = ngx_snprintf(pid, NGX_INT64_LEN + 2, "%P%N", ngx_pid) - pid;
|
len = ngx_snprintf(pid, NGX_INT64_LEN + 2, "%P%N", ngx_pid) - pid;
|
||||||
|
|
||||||
if (ngx_write_file(&file, pid, len, 0) == NGX_ERROR) {
|
if (ngx_write_file(&file, pid, len, 0) == NGX_ERROR) {
|
||||||
return NGX_ERROR;
|
rc = NGX_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1045,7 +1049,7 @@ ngx_create_pidfile(ngx_str_t *name, ngx_log_t *log)
|
|||||||
ngx_close_file_n " \"%s\" failed", file.name.data);
|
ngx_close_file_n " \"%s\" failed", file.name.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NGX_OK;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ struct ngx_cycle_s {
|
|||||||
|
|
||||||
ngx_queue_t reusable_connections_queue;
|
ngx_queue_t reusable_connections_queue;
|
||||||
ngx_uint_t reusable_connections_n;
|
ngx_uint_t reusable_connections_n;
|
||||||
|
time_t connections_reuse_time;
|
||||||
|
|
||||||
ngx_array_t listening;
|
ngx_array_t listening;
|
||||||
ngx_array_t paths;
|
ngx_array_t paths;
|
||||||
|
|||||||
@@ -928,6 +928,9 @@ ngx_int_t
|
|||||||
ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
|
ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
|
||||||
ngx_int_t depth)
|
ngx_int_t depth)
|
||||||
{
|
{
|
||||||
|
SSL_CTX_set_verify(ssl->ctx, SSL_CTX_get_verify_mode(ssl->ctx),
|
||||||
|
ngx_ssl_verify_callback);
|
||||||
|
|
||||||
SSL_CTX_set_verify_depth(ssl->ctx, depth);
|
SSL_CTX_set_verify_depth(ssl->ctx, depth);
|
||||||
|
|
||||||
if (cert->len == 0) {
|
if (cert->len == 0) {
|
||||||
@@ -2818,8 +2821,9 @@ ngx_ssl_free_buffer(ngx_connection_t *c)
|
|||||||
ngx_int_t
|
ngx_int_t
|
||||||
ngx_ssl_shutdown(ngx_connection_t *c)
|
ngx_ssl_shutdown(ngx_connection_t *c)
|
||||||
{
|
{
|
||||||
int n, sslerr, mode;
|
int n, sslerr, mode;
|
||||||
ngx_err_t err;
|
ngx_err_t err;
|
||||||
|
ngx_uint_t tries;
|
||||||
|
|
||||||
ngx_ssl_ocsp_cleanup(c);
|
ngx_ssl_ocsp_cleanup(c);
|
||||||
|
|
||||||
@@ -2860,55 +2864,71 @@ ngx_ssl_shutdown(ngx_connection_t *c)
|
|||||||
|
|
||||||
ngx_ssl_clear_error(c->log);
|
ngx_ssl_clear_error(c->log);
|
||||||
|
|
||||||
n = SSL_shutdown(c->ssl->connection);
|
tries = 2;
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n);
|
for ( ;; ) {
|
||||||
|
|
||||||
sslerr = 0;
|
/*
|
||||||
|
* For bidirectional shutdown, SSL_shutdown() needs to be called
|
||||||
|
* twice: first call sends the "close notify" alert and returns 0,
|
||||||
|
* second call waits for the peer's "close notify" alert.
|
||||||
|
*/
|
||||||
|
|
||||||
/* before 0.9.8m SSL_shutdown() returned 0 instead of -1 on errors */
|
n = SSL_shutdown(c->ssl->connection);
|
||||||
|
|
||||||
|
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_shutdown: %d", n);
|
||||||
|
|
||||||
|
if (n == 1) {
|
||||||
|
SSL_free(c->ssl->connection);
|
||||||
|
c->ssl = NULL;
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n == 0 && tries-- > 1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* before 0.9.8m SSL_shutdown() returned 0 instead of -1 on errors */
|
||||||
|
|
||||||
if (n != 1 && ERR_peek_error()) {
|
|
||||||
sslerr = SSL_get_error(c->ssl->connection, n);
|
sslerr = SSL_get_error(c->ssl->connection, n);
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||||
"SSL_get_error: %d", sslerr);
|
"SSL_get_error: %d", sslerr);
|
||||||
}
|
|
||||||
|
|
||||||
if (n == 1 || sslerr == 0 || sslerr == SSL_ERROR_ZERO_RETURN) {
|
if (sslerr == SSL_ERROR_WANT_READ || sslerr == SSL_ERROR_WANT_WRITE) {
|
||||||
|
c->read->handler = ngx_ssl_shutdown_handler;
|
||||||
|
c->write->handler = ngx_ssl_shutdown_handler;
|
||||||
|
|
||||||
|
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_add_timer(c->read, 3000);
|
||||||
|
|
||||||
|
return NGX_AGAIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sslerr == SSL_ERROR_ZERO_RETURN || ERR_peek_error() == 0) {
|
||||||
|
SSL_free(c->ssl->connection);
|
||||||
|
c->ssl = NULL;
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
|
||||||
|
|
||||||
|
ngx_ssl_connection_error(c, sslerr, err, "SSL_shutdown() failed");
|
||||||
|
|
||||||
SSL_free(c->ssl->connection);
|
SSL_free(c->ssl->connection);
|
||||||
c->ssl = NULL;
|
c->ssl = NULL;
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sslerr == SSL_ERROR_WANT_READ || sslerr == SSL_ERROR_WANT_WRITE) {
|
|
||||||
c->read->handler = ngx_ssl_shutdown_handler;
|
|
||||||
c->write->handler = ngx_ssl_shutdown_handler;
|
|
||||||
|
|
||||||
if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
|
|
||||||
return NGX_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
|
|
||||||
return NGX_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sslerr == SSL_ERROR_WANT_READ) {
|
|
||||||
ngx_add_timer(c->read, 30000);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NGX_AGAIN;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = (sslerr == SSL_ERROR_SYSCALL) ? ngx_errno : 0;
|
|
||||||
|
|
||||||
ngx_ssl_connection_error(c, sslerr, err, "SSL_shutdown() failed");
|
|
||||||
|
|
||||||
SSL_free(c->ssl->connection);
|
|
||||||
c->ssl = NULL;
|
|
||||||
|
|
||||||
return NGX_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -883,6 +883,7 @@ ngx_ssl_ocsp_validate(ngx_connection_t *c)
|
|||||||
|
|
||||||
ocsp = ngx_pcalloc(c->pool, sizeof(ngx_ssl_ocsp_t));
|
ocsp = ngx_pcalloc(c->pool, sizeof(ngx_ssl_ocsp_t));
|
||||||
if (ocsp == NULL) {
|
if (ocsp == NULL) {
|
||||||
|
X509_free(cert);
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -899,6 +900,7 @@ ngx_ssl_ocsp_validate(ngx_connection_t *c)
|
|||||||
if (ocsp->certs) {
|
if (ocsp->certs) {
|
||||||
ocsp->certs = X509_chain_up_ref(ocsp->certs);
|
ocsp->certs = X509_chain_up_ref(ocsp->certs);
|
||||||
if (ocsp->certs == NULL) {
|
if (ocsp->certs == NULL) {
|
||||||
|
X509_free(cert);
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -910,6 +912,7 @@ ngx_ssl_ocsp_validate(ngx_connection_t *c)
|
|||||||
if (store == NULL) {
|
if (store == NULL) {
|
||||||
ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
|
ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
|
||||||
"SSL_CTX_get_cert_store() failed");
|
"SSL_CTX_get_cert_store() failed");
|
||||||
|
X509_free(cert);
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -917,6 +920,7 @@ ngx_ssl_ocsp_validate(ngx_connection_t *c)
|
|||||||
if (store_ctx == NULL) {
|
if (store_ctx == NULL) {
|
||||||
ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
|
ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
|
||||||
"X509_STORE_CTX_new() failed");
|
"X509_STORE_CTX_new() failed");
|
||||||
|
X509_free(cert);
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -926,6 +930,7 @@ ngx_ssl_ocsp_validate(ngx_connection_t *c)
|
|||||||
ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
|
ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
|
||||||
"X509_STORE_CTX_init() failed");
|
"X509_STORE_CTX_init() failed");
|
||||||
X509_STORE_CTX_free(store_ctx);
|
X509_STORE_CTX_free(store_ctx);
|
||||||
|
X509_free(cert);
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -933,6 +938,7 @@ ngx_ssl_ocsp_validate(ngx_connection_t *c)
|
|||||||
if (rc <= 0) {
|
if (rc <= 0) {
|
||||||
ngx_ssl_error(NGX_LOG_ERR, c->log, 0, "X509_verify_cert() failed");
|
ngx_ssl_error(NGX_LOG_ERR, c->log, 0, "X509_verify_cert() failed");
|
||||||
X509_STORE_CTX_free(store_ctx);
|
X509_STORE_CTX_free(store_ctx);
|
||||||
|
X509_free(cert);
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -941,12 +947,15 @@ ngx_ssl_ocsp_validate(ngx_connection_t *c)
|
|||||||
ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
|
ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
|
||||||
"X509_STORE_CTX_get1_chain() failed");
|
"X509_STORE_CTX_get1_chain() failed");
|
||||||
X509_STORE_CTX_free(store_ctx);
|
X509_STORE_CTX_free(store_ctx);
|
||||||
|
X509_free(cert);
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
X509_STORE_CTX_free(store_ctx);
|
X509_STORE_CTX_free(store_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
X509_free(cert);
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||||
"ssl ocsp validate, certs:%d", sk_X509_num(ocsp->certs));
|
"ssl ocsp validate, certs:%d", sk_X509_num(ocsp->certs));
|
||||||
|
|
||||||
@@ -980,6 +989,7 @@ ngx_ssl_ocsp_validate_next(ngx_connection_t *c)
|
|||||||
if (ocsp->ncert == n - 1 || (ocf->depth == 2 && ocsp->ncert == 1)) {
|
if (ocsp->ncert == n - 1 || (ocf->depth == 2 && ocsp->ncert == 1)) {
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
|
||||||
"ssl ocsp validated, certs:%ui", ocsp->ncert);
|
"ssl ocsp validated, certs:%ui", ocsp->ncert);
|
||||||
|
rc = NGX_OK;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -988,7 +998,8 @@ ngx_ssl_ocsp_validate_next(ngx_connection_t *c)
|
|||||||
|
|
||||||
ctx = ngx_ssl_ocsp_start(c->log);
|
ctx = ngx_ssl_ocsp_start(c->log);
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
goto failed;
|
rc = NGX_ERROR;
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
ocsp->ctx = ctx;
|
ocsp->ctx = ctx;
|
||||||
@@ -1012,8 +1023,9 @@ ngx_ssl_ocsp_validate_next(ngx_connection_t *c)
|
|||||||
ctx->uri = ocf->uri;
|
ctx->uri = ocf->uri;
|
||||||
ctx->port = ocf->port;
|
ctx->port = ocf->port;
|
||||||
|
|
||||||
if (ngx_ssl_ocsp_responder(c, ctx) != NGX_OK) {
|
rc = ngx_ssl_ocsp_responder(c, ctx);
|
||||||
goto failed;
|
if (rc != NGX_OK) {
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->uri.len == 0) {
|
if (ctx->uri.len == 0) {
|
||||||
@@ -1025,7 +1037,7 @@ ngx_ssl_ocsp_validate_next(ngx_connection_t *c)
|
|||||||
rc = ngx_ssl_ocsp_cache_lookup(ctx);
|
rc = ngx_ssl_ocsp_cache_lookup(ctx);
|
||||||
|
|
||||||
if (rc == NGX_ERROR) {
|
if (rc == NGX_ERROR) {
|
||||||
goto failed;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc == NGX_DECLINED) {
|
if (rc == NGX_DECLINED) {
|
||||||
@@ -1051,12 +1063,12 @@ ngx_ssl_ocsp_validate_next(ngx_connection_t *c)
|
|||||||
|
|
||||||
done:
|
done:
|
||||||
|
|
||||||
ocsp->status = NGX_OK;
|
ocsp->status = rc;
|
||||||
return;
|
|
||||||
|
|
||||||
failed:
|
if (c->ssl->in_ocsp) {
|
||||||
|
c->ssl->handshaked = 1;
|
||||||
ocsp->status = NGX_ERROR;
|
c->ssl->handler(c);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1073,22 +1085,16 @@ ngx_ssl_ocsp_handler(ngx_ssl_ocsp_ctx_t *ctx)
|
|||||||
|
|
||||||
rc = ngx_ssl_ocsp_verify(ctx);
|
rc = ngx_ssl_ocsp_verify(ctx);
|
||||||
if (rc != NGX_OK) {
|
if (rc != NGX_OK) {
|
||||||
ocsp->status = rc;
|
|
||||||
ngx_ssl_ocsp_done(ctx);
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = ngx_ssl_ocsp_cache_store(ctx);
|
rc = ngx_ssl_ocsp_cache_store(ctx);
|
||||||
if (rc != NGX_OK) {
|
if (rc != NGX_OK) {
|
||||||
ocsp->status = rc;
|
|
||||||
ngx_ssl_ocsp_done(ctx);
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->status != V_OCSP_CERTSTATUS_GOOD) {
|
if (ctx->status != V_OCSP_CERTSTATUS_GOOD) {
|
||||||
ocsp->cert_status = ctx->status;
|
ocsp->cert_status = ctx->status;
|
||||||
ocsp->status = NGX_OK;
|
|
||||||
ngx_ssl_ocsp_done(ctx);
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1096,15 +1102,17 @@ ngx_ssl_ocsp_handler(ngx_ssl_ocsp_ctx_t *ctx)
|
|||||||
|
|
||||||
ngx_ssl_ocsp_validate_next(c);
|
ngx_ssl_ocsp_validate_next(c);
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
|
||||||
if (ocsp->status == NGX_AGAIN || !c->ssl->in_ocsp) {
|
ocsp->status = rc;
|
||||||
return;
|
ngx_ssl_ocsp_done(ctx);
|
||||||
|
|
||||||
|
if (c->ssl->in_ocsp) {
|
||||||
|
c->ssl->handshaked = 1;
|
||||||
|
c->ssl->handler(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
c->ssl->handshaked = 1;
|
|
||||||
|
|
||||||
c->ssl->handler(c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -960,6 +960,22 @@ ngx_event_pipe_copy_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
|
|||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p->upstream_done) {
|
||||||
|
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, p->log, 0,
|
||||||
|
"input data after close");
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p->length == 0) {
|
||||||
|
p->upstream_done = 1;
|
||||||
|
|
||||||
|
ngx_log_error(NGX_LOG_WARN, p->log, 0,
|
||||||
|
"upstream sent more data than specified in "
|
||||||
|
"\"Content-Length\" header");
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
cl = ngx_chain_get_free_buf(p->pool, &p->free);
|
cl = ngx_chain_get_free_buf(p->pool, &p->free);
|
||||||
if (cl == NULL) {
|
if (cl == NULL) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
@@ -987,6 +1003,18 @@ ngx_event_pipe_copy_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
|
|||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (b->last - b->pos > p->length) {
|
||||||
|
|
||||||
|
ngx_log_error(NGX_LOG_WARN, p->log, 0,
|
||||||
|
"upstream sent more data than specified in "
|
||||||
|
"\"Content-Length\" header");
|
||||||
|
|
||||||
|
b->last = b->pos + p->length;
|
||||||
|
p->upstream_done = 1;
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
p->length -= b->last - b->pos;
|
p->length -= b->last - b->pos;
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
|
|||||||
@@ -81,12 +81,15 @@ typedef struct {
|
|||||||
size_t length;
|
size_t length;
|
||||||
size_t padding;
|
size_t padding;
|
||||||
|
|
||||||
|
off_t rest;
|
||||||
|
|
||||||
ngx_chain_t *free;
|
ngx_chain_t *free;
|
||||||
ngx_chain_t *busy;
|
ngx_chain_t *busy;
|
||||||
|
|
||||||
unsigned fastcgi_stdout:1;
|
unsigned fastcgi_stdout:1;
|
||||||
unsigned large_stderr:1;
|
unsigned large_stderr:1;
|
||||||
unsigned header_sent:1;
|
unsigned header_sent:1;
|
||||||
|
unsigned closed:1;
|
||||||
|
|
||||||
ngx_array_t *split_parts;
|
ngx_array_t *split_parts;
|
||||||
|
|
||||||
@@ -2075,13 +2078,31 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
|
|||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_http_fastcgi_input_filter_init(void *data)
|
ngx_http_fastcgi_input_filter_init(void *data)
|
||||||
{
|
{
|
||||||
ngx_http_request_t *r = data;
|
ngx_http_request_t *r = data;
|
||||||
|
|
||||||
|
ngx_http_upstream_t *u;
|
||||||
|
ngx_http_fastcgi_ctx_t *f;
|
||||||
ngx_http_fastcgi_loc_conf_t *flcf;
|
ngx_http_fastcgi_loc_conf_t *flcf;
|
||||||
|
|
||||||
|
u = r->upstream;
|
||||||
|
|
||||||
|
f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module);
|
||||||
flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
|
flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
|
||||||
|
|
||||||
r->upstream->pipe->length = flcf->keep_conn ?
|
u->pipe->length = flcf->keep_conn ?
|
||||||
(off_t) sizeof(ngx_http_fastcgi_header_t) : -1;
|
(off_t) sizeof(ngx_http_fastcgi_header_t) : -1;
|
||||||
|
|
||||||
|
if (u->headers_in.status_n == NGX_HTTP_NO_CONTENT
|
||||||
|
|| u->headers_in.status_n == NGX_HTTP_NOT_MODIFIED)
|
||||||
|
{
|
||||||
|
f->rest = 0;
|
||||||
|
|
||||||
|
} else if (r->method == NGX_HTTP_HEAD) {
|
||||||
|
f->rest = -2;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
f->rest = u->headers_in.content_length_n;
|
||||||
|
}
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
@@ -2106,6 +2127,15 @@ ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
|
|||||||
f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module);
|
f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module);
|
||||||
flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
|
flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
|
||||||
|
|
||||||
|
if (p->upstream_done || f->closed) {
|
||||||
|
r->upstream->keepalive = 0;
|
||||||
|
|
||||||
|
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0,
|
||||||
|
"http fastcgi data after close");
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
b = NULL;
|
b = NULL;
|
||||||
prev = &buf->shadow;
|
prev = &buf->shadow;
|
||||||
|
|
||||||
@@ -2128,13 +2158,25 @@ ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
|
|||||||
if (f->type == NGX_HTTP_FASTCGI_STDOUT && f->length == 0) {
|
if (f->type == NGX_HTTP_FASTCGI_STDOUT && f->length == 0) {
|
||||||
f->state = ngx_http_fastcgi_st_padding;
|
f->state = ngx_http_fastcgi_st_padding;
|
||||||
|
|
||||||
|
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0,
|
||||||
|
"http fastcgi closed stdout");
|
||||||
|
|
||||||
|
if (f->rest > 0) {
|
||||||
|
ngx_log_error(NGX_LOG_ERR, p->log, 0,
|
||||||
|
"upstream prematurely closed "
|
||||||
|
"FastCGI stdout");
|
||||||
|
|
||||||
|
p->upstream_error = 1;
|
||||||
|
p->upstream_eof = 0;
|
||||||
|
f->closed = 1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (!flcf->keep_conn) {
|
if (!flcf->keep_conn) {
|
||||||
p->upstream_done = 1;
|
p->upstream_done = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0,
|
|
||||||
"http fastcgi closed stdout");
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2143,6 +2185,18 @@ ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
|
|||||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0,
|
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0,
|
||||||
"http fastcgi sent end request");
|
"http fastcgi sent end request");
|
||||||
|
|
||||||
|
if (f->rest > 0) {
|
||||||
|
ngx_log_error(NGX_LOG_ERR, p->log, 0,
|
||||||
|
"upstream prematurely closed "
|
||||||
|
"FastCGI request");
|
||||||
|
|
||||||
|
p->upstream_error = 1;
|
||||||
|
p->upstream_eof = 0;
|
||||||
|
f->closed = 1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (!flcf->keep_conn) {
|
if (!flcf->keep_conn) {
|
||||||
p->upstream_done = 1;
|
p->upstream_done = 1;
|
||||||
break;
|
break;
|
||||||
@@ -2252,6 +2306,18 @@ ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (f->rest == -2) {
|
||||||
|
f->rest = r->upstream->headers_in.content_length_n;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (f->rest == 0) {
|
||||||
|
ngx_log_error(NGX_LOG_WARN, p->log, 0,
|
||||||
|
"upstream sent more data than specified in "
|
||||||
|
"\"Content-Length\" header");
|
||||||
|
p->upstream_done = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
cl = ngx_chain_get_free_buf(p->pool, &p->free);
|
cl = ngx_chain_get_free_buf(p->pool, &p->free);
|
||||||
if (cl == NULL) {
|
if (cl == NULL) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
@@ -2289,15 +2355,27 @@ ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
|
|||||||
f->pos += f->length;
|
f->pos += f->length;
|
||||||
b->last = f->pos;
|
b->last = f->pos;
|
||||||
|
|
||||||
continue;
|
} else {
|
||||||
|
f->length -= f->last - f->pos;
|
||||||
|
f->pos = f->last;
|
||||||
|
b->last = f->last;
|
||||||
}
|
}
|
||||||
|
|
||||||
f->length -= f->last - f->pos;
|
if (f->rest > 0) {
|
||||||
|
|
||||||
b->last = f->last;
|
if (b->last - b->pos > f->rest) {
|
||||||
|
ngx_log_error(NGX_LOG_WARN, p->log, 0,
|
||||||
|
"upstream sent more data than specified in "
|
||||||
|
"\"Content-Length\" header");
|
||||||
|
|
||||||
break;
|
b->last = b->pos + f->rest;
|
||||||
|
p->upstream_done = 1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
f->rest -= b->last - b->pos;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flcf->keep_conn) {
|
if (flcf->keep_conn) {
|
||||||
@@ -2391,6 +2469,14 @@ ngx_http_fastcgi_non_buffered_filter(void *data, ssize_t bytes)
|
|||||||
|
|
||||||
if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) {
|
if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) {
|
||||||
|
|
||||||
|
if (f->rest > 0) {
|
||||||
|
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||||
|
"upstream prematurely closed "
|
||||||
|
"FastCGI request");
|
||||||
|
u->error = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (f->pos + f->padding < f->last) {
|
if (f->pos + f->padding < f->last) {
|
||||||
u->length = 0;
|
u->length = 0;
|
||||||
break;
|
break;
|
||||||
@@ -2486,6 +2572,14 @@ ngx_http_fastcgi_non_buffered_filter(void *data, ssize_t bytes)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (f->rest == 0) {
|
||||||
|
ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
|
||||||
|
"upstream sent more data than specified in "
|
||||||
|
"\"Content-Length\" header");
|
||||||
|
u->length = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
cl = ngx_chain_get_free_buf(r->pool, &u->free_bufs);
|
cl = ngx_chain_get_free_buf(r->pool, &u->free_bufs);
|
||||||
if (cl == NULL) {
|
if (cl == NULL) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
@@ -2510,13 +2604,27 @@ ngx_http_fastcgi_non_buffered_filter(void *data, ssize_t bytes)
|
|||||||
f->pos += f->length;
|
f->pos += f->length;
|
||||||
b->last = f->pos;
|
b->last = f->pos;
|
||||||
|
|
||||||
continue;
|
} else {
|
||||||
|
f->length -= f->last - f->pos;
|
||||||
|
f->pos = f->last;
|
||||||
|
b->last = f->last;
|
||||||
}
|
}
|
||||||
|
|
||||||
f->length -= f->last - f->pos;
|
if (f->rest > 0) {
|
||||||
b->last = f->last;
|
|
||||||
|
|
||||||
break;
|
if (b->last - b->pos > f->rest) {
|
||||||
|
ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
|
||||||
|
"upstream sent more data than specified in "
|
||||||
|
"\"Content-Length\" header");
|
||||||
|
|
||||||
|
b->last = b->pos + f->rest;
|
||||||
|
u->length = 0;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
f->rest -= b->last - b->pos;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
|
|||||||
@@ -84,6 +84,8 @@ typedef struct {
|
|||||||
ngx_uint_t pings;
|
ngx_uint_t pings;
|
||||||
ngx_uint_t settings;
|
ngx_uint_t settings;
|
||||||
|
|
||||||
|
off_t length;
|
||||||
|
|
||||||
ssize_t send_window;
|
ssize_t send_window;
|
||||||
size_t recv_window;
|
size_t recv_window;
|
||||||
|
|
||||||
@@ -1953,10 +1955,28 @@ ngx_http_grpc_filter_init(void *data)
|
|||||||
r = ctx->request;
|
r = ctx->request;
|
||||||
u = r->upstream;
|
u = r->upstream;
|
||||||
|
|
||||||
u->length = 1;
|
if (u->headers_in.status_n == NGX_HTTP_NO_CONTENT
|
||||||
|
|| u->headers_in.status_n == NGX_HTTP_NOT_MODIFIED
|
||||||
|
|| r->method == NGX_HTTP_HEAD)
|
||||||
|
{
|
||||||
|
ctx->length = 0;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
ctx->length = u->headers_in.content_length_n;
|
||||||
|
}
|
||||||
|
|
||||||
if (ctx->end_stream) {
|
if (ctx->end_stream) {
|
||||||
|
|
||||||
|
if (ctx->length > 0) {
|
||||||
|
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||||
|
"upstream prematurely closed stream");
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
u->length = 0;
|
u->length = 0;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
u->length = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
@@ -1999,6 +2019,12 @@ ngx_http_grpc_filter(void *data, ssize_t bytes)
|
|||||||
|
|
||||||
if (ctx->done) {
|
if (ctx->done) {
|
||||||
|
|
||||||
|
if (ctx->length > 0) {
|
||||||
|
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||||
|
"upstream prematurely closed stream");
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We have finished parsing the response and the
|
* We have finished parsing the response and the
|
||||||
* remaining control frames. If there are unsent
|
* remaining control frames. If there are unsent
|
||||||
@@ -2052,6 +2078,17 @@ ngx_http_grpc_filter(void *data, ssize_t bytes)
|
|||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ctx->length != -1) {
|
||||||
|
if ((off_t) ctx->rest > ctx->length) {
|
||||||
|
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||||
|
"upstream sent response body larger "
|
||||||
|
"than indicated content length");
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->length -= ctx->rest;
|
||||||
|
}
|
||||||
|
|
||||||
if (ctx->rest > ctx->recv_window) {
|
if (ctx->rest > ctx->recv_window) {
|
||||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||||
"upstream violated stream flow control, "
|
"upstream violated stream flow control, "
|
||||||
|
|||||||
@@ -485,10 +485,11 @@ ngx_http_memcached_filter(void *data, ssize_t bytes)
|
|||||||
|
|
||||||
if (u->length == (ssize_t) ctx->rest) {
|
if (u->length == (ssize_t) ctx->rest) {
|
||||||
|
|
||||||
if (ngx_strncmp(b->last,
|
if (bytes > u->length
|
||||||
|
|| ngx_strncmp(b->last,
|
||||||
ngx_http_memcached_end + NGX_HTTP_MEMCACHED_END - ctx->rest,
|
ngx_http_memcached_end + NGX_HTTP_MEMCACHED_END - ctx->rest,
|
||||||
bytes)
|
bytes)
|
||||||
!= 0)
|
!= 0)
|
||||||
{
|
{
|
||||||
ngx_log_error(NGX_LOG_ERR, ctx->request->connection->log, 0,
|
ngx_log_error(NGX_LOG_ERR, ctx->request->connection->log, 0,
|
||||||
"memcached sent invalid trailer");
|
"memcached sent invalid trailer");
|
||||||
@@ -540,7 +541,9 @@ ngx_http_memcached_filter(void *data, ssize_t bytes)
|
|||||||
|
|
||||||
last += (size_t) (u->length - NGX_HTTP_MEMCACHED_END);
|
last += (size_t) (u->length - NGX_HTTP_MEMCACHED_END);
|
||||||
|
|
||||||
if (ngx_strncmp(last, ngx_http_memcached_end, b->last - last) != 0) {
|
if (bytes > u->length
|
||||||
|
|| ngx_strncmp(last, ngx_http_memcached_end, b->last - last) != 0)
|
||||||
|
{
|
||||||
ngx_log_error(NGX_LOG_ERR, ctx->request->connection->log, 0,
|
ngx_log_error(NGX_LOG_ERR, ctx->request->connection->log, 0,
|
||||||
"memcached sent invalid trailer");
|
"memcached sent invalid trailer");
|
||||||
|
|
||||||
|
|||||||
@@ -2015,6 +2015,25 @@ ngx_http_proxy_copy_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
|
|||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p->upstream_done) {
|
||||||
|
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0,
|
||||||
|
"http proxy data after close");
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p->length == 0) {
|
||||||
|
|
||||||
|
ngx_log_error(NGX_LOG_WARN, p->log, 0,
|
||||||
|
"upstream sent more data than specified in "
|
||||||
|
"\"Content-Length\" header");
|
||||||
|
|
||||||
|
r = p->input_ctx;
|
||||||
|
r->upstream->keepalive = 0;
|
||||||
|
p->upstream_done = 1;
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
cl = ngx_chain_get_free_buf(p->pool, &p->free);
|
cl = ngx_chain_get_free_buf(p->pool, &p->free);
|
||||||
if (cl == NULL) {
|
if (cl == NULL) {
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
@@ -2042,20 +2061,23 @@ ngx_http_proxy_copy_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
|
|||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (b->last - b->pos > p->length) {
|
||||||
|
|
||||||
|
ngx_log_error(NGX_LOG_WARN, p->log, 0,
|
||||||
|
"upstream sent more data than specified in "
|
||||||
|
"\"Content-Length\" header");
|
||||||
|
|
||||||
|
b->last = b->pos + p->length;
|
||||||
|
p->upstream_done = 1;
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
p->length -= b->last - b->pos;
|
p->length -= b->last - b->pos;
|
||||||
|
|
||||||
if (p->length == 0) {
|
if (p->length == 0) {
|
||||||
r = p->input_ctx;
|
r = p->input_ctx;
|
||||||
p->upstream_done = 1;
|
|
||||||
r->upstream->keepalive = !r->upstream->headers_in.connection_close;
|
r->upstream->keepalive = !r->upstream->headers_in.connection_close;
|
||||||
|
|
||||||
} else if (p->length < 0) {
|
|
||||||
r = p->input_ctx;
|
|
||||||
p->upstream_done = 1;
|
|
||||||
|
|
||||||
ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
|
|
||||||
"upstream sent more data than specified in "
|
|
||||||
"\"Content-Length\" header");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
@@ -2082,6 +2104,23 @@ ngx_http_proxy_chunked_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
|
|||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p->upstream_done) {
|
||||||
|
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0,
|
||||||
|
"http proxy data after close");
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p->length == 0) {
|
||||||
|
|
||||||
|
ngx_log_error(NGX_LOG_WARN, p->log, 0,
|
||||||
|
"upstream sent data after final chunk");
|
||||||
|
|
||||||
|
r->upstream->keepalive = 0;
|
||||||
|
p->upstream_done = 1;
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
b = NULL;
|
b = NULL;
|
||||||
prev = &buf->shadow;
|
prev = &buf->shadow;
|
||||||
|
|
||||||
@@ -2144,9 +2183,15 @@ ngx_http_proxy_chunked_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
|
|||||||
|
|
||||||
/* a whole response has been parsed successfully */
|
/* a whole response has been parsed successfully */
|
||||||
|
|
||||||
p->upstream_done = 1;
|
p->length = 0;
|
||||||
r->upstream->keepalive = !r->upstream->headers_in.connection_close;
|
r->upstream->keepalive = !r->upstream->headers_in.connection_close;
|
||||||
|
|
||||||
|
if (buf->pos != buf->last) {
|
||||||
|
ngx_log_error(NGX_LOG_WARN, p->log, 0,
|
||||||
|
"upstream sent data after final chunk");
|
||||||
|
r->upstream->keepalive = 0;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2161,13 +2206,13 @@ ngx_http_proxy_chunked_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
|
|||||||
|
|
||||||
/* invalid response */
|
/* invalid response */
|
||||||
|
|
||||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
ngx_log_error(NGX_LOG_ERR, p->log, 0,
|
||||||
"upstream sent invalid chunked response");
|
"upstream sent invalid chunked response");
|
||||||
|
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, p->log, 0,
|
||||||
"http proxy chunked state %ui, length %O",
|
"http proxy chunked state %ui, length %O",
|
||||||
ctx->chunked.state, p->length);
|
ctx->chunked.state, p->length);
|
||||||
|
|
||||||
@@ -2227,6 +2272,18 @@ ngx_http_proxy_non_buffered_copy_filter(void *data, ssize_t bytes)
|
|||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bytes > u->length) {
|
||||||
|
|
||||||
|
ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
|
||||||
|
"upstream sent more data than specified in "
|
||||||
|
"\"Content-Length\" header");
|
||||||
|
|
||||||
|
cl->buf->last = cl->buf->pos + u->length;
|
||||||
|
u->length = 0;
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
u->length -= bytes;
|
u->length -= bytes;
|
||||||
|
|
||||||
if (u->length == 0) {
|
if (u->length == 0) {
|
||||||
@@ -2313,6 +2370,12 @@ ngx_http_proxy_non_buffered_chunked_filter(void *data, ssize_t bytes)
|
|||||||
u->keepalive = !u->headers_in.connection_close;
|
u->keepalive = !u->headers_in.connection_close;
|
||||||
u->length = 0;
|
u->length = 0;
|
||||||
|
|
||||||
|
if (buf->pos != buf->last) {
|
||||||
|
ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
|
||||||
|
"upstream sent data after final chunk");
|
||||||
|
u->keepalive = 0;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ static ngx_int_t ngx_http_scgi_create_request(ngx_http_request_t *r);
|
|||||||
static ngx_int_t ngx_http_scgi_reinit_request(ngx_http_request_t *r);
|
static ngx_int_t ngx_http_scgi_reinit_request(ngx_http_request_t *r);
|
||||||
static ngx_int_t ngx_http_scgi_process_status_line(ngx_http_request_t *r);
|
static ngx_int_t ngx_http_scgi_process_status_line(ngx_http_request_t *r);
|
||||||
static ngx_int_t ngx_http_scgi_process_header(ngx_http_request_t *r);
|
static ngx_int_t ngx_http_scgi_process_header(ngx_http_request_t *r);
|
||||||
|
static ngx_int_t ngx_http_scgi_input_filter_init(void *data);
|
||||||
static void ngx_http_scgi_abort_request(ngx_http_request_t *r);
|
static void ngx_http_scgi_abort_request(ngx_http_request_t *r);
|
||||||
static void ngx_http_scgi_finalize_request(ngx_http_request_t *r, ngx_int_t rc);
|
static void ngx_http_scgi_finalize_request(ngx_http_request_t *r, ngx_int_t rc);
|
||||||
|
|
||||||
@@ -534,6 +535,10 @@ ngx_http_scgi_handler(ngx_http_request_t *r)
|
|||||||
u->pipe->input_filter = ngx_event_pipe_copy_input_filter;
|
u->pipe->input_filter = ngx_event_pipe_copy_input_filter;
|
||||||
u->pipe->input_ctx = r;
|
u->pipe->input_ctx = r;
|
||||||
|
|
||||||
|
u->input_filter_init = ngx_http_scgi_input_filter_init;
|
||||||
|
u->input_filter = ngx_http_upstream_non_buffered_filter;
|
||||||
|
u->input_filter_ctx = r;
|
||||||
|
|
||||||
if (!scf->upstream.request_buffering
|
if (!scf->upstream.request_buffering
|
||||||
&& scf->upstream.pass_request_body
|
&& scf->upstream.pass_request_body
|
||||||
&& !r->headers_in.chunked)
|
&& !r->headers_in.chunked)
|
||||||
@@ -1145,6 +1150,37 @@ ngx_http_scgi_process_header(ngx_http_request_t *r)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ngx_int_t
|
||||||
|
ngx_http_scgi_input_filter_init(void *data)
|
||||||
|
{
|
||||||
|
ngx_http_request_t *r = data;
|
||||||
|
ngx_http_upstream_t *u;
|
||||||
|
|
||||||
|
u = r->upstream;
|
||||||
|
|
||||||
|
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||||
|
"http scgi filter init s:%ui l:%O",
|
||||||
|
u->headers_in.status_n, u->headers_in.content_length_n);
|
||||||
|
|
||||||
|
if (u->headers_in.status_n == NGX_HTTP_NO_CONTENT
|
||||||
|
|| u->headers_in.status_n == NGX_HTTP_NOT_MODIFIED)
|
||||||
|
{
|
||||||
|
u->pipe->length = 0;
|
||||||
|
u->length = 0;
|
||||||
|
|
||||||
|
} else if (r->method == NGX_HTTP_HEAD) {
|
||||||
|
u->pipe->length = -1;
|
||||||
|
u->length = -1;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
u->pipe->length = u->headers_in.content_length_n;
|
||||||
|
u->length = u->headers_in.content_length_n;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ngx_http_scgi_abort_request(ngx_http_request_t *r)
|
ngx_http_scgi_abort_request(ngx_http_request_t *r)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -180,6 +180,11 @@ ngx_http_slice_header_filter(ngx_http_request_t *r)
|
|||||||
r->headers_out.content_range->hash = 0;
|
r->headers_out.content_range->hash = 0;
|
||||||
r->headers_out.content_range = NULL;
|
r->headers_out.content_range = NULL;
|
||||||
|
|
||||||
|
if (r->headers_out.accept_ranges) {
|
||||||
|
r->headers_out.accept_ranges->hash = 0;
|
||||||
|
r->headers_out.accept_ranges = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
r->allow_ranges = 1;
|
r->allow_ranges = 1;
|
||||||
r->subrequest_ranges = 1;
|
r->subrequest_ranges = 1;
|
||||||
r->single_range = 1;
|
r->single_range = 1;
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ static ngx_int_t ngx_http_uwsgi_create_request(ngx_http_request_t *r);
|
|||||||
static ngx_int_t ngx_http_uwsgi_reinit_request(ngx_http_request_t *r);
|
static ngx_int_t ngx_http_uwsgi_reinit_request(ngx_http_request_t *r);
|
||||||
static ngx_int_t ngx_http_uwsgi_process_status_line(ngx_http_request_t *r);
|
static ngx_int_t ngx_http_uwsgi_process_status_line(ngx_http_request_t *r);
|
||||||
static ngx_int_t ngx_http_uwsgi_process_header(ngx_http_request_t *r);
|
static ngx_int_t ngx_http_uwsgi_process_header(ngx_http_request_t *r);
|
||||||
|
static ngx_int_t ngx_http_uwsgi_input_filter_init(void *data);
|
||||||
static void ngx_http_uwsgi_abort_request(ngx_http_request_t *r);
|
static void ngx_http_uwsgi_abort_request(ngx_http_request_t *r);
|
||||||
static void ngx_http_uwsgi_finalize_request(ngx_http_request_t *r,
|
static void ngx_http_uwsgi_finalize_request(ngx_http_request_t *r,
|
||||||
ngx_int_t rc);
|
ngx_int_t rc);
|
||||||
@@ -703,6 +704,10 @@ ngx_http_uwsgi_handler(ngx_http_request_t *r)
|
|||||||
u->pipe->input_filter = ngx_event_pipe_copy_input_filter;
|
u->pipe->input_filter = ngx_event_pipe_copy_input_filter;
|
||||||
u->pipe->input_ctx = r;
|
u->pipe->input_ctx = r;
|
||||||
|
|
||||||
|
u->input_filter_init = ngx_http_uwsgi_input_filter_init;
|
||||||
|
u->input_filter = ngx_http_upstream_non_buffered_filter;
|
||||||
|
u->input_filter_ctx = r;
|
||||||
|
|
||||||
if (!uwcf->upstream.request_buffering
|
if (!uwcf->upstream.request_buffering
|
||||||
&& uwcf->upstream.pass_request_body
|
&& uwcf->upstream.pass_request_body
|
||||||
&& !r->headers_in.chunked)
|
&& !r->headers_in.chunked)
|
||||||
@@ -1141,6 +1146,7 @@ ngx_http_uwsgi_create_request(ngx_http_request_t *r)
|
|||||||
r->upstream->request_bufs = cl;
|
r->upstream->request_bufs = cl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
b->flush = 1;
|
||||||
cl->next = NULL;
|
cl->next = NULL;
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
@@ -1355,6 +1361,37 @@ ngx_http_uwsgi_process_header(ngx_http_request_t *r)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ngx_int_t
|
||||||
|
ngx_http_uwsgi_input_filter_init(void *data)
|
||||||
|
{
|
||||||
|
ngx_http_request_t *r = data;
|
||||||
|
ngx_http_upstream_t *u;
|
||||||
|
|
||||||
|
u = r->upstream;
|
||||||
|
|
||||||
|
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||||
|
"http uwsgi filter init s:%ui l:%O",
|
||||||
|
u->headers_in.status_n, u->headers_in.content_length_n);
|
||||||
|
|
||||||
|
if (u->headers_in.status_n == NGX_HTTP_NO_CONTENT
|
||||||
|
|| u->headers_in.status_n == NGX_HTTP_NOT_MODIFIED)
|
||||||
|
{
|
||||||
|
u->pipe->length = 0;
|
||||||
|
u->length = 0;
|
||||||
|
|
||||||
|
} else if (r->method == NGX_HTTP_HEAD) {
|
||||||
|
u->pipe->length = -1;
|
||||||
|
u->length = -1;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
u->pipe->length = u->headers_in.content_length_n;
|
||||||
|
u->length = u->headers_in.content_length_n;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ngx_http_uwsgi_abort_request(ngx_http_request_t *r)
|
ngx_http_uwsgi_abort_request(ngx_http_request_t *r)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -233,6 +233,7 @@ ngx_http_xslt_header_filter(ngx_http_request_t *r)
|
|||||||
ngx_http_set_ctx(r, ctx, ngx_http_xslt_filter_module);
|
ngx_http_set_ctx(r, ctx, ngx_http_xslt_filter_module);
|
||||||
|
|
||||||
r->main_filter_need_in_memory = 1;
|
r->main_filter_need_in_memory = 1;
|
||||||
|
r->allow_ranges = 0;
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -1469,14 +1469,14 @@ ngx_http_server_names(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf,
|
|||||||
NGX_HASH_WILDCARD_KEY);
|
NGX_HASH_WILDCARD_KEY);
|
||||||
|
|
||||||
if (rc == NGX_ERROR) {
|
if (rc == NGX_ERROR) {
|
||||||
return NGX_ERROR;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc == NGX_DECLINED) {
|
if (rc == NGX_DECLINED) {
|
||||||
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
||||||
"invalid server name or wildcard \"%V\" on %V",
|
"invalid server name or wildcard \"%V\" on %V",
|
||||||
&name[n].name, &addr->opt.addr_text);
|
&name[n].name, &addr->opt.addr_text);
|
||||||
return NGX_ERROR;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc == NGX_BUSY) {
|
if (rc == NGX_BUSY) {
|
||||||
|
|||||||
@@ -160,6 +160,7 @@ struct ngx_http_file_cache_s {
|
|||||||
|
|
||||||
ngx_path_t *path;
|
ngx_path_t *path;
|
||||||
|
|
||||||
|
off_t min_free;
|
||||||
off_t max_size;
|
off_t max_size;
|
||||||
size_t bsize;
|
size_t bsize;
|
||||||
|
|
||||||
|
|||||||
@@ -1959,7 +1959,7 @@ ngx_http_file_cache_manager(void *data)
|
|||||||
{
|
{
|
||||||
ngx_http_file_cache_t *cache = data;
|
ngx_http_file_cache_t *cache = data;
|
||||||
|
|
||||||
off_t size;
|
off_t size, free;
|
||||||
time_t wait;
|
time_t wait;
|
||||||
ngx_msec_t elapsed, next;
|
ngx_msec_t elapsed, next;
|
||||||
ngx_uint_t count, watermark;
|
ngx_uint_t count, watermark;
|
||||||
@@ -1988,7 +1988,19 @@ ngx_http_file_cache_manager(void *data)
|
|||||||
size, count, (ngx_int_t) watermark);
|
size, count, (ngx_int_t) watermark);
|
||||||
|
|
||||||
if (size < cache->max_size && count < watermark) {
|
if (size < cache->max_size && count < watermark) {
|
||||||
break;
|
|
||||||
|
if (!cache->min_free) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
free = ngx_fs_available(cache->path->name.data);
|
||||||
|
|
||||||
|
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
|
||||||
|
"http file cache free: %O", free);
|
||||||
|
|
||||||
|
if (free > cache->min_free) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wait = ngx_http_file_cache_forced_expire(cache);
|
wait = ngx_http_file_cache_forced_expire(cache);
|
||||||
@@ -2304,7 +2316,7 @@ ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
{
|
{
|
||||||
char *confp = conf;
|
char *confp = conf;
|
||||||
|
|
||||||
off_t max_size;
|
off_t max_size, min_free;
|
||||||
u_char *last, *p;
|
u_char *last, *p;
|
||||||
time_t inactive;
|
time_t inactive;
|
||||||
ssize_t size;
|
ssize_t size;
|
||||||
@@ -2341,6 +2353,7 @@ ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
name.len = 0;
|
name.len = 0;
|
||||||
size = 0;
|
size = 0;
|
||||||
max_size = NGX_MAX_OFF_T_VALUE;
|
max_size = NGX_MAX_OFF_T_VALUE;
|
||||||
|
min_free = 0;
|
||||||
|
|
||||||
value = cf->args->elts;
|
value = cf->args->elts;
|
||||||
|
|
||||||
@@ -2476,6 +2489,29 @@ ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ngx_strncmp(value[i].data, "min_free=", 9) == 0) {
|
||||||
|
|
||||||
|
#if (NGX_WIN32 || NGX_HAVE_STATFS || NGX_HAVE_STATVFS)
|
||||||
|
|
||||||
|
s.len = value[i].len - 9;
|
||||||
|
s.data = value[i].data + 9;
|
||||||
|
|
||||||
|
min_free = ngx_parse_offset(&s);
|
||||||
|
if (min_free < 0) {
|
||||||
|
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||||
|
"invalid min_free value \"%V\"", &value[i]);
|
||||||
|
return NGX_CONF_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||||
|
"min_free is not supported "
|
||||||
|
"on this platform, ignored");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (ngx_strncmp(value[i].data, "loader_files=", 13) == 0) {
|
if (ngx_strncmp(value[i].data, "loader_files=", 13) == 0) {
|
||||||
|
|
||||||
loader_files = ngx_atoi(value[i].data + 13, value[i].len - 13);
|
loader_files = ngx_atoi(value[i].data + 13, value[i].len - 13);
|
||||||
@@ -2607,6 +2643,7 @@ ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
|||||||
|
|
||||||
cache->inactive = inactive;
|
cache->inactive = inactive;
|
||||||
cache->max_size = max_size;
|
cache->max_size = max_size;
|
||||||
|
cache->min_free = min_free;
|
||||||
|
|
||||||
caches = (ngx_array_t *) (confp + cmd->offset);
|
caches = (ngx_array_t *) (confp + cmd->offset);
|
||||||
|
|
||||||
|
|||||||
@@ -1654,6 +1654,12 @@ ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
|
|||||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||||
"http large header copy: %uz", r->header_in->pos - old);
|
"http large header copy: %uz", r->header_in->pos - old);
|
||||||
|
|
||||||
|
if (r->header_in->pos - old > b->end - b->start) {
|
||||||
|
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
|
||||||
|
"too large header to copy");
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
new = b->start;
|
new = b->start;
|
||||||
|
|
||||||
ngx_memcpy(new, old, r->header_in->pos - old);
|
ngx_memcpy(new, old, r->header_in->pos - old);
|
||||||
@@ -3000,6 +3006,12 @@ closed:
|
|||||||
rev->error = 1;
|
rev->error = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (NGX_HTTP_SSL)
|
||||||
|
if (c->ssl) {
|
||||||
|
c->ssl->no_send_shutdown = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
ngx_log_error(NGX_LOG_INFO, c->log, err,
|
ngx_log_error(NGX_LOG_INFO, c->log, err,
|
||||||
"client prematurely closed connection");
|
"client prematurely closed connection");
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
static void ngx_http_read_client_request_body_handler(ngx_http_request_t *r);
|
static void ngx_http_read_client_request_body_handler(ngx_http_request_t *r);
|
||||||
static ngx_int_t ngx_http_do_read_client_request_body(ngx_http_request_t *r);
|
static ngx_int_t ngx_http_do_read_client_request_body(ngx_http_request_t *r);
|
||||||
|
static ngx_int_t ngx_http_copy_pipelined_header(ngx_http_request_t *r,
|
||||||
|
ngx_buf_t *buf);
|
||||||
static ngx_int_t ngx_http_write_request_body(ngx_http_request_t *r);
|
static ngx_int_t ngx_http_write_request_body(ngx_http_request_t *r);
|
||||||
static ngx_int_t ngx_http_read_discarded_request_body(ngx_http_request_t *r);
|
static ngx_int_t ngx_http_read_discarded_request_body(ngx_http_request_t *r);
|
||||||
static ngx_int_t ngx_http_discard_request_body_filter(ngx_http_request_t *r,
|
static ngx_int_t ngx_http_discard_request_body_filter(ngx_http_request_t *r,
|
||||||
@@ -282,28 +284,12 @@ ngx_http_do_read_client_request_body(ngx_http_request_t *r)
|
|||||||
for ( ;; ) {
|
for ( ;; ) {
|
||||||
if (rb->buf->last == rb->buf->end) {
|
if (rb->buf->last == rb->buf->end) {
|
||||||
|
|
||||||
if (rb->buf->pos != rb->buf->last) {
|
/* update chains */
|
||||||
|
|
||||||
/* pass buffer to request body filter chain */
|
rc = ngx_http_request_body_filter(r, NULL);
|
||||||
|
|
||||||
out.buf = rb->buf;
|
if (rc != NGX_OK) {
|
||||||
out.next = NULL;
|
return rc;
|
||||||
|
|
||||||
rc = ngx_http_request_body_filter(r, &out);
|
|
||||||
|
|
||||||
if (rc != NGX_OK) {
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
/* update chains */
|
|
||||||
|
|
||||||
rc = ngx_http_request_body_filter(r, NULL);
|
|
||||||
|
|
||||||
if (rc != NGX_OK) {
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rb->busy != NULL) {
|
if (rb->busy != NULL) {
|
||||||
@@ -355,17 +341,15 @@ ngx_http_do_read_client_request_body(ngx_http_request_t *r)
|
|||||||
rb->buf->last += n;
|
rb->buf->last += n;
|
||||||
r->request_length += n;
|
r->request_length += n;
|
||||||
|
|
||||||
if (n == rest) {
|
/* pass buffer to request body filter chain */
|
||||||
/* pass buffer to request body filter chain */
|
|
||||||
|
|
||||||
out.buf = rb->buf;
|
out.buf = rb->buf;
|
||||||
out.next = NULL;
|
out.next = NULL;
|
||||||
|
|
||||||
rc = ngx_http_request_body_filter(r, &out);
|
rc = ngx_http_request_body_filter(r, &out);
|
||||||
|
|
||||||
if (rc != NGX_OK) {
|
if (rc != NGX_OK) {
|
||||||
return rc;
|
return rc;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rb->rest == 0) {
|
if (rb->rest == 0) {
|
||||||
@@ -386,21 +370,6 @@ ngx_http_do_read_client_request_body(ngx_http_request_t *r)
|
|||||||
|
|
||||||
if (!c->read->ready) {
|
if (!c->read->ready) {
|
||||||
|
|
||||||
if (r->request_body_no_buffering
|
|
||||||
&& rb->buf->pos != rb->buf->last)
|
|
||||||
{
|
|
||||||
/* pass buffer to request body filter chain */
|
|
||||||
|
|
||||||
out.buf = rb->buf;
|
|
||||||
out.next = NULL;
|
|
||||||
|
|
||||||
rc = ngx_http_request_body_filter(r, &out);
|
|
||||||
|
|
||||||
if (rc != NGX_OK) {
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||||
ngx_add_timer(c->read, clcf->client_body_timeout);
|
ngx_add_timer(c->read, clcf->client_body_timeout);
|
||||||
|
|
||||||
@@ -412,6 +381,10 @@ ngx_http_do_read_client_request_body(ngx_http_request_t *r)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ngx_http_copy_pipelined_header(r, rb->buf) != NGX_OK) {
|
||||||
|
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (c->read->timer_set) {
|
if (c->read->timer_set) {
|
||||||
ngx_del_timer(c->read);
|
ngx_del_timer(c->read);
|
||||||
}
|
}
|
||||||
@@ -425,6 +398,88 @@ ngx_http_do_read_client_request_body(ngx_http_request_t *r)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ngx_int_t
|
||||||
|
ngx_http_copy_pipelined_header(ngx_http_request_t *r, ngx_buf_t *buf)
|
||||||
|
{
|
||||||
|
size_t n;
|
||||||
|
ngx_buf_t *b;
|
||||||
|
ngx_chain_t *cl;
|
||||||
|
ngx_http_connection_t *hc;
|
||||||
|
ngx_http_core_srv_conf_t *cscf;
|
||||||
|
|
||||||
|
b = r->header_in;
|
||||||
|
n = buf->last - buf->pos;
|
||||||
|
|
||||||
|
if (buf == b || n == 0) {
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||||
|
"http body pipelined header: %uz", n);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if there is a pipelined request in the client body buffer,
|
||||||
|
* copy it to the r->header_in buffer if there is enough room,
|
||||||
|
* or allocate a large client header buffer
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (n > (size_t) (b->end - b->last)) {
|
||||||
|
|
||||||
|
hc = r->http_connection;
|
||||||
|
|
||||||
|
if (hc->free) {
|
||||||
|
cl = hc->free;
|
||||||
|
hc->free = cl->next;
|
||||||
|
|
||||||
|
b = cl->buf;
|
||||||
|
|
||||||
|
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||||
|
"http large header free: %p %uz",
|
||||||
|
b->pos, b->end - b->last);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
|
||||||
|
|
||||||
|
b = ngx_create_temp_buf(r->connection->pool,
|
||||||
|
cscf->large_client_header_buffers.size);
|
||||||
|
if (b == NULL) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
cl = ngx_alloc_chain_link(r->connection->pool);
|
||||||
|
if (cl == NULL) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
cl->buf = b;
|
||||||
|
|
||||||
|
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||||
|
"http large header alloc: %p %uz",
|
||||||
|
b->pos, b->end - b->last);
|
||||||
|
}
|
||||||
|
|
||||||
|
cl->next = hc->busy;
|
||||||
|
hc->busy = cl;
|
||||||
|
hc->nbusy++;
|
||||||
|
|
||||||
|
r->header_in = b;
|
||||||
|
|
||||||
|
if (n > (size_t) (b->end - b->last)) {
|
||||||
|
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
|
||||||
|
"too large pipelined header after reading body");
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_memcpy(b->last, buf->pos, n);
|
||||||
|
|
||||||
|
b->last += n;
|
||||||
|
r->request_length -= n;
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_http_write_request_body(ngx_http_request_t *r)
|
ngx_http_write_request_body(ngx_http_request_t *r)
|
||||||
{
|
{
|
||||||
@@ -670,8 +725,7 @@ ngx_http_read_discarded_request_body(ngx_http_request_t *r)
|
|||||||
|
|
||||||
for ( ;; ) {
|
for ( ;; ) {
|
||||||
if (r->headers_in.content_length_n == 0) {
|
if (r->headers_in.content_length_n == 0) {
|
||||||
r->read_event_handler = ngx_http_block_reading;
|
break;
|
||||||
return NGX_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!r->connection->read->ready) {
|
if (!r->connection->read->ready) {
|
||||||
@@ -705,15 +759,24 @@ ngx_http_read_discarded_request_body(ngx_http_request_t *r)
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ngx_http_copy_pipelined_header(r, &b) != NGX_OK) {
|
||||||
|
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
r->read_event_handler = ngx_http_block_reading;
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_http_discard_request_body_filter(ngx_http_request_t *r, ngx_buf_t *b)
|
ngx_http_discard_request_body_filter(ngx_http_request_t *r, ngx_buf_t *b)
|
||||||
{
|
{
|
||||||
size_t size;
|
size_t size;
|
||||||
ngx_int_t rc;
|
ngx_int_t rc;
|
||||||
ngx_http_request_body_t *rb;
|
ngx_http_request_body_t *rb;
|
||||||
|
ngx_http_core_srv_conf_t *cscf;
|
||||||
|
|
||||||
if (r->headers_in.chunked) {
|
if (r->headers_in.chunked) {
|
||||||
|
|
||||||
@@ -768,7 +831,10 @@ ngx_http_discard_request_body_filter(ngx_http_request_t *r, ngx_buf_t *b)
|
|||||||
|
|
||||||
/* set amount of data we want to see next time */
|
/* set amount of data we want to see next time */
|
||||||
|
|
||||||
r->headers_in.content_length_n = rb->chunked->length;
|
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
|
||||||
|
|
||||||
|
r->headers_in.content_length_n = ngx_max(rb->chunked->length,
|
||||||
|
(off_t) cscf->large_client_header_buffers.size);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -936,6 +1002,7 @@ ngx_http_request_body_chunked_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||||||
ngx_chain_t *cl, *out, *tl, **ll;
|
ngx_chain_t *cl, *out, *tl, **ll;
|
||||||
ngx_http_request_body_t *rb;
|
ngx_http_request_body_t *rb;
|
||||||
ngx_http_core_loc_conf_t *clcf;
|
ngx_http_core_loc_conf_t *clcf;
|
||||||
|
ngx_http_core_srv_conf_t *cscf;
|
||||||
|
|
||||||
rb = r->request_body;
|
rb = r->request_body;
|
||||||
|
|
||||||
@@ -949,8 +1016,10 @@ ngx_http_request_body_chunked_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
|
||||||
|
|
||||||
r->headers_in.content_length_n = 0;
|
r->headers_in.content_length_n = 0;
|
||||||
rb->rest = 3;
|
rb->rest = cscf->large_client_header_buffers.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
out = NULL;
|
out = NULL;
|
||||||
@@ -958,6 +1027,8 @@ ngx_http_request_body_chunked_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||||||
|
|
||||||
for (cl = in; cl; cl = cl->next) {
|
for (cl = in; cl; cl = cl->next) {
|
||||||
|
|
||||||
|
b = NULL;
|
||||||
|
|
||||||
for ( ;; ) {
|
for ( ;; ) {
|
||||||
|
|
||||||
ngx_log_debug7(NGX_LOG_DEBUG_EVENT, r->connection->log, 0,
|
ngx_log_debug7(NGX_LOG_DEBUG_EVENT, r->connection->log, 0,
|
||||||
@@ -992,6 +1063,29 @@ ngx_http_request_body_chunked_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||||||
return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE;
|
return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (b
|
||||||
|
&& rb->chunked->size <= 128
|
||||||
|
&& cl->buf->last - cl->buf->pos >= rb->chunked->size)
|
||||||
|
{
|
||||||
|
r->headers_in.content_length_n += rb->chunked->size;
|
||||||
|
|
||||||
|
if (rb->chunked->size < 8) {
|
||||||
|
|
||||||
|
while (rb->chunked->size) {
|
||||||
|
*b->last++ = *cl->buf->pos++;
|
||||||
|
rb->chunked->size--;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
ngx_memmove(b->last, cl->buf->pos, rb->chunked->size);
|
||||||
|
b->last += rb->chunked->size;
|
||||||
|
cl->buf->pos += rb->chunked->size;
|
||||||
|
rb->chunked->size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
tl = ngx_chain_get_free_buf(r->pool, &rb->free);
|
tl = ngx_chain_get_free_buf(r->pool, &rb->free);
|
||||||
if (tl == NULL) {
|
if (tl == NULL) {
|
||||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||||
@@ -1057,7 +1151,10 @@ ngx_http_request_body_chunked_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
|||||||
|
|
||||||
/* set rb->rest, amount of data we want to see next time */
|
/* set rb->rest, amount of data we want to see next time */
|
||||||
|
|
||||||
rb->rest = rb->chunked->length;
|
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
|
||||||
|
|
||||||
|
rb->rest = ngx_max(rb->chunked->length,
|
||||||
|
(off_t) cscf->large_client_header_buffers.size);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,9 +77,6 @@ static void
|
|||||||
static void
|
static void
|
||||||
ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r,
|
ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r,
|
||||||
ngx_uint_t do_write);
|
ngx_uint_t do_write);
|
||||||
static ngx_int_t ngx_http_upstream_non_buffered_filter_init(void *data);
|
|
||||||
static ngx_int_t ngx_http_upstream_non_buffered_filter(void *data,
|
|
||||||
ssize_t bytes);
|
|
||||||
#if (NGX_THREADS)
|
#if (NGX_THREADS)
|
||||||
static ngx_int_t ngx_http_upstream_thread_handler(ngx_thread_task_t *task,
|
static ngx_int_t ngx_http_upstream_thread_handler(ngx_thread_task_t *task,
|
||||||
ngx_file_t *file);
|
ngx_file_t *file);
|
||||||
@@ -1919,6 +1916,7 @@ ngx_http_upstream_reinit(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
|||||||
|
|
||||||
u->keepalive = 0;
|
u->keepalive = 0;
|
||||||
u->upgrade = 0;
|
u->upgrade = 0;
|
||||||
|
u->error = 0;
|
||||||
|
|
||||||
ngx_memzero(&u->headers_in, sizeof(ngx_http_upstream_headers_in_t));
|
ngx_memzero(&u->headers_in, sizeof(ngx_http_upstream_headers_in_t));
|
||||||
u->headers_in.content_length_n = -1;
|
u->headers_in.content_length_n = -1;
|
||||||
@@ -2475,7 +2473,7 @@ ngx_http_upstream_test_next(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
|||||||
#if (NGX_HTTP_CACHE)
|
#if (NGX_HTTP_CACHE)
|
||||||
|
|
||||||
if (u->cache_status == NGX_HTTP_CACHE_EXPIRED
|
if (u->cache_status == NGX_HTTP_CACHE_EXPIRED
|
||||||
&& ((u->conf->cache_use_stale & un->mask) || r->cache->stale_error))
|
&& (u->conf->cache_use_stale & un->mask))
|
||||||
{
|
{
|
||||||
ngx_int_t rc;
|
ngx_int_t rc;
|
||||||
|
|
||||||
@@ -3627,7 +3625,7 @@ ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (upstream->read->error) {
|
if (upstream->read->error || u->error) {
|
||||||
ngx_http_upstream_finalize_request(r, u,
|
ngx_http_upstream_finalize_request(r, u,
|
||||||
NGX_HTTP_BAD_GATEWAY);
|
NGX_HTTP_BAD_GATEWAY);
|
||||||
return;
|
return;
|
||||||
@@ -3705,14 +3703,14 @@ ngx_http_upstream_process_non_buffered_request(ngx_http_request_t *r,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static ngx_int_t
|
ngx_int_t
|
||||||
ngx_http_upstream_non_buffered_filter_init(void *data)
|
ngx_http_upstream_non_buffered_filter_init(void *data)
|
||||||
{
|
{
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static ngx_int_t
|
ngx_int_t
|
||||||
ngx_http_upstream_non_buffered_filter(void *data, ssize_t bytes)
|
ngx_http_upstream_non_buffered_filter(void *data, ssize_t bytes)
|
||||||
{
|
{
|
||||||
ngx_http_request_t *r = data;
|
ngx_http_request_t *r = data;
|
||||||
@@ -3748,6 +3746,18 @@ ngx_http_upstream_non_buffered_filter(void *data, ssize_t bytes)
|
|||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bytes > u->length) {
|
||||||
|
|
||||||
|
ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
|
||||||
|
"upstream sent more data than specified in "
|
||||||
|
"\"Content-Length\" header");
|
||||||
|
|
||||||
|
cl->buf->last = cl->buf->pos + u->length;
|
||||||
|
u->length = 0;
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
u->length -= bytes;
|
u->length -= bytes;
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
|
|||||||
@@ -391,6 +391,7 @@ struct ngx_http_upstream_s {
|
|||||||
unsigned buffering:1;
|
unsigned buffering:1;
|
||||||
unsigned keepalive:1;
|
unsigned keepalive:1;
|
||||||
unsigned upgrade:1;
|
unsigned upgrade:1;
|
||||||
|
unsigned error:1;
|
||||||
|
|
||||||
unsigned request_sent:1;
|
unsigned request_sent:1;
|
||||||
unsigned request_body_sent:1;
|
unsigned request_body_sent:1;
|
||||||
@@ -414,6 +415,8 @@ typedef struct {
|
|||||||
|
|
||||||
ngx_int_t ngx_http_upstream_create(ngx_http_request_t *r);
|
ngx_int_t ngx_http_upstream_create(ngx_http_request_t *r);
|
||||||
void ngx_http_upstream_init(ngx_http_request_t *r);
|
void ngx_http_upstream_init(ngx_http_request_t *r);
|
||||||
|
ngx_int_t ngx_http_upstream_non_buffered_filter_init(void *data);
|
||||||
|
ngx_int_t ngx_http_upstream_non_buffered_filter(void *data, ssize_t bytes);
|
||||||
ngx_http_upstream_srv_conf_t *ngx_http_upstream_add(ngx_conf_t *cf,
|
ngx_http_upstream_srv_conf_t *ngx_http_upstream_add(ngx_conf_t *cf,
|
||||||
ngx_url_t *u, ngx_uint_t flags);
|
ngx_url_t *u, ngx_uint_t flags);
|
||||||
char *ngx_http_upstream_bind_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
|
char *ngx_http_upstream_bind_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||||
|
|||||||
+123
-6
@@ -60,6 +60,8 @@ typedef struct {
|
|||||||
static void ngx_http_v2_read_handler(ngx_event_t *rev);
|
static void ngx_http_v2_read_handler(ngx_event_t *rev);
|
||||||
static void ngx_http_v2_write_handler(ngx_event_t *wev);
|
static void ngx_http_v2_write_handler(ngx_event_t *wev);
|
||||||
static void ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c);
|
static void ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c);
|
||||||
|
static void ngx_http_v2_lingering_close(ngx_http_v2_connection_t *h2c);
|
||||||
|
static void ngx_http_v2_lingering_close_handler(ngx_event_t *rev);
|
||||||
|
|
||||||
static u_char *ngx_http_v2_state_proxy_protocol(ngx_http_v2_connection_t *h2c,
|
static u_char *ngx_http_v2_state_proxy_protocol(ngx_http_v2_connection_t *h2c,
|
||||||
u_char *pos, u_char *end);
|
u_char *pos, u_char *end);
|
||||||
@@ -475,6 +477,7 @@ ngx_http_v2_write_handler(ngx_event_t *wev)
|
|||||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||||
"http2 write event timed out");
|
"http2 write event timed out");
|
||||||
c->error = 1;
|
c->error = 1;
|
||||||
|
c->timedout = 1;
|
||||||
ngx_http_v2_finalize_connection(h2c, 0);
|
ngx_http_v2_finalize_connection(h2c, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -663,7 +666,7 @@ ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (h2c->goaway) {
|
if (h2c->goaway) {
|
||||||
ngx_http_close_connection(c);
|
ngx_http_v2_lingering_close(h2c);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -701,6 +704,113 @@ ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
ngx_http_v2_lingering_close(ngx_http_v2_connection_t *h2c)
|
||||||
|
{
|
||||||
|
ngx_event_t *rev, *wev;
|
||||||
|
ngx_connection_t *c;
|
||||||
|
ngx_http_core_loc_conf_t *clcf;
|
||||||
|
|
||||||
|
c = h2c->connection;
|
||||||
|
|
||||||
|
clcf = ngx_http_get_module_loc_conf(h2c->http_connection->conf_ctx,
|
||||||
|
ngx_http_core_module);
|
||||||
|
|
||||||
|
if (clcf->lingering_close == NGX_HTTP_LINGERING_OFF) {
|
||||||
|
ngx_http_close_connection(c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
rev = c->read;
|
||||||
|
rev->handler = ngx_http_v2_lingering_close_handler;
|
||||||
|
|
||||||
|
h2c->lingering_time = ngx_time() + (time_t) (clcf->lingering_time / 1000);
|
||||||
|
ngx_add_timer(rev, clcf->lingering_timeout);
|
||||||
|
|
||||||
|
if (ngx_handle_read_event(rev, 0) != NGX_OK) {
|
||||||
|
ngx_http_close_connection(c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wev = c->write;
|
||||||
|
wev->handler = ngx_http_empty_handler;
|
||||||
|
|
||||||
|
if (wev->active && (ngx_event_flags & NGX_USE_LEVEL_EVENT)) {
|
||||||
|
if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) != NGX_OK) {
|
||||||
|
ngx_http_close_connection(c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ngx_shutdown_socket(c->fd, NGX_WRITE_SHUTDOWN) == -1) {
|
||||||
|
ngx_connection_error(c, ngx_socket_errno,
|
||||||
|
ngx_shutdown_socket_n " failed");
|
||||||
|
ngx_http_close_connection(c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rev->ready) {
|
||||||
|
ngx_http_v2_lingering_close_handler(rev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
ngx_http_v2_lingering_close_handler(ngx_event_t *rev)
|
||||||
|
{
|
||||||
|
ssize_t n;
|
||||||
|
ngx_msec_t timer;
|
||||||
|
ngx_connection_t *c;
|
||||||
|
ngx_http_core_loc_conf_t *clcf;
|
||||||
|
ngx_http_v2_connection_t *h2c;
|
||||||
|
u_char buffer[NGX_HTTP_LINGERING_BUFFER_SIZE];
|
||||||
|
|
||||||
|
c = rev->data;
|
||||||
|
h2c = c->data;
|
||||||
|
|
||||||
|
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||||
|
"http2 lingering close handler");
|
||||||
|
|
||||||
|
if (rev->timedout) {
|
||||||
|
ngx_http_close_connection(c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
timer = (ngx_msec_t) h2c->lingering_time - (ngx_msec_t) ngx_time();
|
||||||
|
if ((ngx_msec_int_t) timer <= 0) {
|
||||||
|
ngx_http_close_connection(c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
n = c->recv(c, buffer, NGX_HTTP_LINGERING_BUFFER_SIZE);
|
||||||
|
|
||||||
|
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "lingering read: %z", n);
|
||||||
|
|
||||||
|
if (n == NGX_ERROR || n == 0) {
|
||||||
|
ngx_http_close_connection(c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
} while (rev->ready);
|
||||||
|
|
||||||
|
if (ngx_handle_read_event(rev, 0) != NGX_OK) {
|
||||||
|
ngx_http_close_connection(c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
clcf = ngx_http_get_module_loc_conf(h2c->http_connection->conf_ctx,
|
||||||
|
ngx_http_core_module);
|
||||||
|
timer *= 1000;
|
||||||
|
|
||||||
|
if (timer > clcf->lingering_timeout) {
|
||||||
|
timer = clcf->lingering_timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_add_timer(rev, timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static u_char *
|
static u_char *
|
||||||
ngx_http_v2_state_proxy_protocol(ngx_http_v2_connection_t *h2c, u_char *pos,
|
ngx_http_v2_state_proxy_protocol(ngx_http_v2_connection_t *h2c, u_char *pos,
|
||||||
u_char *end)
|
u_char *end)
|
||||||
@@ -4551,16 +4661,15 @@ ngx_http_v2_finalize_connection(ngx_http_v2_connection_t *h2c,
|
|||||||
h2c->blocked = 1;
|
h2c->blocked = 1;
|
||||||
|
|
||||||
if (!c->error && !h2c->goaway) {
|
if (!c->error && !h2c->goaway) {
|
||||||
|
h2c->goaway = 1;
|
||||||
|
|
||||||
if (ngx_http_v2_send_goaway(h2c, status) != NGX_ERROR) {
|
if (ngx_http_v2_send_goaway(h2c, status) != NGX_ERROR) {
|
||||||
(void) ngx_http_v2_send_output_queue(h2c);
|
(void) ngx_http_v2_send_output_queue(h2c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c->error = 1;
|
|
||||||
|
|
||||||
if (!h2c->processing && !h2c->pushing) {
|
if (!h2c->processing && !h2c->pushing) {
|
||||||
ngx_http_close_connection(c);
|
goto done;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
c->read->handler = ngx_http_empty_handler;
|
c->read->handler = ngx_http_empty_handler;
|
||||||
@@ -4608,10 +4717,18 @@ ngx_http_v2_finalize_connection(ngx_http_v2_connection_t *h2c,
|
|||||||
h2c->blocked = 0;
|
h2c->blocked = 0;
|
||||||
|
|
||||||
if (h2c->processing || h2c->pushing) {
|
if (h2c->processing || h2c->pushing) {
|
||||||
|
c->error = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_http_close_connection(c);
|
done:
|
||||||
|
|
||||||
|
if (c->error) {
|
||||||
|
ngx_http_close_connection(c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_http_v2_lingering_close(h2c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -207,6 +207,8 @@ struct ngx_http_v2_connection_s {
|
|||||||
ngx_uint_t last_sid;
|
ngx_uint_t last_sid;
|
||||||
ngx_uint_t last_push;
|
ngx_uint_t last_push;
|
||||||
|
|
||||||
|
time_t lingering_time;
|
||||||
|
|
||||||
unsigned closed_nodes:8;
|
unsigned closed_nodes:8;
|
||||||
unsigned settings_ack:1;
|
unsigned settings_ack:1;
|
||||||
unsigned table_update:1;
|
unsigned table_update:1;
|
||||||
|
|||||||
@@ -875,9 +875,28 @@ ngx_fs_bsize(u_char *name)
|
|||||||
return 512;
|
return 512;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (NGX_LINUX)
|
||||||
|
if ((size_t) fs.f_bsize > ngx_pagesize) {
|
||||||
|
return 512;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return (size_t) fs.f_bsize;
|
return (size_t) fs.f_bsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
off_t
|
||||||
|
ngx_fs_available(u_char *name)
|
||||||
|
{
|
||||||
|
struct statfs fs;
|
||||||
|
|
||||||
|
if (statfs((char *) name, &fs) == -1) {
|
||||||
|
return NGX_MAX_OFF_T_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (off_t) fs.f_bavail * fs.f_bsize;
|
||||||
|
}
|
||||||
|
|
||||||
#elif (NGX_HAVE_STATVFS)
|
#elif (NGX_HAVE_STATVFS)
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
@@ -893,9 +912,28 @@ ngx_fs_bsize(u_char *name)
|
|||||||
return 512;
|
return 512;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (NGX_LINUX)
|
||||||
|
if ((size_t) fs.f_frsize > ngx_pagesize) {
|
||||||
|
return 512;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return (size_t) fs.f_frsize;
|
return (size_t) fs.f_frsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
off_t
|
||||||
|
ngx_fs_available(u_char *name)
|
||||||
|
{
|
||||||
|
struct statvfs fs;
|
||||||
|
|
||||||
|
if (statvfs((char *) name, &fs) == -1) {
|
||||||
|
return NGX_MAX_OFF_T_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (off_t) fs.f_bavail * fs.f_frsize;
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
@@ -904,4 +942,11 @@ ngx_fs_bsize(u_char *name)
|
|||||||
return 512;
|
return 512;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
off_t
|
||||||
|
ngx_fs_available(u_char *name)
|
||||||
|
{
|
||||||
|
return NGX_MAX_OFF_T_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -185,7 +185,10 @@ ngx_int_t ngx_set_file_time(u_char *name, ngx_fd_t fd, time_t s);
|
|||||||
#define ngx_is_exec(sb) (((sb)->st_mode & S_IXUSR) == S_IXUSR)
|
#define ngx_is_exec(sb) (((sb)->st_mode & S_IXUSR) == S_IXUSR)
|
||||||
#define ngx_file_access(sb) ((sb)->st_mode & 0777)
|
#define ngx_file_access(sb) ((sb)->st_mode & 0777)
|
||||||
#define ngx_file_size(sb) (sb)->st_size
|
#define ngx_file_size(sb) (sb)->st_size
|
||||||
#define ngx_file_fs_size(sb) ngx_max((sb)->st_size, (sb)->st_blocks * 512)
|
#define ngx_file_fs_size(sb) \
|
||||||
|
(((sb)->st_blocks * 512 > (sb)->st_size \
|
||||||
|
&& (sb)->st_blocks * 512 < (sb)->st_size + 8 * (sb)->st_blksize) \
|
||||||
|
? (sb)->st_blocks * 512 : (sb)->st_size)
|
||||||
#define ngx_file_mtime(sb) (sb)->st_mtime
|
#define ngx_file_mtime(sb) (sb)->st_mtime
|
||||||
#define ngx_file_uniq(sb) (sb)->st_ino
|
#define ngx_file_uniq(sb) (sb)->st_ino
|
||||||
|
|
||||||
@@ -346,6 +349,7 @@ ngx_int_t ngx_directio_off(ngx_fd_t fd);
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
size_t ngx_fs_bsize(u_char *name);
|
size_t ngx_fs_bsize(u_char *name);
|
||||||
|
off_t ngx_fs_available(u_char *name);
|
||||||
|
|
||||||
|
|
||||||
#if (NGX_HAVE_OPENAT)
|
#if (NGX_HAVE_OPENAT)
|
||||||
|
|||||||
@@ -77,12 +77,11 @@ ngx_master_process_cycle(ngx_cycle_t *cycle)
|
|||||||
u_char *p;
|
u_char *p;
|
||||||
size_t size;
|
size_t size;
|
||||||
ngx_int_t i;
|
ngx_int_t i;
|
||||||
ngx_uint_t n, sigio;
|
ngx_uint_t sigio;
|
||||||
sigset_t set;
|
sigset_t set;
|
||||||
struct itimerval itv;
|
struct itimerval itv;
|
||||||
ngx_uint_t live;
|
ngx_uint_t live;
|
||||||
ngx_msec_t delay;
|
ngx_msec_t delay;
|
||||||
ngx_listening_t *ls;
|
|
||||||
ngx_core_conf_t *ccf;
|
ngx_core_conf_t *ccf;
|
||||||
|
|
||||||
sigemptyset(&set);
|
sigemptyset(&set);
|
||||||
@@ -204,16 +203,7 @@ ngx_master_process_cycle(ngx_cycle_t *cycle)
|
|||||||
if (ngx_quit) {
|
if (ngx_quit) {
|
||||||
ngx_signal_worker_processes(cycle,
|
ngx_signal_worker_processes(cycle,
|
||||||
ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
|
ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
|
||||||
|
ngx_close_listening_sockets(cycle);
|
||||||
ls = cycle->listening.elts;
|
|
||||||
for (n = 0; n < cycle->listening.nelts; n++) {
|
|
||||||
if (ngx_close_socket(ls[n].fd) == -1) {
|
|
||||||
ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
|
|
||||||
ngx_close_socket_n " %V failed",
|
|
||||||
&ls[n].addr_text);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cycle->listening.nelts = 0;
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -189,6 +189,13 @@ ngx_udp_output_chain_to_iovec(ngx_iovec_t *vec, ngx_chain_t *in, ngx_log_t *log)
|
|||||||
return cl;
|
return cl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* zero-sized datagram; pretend to have at least 1 iov */
|
||||||
|
if (n == 0) {
|
||||||
|
iov = &vec->iovs[n++];
|
||||||
|
iov->iov_base = NULL;
|
||||||
|
iov->iov_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
vec->count = n;
|
vec->count = n;
|
||||||
vec->size = total;
|
vec->size = total;
|
||||||
|
|
||||||
|
|||||||
@@ -658,6 +658,19 @@ ngx_fs_bsize(u_char *name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
off_t
|
||||||
|
ngx_fs_available(u_char *name)
|
||||||
|
{
|
||||||
|
ULARGE_INTEGER navail;
|
||||||
|
|
||||||
|
if (GetDiskFreeSpaceEx((const char *) name, &navail, NULL, NULL) == 0) {
|
||||||
|
return NGX_MAX_OFF_T_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (off_t) navail.QuadPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_win32_check_filename(u_char *name, u_short *u, size_t len)
|
ngx_win32_check_filename(u_char *name, u_short *u, size_t len)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -259,6 +259,7 @@ ngx_int_t ngx_directio_off(ngx_fd_t fd);
|
|||||||
#define ngx_directio_off_n "ngx_directio_off_n"
|
#define ngx_directio_off_n "ngx_directio_off_n"
|
||||||
|
|
||||||
size_t ngx_fs_bsize(u_char *name);
|
size_t ngx_fs_bsize(u_char *name);
|
||||||
|
off_t ngx_fs_available(u_char *name);
|
||||||
|
|
||||||
|
|
||||||
#define ngx_stdout GetStdHandle(STD_OUTPUT_HANDLE)
|
#define ngx_stdout GetStdHandle(STD_OUTPUT_HANDLE)
|
||||||
|
|||||||
@@ -839,7 +839,7 @@ ngx_stream_proxy_init_upstream(ngx_stream_session_t *s)
|
|||||||
u->upstream_buf.last = p;
|
u->upstream_buf.last = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->buffer && c->buffer->pos < c->buffer->last) {
|
if (c->buffer && c->buffer->pos <= c->buffer->last) {
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0,
|
ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0,
|
||||||
"stream proxy add preread buffer: %uz",
|
"stream proxy add preread buffer: %uz",
|
||||||
c->buffer->last - c->buffer->pos);
|
c->buffer->last - c->buffer->pos);
|
||||||
@@ -853,6 +853,7 @@ ngx_stream_proxy_init_upstream(ngx_stream_session_t *s)
|
|||||||
*cl->buf = *c->buffer;
|
*cl->buf = *c->buffer;
|
||||||
|
|
||||||
cl->buf->tag = (ngx_buf_tag_t) &ngx_stream_proxy_module;
|
cl->buf->tag = (ngx_buf_tag_t) &ngx_stream_proxy_module;
|
||||||
|
cl->buf->temporary = (cl->buf->pos == cl->buf->last) ? 0 : 1;
|
||||||
cl->buf->flush = 1;
|
cl->buf->flush = 1;
|
||||||
|
|
||||||
cl->next = u->upstream_out;
|
cl->next = u->upstream_out;
|
||||||
|
|||||||
@@ -234,7 +234,8 @@ ngx_stream_write_filter(ngx_stream_session_t *s, ngx_chain_t *in,
|
|||||||
|
|
||||||
if (size == 0
|
if (size == 0
|
||||||
&& !(c->buffered & NGX_LOWLEVEL_BUFFERED)
|
&& !(c->buffered & NGX_LOWLEVEL_BUFFERED)
|
||||||
&& !(last && c->need_last_buf))
|
&& !(last && c->need_last_buf)
|
||||||
|
&& !(c->type == SOCK_DGRAM && flush))
|
||||||
{
|
{
|
||||||
if (last || flush || sync) {
|
if (last || flush || sync) {
|
||||||
for (cl = *out; cl; /* void */) {
|
for (cl = *out; cl; /* void */) {
|
||||||
|
|||||||
Reference in New Issue
Block a user