Update Nginx auf 1.13.1
This commit is contained in:
36
auto/cc/conf
36
auto/cc/conf
@@ -178,21 +178,25 @@ if [ "$NGX_PLATFORM" != win32 ]; then
|
||||
fi
|
||||
|
||||
|
||||
ngx_feature="gcc builtin atomic operations"
|
||||
ngx_feature_name=NGX_HAVE_GCC_ATOMIC
|
||||
ngx_feature_run=yes
|
||||
ngx_feature_incs=
|
||||
ngx_feature_path=
|
||||
ngx_feature_libs=
|
||||
ngx_feature_test="long n = 0;
|
||||
if (!__sync_bool_compare_and_swap(&n, 0, 1))
|
||||
return 1;
|
||||
if (__sync_fetch_and_add(&n, 1) != 1)
|
||||
return 1;
|
||||
if (n != 2)
|
||||
return 1;
|
||||
__sync_synchronize();"
|
||||
. auto/feature
|
||||
if [ "$NGX_CC_NAME" = "sunc" ]; then
|
||||
echo "checking for gcc builtin atomic operations ... disabled"
|
||||
else
|
||||
ngx_feature="gcc builtin atomic operations"
|
||||
ngx_feature_name=NGX_HAVE_GCC_ATOMIC
|
||||
ngx_feature_run=yes
|
||||
ngx_feature_incs=
|
||||
ngx_feature_path=
|
||||
ngx_feature_libs=
|
||||
ngx_feature_test="long n = 0;
|
||||
if (!__sync_bool_compare_and_swap(&n, 0, 1))
|
||||
return 1;
|
||||
if (__sync_fetch_and_add(&n, 1) != 1)
|
||||
return 1;
|
||||
if (n != 2)
|
||||
return 1;
|
||||
__sync_synchronize();"
|
||||
. auto/feature
|
||||
fi
|
||||
|
||||
|
||||
if [ "$NGX_CC_NAME" = "ccc" ]; then
|
||||
@@ -209,7 +213,7 @@ if [ "$NGX_PLATFORM" != win32 ]; then
|
||||
var(0, buf, \"%d\", 1);
|
||||
if (buf[0] != '1') return 1"
|
||||
. auto/feature
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
ngx_feature="gcc variadic macros"
|
||||
|
||||
@@ -8,7 +8,10 @@
|
||||
# Sun C 5.9 SunOS_i386 2007/05/03 Sun Studio 12
|
||||
# Sun C 5.9 SunOS_sparc 2007/05/03
|
||||
# Sun C 5.10 SunOS_i386 2009/06/03 Sun Studio 12.1
|
||||
# Sun C 5.11 SunOS_i386 2010/08/13 Sun Studio 12.2
|
||||
# Sun C 5.11 SunOS_i386 2010/08/13 Oracle Solaris Studio 12.2
|
||||
# Sun C 5.12 SunOS_i386 2011/11/16 Oracle Solaris Studio 12.3
|
||||
# Sun C 5.13 SunOS_i386 2014/10/20 Oracle Solaris Studio 12.4
|
||||
# Sun C 5.14 SunOS_i386 2016/05/31 Oracle Developer Studio 12.5
|
||||
|
||||
NGX_SUNC_VER=`$CC -V 2>&1 | grep 'Sun C' 2>&1 \
|
||||
| sed -e 's/^.* Sun C \(.*\)/\1/'`
|
||||
|
||||
1651
auto/modules
1651
auto/modules
File diff suppressed because it is too large
Load Diff
13
auto/options
13
auto/options
@@ -574,19 +574,6 @@ END
|
||||
fi
|
||||
|
||||
|
||||
if [ $HTTP = NO ]; then
|
||||
HTTP_CHARSET=NO
|
||||
HTTP_GZIP=NO
|
||||
HTTP_SSI=NO
|
||||
HTTP_USERID=NO
|
||||
HTTP_ACCESS=NO
|
||||
HTTP_STATUS=NO
|
||||
HTTP_REWRITE=NO
|
||||
HTTP_PROXY=NO
|
||||
HTTP_FASTCGI=NO
|
||||
fi
|
||||
|
||||
|
||||
if [ ".$NGX_PLATFORM" = ".win32" ]; then
|
||||
NGX_WINE=$WINE
|
||||
fi
|
||||
|
||||
@@ -17,6 +17,9 @@ ngx_spacer='
|
||||
MAIN_LINK=
|
||||
MODULE_LINK="-shared -Wl,-undefined,dynamic_lookup"
|
||||
|
||||
CC_AUX_FLAGS="$CC_AUX_FLAGS -D__APPLE_USE_RFC_3542"
|
||||
|
||||
|
||||
# kqueue
|
||||
|
||||
echo " + kqueue found"
|
||||
@@ -86,7 +89,6 @@ ngx_feature_test="int kq;
|
||||
|
||||
# sendfile()
|
||||
|
||||
CC_AUX_FLAGS="$CC_AUX_FLAGS"
|
||||
ngx_feature="sendfile()"
|
||||
ngx_feature_name="NGX_HAVE_SENDFILE"
|
||||
ngx_feature_run=yes
|
||||
|
||||
@@ -157,20 +157,6 @@ ngx_feature_test="if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) return 1"
|
||||
. auto/feature
|
||||
|
||||
|
||||
# sched_setaffinity()
|
||||
|
||||
ngx_feature="sched_setaffinity()"
|
||||
ngx_feature_name="NGX_HAVE_SCHED_SETAFFINITY"
|
||||
ngx_feature_run=no
|
||||
ngx_feature_incs="#include <sched.h>"
|
||||
ngx_feature_path=
|
||||
ngx_feature_libs=
|
||||
ngx_feature_test="cpu_set_t mask;
|
||||
CPU_ZERO(&mask);
|
||||
sched_setaffinity(0, sizeof(cpu_set_t), &mask)"
|
||||
. auto/feature
|
||||
|
||||
|
||||
# crypt_r()
|
||||
|
||||
ngx_feature="crypt_r()"
|
||||
|
||||
25
auto/unix
Executable file → Normal file
25
auto/unix
Executable file → Normal file
@@ -300,6 +300,18 @@ if [ $ngx_found = no ]; then
|
||||
fi
|
||||
|
||||
|
||||
ngx_feature="sched_setaffinity()"
|
||||
ngx_feature_name="NGX_HAVE_SCHED_SETAFFINITY"
|
||||
ngx_feature_run=no
|
||||
ngx_feature_incs="#include <sched.h>"
|
||||
ngx_feature_path=
|
||||
ngx_feature_libs=
|
||||
ngx_feature_test="cpu_set_t mask;
|
||||
CPU_ZERO(&mask);
|
||||
sched_setaffinity(0, sizeof(cpu_set_t), &mask)"
|
||||
. auto/feature
|
||||
|
||||
|
||||
ngx_feature="SO_SETFIB"
|
||||
ngx_feature_name="NGX_HAVE_SETFIB"
|
||||
ngx_feature_run=no
|
||||
@@ -394,6 +406,19 @@ ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_RECVDSTADDR, NULL, 0)"
|
||||
. auto/feature
|
||||
|
||||
|
||||
# BSD way to set IPv4 datagram source address
|
||||
|
||||
ngx_feature="IP_SENDSRCADDR"
|
||||
ngx_feature_name="NGX_HAVE_IP_SENDSRCADDR"
|
||||
ngx_feature_run=no
|
||||
ngx_feature_incs="#include <sys/socket.h>
|
||||
#include <netinet/in.h>"
|
||||
ngx_feature_path=
|
||||
ngx_feature_libs=
|
||||
ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_SENDSRCADDR, NULL, 0)"
|
||||
. auto/feature
|
||||
|
||||
|
||||
# Linux way to get IPv4 datagram destination address
|
||||
|
||||
ngx_feature="IP_PKTINFO"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -124,6 +124,13 @@ static ngx_command_t ngx_core_commands[] = {
|
||||
offsetof(ngx_core_conf_t, rlimit_core),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("worker_shutdown_timeout"),
|
||||
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_msec_slot,
|
||||
0,
|
||||
offsetof(ngx_core_conf_t, shutdown_timeout),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("working_directory"),
|
||||
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_str_slot,
|
||||
@@ -1014,6 +1021,7 @@ ngx_core_module_create_conf(ngx_cycle_t *cycle)
|
||||
ccf->daemon = NGX_CONF_UNSET;
|
||||
ccf->master = NGX_CONF_UNSET;
|
||||
ccf->timer_resolution = NGX_CONF_UNSET_MSEC;
|
||||
ccf->shutdown_timeout = NGX_CONF_UNSET_MSEC;
|
||||
|
||||
ccf->worker_processes = NGX_CONF_UNSET;
|
||||
ccf->debug_points = NGX_CONF_UNSET;
|
||||
@@ -1042,6 +1050,7 @@ ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf)
|
||||
ngx_conf_init_value(ccf->daemon, 1);
|
||||
ngx_conf_init_value(ccf->master, 1);
|
||||
ngx_conf_init_msec_value(ccf->timer_resolution, 0);
|
||||
ngx_conf_init_msec_value(ccf->shutdown_timeout, 0);
|
||||
|
||||
ngx_conf_init_value(ccf->worker_processes, 1);
|
||||
ngx_conf_init_value(ccf->debug_points, 0);
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
#define _NGINX_H_INCLUDED_
|
||||
|
||||
|
||||
#define nginx_version 1011009
|
||||
#define NGINX_VERSION "1.11.9"
|
||||
#define nginx_version 1013001
|
||||
#define NGINX_VERSION "1.13.1"
|
||||
#define NGINX_VER "nginx/" NGINX_VERSION
|
||||
|
||||
#ifdef NGX_BUILD
|
||||
|
||||
@@ -1345,6 +1345,49 @@ ngx_connection_local_sockaddr(ngx_connection_t *c, ngx_str_t *s,
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_tcp_nodelay(ngx_connection_t *c)
|
||||
{
|
||||
int tcp_nodelay;
|
||||
|
||||
if (c->tcp_nodelay != NGX_TCP_NODELAY_UNSET) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_CORE, c->log, 0, "tcp_nodelay");
|
||||
|
||||
tcp_nodelay = 1;
|
||||
|
||||
if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
|
||||
(const void *) &tcp_nodelay, sizeof(int))
|
||||
== -1)
|
||||
{
|
||||
#if (NGX_SOLARIS)
|
||||
if (c->log_error == NGX_ERROR_INFO) {
|
||||
|
||||
/* Solaris returns EINVAL if a socket has been shut down */
|
||||
c->log_error = NGX_ERROR_IGNORE_EINVAL;
|
||||
|
||||
ngx_connection_error(c, ngx_socket_errno,
|
||||
"setsockopt(TCP_NODELAY) failed");
|
||||
|
||||
c->log_error = NGX_ERROR_INFO;
|
||||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
ngx_connection_error(c, ngx_socket_errno,
|
||||
"setsockopt(TCP_NODELAY) failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
c->tcp_nodelay = NGX_TCP_NODELAY_SET;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_connection_error(ngx_connection_t *c, ngx_err_t err, char *text)
|
||||
{
|
||||
|
||||
@@ -214,6 +214,7 @@ void ngx_close_connection(ngx_connection_t *c);
|
||||
void ngx_close_idle_connections(ngx_cycle_t *cycle);
|
||||
ngx_int_t ngx_connection_local_sockaddr(ngx_connection_t *c, ngx_str_t *s,
|
||||
ngx_uint_t port);
|
||||
ngx_int_t ngx_tcp_nodelay(ngx_connection_t *c);
|
||||
ngx_int_t ngx_connection_error(ngx_connection_t *c, ngx_err_t err, char *text);
|
||||
|
||||
ngx_connection_t *ngx_get_connection(ngx_socket_t s, ngx_log_t *log);
|
||||
|
||||
@@ -15,6 +15,7 @@ static ngx_int_t ngx_init_zone_pool(ngx_cycle_t *cycle,
|
||||
ngx_shm_zone_t *shm_zone);
|
||||
static ngx_int_t ngx_test_lockfile(u_char *file, ngx_log_t *log);
|
||||
static void ngx_clean_old_cycles(ngx_event_t *ev);
|
||||
static void ngx_shutdown_timer_handler(ngx_event_t *ev);
|
||||
|
||||
|
||||
volatile ngx_cycle_t *ngx_cycle;
|
||||
@@ -22,6 +23,7 @@ ngx_array_t ngx_old_cycles;
|
||||
|
||||
static ngx_pool_t *ngx_temp_pool;
|
||||
static ngx_event_t ngx_cleaner_event;
|
||||
static ngx_event_t ngx_shutdown_event;
|
||||
|
||||
ngx_uint_t ngx_test_config;
|
||||
ngx_uint_t ngx_dump_config;
|
||||
@@ -113,16 +115,14 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
|
||||
|
||||
n = old_cycle->paths.nelts ? old_cycle->paths.nelts : 10;
|
||||
|
||||
cycle->paths.elts = ngx_pcalloc(pool, n * sizeof(ngx_path_t *));
|
||||
if (cycle->paths.elts == NULL) {
|
||||
if (ngx_array_init(&cycle->paths, pool, n, sizeof(ngx_path_t *))
|
||||
!= NGX_OK)
|
||||
{
|
||||
ngx_destroy_pool(pool);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cycle->paths.nelts = 0;
|
||||
cycle->paths.size = sizeof(ngx_path_t *);
|
||||
cycle->paths.nalloc = n;
|
||||
cycle->paths.pool = pool;
|
||||
ngx_memzero(cycle->paths.elts, n * sizeof(ngx_path_t *));
|
||||
|
||||
|
||||
if (ngx_array_init(&cycle->config_dump, pool, 1, sizeof(ngx_conf_dump_t))
|
||||
@@ -173,16 +173,14 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
|
||||
|
||||
n = old_cycle->listening.nelts ? old_cycle->listening.nelts : 10;
|
||||
|
||||
cycle->listening.elts = ngx_pcalloc(pool, n * sizeof(ngx_listening_t));
|
||||
if (cycle->listening.elts == NULL) {
|
||||
if (ngx_array_init(&cycle->listening, pool, n, sizeof(ngx_listening_t))
|
||||
!= NGX_OK)
|
||||
{
|
||||
ngx_destroy_pool(pool);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cycle->listening.nelts = 0;
|
||||
cycle->listening.size = sizeof(ngx_listening_t);
|
||||
cycle->listening.nalloc = n;
|
||||
cycle->listening.pool = pool;
|
||||
ngx_memzero(cycle->listening.elts, n * sizeof(ngx_listening_t));
|
||||
|
||||
|
||||
ngx_queue_init(&cycle->reusable_connections_queue);
|
||||
@@ -766,15 +764,15 @@ old_shm_zone_done:
|
||||
}
|
||||
|
||||
n = 10;
|
||||
ngx_old_cycles.elts = ngx_pcalloc(ngx_temp_pool,
|
||||
n * sizeof(ngx_cycle_t *));
|
||||
if (ngx_old_cycles.elts == NULL) {
|
||||
|
||||
if (ngx_array_init(&ngx_old_cycles, ngx_temp_pool, n,
|
||||
sizeof(ngx_cycle_t *))
|
||||
!= NGX_OK)
|
||||
{
|
||||
exit(1);
|
||||
}
|
||||
ngx_old_cycles.nelts = 0;
|
||||
ngx_old_cycles.size = sizeof(ngx_cycle_t *);
|
||||
ngx_old_cycles.nalloc = n;
|
||||
ngx_old_cycles.pool = ngx_temp_pool;
|
||||
|
||||
ngx_memzero(ngx_old_cycles.elts, n * sizeof(ngx_cycle_t *));
|
||||
|
||||
ngx_cleaner_event.handler = ngx_clean_old_cycles;
|
||||
ngx_cleaner_event.log = cycle->log;
|
||||
@@ -1333,3 +1331,54 @@ ngx_clean_old_cycles(ngx_event_t *ev)
|
||||
ngx_old_cycles.nelts = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_set_shutdown_timer(ngx_cycle_t *cycle)
|
||||
{
|
||||
ngx_core_conf_t *ccf;
|
||||
|
||||
ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
|
||||
|
||||
if (ccf->shutdown_timeout) {
|
||||
ngx_shutdown_event.handler = ngx_shutdown_timer_handler;
|
||||
ngx_shutdown_event.data = cycle;
|
||||
ngx_shutdown_event.log = cycle->log;
|
||||
ngx_shutdown_event.cancelable = 1;
|
||||
|
||||
ngx_add_timer(&ngx_shutdown_event, ccf->shutdown_timeout);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ngx_shutdown_timer_handler(ngx_event_t *ev)
|
||||
{
|
||||
ngx_uint_t i;
|
||||
ngx_cycle_t *cycle;
|
||||
ngx_connection_t *c;
|
||||
|
||||
cycle = ev->data;
|
||||
|
||||
c = cycle->connections;
|
||||
|
||||
for (i = 0; i < cycle->connection_n; i++) {
|
||||
|
||||
if (c[i].fd == (ngx_socket_t) -1
|
||||
|| c[i].read == NULL
|
||||
|| c[i].read->accept
|
||||
|| c[i].read->channel
|
||||
|| c[i].read->resolver)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_CORE, ev->log, 0,
|
||||
"*%uA shutdown timeout", c[i].number);
|
||||
|
||||
c[i].close = 1;
|
||||
c[i].error = 1;
|
||||
|
||||
c[i].read->handler(c[i].read);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +88,7 @@ typedef struct {
|
||||
ngx_flag_t master;
|
||||
|
||||
ngx_msec_t timer_resolution;
|
||||
ngx_msec_t shutdown_timeout;
|
||||
|
||||
ngx_int_t worker_processes;
|
||||
ngx_int_t debug_points;
|
||||
@@ -129,6 +130,7 @@ ngx_pid_t ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv);
|
||||
ngx_cpuset_t *ngx_get_cpu_affinity(ngx_uint_t n);
|
||||
ngx_shm_zone_t *ngx_shared_memory_add(ngx_conf_t *cf, ngx_str_t *name,
|
||||
size_t size, void *tag);
|
||||
void ngx_set_shutdown_timer(ngx_cycle_t *cycle);
|
||||
|
||||
|
||||
extern volatile ngx_cycle_t *ngx_cycle;
|
||||
|
||||
@@ -35,8 +35,10 @@ ngx_murmur_hash2(u_char *data, size_t len)
|
||||
switch (len) {
|
||||
case 3:
|
||||
h ^= data[2] << 16;
|
||||
/* fall through */
|
||||
case 2:
|
||||
h ^= data[1] << 8;
|
||||
/* fall through */
|
||||
case 1:
|
||||
h ^= data[0];
|
||||
h *= 0x5bd1e995;
|
||||
|
||||
@@ -72,9 +72,6 @@ typedef struct {
|
||||
} ngx_pool_cleanup_file_t;
|
||||
|
||||
|
||||
void *ngx_alloc(size_t size, ngx_log_t *log);
|
||||
void *ngx_calloc(size_t size, ngx_log_t *log);
|
||||
|
||||
ngx_pool_t *ngx_create_pool(size_t size, ngx_log_t *log);
|
||||
void ngx_destroy_pool(ngx_pool_t *pool);
|
||||
void ngx_reset_pool(ngx_pool_t *pool);
|
||||
|
||||
@@ -17,6 +17,11 @@ ngx_parse_size(ngx_str_t *line)
|
||||
ssize_t size, scale, max;
|
||||
|
||||
len = line->len;
|
||||
|
||||
if (len == 0) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
unit = line->data[len - 1];
|
||||
|
||||
switch (unit) {
|
||||
@@ -58,6 +63,11 @@ ngx_parse_offset(ngx_str_t *line)
|
||||
size_t len;
|
||||
|
||||
len = line->len;
|
||||
|
||||
if (len == 0) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
unit = line->data[len - 1];
|
||||
|
||||
switch (unit) {
|
||||
|
||||
@@ -28,7 +28,7 @@ ngx_rbtree_insert(ngx_rbtree_t *tree, ngx_rbtree_node_t *node)
|
||||
|
||||
/* a binary tree insert */
|
||||
|
||||
root = (ngx_rbtree_node_t **) &tree->root;
|
||||
root = &tree->root;
|
||||
sentinel = tree->sentinel;
|
||||
|
||||
if (*root == sentinel) {
|
||||
@@ -161,7 +161,7 @@ ngx_rbtree_delete(ngx_rbtree_t *tree, ngx_rbtree_node_t *node)
|
||||
|
||||
/* a binary tree delete */
|
||||
|
||||
root = (ngx_rbtree_node_t **) &tree->root;
|
||||
root = &tree->root;
|
||||
sentinel = tree->sentinel;
|
||||
|
||||
if (node->left == sentinel) {
|
||||
@@ -378,3 +378,32 @@ ngx_rbtree_right_rotate(ngx_rbtree_node_t **root, ngx_rbtree_node_t *sentinel,
|
||||
temp->right = node;
|
||||
node->parent = temp;
|
||||
}
|
||||
|
||||
|
||||
ngx_rbtree_node_t *
|
||||
ngx_rbtree_next(ngx_rbtree_t *tree, ngx_rbtree_node_t *node)
|
||||
{
|
||||
ngx_rbtree_node_t *root, *sentinel, *parent;
|
||||
|
||||
sentinel = tree->sentinel;
|
||||
|
||||
if (node->right != sentinel) {
|
||||
return ngx_rbtree_min(node->right, sentinel);
|
||||
}
|
||||
|
||||
root = tree->root;
|
||||
|
||||
for ( ;; ) {
|
||||
parent = node->parent;
|
||||
|
||||
if (node == root) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (node == parent->left) {
|
||||
return parent;
|
||||
}
|
||||
|
||||
node = parent;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,8 @@ void ngx_rbtree_insert_value(ngx_rbtree_node_t *root, ngx_rbtree_node_t *node,
|
||||
ngx_rbtree_node_t *sentinel);
|
||||
void ngx_rbtree_insert_timer_value(ngx_rbtree_node_t *root,
|
||||
ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel);
|
||||
ngx_rbtree_node_t *ngx_rbtree_next(ngx_rbtree_t *tree,
|
||||
ngx_rbtree_node_t *node);
|
||||
|
||||
|
||||
#define ngx_rbt_red(node) ((node)->color = 1)
|
||||
|
||||
@@ -56,8 +56,8 @@ typedef struct {
|
||||
((u_char *) (n) - offsetof(ngx_resolver_node_t, node))
|
||||
|
||||
|
||||
ngx_int_t ngx_udp_connect(ngx_resolver_connection_t *rec);
|
||||
ngx_int_t ngx_tcp_connect(ngx_resolver_connection_t *rec);
|
||||
static ngx_int_t ngx_udp_connect(ngx_resolver_connection_t *rec);
|
||||
static ngx_int_t ngx_tcp_connect(ngx_resolver_connection_t *rec);
|
||||
|
||||
|
||||
static void ngx_resolver_cleanup(void *data);
|
||||
@@ -4379,7 +4379,7 @@ ngx_resolver_log_error(ngx_log_t *log, u_char *buf, size_t len)
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
static ngx_int_t
|
||||
ngx_udp_connect(ngx_resolver_connection_t *rec)
|
||||
{
|
||||
int rc;
|
||||
@@ -4463,7 +4463,7 @@ failed:
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
static ngx_int_t
|
||||
ngx_tcp_connect(ngx_resolver_connection_t *rec)
|
||||
{
|
||||
int rc;
|
||||
|
||||
@@ -1808,7 +1808,19 @@ ngx_escape_json(u_char *dst, u_char *src, size_t size)
|
||||
len++;
|
||||
|
||||
} else if (ch <= 0x1f) {
|
||||
len += sizeof("\\u001F") - 2;
|
||||
|
||||
switch (ch) {
|
||||
case '\n':
|
||||
case '\r':
|
||||
case '\t':
|
||||
case '\b':
|
||||
case '\f':
|
||||
len++;
|
||||
break;
|
||||
|
||||
default:
|
||||
len += sizeof("\\u001F") - 2;
|
||||
}
|
||||
}
|
||||
|
||||
size--;
|
||||
@@ -1829,12 +1841,37 @@ ngx_escape_json(u_char *dst, u_char *src, size_t size)
|
||||
*dst++ = ch;
|
||||
|
||||
} else {
|
||||
*dst++ = '\\'; *dst++ = 'u'; *dst++ = '0'; *dst++ = '0';
|
||||
*dst++ = '0' + (ch >> 4);
|
||||
*dst++ = '\\';
|
||||
|
||||
ch &= 0xf;
|
||||
switch (ch) {
|
||||
case '\n':
|
||||
*dst++ = 'n';
|
||||
break;
|
||||
|
||||
*dst++ = (ch < 10) ? ('0' + ch) : ('A' + ch - 10);
|
||||
case '\r':
|
||||
*dst++ = 'r';
|
||||
break;
|
||||
|
||||
case '\t':
|
||||
*dst++ = 't';
|
||||
break;
|
||||
|
||||
case '\b':
|
||||
*dst++ = 'b';
|
||||
break;
|
||||
|
||||
case '\f':
|
||||
*dst++ = 'f';
|
||||
break;
|
||||
|
||||
default:
|
||||
*dst++ = 'u'; *dst++ = '0'; *dst++ = '0';
|
||||
*dst++ = '0' + (ch >> 4);
|
||||
|
||||
ch &= 0xf;
|
||||
|
||||
*dst++ = (ch < 10) ? ('0' + ch) : ('A' + ch - 10);
|
||||
}
|
||||
}
|
||||
|
||||
size--;
|
||||
|
||||
@@ -78,7 +78,7 @@ static ngx_command_t ngx_devpoll_commands[] = {
|
||||
};
|
||||
|
||||
|
||||
ngx_event_module_t ngx_devpoll_module_ctx = {
|
||||
static ngx_event_module_t ngx_devpoll_module_ctx = {
|
||||
&devpoll_name,
|
||||
ngx_devpoll_create_conf, /* create configuration */
|
||||
ngx_devpoll_init_conf, /* init configuration */
|
||||
@@ -336,7 +336,7 @@ ngx_devpoll_set_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
static ngx_int_t
|
||||
ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
|
||||
ngx_uint_t flags)
|
||||
{
|
||||
|
||||
@@ -176,7 +176,7 @@ static ngx_command_t ngx_epoll_commands[] = {
|
||||
};
|
||||
|
||||
|
||||
ngx_event_module_t ngx_epoll_module_ctx = {
|
||||
static ngx_event_module_t ngx_epoll_module_ctx = {
|
||||
&epoll_name,
|
||||
ngx_epoll_create_conf, /* create configuration */
|
||||
ngx_epoll_init_conf, /* init configuration */
|
||||
|
||||
@@ -169,7 +169,7 @@ static ngx_command_t ngx_eventport_commands[] = {
|
||||
};
|
||||
|
||||
|
||||
ngx_event_module_t ngx_eventport_module_ctx = {
|
||||
static ngx_event_module_t ngx_eventport_module_ctx = {
|
||||
&eventport_name,
|
||||
ngx_eventport_create_conf, /* create configuration */
|
||||
ngx_eventport_init_conf, /* init configuration */
|
||||
@@ -432,7 +432,7 @@ ngx_eventport_notify(ngx_event_handler_pt handler)
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
static ngx_int_t
|
||||
ngx_eventport_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
|
||||
ngx_uint_t flags)
|
||||
{
|
||||
|
||||
@@ -73,7 +73,7 @@ static ngx_command_t ngx_kqueue_commands[] = {
|
||||
};
|
||||
|
||||
|
||||
ngx_event_module_t ngx_kqueue_module_ctx = {
|
||||
static ngx_event_module_t ngx_kqueue_module_ctx = {
|
||||
&kqueue_name,
|
||||
ngx_kqueue_create_conf, /* create configuration */
|
||||
ngx_kqueue_init_conf, /* init configuration */
|
||||
|
||||
@@ -25,9 +25,9 @@ static struct pollfd *event_list;
|
||||
static ngx_uint_t nevents;
|
||||
|
||||
|
||||
static ngx_str_t poll_name = ngx_string("poll");
|
||||
static ngx_str_t poll_name = ngx_string("poll");
|
||||
|
||||
ngx_event_module_t ngx_poll_module_ctx = {
|
||||
static ngx_event_module_t ngx_poll_module_ctx = {
|
||||
&poll_name,
|
||||
NULL, /* create configuration */
|
||||
ngx_poll_init_conf, /* init configuration */
|
||||
|
||||
@@ -33,9 +33,9 @@ static ngx_uint_t nevents;
|
||||
static ngx_event_t **event_index;
|
||||
|
||||
|
||||
static ngx_str_t select_name = ngx_string("select");
|
||||
static ngx_str_t select_name = ngx_string("select");
|
||||
|
||||
ngx_event_module_t ngx_select_module_ctx = {
|
||||
static ngx_event_module_t ngx_select_module_ctx = {
|
||||
&select_name,
|
||||
NULL, /* create configuration */
|
||||
ngx_select_init_conf, /* init configuration */
|
||||
|
||||
@@ -34,9 +34,9 @@ static ngx_uint_t nevents;
|
||||
static ngx_event_t **event_index;
|
||||
|
||||
|
||||
static ngx_str_t select_name = ngx_string("select");
|
||||
static ngx_str_t select_name = ngx_string("select");
|
||||
|
||||
ngx_event_module_t ngx_select_module_ctx = {
|
||||
static ngx_event_module_t ngx_select_module_ctx = {
|
||||
&select_name,
|
||||
NULL, /* create configuration */
|
||||
ngx_select_init_conf, /* init configuration */
|
||||
|
||||
@@ -59,20 +59,20 @@ ngx_int_t ngx_accept_disabled;
|
||||
|
||||
#if (NGX_STAT_STUB)
|
||||
|
||||
ngx_atomic_t ngx_stat_accepted0;
|
||||
ngx_atomic_t *ngx_stat_accepted = &ngx_stat_accepted0;
|
||||
ngx_atomic_t ngx_stat_handled0;
|
||||
ngx_atomic_t *ngx_stat_handled = &ngx_stat_handled0;
|
||||
ngx_atomic_t ngx_stat_requests0;
|
||||
ngx_atomic_t *ngx_stat_requests = &ngx_stat_requests0;
|
||||
ngx_atomic_t ngx_stat_active0;
|
||||
ngx_atomic_t *ngx_stat_active = &ngx_stat_active0;
|
||||
ngx_atomic_t ngx_stat_reading0;
|
||||
ngx_atomic_t *ngx_stat_reading = &ngx_stat_reading0;
|
||||
ngx_atomic_t ngx_stat_writing0;
|
||||
ngx_atomic_t *ngx_stat_writing = &ngx_stat_writing0;
|
||||
ngx_atomic_t ngx_stat_waiting0;
|
||||
ngx_atomic_t *ngx_stat_waiting = &ngx_stat_waiting0;
|
||||
static ngx_atomic_t ngx_stat_accepted0;
|
||||
ngx_atomic_t *ngx_stat_accepted = &ngx_stat_accepted0;
|
||||
static ngx_atomic_t ngx_stat_handled0;
|
||||
ngx_atomic_t *ngx_stat_handled = &ngx_stat_handled0;
|
||||
static ngx_atomic_t ngx_stat_requests0;
|
||||
ngx_atomic_t *ngx_stat_requests = &ngx_stat_requests0;
|
||||
static ngx_atomic_t ngx_stat_active0;
|
||||
ngx_atomic_t *ngx_stat_active = &ngx_stat_active0;
|
||||
static ngx_atomic_t ngx_stat_reading0;
|
||||
ngx_atomic_t *ngx_stat_reading = &ngx_stat_reading0;
|
||||
static ngx_atomic_t ngx_stat_writing0;
|
||||
ngx_atomic_t *ngx_stat_writing = &ngx_stat_writing0;
|
||||
static ngx_atomic_t ngx_stat_waiting0;
|
||||
ngx_atomic_t *ngx_stat_waiting = &ngx_stat_waiting0;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -165,7 +165,7 @@ static ngx_command_t ngx_event_core_commands[] = {
|
||||
};
|
||||
|
||||
|
||||
ngx_event_module_t ngx_event_core_module_ctx = {
|
||||
static ngx_event_module_t ngx_event_core_module_ctx = {
|
||||
&event_core_name,
|
||||
ngx_event_core_create_conf, /* create configuration */
|
||||
ngx_event_core_init_conf, /* init configuration */
|
||||
@@ -500,8 +500,7 @@ ngx_event_module_init(ngx_cycle_t *cycle)
|
||||
#endif
|
||||
|
||||
shm.size = size;
|
||||
shm.name.len = sizeof("nginx_shared_zone") - 1;
|
||||
shm.name.data = (u_char *) "nginx_shared_zone";
|
||||
ngx_str_set(&shm.name, "nginx_shared_zone");
|
||||
shm.log = cycle->log;
|
||||
|
||||
if (ngx_shm_alloc(&shm) != NGX_OK) {
|
||||
|
||||
@@ -238,7 +238,7 @@ ngx_event_accept(ngx_event_t *ev)
|
||||
|
||||
if (ev->deferred_accept) {
|
||||
rev->ready = 1;
|
||||
#if (NGX_HAVE_KQUEUE)
|
||||
#if (NGX_HAVE_KQUEUE || NGX_HAVE_EPOLLRDHUP)
|
||||
rev->available = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -121,7 +121,17 @@ ngx_ssl_init(ngx_log_t *log)
|
||||
{
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100003L
|
||||
|
||||
OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
|
||||
if (OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL) == 0) {
|
||||
ngx_ssl_error(NGX_LOG_ALERT, log, 0, "OPENSSL_init_ssl() failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* OPENSSL_init_ssl() may leave errors in the error queue
|
||||
* while returning success
|
||||
*/
|
||||
|
||||
ERR_clear_error();
|
||||
|
||||
#else
|
||||
|
||||
@@ -313,6 +323,12 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data)
|
||||
SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_TLSv1_2);
|
||||
}
|
||||
#endif
|
||||
#ifdef SSL_OP_NO_TLSv1_3
|
||||
SSL_CTX_clear_options(ssl->ctx, SSL_OP_NO_TLSv1_3);
|
||||
if (!(protocols & NGX_SSL_TLSv1_3)) {
|
||||
SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_TLSv1_3);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SSL_OP_NO_COMPRESSION
|
||||
SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_COMPRESSION);
|
||||
@@ -821,7 +837,9 @@ ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where, int ret)
|
||||
BIO *rbio, *wbio;
|
||||
ngx_connection_t *c;
|
||||
|
||||
if (where & SSL_CB_HANDSHAKE_START) {
|
||||
if ((where & SSL_CB_HANDSHAKE_START)
|
||||
&& SSL_is_server((ngx_ssl_conn_t *) ssl_conn))
|
||||
{
|
||||
c = ngx_ssl_get_connection((ngx_ssl_conn_t *) ssl_conn);
|
||||
|
||||
if (c->ssl->handshaked) {
|
||||
@@ -1072,7 +1090,7 @@ ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *name)
|
||||
* maximum interoperability.
|
||||
*/
|
||||
|
||||
#ifdef SSL_CTRL_SET_CURVES_LIST
|
||||
#if (defined SSL_CTX_set1_curves_list || defined SSL_CTRL_SET_CURVES_LIST)
|
||||
|
||||
/*
|
||||
* OpenSSL 1.0.2+ allows configuring a curve list instead of a single
|
||||
@@ -1282,7 +1300,7 @@ ngx_ssl_handshake(ngx_connection_t *c)
|
||||
#ifdef SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS
|
||||
|
||||
/* initial handshake done, disable renegotiation (CVE-2009-3555) */
|
||||
if (c->ssl->connection->s3) {
|
||||
if (c->ssl->connection->s3 && SSL_is_server(c->ssl->connection)) {
|
||||
c->ssl->connection->s3->flags |= SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,11 @@
|
||||
#define ngx_ssl_conn_t SSL
|
||||
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10002000L)
|
||||
#define SSL_is_server(s) (s)->server
|
||||
#endif
|
||||
|
||||
|
||||
struct ngx_ssl_s {
|
||||
SSL_CTX *ctx;
|
||||
ngx_log_t *log;
|
||||
@@ -131,6 +136,7 @@ typedef struct {
|
||||
#define NGX_SSL_TLSv1 0x0008
|
||||
#define NGX_SSL_TLSv1_1 0x0010
|
||||
#define NGX_SSL_TLSv1_2 0x0020
|
||||
#define NGX_SSL_TLSv1_3 0x0040
|
||||
|
||||
|
||||
#define NGX_SSL_BUFFER 1
|
||||
|
||||
@@ -67,7 +67,7 @@ ngx_event_expire_timers(void)
|
||||
|
||||
node = ngx_rbtree_min(root, sentinel);
|
||||
|
||||
/* node->key > ngx_current_time */
|
||||
/* node->key > ngx_current_msec */
|
||||
|
||||
if ((ngx_msec_int_t) (node->key - ngx_current_msec) > 0) {
|
||||
return;
|
||||
@@ -96,43 +96,31 @@ ngx_event_expire_timers(void)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_event_cancel_timers(void)
|
||||
ngx_int_t
|
||||
ngx_event_no_timers_left(void)
|
||||
{
|
||||
ngx_event_t *ev;
|
||||
ngx_rbtree_node_t *node, *root, *sentinel;
|
||||
|
||||
sentinel = ngx_event_timer_rbtree.sentinel;
|
||||
root = ngx_event_timer_rbtree.root;
|
||||
|
||||
for ( ;; ) {
|
||||
root = ngx_event_timer_rbtree.root;
|
||||
|
||||
if (root == sentinel) {
|
||||
return;
|
||||
}
|
||||
|
||||
node = ngx_rbtree_min(root, sentinel);
|
||||
if (root == sentinel) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
for (node = ngx_rbtree_min(root, sentinel);
|
||||
node;
|
||||
node = ngx_rbtree_next(&ngx_event_timer_rbtree, node))
|
||||
{
|
||||
ev = (ngx_event_t *) ((char *) node - offsetof(ngx_event_t, timer));
|
||||
|
||||
if (!ev->cancelable) {
|
||||
return;
|
||||
return NGX_AGAIN;
|
||||
}
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
|
||||
"event timer cancel: %d: %M",
|
||||
ngx_event_ident(ev->data), ev->timer.key);
|
||||
|
||||
ngx_rbtree_delete(&ngx_event_timer_rbtree, &ev->timer);
|
||||
|
||||
#if (NGX_DEBUG)
|
||||
ev->timer.left = NULL;
|
||||
ev->timer.right = NULL;
|
||||
ev->timer.parent = NULL;
|
||||
#endif
|
||||
|
||||
ev->timer_set = 0;
|
||||
|
||||
ev->handler(ev);
|
||||
}
|
||||
|
||||
/* only cancelable timers left */
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
ngx_int_t ngx_event_timer_init(ngx_log_t *log);
|
||||
ngx_msec_t ngx_event_find_timer(void);
|
||||
void ngx_event_expire_timers(void);
|
||||
void ngx_event_cancel_timers(void);
|
||||
ngx_int_t ngx_event_no_timers_left(void);
|
||||
|
||||
|
||||
extern ngx_rbtree_t ngx_event_timer_rbtree;
|
||||
|
||||
@@ -309,28 +309,22 @@ ngx_http_access_rule(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
ngx_http_access_rule_un_t *rule_un;
|
||||
#endif
|
||||
|
||||
all = 0;
|
||||
ngx_memzero(&cidr, sizeof(ngx_cidr_t));
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
all = (value[1].len == 3 && ngx_strcmp(value[1].data, "all") == 0);
|
||||
|
||||
if (!all) {
|
||||
if (value[1].len == 3 && ngx_strcmp(value[1].data, "all") == 0) {
|
||||
all = 1;
|
||||
|
||||
#if (NGX_HAVE_UNIX_DOMAIN)
|
||||
|
||||
if (value[1].len == 5 && ngx_strcmp(value[1].data, "unix:") == 0) {
|
||||
cidr.family = AF_UNIX;
|
||||
rc = NGX_OK;
|
||||
|
||||
} else {
|
||||
rc = ngx_ptocidr(&value[1], &cidr);
|
||||
}
|
||||
|
||||
#else
|
||||
rc = ngx_ptocidr(&value[1], &cidr);
|
||||
} else if (value[1].len == 5 && ngx_strcmp(value[1].data, "unix:") == 0) {
|
||||
cidr.family = AF_UNIX;
|
||||
#endif
|
||||
|
||||
} else {
|
||||
rc = ngx_ptocidr(&value[1], &cidr);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid parameter \"%V\"", &value[1]);
|
||||
|
||||
@@ -361,6 +361,8 @@ ngx_http_auth_basic_set_realm(ngx_http_request_t *r, ngx_str_t *realm)
|
||||
|
||||
basic = ngx_pnalloc(r->pool, len);
|
||||
if (basic == NULL) {
|
||||
r->headers_out.www_authenticate->hash = 0;
|
||||
r->headers_out.www_authenticate = NULL;
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ static char *ngx_http_charset_merge_loc_conf(ngx_conf_t *cf,
|
||||
static ngx_int_t ngx_http_charset_postconfiguration(ngx_conf_t *cf);
|
||||
|
||||
|
||||
ngx_str_t ngx_http_charset_default_types[] = {
|
||||
static ngx_str_t ngx_http_charset_default_types[] = {
|
||||
ngx_string("text/html"),
|
||||
ngx_string("text/xml"),
|
||||
ngx_string("text/plain"),
|
||||
|
||||
@@ -1080,6 +1080,7 @@ ngx_http_dav_location(ngx_http_request_t *r, u_char *path)
|
||||
} else {
|
||||
location = ngx_pnalloc(r->pool, r->uri.len);
|
||||
if (location == NULL) {
|
||||
ngx_http_clear_location(r);
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@@ -211,6 +211,7 @@ static ngx_conf_bitmask_t ngx_http_fastcgi_next_upstream_masks[] = {
|
||||
{ ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 },
|
||||
{ ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 },
|
||||
{ ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
|
||||
{ ngx_string("http_429"), NGX_HTTP_UPSTREAM_FT_HTTP_429 },
|
||||
{ ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING },
|
||||
{ ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
|
||||
{ ngx_null_string, 0 }
|
||||
@@ -469,6 +470,13 @@ static ngx_command_t ngx_http_fastcgi_commands[] = {
|
||||
offsetof(ngx_http_fastcgi_loc_conf_t, upstream.cache_revalidate),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("fastcgi_cache_background_update"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
|
||||
ngx_conf_set_flag_slot,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
offsetof(ngx_http_fastcgi_loc_conf_t, upstream.cache_background_update),
|
||||
NULL },
|
||||
|
||||
#endif
|
||||
|
||||
{ ngx_string("fastcgi_temp_path"),
|
||||
@@ -1870,6 +1878,7 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
|
||||
|
||||
p = ngx_pnalloc(r->pool, size);
|
||||
if (p == NULL) {
|
||||
h->hash = 0;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
@@ -1892,6 +1901,7 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
|
||||
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
|
||||
"invalid header after joining "
|
||||
"FastCGI records");
|
||||
h->hash = 0;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
@@ -1917,6 +1927,7 @@ ngx_http_fastcgi_process_header(ngx_http_request_t *r)
|
||||
h->key.len + 1 + h->value.len + 1
|
||||
+ h->key.len);
|
||||
if (h->key.data == NULL) {
|
||||
h->hash = 0;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
@@ -2769,6 +2780,7 @@ ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf)
|
||||
conf->upstream.cache_lock_timeout = NGX_CONF_UNSET_MSEC;
|
||||
conf->upstream.cache_lock_age = NGX_CONF_UNSET_MSEC;
|
||||
conf->upstream.cache_revalidate = NGX_CONF_UNSET;
|
||||
conf->upstream.cache_background_update = NGX_CONF_UNSET;
|
||||
#endif
|
||||
|
||||
conf->upstream.hide_headers = NGX_CONF_UNSET_PTR;
|
||||
@@ -3061,6 +3073,9 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
ngx_conf_merge_value(conf->upstream.cache_revalidate,
|
||||
prev->upstream.cache_revalidate, 0);
|
||||
|
||||
ngx_conf_merge_value(conf->upstream.cache_background_update,
|
||||
prev->upstream.cache_background_update, 0);
|
||||
|
||||
#endif
|
||||
|
||||
ngx_conf_merge_value(conf->upstream.pass_request_headers,
|
||||
|
||||
@@ -203,7 +203,7 @@ ngx_http_flv_handler(ngx_http_request_t *r)
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
|
||||
b = ngx_calloc_buf(r->pool);
|
||||
if (b == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
@@ -217,7 +217,7 @@ ngx_http_flv_handler(ngx_http_request_t *r)
|
||||
}
|
||||
|
||||
|
||||
b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
|
||||
b = ngx_calloc_buf(r->pool);
|
||||
if (b == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
@@ -644,7 +644,7 @@ ngx_http_gzip_filter_gzheader(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx)
|
||||
static u_char gzheader[10] =
|
||||
{ 0x1f, 0x8b, Z_DEFLATED, 0, 0, 0, 0, 0, 0, 3 };
|
||||
|
||||
b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
|
||||
b = ngx_calloc_buf(r->pool);
|
||||
if (b == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
@@ -671,6 +671,8 @@ ngx_http_gzip_filter_gzheader(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx)
|
||||
static ngx_int_t
|
||||
ngx_http_gzip_filter_add_data(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx)
|
||||
{
|
||||
ngx_chain_t *cl;
|
||||
|
||||
if (ctx->zstream.avail_in || ctx->flush != Z_NO_FLUSH || ctx->redo) {
|
||||
return NGX_OK;
|
||||
}
|
||||
@@ -694,13 +696,16 @@ ngx_http_gzip_filter_add_data(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx)
|
||||
ctx->copy_buf = NULL;
|
||||
}
|
||||
|
||||
ctx->in_buf = ctx->in->buf;
|
||||
cl = ctx->in;
|
||||
ctx->in_buf = cl->buf;
|
||||
ctx->in = cl->next;
|
||||
|
||||
if (ctx->in_buf->tag == (ngx_buf_tag_t) &ngx_http_gzip_filter_module) {
|
||||
ctx->copy_buf = ctx->in;
|
||||
}
|
||||
ctx->copy_buf = cl;
|
||||
|
||||
ctx->in = ctx->in->next;
|
||||
} else {
|
||||
ngx_free_chain(r->pool, cl);
|
||||
}
|
||||
|
||||
ctx->zstream.next_in = ctx->in_buf->pos;
|
||||
ctx->zstream.avail_in = ctx->in_buf->last - ctx->in_buf->pos;
|
||||
@@ -733,6 +738,7 @@ ngx_http_gzip_filter_add_data(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx)
|
||||
static ngx_int_t
|
||||
ngx_http_gzip_filter_get_buf(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx)
|
||||
{
|
||||
ngx_chain_t *cl;
|
||||
ngx_http_gzip_conf_t *conf;
|
||||
|
||||
if (ctx->zstream.avail_out) {
|
||||
@@ -742,8 +748,12 @@ ngx_http_gzip_filter_get_buf(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx)
|
||||
conf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_filter_module);
|
||||
|
||||
if (ctx->free) {
|
||||
ctx->out_buf = ctx->free->buf;
|
||||
ctx->free = ctx->free->next;
|
||||
|
||||
cl = ctx->free;
|
||||
ctx->out_buf = cl->buf;
|
||||
ctx->free = cl->next;
|
||||
|
||||
ngx_free_chain(r->pool, cl);
|
||||
|
||||
} else if (ctx->bufs < conf->bufs.num) {
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ static ngx_command_t ngx_http_gzip_static_commands[] = {
|
||||
};
|
||||
|
||||
|
||||
ngx_http_module_t ngx_http_gzip_static_module_ctx = {
|
||||
static ngx_http_module_t ngx_http_gzip_static_module_ctx = {
|
||||
NULL, /* preconfiguration */
|
||||
ngx_http_gzip_static_init, /* postconfiguration */
|
||||
|
||||
@@ -238,7 +238,7 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r)
|
||||
|
||||
h = ngx_list_push(&r->headers_out.headers);
|
||||
if (h == NULL) {
|
||||
return NGX_ERROR;
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
h->hash = 1;
|
||||
@@ -248,7 +248,7 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r)
|
||||
|
||||
/* we need to allocate all before the header would be sent */
|
||||
|
||||
b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
|
||||
b = ngx_calloc_buf(r->pool);
|
||||
if (b == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
@@ -173,6 +173,7 @@ ngx_http_headers_filter(ngx_http_request_t *r)
|
||||
case NGX_HTTP_SEE_OTHER:
|
||||
case NGX_HTTP_NOT_MODIFIED:
|
||||
case NGX_HTTP_TEMPORARY_REDIRECT:
|
||||
case NGX_HTTP_PERMANENT_REDIRECT:
|
||||
safe_status = 1;
|
||||
break;
|
||||
|
||||
@@ -270,11 +271,6 @@ ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf)
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ccp = ngx_array_push(&r->headers_out.cache_control);
|
||||
if (ccp == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
cc = ngx_list_push(&r->headers_out.headers);
|
||||
if (cc == NULL) {
|
||||
return NGX_ERROR;
|
||||
@@ -282,6 +278,12 @@ ngx_http_set_expires(ngx_http_request_t *r, ngx_http_headers_conf_t *conf)
|
||||
|
||||
cc->hash = 1;
|
||||
ngx_str_set(&cc->key, "Cache-Control");
|
||||
|
||||
ccp = ngx_array_push(&r->headers_out.cache_control);
|
||||
if (ccp == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*ccp = cc;
|
||||
|
||||
} else {
|
||||
@@ -469,11 +471,6 @@ ngx_http_add_cache_control(ngx_http_request_t *r, ngx_http_header_val_t *hv,
|
||||
}
|
||||
}
|
||||
|
||||
ccp = ngx_array_push(&r->headers_out.cache_control);
|
||||
if (ccp == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
cc = ngx_list_push(&r->headers_out.headers);
|
||||
if (cc == NULL) {
|
||||
return NGX_ERROR;
|
||||
@@ -483,6 +480,11 @@ ngx_http_add_cache_control(ngx_http_request_t *r, ngx_http_header_val_t *hv,
|
||||
ngx_str_set(&cc->key, "Cache-Control");
|
||||
cc->value = *value;
|
||||
|
||||
ccp = ngx_array_push(&r->headers_out.cache_control);
|
||||
if (ccp == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*ccp = cc;
|
||||
|
||||
return NGX_OK;
|
||||
|
||||
@@ -581,7 +581,7 @@ ngx_http_image_json(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
|
||||
size_t len;
|
||||
ngx_buf_t *b;
|
||||
|
||||
b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
|
||||
b = ngx_calloc_buf(r->pool);
|
||||
if (b == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -633,7 +633,7 @@ ngx_http_image_asis(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
|
||||
{
|
||||
ngx_buf_t *b;
|
||||
|
||||
b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
|
||||
b = ngx_calloc_buf(r->pool);
|
||||
if (b == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -1067,7 +1067,7 @@ transparent:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
|
||||
b = ngx_calloc_buf(r->pool);
|
||||
if (b == NULL) {
|
||||
gdFree(out);
|
||||
return NULL;
|
||||
|
||||
@@ -217,13 +217,13 @@ ngx_http_index_handler(ngx_http_request_t *r)
|
||||
if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
|
||||
!= NGX_OK)
|
||||
{
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, of.err,
|
||||
"%s \"%s\" failed", of.failed, path.data);
|
||||
|
||||
if (of.err == 0) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, of.err,
|
||||
"%s \"%s\" failed", of.failed, path.data);
|
||||
|
||||
#if (NGX_HAVE_OPENAT)
|
||||
if (of.err == NGX_EMLINK
|
||||
|| of.err == NGX_ELOOP)
|
||||
|
||||
@@ -276,6 +276,8 @@ ngx_http_limit_req_handler(ngx_http_request_t *r)
|
||||
|
||||
r->read_event_handler = ngx_http_test_reading;
|
||||
r->write_event_handler = ngx_http_limit_req_delay;
|
||||
|
||||
r->connection->write->delayed = 1;
|
||||
ngx_add_timer(r->connection->write, delay);
|
||||
|
||||
return NGX_AGAIN;
|
||||
@@ -292,7 +294,7 @@ ngx_http_limit_req_delay(ngx_http_request_t *r)
|
||||
|
||||
wev = r->connection->write;
|
||||
|
||||
if (!wev->timedout) {
|
||||
if (wev->delayed) {
|
||||
|
||||
if (ngx_handle_write_event(wev, 0) != NGX_OK) {
|
||||
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
@@ -301,8 +303,6 @@ ngx_http_limit_req_delay(ngx_http_request_t *r)
|
||||
return;
|
||||
}
|
||||
|
||||
wev->timedout = 0;
|
||||
|
||||
if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) {
|
||||
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return;
|
||||
|
||||
@@ -552,6 +552,11 @@ ngx_http_log_script_write(ngx_http_request_t *r, ngx_http_log_script_t *script,
|
||||
if (ngx_open_cached_file(llcf->open_file_cache, &log, &of, r->pool)
|
||||
!= NGX_OK)
|
||||
{
|
||||
if (of.err == 0) {
|
||||
/* simulate successful logging */
|
||||
return len;
|
||||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
|
||||
"%s \"%s\" failed", of.failed, log.data);
|
||||
/* simulate successful logging */
|
||||
@@ -748,23 +753,10 @@ ngx_http_log_flush(ngx_open_file_t *file, ngx_log_t *log)
|
||||
static void
|
||||
ngx_http_log_flush_handler(ngx_event_t *ev)
|
||||
{
|
||||
ngx_open_file_t *file;
|
||||
ngx_http_log_buf_t *buffer;
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0,
|
||||
"http log buffer flush handler");
|
||||
|
||||
if (ev->timedout) {
|
||||
ngx_http_log_flush(ev->data, ev->log);
|
||||
return;
|
||||
}
|
||||
|
||||
/* cancel the flush timer for graceful shutdown */
|
||||
|
||||
file = ev->data;
|
||||
buffer = file->data;
|
||||
|
||||
buffer->event = NULL;
|
||||
ngx_http_log_flush(ev->data, ev->log);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -636,7 +636,7 @@ ngx_http_mp4_handler(ngx_http_request_t *r)
|
||||
}
|
||||
|
||||
if (mp4 == NULL) {
|
||||
b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
|
||||
b = ngx_calloc_buf(r->pool);
|
||||
if (b == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
@@ -220,6 +220,7 @@ static ngx_conf_bitmask_t ngx_http_proxy_next_upstream_masks[] = {
|
||||
{ ngx_string("http_504"), NGX_HTTP_UPSTREAM_FT_HTTP_504 },
|
||||
{ ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 },
|
||||
{ ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
|
||||
{ ngx_string("http_429"), NGX_HTTP_UPSTREAM_FT_HTTP_429 },
|
||||
{ ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING },
|
||||
{ ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
|
||||
{ ngx_null_string, 0 }
|
||||
@@ -234,6 +235,7 @@ static ngx_conf_bitmask_t ngx_http_proxy_ssl_protocols[] = {
|
||||
{ ngx_string("TLSv1"), NGX_SSL_TLSv1 },
|
||||
{ ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 },
|
||||
{ ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 },
|
||||
{ ngx_string("TLSv1.3"), NGX_SSL_TLSv1_3 },
|
||||
{ ngx_null_string, 0 }
|
||||
};
|
||||
|
||||
@@ -548,6 +550,13 @@ static ngx_command_t ngx_http_proxy_commands[] = {
|
||||
offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_convert_head),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("proxy_cache_background_update"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
|
||||
ngx_conf_set_flag_slot,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_background_update),
|
||||
NULL },
|
||||
|
||||
#endif
|
||||
|
||||
{ ngx_string("proxy_temp_path"),
|
||||
@@ -1789,6 +1798,7 @@ ngx_http_proxy_process_header(ngx_http_request_t *r)
|
||||
h->key.data = ngx_pnalloc(r->pool,
|
||||
h->key.len + 1 + h->value.len + 1 + h->key.len);
|
||||
if (h->key.data == NULL) {
|
||||
h->hash = 0;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
@@ -2863,6 +2873,7 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
|
||||
conf->upstream.cache_lock_age = NGX_CONF_UNSET_MSEC;
|
||||
conf->upstream.cache_revalidate = NGX_CONF_UNSET;
|
||||
conf->upstream.cache_convert_head = NGX_CONF_UNSET;
|
||||
conf->upstream.cache_background_update = NGX_CONF_UNSET;
|
||||
#endif
|
||||
|
||||
conf->upstream.hide_headers = NGX_CONF_UNSET_PTR;
|
||||
@@ -3168,6 +3179,9 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
ngx_conf_merge_value(conf->upstream.cache_convert_head,
|
||||
prev->upstream.cache_convert_head, 1);
|
||||
|
||||
ngx_conf_merge_value(conf->upstream.cache_background_update,
|
||||
prev->upstream.cache_background_update, 0);
|
||||
|
||||
#endif
|
||||
|
||||
if (conf->method == NULL) {
|
||||
|
||||
@@ -425,6 +425,8 @@ ngx_http_range_singlepart_header(ngx_http_request_t *r,
|
||||
content_range->value.data = ngx_pnalloc(r->pool,
|
||||
sizeof("bytes -/") - 1 + 3 * NGX_OFF_T_LEN);
|
||||
if (content_range->value.data == NULL) {
|
||||
content_range->hash = 0;
|
||||
r->headers_out.content_range = NULL;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
@@ -594,6 +596,8 @@ ngx_http_range_not_satisfiable(ngx_http_request_t *r)
|
||||
content_range->value.data = ngx_pnalloc(r->pool,
|
||||
sizeof("bytes */") - 1 + NGX_OFF_T_LEN);
|
||||
if (content_range->value.data == NULL) {
|
||||
content_range->hash = 0;
|
||||
r->headers_out.content_range = NULL;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@@ -317,9 +317,15 @@ ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_http_realip_loc_conf_t *rlcf = conf;
|
||||
|
||||
ngx_int_t rc;
|
||||
ngx_str_t *value;
|
||||
ngx_cidr_t *cidr;
|
||||
ngx_int_t rc;
|
||||
ngx_str_t *value;
|
||||
ngx_url_t u;
|
||||
ngx_cidr_t c, *cidr;
|
||||
ngx_uint_t i;
|
||||
struct sockaddr_in *sin;
|
||||
#if (NGX_HAVE_INET6)
|
||||
struct sockaddr_in6 *sin6;
|
||||
#endif
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
@@ -331,31 +337,78 @@ ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
}
|
||||
}
|
||||
|
||||
cidr = ngx_array_push(rlcf->from);
|
||||
if (cidr == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
#if (NGX_HAVE_UNIX_DOMAIN)
|
||||
|
||||
if (ngx_strcmp(value[1].data, "unix:") == 0) {
|
||||
cidr = ngx_array_push(rlcf->from);
|
||||
if (cidr == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
cidr->family = AF_UNIX;
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
rc = ngx_ptocidr(&value[1], cidr);
|
||||
rc = ngx_ptocidr(&value[1], &c);
|
||||
|
||||
if (rc != NGX_ERROR) {
|
||||
if (rc == NGX_DONE) {
|
||||
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||
"low address bits of %V are meaningless",
|
||||
&value[1]);
|
||||
}
|
||||
|
||||
cidr = ngx_array_push(rlcf->from);
|
||||
if (cidr == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
*cidr = c;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
ngx_memzero(&u, sizeof(ngx_url_t));
|
||||
u.host = value[1];
|
||||
|
||||
if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) {
|
||||
if (u.err) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"%s in set_real_ip_from \"%V\"",
|
||||
u.err, &u.host);
|
||||
}
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"",
|
||||
&value[1]);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (rc == NGX_DONE) {
|
||||
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||
"low address bits of %V are meaningless", &value[1]);
|
||||
cidr = ngx_array_push_n(rlcf->from, u.naddrs);
|
||||
if (cidr == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
ngx_memzero(cidr, u.naddrs * sizeof(ngx_cidr_t));
|
||||
|
||||
for (i = 0; i < u.naddrs; i++) {
|
||||
cidr[i].family = u.addrs[i].sockaddr->sa_family;
|
||||
|
||||
switch (cidr[i].family) {
|
||||
|
||||
#if (NGX_HAVE_INET6)
|
||||
case AF_INET6:
|
||||
sin6 = (struct sockaddr_in6 *) u.addrs[i].sockaddr;
|
||||
cidr[i].u.in6.addr = sin6->sin6_addr;
|
||||
ngx_memset(cidr[i].u.in6.mask.s6_addr, 0xff, 16);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default: /* AF_INET */
|
||||
sin = (struct sockaddr_in *) u.addrs[i].sockaddr;
|
||||
cidr[i].u.in.addr = sin->sin_addr.s_addr;
|
||||
cidr[i].u.in.mask = 0xffffffff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
|
||||
@@ -917,7 +917,8 @@ ngx_http_rewrite_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
value[1].len--;
|
||||
value[1].data++;
|
||||
|
||||
v = ngx_http_add_variable(cf, &value[1], NGX_HTTP_VAR_CHANGEABLE);
|
||||
v = ngx_http_add_variable(cf, &value[1],
|
||||
NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_WEAK);
|
||||
if (v == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
@@ -927,15 +928,7 @@ ngx_http_rewrite_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (v->get_handler == NULL
|
||||
&& ngx_strncasecmp(value[1].data, (u_char *) "http_", 5) != 0
|
||||
&& ngx_strncasecmp(value[1].data, (u_char *) "sent_http_", 10) != 0
|
||||
&& ngx_strncasecmp(value[1].data, (u_char *) "upstream_http_", 14) != 0
|
||||
&& ngx_strncasecmp(value[1].data, (u_char *) "cookie_", 7) != 0
|
||||
&& ngx_strncasecmp(value[1].data, (u_char *) "upstream_cookie_", 16)
|
||||
!= 0
|
||||
&& ngx_strncasecmp(value[1].data, (u_char *) "arg_", 4) != 0)
|
||||
{
|
||||
if (v->get_handler == NULL) {
|
||||
v->get_handler = ngx_http_rewrite_var;
|
||||
v->data = index;
|
||||
}
|
||||
|
||||
@@ -82,6 +82,7 @@ static ngx_conf_bitmask_t ngx_http_scgi_next_upstream_masks[] = {
|
||||
{ ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 },
|
||||
{ ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 },
|
||||
{ ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
|
||||
{ ngx_string("http_429"), NGX_HTTP_UPSTREAM_FT_HTTP_429 },
|
||||
{ ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING },
|
||||
{ ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
|
||||
{ ngx_null_string, 0 }
|
||||
@@ -319,6 +320,13 @@ static ngx_command_t ngx_http_scgi_commands[] = {
|
||||
offsetof(ngx_http_scgi_loc_conf_t, upstream.cache_revalidate),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("scgi_cache_background_update"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
|
||||
ngx_conf_set_flag_slot,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
offsetof(ngx_http_scgi_loc_conf_t, upstream.cache_background_update),
|
||||
NULL },
|
||||
|
||||
#endif
|
||||
|
||||
{ ngx_string("scgi_temp_path"),
|
||||
@@ -1032,6 +1040,7 @@ ngx_http_scgi_process_header(ngx_http_request_t *r)
|
||||
h->key.len + 1 + h->value.len + 1
|
||||
+ h->key.len);
|
||||
if (h->key.data == NULL) {
|
||||
h->hash = 0;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
@@ -1219,6 +1228,7 @@ ngx_http_scgi_create_loc_conf(ngx_conf_t *cf)
|
||||
conf->upstream.cache_lock_timeout = NGX_CONF_UNSET_MSEC;
|
||||
conf->upstream.cache_lock_age = NGX_CONF_UNSET_MSEC;
|
||||
conf->upstream.cache_revalidate = NGX_CONF_UNSET;
|
||||
conf->upstream.cache_background_update = NGX_CONF_UNSET;
|
||||
#endif
|
||||
|
||||
conf->upstream.hide_headers = NGX_CONF_UNSET_PTR;
|
||||
@@ -1506,6 +1516,9 @@ ngx_http_scgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
ngx_conf_merge_value(conf->upstream.cache_revalidate,
|
||||
prev->upstream.cache_revalidate, 0);
|
||||
|
||||
ngx_conf_merge_value(conf->upstream.cache_background_update,
|
||||
prev->upstream.cache_background_update, 0);
|
||||
|
||||
#endif
|
||||
|
||||
ngx_conf_merge_value(conf->upstream.pass_request_headers,
|
||||
|
||||
@@ -11,23 +11,25 @@
|
||||
|
||||
|
||||
typedef struct {
|
||||
size_t size;
|
||||
size_t size;
|
||||
} ngx_http_slice_loc_conf_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
off_t start;
|
||||
off_t end;
|
||||
ngx_str_t range;
|
||||
ngx_str_t etag;
|
||||
ngx_uint_t last; /* unsigned last:1; */
|
||||
off_t start;
|
||||
off_t end;
|
||||
ngx_str_t range;
|
||||
ngx_str_t etag;
|
||||
unsigned last:1;
|
||||
unsigned active:1;
|
||||
ngx_http_request_t *sr;
|
||||
} ngx_http_slice_ctx_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
off_t start;
|
||||
off_t end;
|
||||
off_t complete_length;
|
||||
off_t start;
|
||||
off_t end;
|
||||
off_t complete_length;
|
||||
} ngx_http_slice_content_range_t;
|
||||
|
||||
|
||||
@@ -169,6 +171,7 @@ ngx_http_slice_header_filter(ngx_http_request_t *r)
|
||||
}
|
||||
|
||||
ctx->start = end;
|
||||
ctx->active = 1;
|
||||
|
||||
r->headers_out.status = NGX_HTTP_OK;
|
||||
r->headers_out.status_line.len = 0;
|
||||
@@ -209,7 +212,6 @@ ngx_http_slice_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
||||
{
|
||||
ngx_int_t rc;
|
||||
ngx_chain_t *cl;
|
||||
ngx_http_request_t *sr;
|
||||
ngx_http_slice_ctx_t *ctx;
|
||||
ngx_http_slice_loc_conf_t *slcf;
|
||||
|
||||
@@ -234,6 +236,16 @@ ngx_http_slice_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (ctx->sr && !ctx->sr->done) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (!ctx->active) {
|
||||
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
|
||||
"missing slice response");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (ctx->start >= ctx->end) {
|
||||
ngx_http_set_ctx(r, NULL, ngx_http_slice_filter_module);
|
||||
ngx_http_send_special(r, NGX_HTTP_LAST);
|
||||
@@ -244,11 +256,14 @@ ngx_http_slice_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (ngx_http_subrequest(r, &r->uri, &r->args, &sr, NULL, 0) != NGX_OK) {
|
||||
if (ngx_http_subrequest(r, &r->uri, &r->args, &ctx->sr, NULL,
|
||||
NGX_HTTP_SUBREQUEST_CLONE)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_http_set_ctx(sr, ctx, ngx_http_slice_filter_module);
|
||||
ngx_http_set_ctx(ctx->sr, ctx, ngx_http_slice_filter_module);
|
||||
|
||||
slcf = ngx_http_get_module_loc_conf(r, ngx_http_slice_filter_module);
|
||||
|
||||
@@ -256,6 +271,8 @@ ngx_http_slice_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
||||
ctx->start + (off_t) slcf->size - 1)
|
||||
- ctx->range.data;
|
||||
|
||||
ctx->active = 0;
|
||||
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http slice subrequest: \"%V\"", &ctx->range);
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ static ngx_conf_bitmask_t ngx_http_ssl_protocols[] = {
|
||||
{ ngx_string("TLSv1"), NGX_SSL_TLSv1 },
|
||||
{ ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 },
|
||||
{ ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 },
|
||||
{ ngx_string("TLSv1.3"), NGX_SSL_TLSv1_3 },
|
||||
{ ngx_null_string, 0 }
|
||||
};
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ static ngx_int_t ngx_http_static_handler(ngx_http_request_t *r);
|
||||
static ngx_int_t ngx_http_static_init(ngx_conf_t *cf);
|
||||
|
||||
|
||||
ngx_http_module_t ngx_http_static_module_ctx = {
|
||||
static ngx_http_module_t ngx_http_static_module_ctx = {
|
||||
NULL, /* preconfiguration */
|
||||
ngx_http_static_init, /* postconfiguration */
|
||||
|
||||
@@ -169,6 +169,7 @@ ngx_http_static_handler(ngx_http_request_t *r)
|
||||
|
||||
location = ngx_pnalloc(r->pool, len);
|
||||
if (location == NULL) {
|
||||
ngx_http_clear_location(r);
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
@@ -233,7 +234,7 @@ ngx_http_static_handler(ngx_http_request_t *r)
|
||||
|
||||
/* we need to allocate all before the header would be sent */
|
||||
|
||||
b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
|
||||
b = ngx_calloc_buf(r->pool);
|
||||
if (b == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
@@ -248,8 +248,6 @@ ngx_http_sub_header_filter(ngx_http_request_t *r)
|
||||
ctx->matches->nelts);
|
||||
}
|
||||
|
||||
ngx_http_set_ctx(r, ctx, ngx_http_sub_filter_module);
|
||||
|
||||
ctx->saved.data = ngx_pnalloc(r->pool, ctx->tables->max_match_len - 1);
|
||||
if (ctx->saved.data == NULL) {
|
||||
return NGX_ERROR;
|
||||
@@ -260,6 +258,8 @@ ngx_http_sub_header_filter(ngx_http_request_t *r)
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ngx_http_set_ctx(r, ctx, ngx_http_sub_filter_module);
|
||||
|
||||
ctx->offset = ctx->tables->min_match_len - 1;
|
||||
ctx->last_out = &ctx->out;
|
||||
|
||||
|
||||
@@ -114,6 +114,7 @@ static ngx_conf_bitmask_t ngx_http_uwsgi_next_upstream_masks[] = {
|
||||
{ ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 },
|
||||
{ ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 },
|
||||
{ ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
|
||||
{ ngx_string("http_429"), NGX_HTTP_UPSTREAM_FT_HTTP_429 },
|
||||
{ ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING },
|
||||
{ ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
|
||||
{ ngx_null_string, 0 }
|
||||
@@ -128,6 +129,7 @@ static ngx_conf_bitmask_t ngx_http_uwsgi_ssl_protocols[] = {
|
||||
{ ngx_string("TLSv1"), NGX_SSL_TLSv1 },
|
||||
{ ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 },
|
||||
{ ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 },
|
||||
{ ngx_string("TLSv1.3"), NGX_SSL_TLSv1_3 },
|
||||
{ ngx_null_string, 0 }
|
||||
};
|
||||
|
||||
@@ -379,6 +381,13 @@ static ngx_command_t ngx_http_uwsgi_commands[] = {
|
||||
offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_revalidate),
|
||||
NULL },
|
||||
|
||||
{ ngx_string("uwsgi_cache_background_update"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_flag_slot,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
offsetof(ngx_http_uwsgi_loc_conf_t, upstream.cache_background_update),
|
||||
NULL },
|
||||
|
||||
#endif
|
||||
|
||||
{ ngx_string("uwsgi_temp_path"),
|
||||
@@ -1235,6 +1244,7 @@ ngx_http_uwsgi_process_header(ngx_http_request_t *r)
|
||||
h->key.len + 1 + h->value.len + 1
|
||||
+ h->key.len);
|
||||
if (h->key.data == NULL) {
|
||||
h->hash = 0;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
@@ -1425,6 +1435,7 @@ ngx_http_uwsgi_create_loc_conf(ngx_conf_t *cf)
|
||||
conf->upstream.cache_lock_timeout = NGX_CONF_UNSET_MSEC;
|
||||
conf->upstream.cache_lock_age = NGX_CONF_UNSET_MSEC;
|
||||
conf->upstream.cache_revalidate = NGX_CONF_UNSET;
|
||||
conf->upstream.cache_background_update = NGX_CONF_UNSET;
|
||||
#endif
|
||||
|
||||
conf->upstream.hide_headers = NGX_CONF_UNSET_PTR;
|
||||
@@ -1720,6 +1731,9 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
ngx_conf_merge_value(conf->upstream.cache_revalidate,
|
||||
prev->upstream.cache_revalidate, 0);
|
||||
|
||||
ngx_conf_merge_value(conf->upstream.cache_background_update,
|
||||
prev->upstream.cache_background_update, 0);
|
||||
|
||||
#endif
|
||||
|
||||
ngx_conf_merge_value(conf->upstream.pass_request_headers,
|
||||
|
||||
@@ -109,7 +109,7 @@ static ngx_int_t ngx_http_xslt_filter_init(ngx_conf_t *cf);
|
||||
static void ngx_http_xslt_filter_exit(ngx_cycle_t *cycle);
|
||||
|
||||
|
||||
ngx_str_t ngx_http_xslt_default_types[] = {
|
||||
static ngx_str_t ngx_http_xslt_default_types[] = {
|
||||
ngx_string("text/xml"),
|
||||
ngx_null_string
|
||||
};
|
||||
@@ -584,7 +584,7 @@ ngx_http_xslt_apply_stylesheet(ngx_http_request_t *r,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
|
||||
b = ngx_calloc_buf(r->pool);
|
||||
if (b == NULL) {
|
||||
ngx_free(buf);
|
||||
return NULL;
|
||||
|
||||
@@ -24,6 +24,7 @@ our @EXPORT = qw(
|
||||
HTTP_SEE_OTHER
|
||||
HTTP_NOT_MODIFIED
|
||||
HTTP_TEMPORARY_REDIRECT
|
||||
HTTP_PERMANENT_REDIRECT
|
||||
|
||||
HTTP_BAD_REQUEST
|
||||
HTTP_UNAUTHORIZED
|
||||
@@ -72,6 +73,7 @@ use constant HTTP_REDIRECT => 302;
|
||||
use constant HTTP_SEE_OTHER => 303;
|
||||
use constant HTTP_NOT_MODIFIED => 304;
|
||||
use constant HTTP_TEMPORARY_REDIRECT => 307;
|
||||
use constant HTTP_PERMANENT_REDIRECT => 308;
|
||||
|
||||
use constant HTTP_BAD_REQUEST => 400;
|
||||
use constant HTTP_UNAUTHORIZED => 401;
|
||||
|
||||
@@ -510,10 +510,12 @@ header_out(r, key, value)
|
||||
header->hash = 1;
|
||||
|
||||
if (ngx_http_perl_sv2str(aTHX_ r, &header->key, key) != NGX_OK) {
|
||||
header->hash = 0;
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
if (ngx_http_perl_sv2str(aTHX_ r, &header->value, value) != NGX_OK) {
|
||||
header->hash = 0;
|
||||
XSRETURN_EMPTY;
|
||||
}
|
||||
|
||||
@@ -1001,6 +1003,7 @@ sleep(r, sleep, next)
|
||||
|
||||
ctx->next = SvRV(ST(2));
|
||||
|
||||
r->connection->write->delayed = 1;
|
||||
ngx_add_timer(r->connection->write, sleep);
|
||||
|
||||
r->write_event_handler = ngx_http_perl_sleep_handler;
|
||||
|
||||
@@ -278,15 +278,16 @@ ngx_http_perl_sleep_handler(ngx_http_request_t *r)
|
||||
|
||||
wev = r->connection->write;
|
||||
|
||||
if (wev->timedout) {
|
||||
wev->timedout = 0;
|
||||
ngx_http_perl_handle_request(r);
|
||||
if (wev->delayed) {
|
||||
|
||||
if (ngx_handle_write_event(wev, 0) != NGX_OK) {
|
||||
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (ngx_handle_write_event(wev, 0) != NGX_OK) {
|
||||
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
ngx_http_perl_handle_request(r);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -24,10 +24,10 @@
|
||||
#define NGX_HTTP_CACHE_SCARCE 8
|
||||
|
||||
#define NGX_HTTP_CACHE_KEY_LEN 16
|
||||
#define NGX_HTTP_CACHE_ETAG_LEN 42
|
||||
#define NGX_HTTP_CACHE_VARY_LEN 42
|
||||
#define NGX_HTTP_CACHE_ETAG_LEN 128
|
||||
#define NGX_HTTP_CACHE_VARY_LEN 128
|
||||
|
||||
#define NGX_HTTP_CACHE_VERSION 3
|
||||
#define NGX_HTTP_CACHE_VERSION 5
|
||||
|
||||
|
||||
typedef struct {
|
||||
@@ -71,6 +71,8 @@ struct ngx_http_cache_s {
|
||||
|
||||
ngx_file_uniq_t uniq;
|
||||
time_t valid_sec;
|
||||
time_t updating_sec;
|
||||
time_t error_sec;
|
||||
time_t last_modified;
|
||||
time_t date;
|
||||
|
||||
@@ -114,12 +116,18 @@ struct ngx_http_cache_s {
|
||||
unsigned purged:1;
|
||||
unsigned reading:1;
|
||||
unsigned secondary:1;
|
||||
unsigned background:1;
|
||||
|
||||
unsigned stale_updating:1;
|
||||
unsigned stale_error:1;
|
||||
};
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_uint_t version;
|
||||
time_t valid_sec;
|
||||
time_t updating_sec;
|
||||
time_t error_sec;
|
||||
time_t last_modified;
|
||||
time_t date;
|
||||
uint32_t crc32;
|
||||
|
||||
@@ -187,15 +187,24 @@ static void
|
||||
ngx_http_copy_aio_event_handler(ngx_event_t *ev)
|
||||
{
|
||||
ngx_event_aio_t *aio;
|
||||
ngx_connection_t *c;
|
||||
ngx_http_request_t *r;
|
||||
|
||||
aio = ev->data;
|
||||
r = aio->data;
|
||||
c = r->connection;
|
||||
|
||||
ngx_http_set_log_request(c->log, r);
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||
"http aio: \"%V?%V\"", &r->uri, &r->args);
|
||||
|
||||
r->main->blocked--;
|
||||
r->aio = 0;
|
||||
|
||||
r->connection->write->handler(r->connection->write);
|
||||
r->write_event_handler(r);
|
||||
|
||||
ngx_http_run_posted_requests(c);
|
||||
}
|
||||
|
||||
|
||||
@@ -300,14 +309,33 @@ ngx_http_copy_thread_handler(ngx_thread_task_t *task, ngx_file_t *file)
|
||||
static void
|
||||
ngx_http_copy_thread_event_handler(ngx_event_t *ev)
|
||||
{
|
||||
ngx_connection_t *c;
|
||||
ngx_http_request_t *r;
|
||||
|
||||
r = ev->data;
|
||||
c = r->connection;
|
||||
|
||||
ngx_http_set_log_request(c->log, r);
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||
"http thread: \"%V?%V\"", &r->uri, &r->args);
|
||||
|
||||
r->main->blocked--;
|
||||
r->aio = 0;
|
||||
|
||||
r->connection->write->handler(r->connection->write);
|
||||
if (r->done) {
|
||||
/*
|
||||
* trigger connection event handler if the subrequest was
|
||||
* already finalized; this can happen if the handler is used
|
||||
* for sendfile() in threads
|
||||
*/
|
||||
|
||||
c->write->handler(c->write);
|
||||
|
||||
} else {
|
||||
r->write_event_handler(r);
|
||||
ngx_http_run_posted_requests(c);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -120,6 +120,14 @@ static ngx_conf_enum_t ngx_http_core_lingering_close[] = {
|
||||
};
|
||||
|
||||
|
||||
static ngx_conf_enum_t ngx_http_core_server_tokens[] = {
|
||||
{ ngx_string("off"), NGX_HTTP_SERVER_TOKENS_OFF },
|
||||
{ ngx_string("on"), NGX_HTTP_SERVER_TOKENS_ON },
|
||||
{ ngx_string("build"), NGX_HTTP_SERVER_TOKENS_BUILD },
|
||||
{ ngx_null_string, 0 }
|
||||
};
|
||||
|
||||
|
||||
static ngx_conf_enum_t ngx_http_core_if_modified_since[] = {
|
||||
{ ngx_string("off"), NGX_HTTP_IMS_OFF },
|
||||
{ ngx_string("exact"), NGX_HTTP_IMS_EXACT },
|
||||
@@ -599,11 +607,11 @@ static ngx_command_t ngx_http_core_commands[] = {
|
||||
NULL },
|
||||
|
||||
{ ngx_string("server_tokens"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
|
||||
ngx_conf_set_flag_slot,
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||
ngx_conf_set_enum_slot,
|
||||
NGX_HTTP_LOC_CONF_OFFSET,
|
||||
offsetof(ngx_http_core_loc_conf_t, server_tokens),
|
||||
NULL },
|
||||
&ngx_http_core_server_tokens },
|
||||
|
||||
{ ngx_string("if_modified_since"),
|
||||
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
|
||||
@@ -994,6 +1002,7 @@ ngx_http_core_find_config_phase(ngx_http_request_t *r,
|
||||
p = ngx_pnalloc(r->pool, len);
|
||||
|
||||
if (p == NULL) {
|
||||
ngx_http_clear_location(r);
|
||||
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return NGX_OK;
|
||||
}
|
||||
@@ -1306,6 +1315,11 @@ ngx_http_core_try_files_phase(ngx_http_request_t *r,
|
||||
if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
|
||||
!= NGX_OK)
|
||||
{
|
||||
if (of.err == 0) {
|
||||
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (of.err != NGX_ENOENT
|
||||
&& of.err != NGX_ENOTDIR
|
||||
&& of.err != NGX_ENAMETOOLONG)
|
||||
@@ -1881,7 +1895,8 @@ ngx_http_send_response(ngx_http_request_t *r, ngx_uint_t status,
|
||||
if (status == NGX_HTTP_MOVED_PERMANENTLY
|
||||
|| status == NGX_HTTP_MOVED_TEMPORARILY
|
||||
|| status == NGX_HTTP_SEE_OTHER
|
||||
|| status == NGX_HTTP_TEMPORARY_REDIRECT)
|
||||
|| status == NGX_HTTP_TEMPORARY_REDIRECT
|
||||
|| status == NGX_HTTP_PERMANENT_REDIRECT)
|
||||
{
|
||||
ngx_http_clear_location(r);
|
||||
|
||||
@@ -1913,7 +1928,7 @@ ngx_http_send_response(ngx_http_request_t *r, ngx_uint_t status,
|
||||
return ngx_http_send_header(r);
|
||||
}
|
||||
|
||||
b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
|
||||
b = ngx_calloc_buf(r->pool);
|
||||
if (b == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
@@ -2503,6 +2518,7 @@ ngx_http_subrequest(ngx_http_request_t *r,
|
||||
|
||||
sr->subrequest_in_memory = (flags & NGX_HTTP_SUBREQUEST_IN_MEMORY) != 0;
|
||||
sr->waited = (flags & NGX_HTTP_SUBREQUEST_WAITED) != 0;
|
||||
sr->background = (flags & NGX_HTTP_SUBREQUEST_BACKGROUND) != 0;
|
||||
|
||||
sr->unparsed_uri = r->unparsed_uri;
|
||||
sr->method_name = ngx_http_core_get_method;
|
||||
@@ -2516,29 +2532,31 @@ ngx_http_subrequest(ngx_http_request_t *r,
|
||||
sr->read_event_handler = ngx_http_request_empty_handler;
|
||||
sr->write_event_handler = ngx_http_handler;
|
||||
|
||||
if (c->data == r && r->postponed == NULL) {
|
||||
c->data = sr;
|
||||
}
|
||||
|
||||
sr->variables = r->variables;
|
||||
|
||||
sr->log_handler = r->log_handler;
|
||||
|
||||
pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t));
|
||||
if (pr == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
if (!sr->background) {
|
||||
if (c->data == r && r->postponed == NULL) {
|
||||
c->data = sr;
|
||||
}
|
||||
|
||||
pr->request = sr;
|
||||
pr->out = NULL;
|
||||
pr->next = NULL;
|
||||
pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t));
|
||||
if (pr == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (r->postponed) {
|
||||
for (p = r->postponed; p->next; p = p->next) { /* void */ }
|
||||
p->next = pr;
|
||||
pr->request = sr;
|
||||
pr->out = NULL;
|
||||
pr->next = NULL;
|
||||
|
||||
} else {
|
||||
r->postponed = pr;
|
||||
if (r->postponed) {
|
||||
for (p = r->postponed; p->next; p = p->next) { /* void */ }
|
||||
p->next = pr;
|
||||
|
||||
} else {
|
||||
r->postponed = pr;
|
||||
}
|
||||
}
|
||||
|
||||
sr->internal = 1;
|
||||
@@ -2558,6 +2576,18 @@ ngx_http_subrequest(ngx_http_request_t *r,
|
||||
|
||||
*psr = sr;
|
||||
|
||||
if (flags & NGX_HTTP_SUBREQUEST_CLONE) {
|
||||
sr->method = r->method;
|
||||
sr->method_name = r->method_name;
|
||||
sr->loc_conf = r->loc_conf;
|
||||
sr->valid_location = r->valid_location;
|
||||
sr->content_handler = r->content_handler;
|
||||
sr->phase_handler = r->phase_handler;
|
||||
sr->write_event_handler = ngx_http_core_run_phases;
|
||||
|
||||
ngx_http_update_location_config(sr);
|
||||
}
|
||||
|
||||
return ngx_http_post_request(sr, NULL);
|
||||
}
|
||||
|
||||
@@ -3576,9 +3606,9 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf)
|
||||
clcf->log_not_found = NGX_CONF_UNSET;
|
||||
clcf->log_subrequest = NGX_CONF_UNSET;
|
||||
clcf->recursive_error_pages = NGX_CONF_UNSET;
|
||||
clcf->server_tokens = NGX_CONF_UNSET;
|
||||
clcf->chunked_transfer_encoding = NGX_CONF_UNSET;
|
||||
clcf->etag = NGX_CONF_UNSET;
|
||||
clcf->server_tokens = NGX_CONF_UNSET_UINT;
|
||||
clcf->types_hash_max_size = NGX_CONF_UNSET_UINT;
|
||||
clcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT;
|
||||
|
||||
@@ -3842,11 +3872,13 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
ngx_conf_merge_value(conf->log_subrequest, prev->log_subrequest, 0);
|
||||
ngx_conf_merge_value(conf->recursive_error_pages,
|
||||
prev->recursive_error_pages, 0);
|
||||
ngx_conf_merge_value(conf->server_tokens, prev->server_tokens, 1);
|
||||
ngx_conf_merge_value(conf->chunked_transfer_encoding,
|
||||
prev->chunked_transfer_encoding, 1);
|
||||
ngx_conf_merge_value(conf->etag, prev->etag, 1);
|
||||
|
||||
ngx_conf_merge_uint_value(conf->server_tokens, prev->server_tokens,
|
||||
NGX_HTTP_SERVER_TOKENS_ON);
|
||||
|
||||
ngx_conf_merge_ptr_value(conf->open_file_cache,
|
||||
prev->open_file_cache, NULL);
|
||||
|
||||
@@ -4383,16 +4415,14 @@ ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
if (clcf->root.data) {
|
||||
|
||||
if ((clcf->alias != 0) == alias) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"\"%V\" directive is duplicate",
|
||||
&cmd->name);
|
||||
} else {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"\"%V\" directive is duplicate, "
|
||||
"\"%s\" directive was specified earlier",
|
||||
&cmd->name, clcf->alias ? "alias" : "root");
|
||||
return "is duplicate";
|
||||
}
|
||||
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"\"%V\" directive is duplicate, "
|
||||
"\"%s\" directive was specified earlier",
|
||||
&cmd->name, clcf->alias ? "alias" : "root");
|
||||
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
@@ -4507,7 +4537,7 @@ ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
|
||||
if (pclcf->limit_except) {
|
||||
return "duplicate";
|
||||
return "is duplicate";
|
||||
}
|
||||
|
||||
pclcf->limit_except = 0xffffffff;
|
||||
|
||||
@@ -55,6 +55,11 @@ typedef struct ngx_thread_pool_s ngx_thread_pool_t;
|
||||
#define NGX_HTTP_KEEPALIVE_DISABLE_SAFARI 0x0008
|
||||
|
||||
|
||||
#define NGX_HTTP_SERVER_TOKENS_OFF 0
|
||||
#define NGX_HTTP_SERVER_TOKENS_ON 1
|
||||
#define NGX_HTTP_SERVER_TOKENS_BUILD 2
|
||||
|
||||
|
||||
typedef struct ngx_http_location_tree_node_s ngx_http_location_tree_node_t;
|
||||
typedef struct ngx_http_core_loc_conf_s ngx_http_core_loc_conf_t;
|
||||
|
||||
@@ -153,7 +158,8 @@ typedef struct {
|
||||
|
||||
ngx_hash_t variables_hash;
|
||||
|
||||
ngx_array_t variables; /* ngx_http_variable_t */
|
||||
ngx_array_t variables; /* ngx_http_variable_t */
|
||||
ngx_array_t prefix_variables; /* ngx_http_variable_t */
|
||||
ngx_uint_t ncaptures;
|
||||
|
||||
ngx_uint_t server_names_hash_max_size;
|
||||
@@ -393,7 +399,7 @@ struct ngx_http_core_loc_conf_s {
|
||||
ngx_flag_t log_not_found; /* log_not_found */
|
||||
ngx_flag_t log_subrequest; /* log_subrequest */
|
||||
ngx_flag_t recursive_error_pages; /* recursive_error_pages */
|
||||
ngx_flag_t server_tokens; /* server_tokens */
|
||||
ngx_uint_t server_tokens; /* server_tokens */
|
||||
ngx_flag_t chunked_transfer_encoding; /* chunked_transfer_encoding */
|
||||
ngx_flag_t etag; /* etag */
|
||||
|
||||
|
||||
@@ -601,6 +601,8 @@ ngx_http_file_cache_read(ngx_http_request_t *r, ngx_http_cache_t *c)
|
||||
c->buf->last += n;
|
||||
|
||||
c->valid_sec = h->valid_sec;
|
||||
c->updating_sec = h->updating_sec;
|
||||
c->error_sec = h->error_sec;
|
||||
c->last_modified = h->last_modified;
|
||||
c->date = h->date;
|
||||
c->valid_msec = h->valid_msec;
|
||||
@@ -632,6 +634,8 @@ ngx_http_file_cache_read(ngx_http_request_t *r, ngx_http_cache_t *c)
|
||||
now = ngx_time();
|
||||
|
||||
if (c->valid_sec < now) {
|
||||
c->stale_updating = c->valid_sec + c->updating_sec >= now;
|
||||
c->stale_error = c->valid_sec + c->error_sec >= now;
|
||||
|
||||
ngx_shmtx_lock(&cache->shpool->mutex);
|
||||
|
||||
@@ -1252,6 +1256,8 @@ ngx_http_file_cache_set_header(ngx_http_request_t *r, u_char *buf)
|
||||
|
||||
h->version = NGX_HTTP_CACHE_VERSION;
|
||||
h->valid_sec = c->valid_sec;
|
||||
h->updating_sec = c->updating_sec;
|
||||
h->error_sec = c->error_sec;
|
||||
h->last_modified = c->last_modified;
|
||||
h->date = c->date;
|
||||
h->crc32 = c->crc32;
|
||||
@@ -1513,6 +1519,8 @@ ngx_http_file_cache_update_header(ngx_http_request_t *r)
|
||||
|
||||
h.version = NGX_HTTP_CACHE_VERSION;
|
||||
h.valid_sec = c->valid_sec;
|
||||
h.updating_sec = c->updating_sec;
|
||||
h.error_sec = c->error_sec;
|
||||
h.last_modified = c->last_modified;
|
||||
h.date = c->date;
|
||||
h.crc32 = c->crc32;
|
||||
@@ -1569,7 +1577,7 @@ ngx_http_cache_send(ngx_http_request_t *r)
|
||||
|
||||
/* we need to allocate all before the header would be sent */
|
||||
|
||||
b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
|
||||
b = ngx_calloc_buf(r->pool);
|
||||
if (b == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
@@ -1680,7 +1688,7 @@ ngx_http_file_cache_cleanup(void *data)
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->file.log, 0,
|
||||
"http file cache cleanup");
|
||||
|
||||
if (c->updating) {
|
||||
if (c->updating && !c->background) {
|
||||
ngx_log_error(NGX_LOG_ALERT, c->file.log, 0,
|
||||
"stalled cache updating, error:%ui", c->error);
|
||||
}
|
||||
@@ -1692,13 +1700,14 @@ ngx_http_file_cache_cleanup(void *data)
|
||||
static time_t
|
||||
ngx_http_file_cache_forced_expire(ngx_http_file_cache_t *cache)
|
||||
{
|
||||
u_char *name;
|
||||
u_char *name, *p;
|
||||
size_t len;
|
||||
time_t wait;
|
||||
ngx_uint_t tries;
|
||||
ngx_path_t *path;
|
||||
ngx_queue_t *q;
|
||||
ngx_queue_t *q, *sentinel;
|
||||
ngx_http_file_cache_node_t *fcn;
|
||||
u_char key[2 * NGX_HTTP_CACHE_KEY_LEN];
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
|
||||
"http file cache forced expire");
|
||||
@@ -1715,13 +1724,21 @@ ngx_http_file_cache_forced_expire(ngx_http_file_cache_t *cache)
|
||||
|
||||
wait = 10;
|
||||
tries = 20;
|
||||
sentinel = NULL;
|
||||
|
||||
ngx_shmtx_lock(&cache->shpool->mutex);
|
||||
|
||||
for (q = ngx_queue_last(&cache->sh->queue);
|
||||
q != ngx_queue_sentinel(&cache->sh->queue);
|
||||
q = ngx_queue_prev(q))
|
||||
{
|
||||
for ( ;; ) {
|
||||
if (ngx_queue_empty(&cache->sh->queue)) {
|
||||
break;
|
||||
}
|
||||
|
||||
q = ngx_queue_last(&cache->sh->queue);
|
||||
|
||||
if (q == sentinel) {
|
||||
break;
|
||||
}
|
||||
|
||||
fcn = ngx_queue_data(q, ngx_http_file_cache_node_t, queue);
|
||||
|
||||
ngx_log_debug6(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
|
||||
@@ -1732,15 +1749,37 @@ ngx_http_file_cache_forced_expire(ngx_http_file_cache_t *cache)
|
||||
if (fcn->count == 0) {
|
||||
ngx_http_file_cache_delete(cache, q, name);
|
||||
wait = 0;
|
||||
|
||||
} else {
|
||||
if (--tries) {
|
||||
continue;
|
||||
}
|
||||
|
||||
wait = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
p = ngx_hex_dump(key, (u_char *) &fcn->node.key,
|
||||
sizeof(ngx_rbtree_key_t));
|
||||
len = NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t);
|
||||
(void) ngx_hex_dump(p, fcn->key, len);
|
||||
|
||||
/*
|
||||
* abnormally exited workers may leave locked cache entries,
|
||||
* and although it may be safe to remove them completely,
|
||||
* we prefer to just move them to the top of the inactive queue
|
||||
*/
|
||||
|
||||
ngx_queue_remove(q);
|
||||
fcn->expire = ngx_time() + cache->inactive;
|
||||
ngx_queue_insert_head(&cache->sh->queue, &fcn->queue);
|
||||
|
||||
ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
|
||||
"ignore long locked inactive cache entry %*s, count:%d",
|
||||
(size_t) 2 * NGX_HTTP_CACHE_KEY_LEN, key, fcn->count);
|
||||
|
||||
if (sentinel == NULL) {
|
||||
sentinel = q;
|
||||
}
|
||||
|
||||
if (--tries) {
|
||||
continue;
|
||||
}
|
||||
|
||||
wait = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,8 +46,9 @@ ngx_module_t ngx_http_header_filter_module = {
|
||||
};
|
||||
|
||||
|
||||
static char ngx_http_server_string[] = "Server: nginx" CRLF;
|
||||
static char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF;
|
||||
static u_char ngx_http_server_string[] = "Server: nginx" CRLF;
|
||||
static u_char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF;
|
||||
static u_char ngx_http_server_build_string[] = "Server: " NGINX_VER_BUILD CRLF;
|
||||
|
||||
|
||||
static ngx_str_t ngx_http_status_lines[] = {
|
||||
@@ -74,8 +75,9 @@ static ngx_str_t ngx_http_status_lines[] = {
|
||||
ngx_null_string, /* "305 Use Proxy" */
|
||||
ngx_null_string, /* "306 unused" */
|
||||
ngx_string("307 Temporary Redirect"),
|
||||
ngx_string("308 Permanent Redirect"),
|
||||
|
||||
#define NGX_HTTP_LAST_3XX 308
|
||||
#define NGX_HTTP_LAST_3XX 309
|
||||
#define NGX_HTTP_OFF_4XX (NGX_HTTP_LAST_3XX - 301 + NGX_HTTP_OFF_3XX)
|
||||
|
||||
ngx_string("400 Bad Request"),
|
||||
@@ -100,12 +102,16 @@ static ngx_str_t ngx_http_status_lines[] = {
|
||||
ngx_null_string, /* "419 unused" */
|
||||
ngx_null_string, /* "420 unused" */
|
||||
ngx_string("421 Misdirected Request"),
|
||||
ngx_null_string, /* "422 Unprocessable Entity" */
|
||||
ngx_null_string, /* "423 Locked" */
|
||||
ngx_null_string, /* "424 Failed Dependency" */
|
||||
ngx_null_string, /* "425 unused" */
|
||||
ngx_null_string, /* "426 Upgrade Required" */
|
||||
ngx_null_string, /* "427 unused" */
|
||||
ngx_null_string, /* "428 Precondition Required" */
|
||||
ngx_string("429 Too Many Requests"),
|
||||
|
||||
/* ngx_null_string, */ /* "422 Unprocessable Entity" */
|
||||
/* ngx_null_string, */ /* "423 Locked" */
|
||||
/* ngx_null_string, */ /* "424 Failed Dependency" */
|
||||
|
||||
#define NGX_HTTP_LAST_4XX 422
|
||||
#define NGX_HTTP_LAST_4XX 430
|
||||
#define NGX_HTTP_OFF_5XX (NGX_HTTP_LAST_4XX - 400 + NGX_HTTP_OFF_4XX)
|
||||
|
||||
ngx_string("500 Internal Server Error"),
|
||||
@@ -113,7 +119,7 @@ static ngx_str_t ngx_http_status_lines[] = {
|
||||
ngx_string("502 Bad Gateway"),
|
||||
ngx_string("503 Service Temporarily Unavailable"),
|
||||
ngx_string("504 Gateway Time-out"),
|
||||
ngx_null_string, /* "505 HTTP Version Not Supported" */
|
||||
ngx_string("505 HTTP Version Not Supported"),
|
||||
ngx_null_string, /* "506 Variant Also Negotiates" */
|
||||
ngx_string("507 Insufficient Storage"),
|
||||
|
||||
@@ -274,8 +280,15 @@ ngx_http_header_filter(ngx_http_request_t *r)
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
|
||||
if (r->headers_out.server == NULL) {
|
||||
len += clcf->server_tokens ? sizeof(ngx_http_server_full_string) - 1:
|
||||
sizeof(ngx_http_server_string) - 1;
|
||||
if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_ON) {
|
||||
len += sizeof(ngx_http_server_full_string) - 1;
|
||||
|
||||
} else if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_BUILD) {
|
||||
len += sizeof(ngx_http_server_build_string) - 1;
|
||||
|
||||
} else {
|
||||
len += sizeof(ngx_http_server_string) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (r->headers_out.date == NULL) {
|
||||
@@ -436,12 +449,16 @@ ngx_http_header_filter(ngx_http_request_t *r)
|
||||
*b->last++ = CR; *b->last++ = LF;
|
||||
|
||||
if (r->headers_out.server == NULL) {
|
||||
if (clcf->server_tokens) {
|
||||
p = (u_char *) ngx_http_server_full_string;
|
||||
if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_ON) {
|
||||
p = ngx_http_server_full_string;
|
||||
len = sizeof(ngx_http_server_full_string) - 1;
|
||||
|
||||
} else if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_BUILD) {
|
||||
p = ngx_http_server_build_string;
|
||||
len = sizeof(ngx_http_server_build_string) - 1;
|
||||
|
||||
} else {
|
||||
p = (u_char *) ngx_http_server_string;
|
||||
p = ngx_http_server_string;
|
||||
len = sizeof(ngx_http_server_string) - 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -723,6 +723,11 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
|
||||
}
|
||||
|
||||
r->http_major = ch - '0';
|
||||
|
||||
if (r->http_major > 1) {
|
||||
return NGX_HTTP_PARSE_INVALID_VERSION;
|
||||
}
|
||||
|
||||
state = sw_major_digit;
|
||||
break;
|
||||
|
||||
@@ -737,11 +742,12 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
|
||||
return NGX_HTTP_PARSE_INVALID_REQUEST;
|
||||
}
|
||||
|
||||
if (r->http_major > 99) {
|
||||
return NGX_HTTP_PARSE_INVALID_REQUEST;
|
||||
r->http_major = r->http_major * 10 + ch - '0';
|
||||
|
||||
if (r->http_major > 1) {
|
||||
return NGX_HTTP_PARSE_INVALID_VERSION;
|
||||
}
|
||||
|
||||
r->http_major = r->http_major * 10 + ch - '0';
|
||||
break;
|
||||
|
||||
/* first digit of minor HTTP version */
|
||||
@@ -1390,6 +1396,7 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r, ngx_uint_t merge_slashes)
|
||||
goto done;
|
||||
case '+':
|
||||
r->plus_in_uri = 1;
|
||||
/* fall through */
|
||||
default:
|
||||
state = sw_usual;
|
||||
*u++ = ch;
|
||||
@@ -1431,6 +1438,7 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r, ngx_uint_t merge_slashes)
|
||||
goto done;
|
||||
case '+':
|
||||
r->plus_in_uri = 1;
|
||||
/* fall through */
|
||||
default:
|
||||
state = sw_usual;
|
||||
*u++ = ch;
|
||||
@@ -1478,6 +1486,7 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r, ngx_uint_t merge_slashes)
|
||||
goto done;
|
||||
case '+':
|
||||
r->plus_in_uri = 1;
|
||||
/* fall through */
|
||||
default:
|
||||
state = sw_usual;
|
||||
*u++ = ch;
|
||||
|
||||
@@ -72,6 +72,9 @@ static char *ngx_http_client_errors[] = {
|
||||
/* NGX_HTTP_PARSE_INVALID_REQUEST */
|
||||
"client sent invalid request",
|
||||
|
||||
/* NGX_HTTP_PARSE_INVALID_VERSION */
|
||||
"client sent invalid version",
|
||||
|
||||
/* NGX_HTTP_PARSE_INVALID_09_METHOD */
|
||||
"client sent invalid method in HTTP/0.9 request"
|
||||
};
|
||||
@@ -549,7 +552,7 @@ ngx_http_create_request(ngx_connection_t *c)
|
||||
|
||||
ngx_set_connection_log(r->connection, clcf->error_log);
|
||||
|
||||
r->header_in = hc->nbusy ? hc->busy[0] : c->buffer;
|
||||
r->header_in = hc->busy ? hc->busy->buf : c->buffer;
|
||||
|
||||
if (ngx_list_init(&r->headers_out.headers, r->pool, 20,
|
||||
sizeof(ngx_table_elt_t))
|
||||
@@ -620,14 +623,15 @@ ngx_http_create_request(ngx_connection_t *c)
|
||||
static void
|
||||
ngx_http_ssl_handshake(ngx_event_t *rev)
|
||||
{
|
||||
u_char *p, buf[NGX_PROXY_PROTOCOL_MAX_HEADER + 1];
|
||||
size_t size;
|
||||
ssize_t n;
|
||||
ngx_err_t err;
|
||||
ngx_int_t rc;
|
||||
ngx_connection_t *c;
|
||||
ngx_http_connection_t *hc;
|
||||
ngx_http_ssl_srv_conf_t *sscf;
|
||||
u_char *p, buf[NGX_PROXY_PROTOCOL_MAX_HEADER + 1];
|
||||
size_t size;
|
||||
ssize_t n;
|
||||
ngx_err_t err;
|
||||
ngx_int_t rc;
|
||||
ngx_connection_t *c;
|
||||
ngx_http_connection_t *hc;
|
||||
ngx_http_ssl_srv_conf_t *sscf;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
|
||||
c = rev->data;
|
||||
hc = c->data;
|
||||
@@ -709,6 +713,14 @@ ngx_http_ssl_handshake(ngx_event_t *rev)
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0,
|
||||
"https ssl handshake: 0x%02Xd", buf[0]);
|
||||
|
||||
clcf = ngx_http_get_module_loc_conf(hc->conf_ctx,
|
||||
ngx_http_core_module);
|
||||
|
||||
if (clcf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) {
|
||||
ngx_http_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
sscf = ngx_http_get_module_srv_conf(hc->conf_ctx,
|
||||
ngx_http_ssl_module);
|
||||
|
||||
@@ -884,6 +896,8 @@ ngx_http_ssl_servername(ngx_ssl_conn_t *ssl_conn, int *ad, void *arg)
|
||||
|
||||
sscf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_ssl_module);
|
||||
|
||||
c->ssl->buffer_size = sscf->buffer_size;
|
||||
|
||||
if (sscf->ssl.ctx) {
|
||||
SSL_set_SSL_CTX(ssl_conn, sscf->ssl.ctx);
|
||||
|
||||
@@ -1034,7 +1048,14 @@ ngx_http_process_request_line(ngx_event_t *rev)
|
||||
|
||||
ngx_log_error(NGX_LOG_INFO, c->log, 0,
|
||||
ngx_http_client_errors[rc - NGX_HTTP_CLIENT_ERROR]);
|
||||
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
|
||||
|
||||
if (rc == NGX_HTTP_PARSE_INVALID_VERSION) {
|
||||
ngx_http_finalize_request(r, NGX_HTTP_VERSION_NOT_SUPPORTED);
|
||||
|
||||
} else {
|
||||
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1429,6 +1450,7 @@ ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
|
||||
{
|
||||
u_char *old, *new;
|
||||
ngx_buf_t *b;
|
||||
ngx_chain_t *cl;
|
||||
ngx_http_connection_t *hc;
|
||||
ngx_http_core_srv_conf_t *cscf;
|
||||
|
||||
@@ -1458,8 +1480,11 @@ ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
|
||||
|
||||
hc = r->http_connection;
|
||||
|
||||
if (hc->nfree) {
|
||||
b = hc->free[--hc->nfree];
|
||||
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",
|
||||
@@ -1467,20 +1492,19 @@ ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
|
||||
|
||||
} else if (hc->nbusy < cscf->large_client_header_buffers.num) {
|
||||
|
||||
if (hc->busy == NULL) {
|
||||
hc->busy = ngx_palloc(r->connection->pool,
|
||||
cscf->large_client_header_buffers.num * sizeof(ngx_buf_t *));
|
||||
if (hc->busy == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -1489,7 +1513,9 @@ ngx_http_alloc_large_header_buffer(ngx_http_request_t *r,
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
hc->busy[hc->nbusy++] = b;
|
||||
cl->next = hc->busy;
|
||||
hc->busy = cl;
|
||||
hc->nbusy++;
|
||||
|
||||
if (r->state == 0) {
|
||||
/*
|
||||
@@ -2191,6 +2217,11 @@ ngx_http_request_handler(ngx_event_t *ev)
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||
"http run request: \"%V?%V\"", &r->uri, &r->args);
|
||||
|
||||
if (ev->delayed && ev->timedout) {
|
||||
ev->delayed = 0;
|
||||
ev->timedout = 0;
|
||||
}
|
||||
|
||||
if (ev->write) {
|
||||
r->write_event_handler(r);
|
||||
|
||||
@@ -2300,10 +2331,6 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
|
||||
return;
|
||||
}
|
||||
|
||||
if (r->main->blocked) {
|
||||
r->write_event_handler = ngx_http_request_finalizer;
|
||||
}
|
||||
|
||||
ngx_http_terminate_request(r, rc);
|
||||
return;
|
||||
}
|
||||
@@ -2335,6 +2362,26 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
|
||||
}
|
||||
|
||||
if (r != r->main) {
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
|
||||
if (r->background) {
|
||||
if (!r->logged) {
|
||||
if (clcf->log_subrequest) {
|
||||
ngx_http_log_request(r);
|
||||
}
|
||||
|
||||
r->logged = 1;
|
||||
|
||||
} else {
|
||||
ngx_log_error(NGX_LOG_ALERT, c->log, 0,
|
||||
"subrequest: \"%V?%V\" logged again",
|
||||
&r->uri, &r->args);
|
||||
}
|
||||
|
||||
r->done = 1;
|
||||
ngx_http_finalize_connection(r);
|
||||
return;
|
||||
}
|
||||
|
||||
if (r->buffered || r->postponed) {
|
||||
|
||||
@@ -2352,9 +2399,6 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
|
||||
r->main->count--;
|
||||
|
||||
if (!r->logged) {
|
||||
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
|
||||
if (clcf->log_subrequest) {
|
||||
ngx_http_log_request(r);
|
||||
}
|
||||
@@ -2401,7 +2445,7 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
|
||||
return;
|
||||
}
|
||||
|
||||
if (r->buffered || c->buffered || r->postponed || r->blocked) {
|
||||
if (r->buffered || c->buffered || r->postponed) {
|
||||
|
||||
if (ngx_http_set_write_handler(r) != NGX_OK) {
|
||||
ngx_http_terminate_request(r, 0);
|
||||
@@ -2418,6 +2462,8 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
|
||||
}
|
||||
|
||||
r->done = 1;
|
||||
|
||||
r->read_event_handler = ngx_http_block_reading;
|
||||
r->write_event_handler = ngx_http_request_empty_handler;
|
||||
|
||||
if (!r->post_action) {
|
||||
@@ -2480,6 +2526,8 @@ ngx_http_terminate_request(ngx_http_request_t *r, ngx_int_t rc)
|
||||
if (mr->write_event_handler) {
|
||||
|
||||
if (mr->blocked) {
|
||||
r->connection->error = 1;
|
||||
r->write_event_handler = ngx_http_request_finalizer;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2536,6 +2584,8 @@ ngx_http_finalize_connection(ngx_http_request_t *r)
|
||||
return;
|
||||
}
|
||||
|
||||
r = r->main;
|
||||
|
||||
if (r->reading_body) {
|
||||
r->keepalive = 0;
|
||||
r->lingering_close = 1;
|
||||
@@ -2600,7 +2650,7 @@ ngx_http_set_write_handler(ngx_http_request_t *r)
|
||||
static void
|
||||
ngx_http_writer(ngx_http_request_t *r)
|
||||
{
|
||||
int rc;
|
||||
ngx_int_t rc;
|
||||
ngx_event_t *wev;
|
||||
ngx_connection_t *c;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
@@ -2614,34 +2664,22 @@ ngx_http_writer(ngx_http_request_t *r)
|
||||
clcf = ngx_http_get_module_loc_conf(r->main, ngx_http_core_module);
|
||||
|
||||
if (wev->timedout) {
|
||||
if (!wev->delayed) {
|
||||
ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT,
|
||||
"client timed out");
|
||||
c->timedout = 1;
|
||||
|
||||
ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT);
|
||||
return;
|
||||
}
|
||||
|
||||
wev->timedout = 0;
|
||||
wev->delayed = 0;
|
||||
|
||||
if (!wev->ready) {
|
||||
ngx_add_timer(wev, clcf->send_timeout);
|
||||
|
||||
if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
|
||||
ngx_http_close_request(r, 0);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT,
|
||||
"client timed out");
|
||||
c->timedout = 1;
|
||||
|
||||
ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (wev->delayed || r->aio) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0,
|
||||
"http writer delayed");
|
||||
|
||||
if (!wev->delayed) {
|
||||
ngx_add_timer(wev, clcf->send_timeout);
|
||||
}
|
||||
|
||||
if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
|
||||
ngx_http_close_request(r, 0);
|
||||
}
|
||||
@@ -2652,7 +2690,7 @@ ngx_http_writer(ngx_http_request_t *r)
|
||||
rc = ngx_http_output_filter(r, NULL);
|
||||
|
||||
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||
"http writer output filter: %d, \"%V?%V\"",
|
||||
"http writer output filter: %i, \"%V?%V\"",
|
||||
rc, &r->uri, &r->args);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
@@ -2833,12 +2871,11 @@ static void
|
||||
ngx_http_set_keepalive(ngx_http_request_t *r)
|
||||
{
|
||||
int tcp_nodelay;
|
||||
ngx_int_t i;
|
||||
ngx_buf_t *b, *f;
|
||||
ngx_chain_t *cl, *ln;
|
||||
ngx_event_t *rev, *wev;
|
||||
ngx_connection_t *c;
|
||||
ngx_http_connection_t *hc;
|
||||
ngx_http_core_srv_conf_t *cscf;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
|
||||
c = r->connection;
|
||||
@@ -2874,26 +2911,33 @@ ngx_http_set_keepalive(ngx_http_request_t *r)
|
||||
* Now we would move the large header buffers to the free list.
|
||||
*/
|
||||
|
||||
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
|
||||
for (cl = hc->busy; cl; /* void */) {
|
||||
ln = cl;
|
||||
cl = cl->next;
|
||||
|
||||
if (hc->free == NULL) {
|
||||
hc->free = ngx_palloc(c->pool,
|
||||
cscf->large_client_header_buffers.num * sizeof(ngx_buf_t *));
|
||||
|
||||
if (hc->free == NULL) {
|
||||
ngx_http_close_request(r, 0);
|
||||
return;
|
||||
if (ln->buf == b) {
|
||||
ngx_free_chain(c->pool, ln);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < hc->nbusy - 1; i++) {
|
||||
f = hc->busy[i];
|
||||
hc->free[hc->nfree++] = f;
|
||||
f = ln->buf;
|
||||
f->pos = f->start;
|
||||
f->last = f->start;
|
||||
|
||||
ln->next = hc->free;
|
||||
hc->free = ln;
|
||||
}
|
||||
|
||||
hc->busy[0] = b;
|
||||
cl = ngx_alloc_chain_link(c->pool);
|
||||
if (cl == NULL) {
|
||||
ngx_http_close_request(r, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
cl->buf = b;
|
||||
cl->next = NULL;
|
||||
|
||||
hc->busy = cl;
|
||||
hc->nbusy = 1;
|
||||
}
|
||||
}
|
||||
@@ -2964,27 +3008,32 @@ ngx_http_set_keepalive(ngx_http_request_t *r)
|
||||
b->last = b->start;
|
||||
}
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "hc free: %p %i",
|
||||
hc->free, hc->nfree);
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "hc free: %p",
|
||||
hc->free);
|
||||
|
||||
if (hc->free) {
|
||||
for (i = 0; i < hc->nfree; i++) {
|
||||
ngx_pfree(c->pool, hc->free[i]->start);
|
||||
hc->free[i] = NULL;
|
||||
for (cl = hc->free; cl; /* void */) {
|
||||
ln = cl;
|
||||
cl = cl->next;
|
||||
ngx_pfree(c->pool, ln->buf->start);
|
||||
ngx_free_chain(c->pool, ln);
|
||||
}
|
||||
|
||||
hc->nfree = 0;
|
||||
hc->free = NULL;
|
||||
}
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "hc busy: %p %i",
|
||||
hc->busy, hc->nbusy);
|
||||
|
||||
if (hc->busy) {
|
||||
for (i = 0; i < hc->nbusy; i++) {
|
||||
ngx_pfree(c->pool, hc->busy[i]->start);
|
||||
hc->busy[i] = NULL;
|
||||
for (cl = hc->busy; cl; /* void */) {
|
||||
ln = cl;
|
||||
cl = cl->next;
|
||||
ngx_pfree(c->pool, ln->buf->start);
|
||||
ngx_free_chain(c->pool, ln);
|
||||
}
|
||||
|
||||
hc->busy = NULL;
|
||||
hc->nbusy = 0;
|
||||
}
|
||||
|
||||
@@ -3019,30 +3068,9 @@ ngx_http_set_keepalive(ngx_http_request_t *r)
|
||||
tcp_nodelay = 1;
|
||||
}
|
||||
|
||||
if (tcp_nodelay
|
||||
&& clcf->tcp_nodelay
|
||||
&& c->tcp_nodelay == NGX_TCP_NODELAY_UNSET)
|
||||
{
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");
|
||||
|
||||
if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
|
||||
(const void *) &tcp_nodelay, sizeof(int))
|
||||
== -1)
|
||||
{
|
||||
#if (NGX_SOLARIS)
|
||||
/* Solaris returns EINVAL if a socket has been shut down */
|
||||
c->log_error = NGX_ERROR_IGNORE_EINVAL;
|
||||
#endif
|
||||
|
||||
ngx_connection_error(c, ngx_socket_errno,
|
||||
"setsockopt(TCP_NODELAY) failed");
|
||||
|
||||
c->log_error = NGX_ERROR_INFO;
|
||||
ngx_http_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
c->tcp_nodelay = NGX_TCP_NODELAY_SET;
|
||||
if (tcp_nodelay && clcf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) {
|
||||
ngx_http_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
@@ -54,15 +54,19 @@
|
||||
#define NGX_HTTP_CLIENT_ERROR 10
|
||||
#define NGX_HTTP_PARSE_INVALID_METHOD 10
|
||||
#define NGX_HTTP_PARSE_INVALID_REQUEST 11
|
||||
#define NGX_HTTP_PARSE_INVALID_09_METHOD 12
|
||||
#define NGX_HTTP_PARSE_INVALID_VERSION 12
|
||||
#define NGX_HTTP_PARSE_INVALID_09_METHOD 13
|
||||
|
||||
#define NGX_HTTP_PARSE_INVALID_HEADER 13
|
||||
#define NGX_HTTP_PARSE_INVALID_HEADER 14
|
||||
|
||||
|
||||
/* unused 1 */
|
||||
#define NGX_HTTP_SUBREQUEST_IN_MEMORY 2
|
||||
#define NGX_HTTP_SUBREQUEST_WAITED 4
|
||||
#define NGX_HTTP_LOG_UNSAFE 8
|
||||
#define NGX_HTTP_SUBREQUEST_CLONE 8
|
||||
#define NGX_HTTP_SUBREQUEST_BACKGROUND 16
|
||||
|
||||
#define NGX_HTTP_LOG_UNSAFE 1
|
||||
|
||||
|
||||
#define NGX_HTTP_CONTINUE 100
|
||||
@@ -81,6 +85,7 @@
|
||||
#define NGX_HTTP_SEE_OTHER 303
|
||||
#define NGX_HTTP_NOT_MODIFIED 304
|
||||
#define NGX_HTTP_TEMPORARY_REDIRECT 307
|
||||
#define NGX_HTTP_PERMANENT_REDIRECT 308
|
||||
|
||||
#define NGX_HTTP_BAD_REQUEST 400
|
||||
#define NGX_HTTP_UNAUTHORIZED 401
|
||||
@@ -96,6 +101,7 @@
|
||||
#define NGX_HTTP_UNSUPPORTED_MEDIA_TYPE 415
|
||||
#define NGX_HTTP_RANGE_NOT_SATISFIABLE 416
|
||||
#define NGX_HTTP_MISDIRECTED_REQUEST 421
|
||||
#define NGX_HTTP_TOO_MANY_REQUESTS 429
|
||||
|
||||
|
||||
/* Our own HTTP codes */
|
||||
@@ -132,6 +138,7 @@
|
||||
#define NGX_HTTP_BAD_GATEWAY 502
|
||||
#define NGX_HTTP_SERVICE_UNAVAILABLE 503
|
||||
#define NGX_HTTP_GATEWAY_TIME_OUT 504
|
||||
#define NGX_HTTP_VERSION_NOT_SUPPORTED 505
|
||||
#define NGX_HTTP_INSUFFICIENT_STORAGE 507
|
||||
|
||||
|
||||
@@ -307,11 +314,10 @@ typedef struct {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
ngx_buf_t **busy;
|
||||
ngx_chain_t *busy;
|
||||
ngx_int_t nbusy;
|
||||
|
||||
ngx_buf_t **free;
|
||||
ngx_int_t nfree;
|
||||
ngx_chain_t *free;
|
||||
|
||||
unsigned ssl:1;
|
||||
unsigned proxy_protocol:1;
|
||||
@@ -537,6 +543,7 @@ struct ngx_http_request_s {
|
||||
unsigned stat_writing:1;
|
||||
unsigned stat_processing:1;
|
||||
|
||||
unsigned background:1;
|
||||
unsigned health_check:1;
|
||||
|
||||
/* used to parse HTTP headers */
|
||||
|
||||
@@ -46,13 +46,6 @@ ngx_http_read_client_request_body(ngx_http_request_t *r,
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
#if (NGX_HTTP_V2)
|
||||
if (r->stream) {
|
||||
rc = ngx_http_v2_read_request_body(r, post_handler);
|
||||
goto done;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ngx_http_test_expect(r) != NGX_OK) {
|
||||
rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
goto done;
|
||||
@@ -85,6 +78,13 @@ ngx_http_read_client_request_body(ngx_http_request_t *r,
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
#if (NGX_HTTP_V2)
|
||||
if (r->stream) {
|
||||
rc = ngx_http_v2_read_request_body(r);
|
||||
goto done;
|
||||
}
|
||||
#endif
|
||||
|
||||
preread = r->header_in->last - r->header_in->pos;
|
||||
|
||||
if (preread) {
|
||||
@@ -805,7 +805,11 @@ ngx_http_test_expect(ngx_http_request_t *r)
|
||||
|
||||
if (r->expect_tested
|
||||
|| r->headers_in.expect == NULL
|
||||
|| r->http_version < NGX_HTTP_VERSION_11)
|
||||
|| r->http_version < NGX_HTTP_VERSION_11
|
||||
#if (NGX_HTTP_V2)
|
||||
|| r->stream != NULL
|
||||
#endif
|
||||
)
|
||||
{
|
||||
return NGX_OK;
|
||||
}
|
||||
@@ -835,6 +839,8 @@ ngx_http_test_expect(ngx_http_request_t *r)
|
||||
|
||||
/* we assume that such small packet should be send successfully */
|
||||
|
||||
r->connection->error = 1;
|
||||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
@@ -1085,6 +1091,7 @@ ngx_http_request_body_save_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
||||
|
||||
#if (NGX_DEBUG)
|
||||
|
||||
#if 0
|
||||
for (cl = rb->bufs; cl; cl = cl->next) {
|
||||
ngx_log_debug7(NGX_LOG_DEBUG_EVENT, r->connection->log, 0,
|
||||
"http body old buf t:%d f:%d %p, pos %p, size: %z "
|
||||
@@ -1095,6 +1102,7 @@ ngx_http_request_body_save_filter(ngx_http_request_t *r, ngx_chain_t *in)
|
||||
cl->buf->file_pos,
|
||||
cl->buf->file_last - cl->buf->file_pos);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (cl = in; cl; cl = cl->next) {
|
||||
ngx_log_debug7(NGX_LOG_DEBUG_EVENT, r->connection->log, 0,
|
||||
|
||||
@@ -220,7 +220,7 @@ ngx_http_set_complex_value_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
cv = (ngx_http_complex_value_t **) (p + cmd->offset);
|
||||
|
||||
if (*cv != NULL) {
|
||||
return "duplicate";
|
||||
return "is duplicate";
|
||||
}
|
||||
|
||||
*cv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
|
||||
@@ -1513,6 +1513,12 @@ ngx_http_script_file_code(ngx_http_script_engine_t *e)
|
||||
if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
|
||||
!= NGX_OK)
|
||||
{
|
||||
if (of.err == 0) {
|
||||
e->ip = ngx_http_script_exit;
|
||||
e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
if (of.err != NGX_ENOENT
|
||||
&& of.err != NGX_ENOTDIR
|
||||
&& of.err != NGX_ENAMETOOLONG)
|
||||
|
||||
@@ -25,6 +25,13 @@ static u_char ngx_http_error_full_tail[] =
|
||||
;
|
||||
|
||||
|
||||
static u_char ngx_http_error_build_tail[] =
|
||||
"<hr><center>" NGINX_VER_BUILD "</center>" CRLF
|
||||
"</body>" CRLF
|
||||
"</html>" CRLF
|
||||
;
|
||||
|
||||
|
||||
static u_char ngx_http_error_tail[] =
|
||||
"<hr><center>nginx</center>" CRLF
|
||||
"</body>" CRLF
|
||||
@@ -82,6 +89,14 @@ static char ngx_http_error_307_page[] =
|
||||
;
|
||||
|
||||
|
||||
static char ngx_http_error_308_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>308 Permanent Redirect</title></head>" CRLF
|
||||
"<body bgcolor=\"white\">" CRLF
|
||||
"<center><h1>308 Permanent Redirect</h1></center>" CRLF
|
||||
;
|
||||
|
||||
|
||||
static char ngx_http_error_400_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>400 Bad Request</title></head>" CRLF
|
||||
@@ -218,6 +233,14 @@ static char ngx_http_error_421_page[] =
|
||||
;
|
||||
|
||||
|
||||
static char ngx_http_error_429_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>429 Too Many Requests</title></head>" CRLF
|
||||
"<body bgcolor=\"white\">" CRLF
|
||||
"<center><h1>429 Too Many Requests</h1></center>" CRLF
|
||||
;
|
||||
|
||||
|
||||
static char ngx_http_error_494_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>400 Request Header Or Cookie Too Large</title></head>"
|
||||
@@ -298,6 +321,14 @@ static char ngx_http_error_504_page[] =
|
||||
;
|
||||
|
||||
|
||||
static char ngx_http_error_505_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>505 HTTP Version Not Supported</title></head>" CRLF
|
||||
"<body bgcolor=\"white\">" CRLF
|
||||
"<center><h1>505 HTTP Version Not Supported</h1></center>" CRLF
|
||||
;
|
||||
|
||||
|
||||
static char ngx_http_error_507_page[] =
|
||||
"<html>" CRLF
|
||||
"<head><title>507 Insufficient Storage</title></head>" CRLF
|
||||
@@ -321,8 +352,9 @@ static ngx_str_t ngx_http_error_pages[] = {
|
||||
ngx_null_string, /* 305 */
|
||||
ngx_null_string, /* 306 */
|
||||
ngx_string(ngx_http_error_307_page),
|
||||
ngx_string(ngx_http_error_308_page),
|
||||
|
||||
#define NGX_HTTP_LAST_3XX 308
|
||||
#define NGX_HTTP_LAST_3XX 309
|
||||
#define NGX_HTTP_OFF_4XX (NGX_HTTP_LAST_3XX - 301 + NGX_HTTP_OFF_3XX)
|
||||
|
||||
ngx_string(ngx_http_error_400_page),
|
||||
@@ -347,8 +379,16 @@ static ngx_str_t ngx_http_error_pages[] = {
|
||||
ngx_null_string, /* 419 */
|
||||
ngx_null_string, /* 420 */
|
||||
ngx_string(ngx_http_error_421_page),
|
||||
ngx_null_string, /* 422 */
|
||||
ngx_null_string, /* 423 */
|
||||
ngx_null_string, /* 424 */
|
||||
ngx_null_string, /* 425 */
|
||||
ngx_null_string, /* 426 */
|
||||
ngx_null_string, /* 427 */
|
||||
ngx_null_string, /* 428 */
|
||||
ngx_string(ngx_http_error_429_page),
|
||||
|
||||
#define NGX_HTTP_LAST_4XX 422
|
||||
#define NGX_HTTP_LAST_4XX 430
|
||||
#define NGX_HTTP_OFF_5XX (NGX_HTTP_LAST_4XX - 400 + NGX_HTTP_OFF_4XX)
|
||||
|
||||
ngx_string(ngx_http_error_494_page), /* 494, request header too large */
|
||||
@@ -363,7 +403,7 @@ static ngx_str_t ngx_http_error_pages[] = {
|
||||
ngx_string(ngx_http_error_502_page),
|
||||
ngx_string(ngx_http_error_503_page),
|
||||
ngx_string(ngx_http_error_504_page),
|
||||
ngx_null_string, /* 505 */
|
||||
ngx_string(ngx_http_error_505_page),
|
||||
ngx_null_string, /* 506 */
|
||||
ngx_string(ngx_http_error_507_page)
|
||||
|
||||
@@ -592,7 +632,8 @@ ngx_http_send_error_page(ngx_http_request_t *r, ngx_http_err_page_t *err_page)
|
||||
if (overwrite != NGX_HTTP_MOVED_PERMANENTLY
|
||||
&& overwrite != NGX_HTTP_MOVED_TEMPORARILY
|
||||
&& overwrite != NGX_HTTP_SEE_OTHER
|
||||
&& overwrite != NGX_HTTP_TEMPORARY_REDIRECT)
|
||||
&& overwrite != NGX_HTTP_TEMPORARY_REDIRECT
|
||||
&& overwrite != NGX_HTTP_PERMANENT_REDIRECT)
|
||||
{
|
||||
r->err_status = NGX_HTTP_MOVED_TEMPORARILY;
|
||||
}
|
||||
@@ -628,10 +669,14 @@ ngx_http_send_special_response(ngx_http_request_t *r,
|
||||
ngx_uint_t msie_padding;
|
||||
ngx_chain_t out[3];
|
||||
|
||||
if (clcf->server_tokens) {
|
||||
if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_ON) {
|
||||
len = sizeof(ngx_http_error_full_tail) - 1;
|
||||
tail = ngx_http_error_full_tail;
|
||||
|
||||
} else if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_BUILD) {
|
||||
len = sizeof(ngx_http_error_build_tail) - 1;
|
||||
tail = ngx_http_error_build_tail;
|
||||
|
||||
} else {
|
||||
len = sizeof(ngx_http_error_tail) - 1;
|
||||
tail = ngx_http_error_tail;
|
||||
|
||||
@@ -17,6 +17,8 @@ static ngx_int_t ngx_http_upstream_cache_get(ngx_http_request_t *r,
|
||||
ngx_http_upstream_t *u, ngx_http_file_cache_t **cache);
|
||||
static ngx_int_t ngx_http_upstream_cache_send(ngx_http_request_t *r,
|
||||
ngx_http_upstream_t *u);
|
||||
static ngx_int_t ngx_http_upstream_cache_background_update(
|
||||
ngx_http_request_t *r, ngx_http_upstream_t *u);
|
||||
static ngx_int_t ngx_http_upstream_cache_check_range(ngx_http_request_t *r,
|
||||
ngx_http_upstream_t *u);
|
||||
static ngx_int_t ngx_http_upstream_cache_status(ngx_http_request_t *r,
|
||||
@@ -162,6 +164,10 @@ static ngx_int_t ngx_http_upstream_response_time_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_upstream_response_length_variable(
|
||||
ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_upstream_header_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
static ngx_int_t ngx_http_upstream_cookie_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
|
||||
static char *ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy);
|
||||
static char *ngx_http_upstream_server(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
@@ -182,7 +188,7 @@ static ngx_int_t ngx_http_upstream_ssl_name(ngx_http_request_t *r,
|
||||
#endif
|
||||
|
||||
|
||||
ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = {
|
||||
static ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = {
|
||||
|
||||
{ ngx_string("Status"),
|
||||
ngx_http_upstream_process_header_line,
|
||||
@@ -413,6 +419,12 @@ static ngx_http_variable_t ngx_http_upstream_vars[] = {
|
||||
|
||||
#endif
|
||||
|
||||
{ ngx_string("upstream_http_"), NULL, ngx_http_upstream_header_variable,
|
||||
0, NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_PREFIX, 0 },
|
||||
|
||||
{ ngx_string("upstream_cookie_"), NULL, ngx_http_upstream_cookie_variable,
|
||||
0, NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_PREFIX, 0 },
|
||||
|
||||
{ ngx_null_string, NULL, NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
@@ -424,6 +436,7 @@ static ngx_http_upstream_next_t ngx_http_upstream_next_errors[] = {
|
||||
{ 504, NGX_HTTP_UPSTREAM_FT_HTTP_504 },
|
||||
{ 403, NGX_HTTP_UPSTREAM_FT_HTTP_403 },
|
||||
{ 404, NGX_HTTP_UPSTREAM_FT_HTTP_404 },
|
||||
{ 429, NGX_HTTP_UPSTREAM_FT_HTTP_429 },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
@@ -568,6 +581,10 @@ ngx_http_upstream_init_request(ngx_http_request_t *r)
|
||||
rc = NGX_DECLINED;
|
||||
r->cached = 0;
|
||||
}
|
||||
|
||||
if (ngx_http_upstream_cache_background_update(r, u) != NGX_OK) {
|
||||
rc = NGX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (rc != NGX_DECLINED) {
|
||||
@@ -859,9 +876,24 @@ ngx_http_upstream_cache(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
||||
|
||||
switch (rc) {
|
||||
|
||||
case NGX_HTTP_CACHE_STALE:
|
||||
|
||||
if (((u->conf->cache_use_stale & NGX_HTTP_UPSTREAM_FT_UPDATING)
|
||||
|| c->stale_updating) && !r->background
|
||||
&& u->conf->cache_background_update)
|
||||
{
|
||||
r->cache->background = 1;
|
||||
u->cache_status = rc;
|
||||
rc = NGX_OK;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case NGX_HTTP_CACHE_UPDATING:
|
||||
|
||||
if (u->conf->cache_use_stale & NGX_HTTP_UPSTREAM_FT_UPDATING) {
|
||||
if (((u->conf->cache_use_stale & NGX_HTTP_UPSTREAM_FT_UPDATING)
|
||||
|| c->stale_updating) && !r->background)
|
||||
{
|
||||
u->cache_status = rc;
|
||||
rc = NGX_OK;
|
||||
|
||||
@@ -884,6 +916,9 @@ ngx_http_upstream_cache(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
||||
case NGX_HTTP_CACHE_STALE:
|
||||
|
||||
c->valid_sec = 0;
|
||||
c->updating_sec = 0;
|
||||
c->error_sec = 0;
|
||||
|
||||
u->buffer.start = NULL;
|
||||
u->cache_status = NGX_HTTP_CACHE_EXPIRED;
|
||||
|
||||
@@ -1030,6 +1065,30 @@ ngx_http_upstream_cache_send(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_cache_background_update(ngx_http_request_t *r,
|
||||
ngx_http_upstream_t *u)
|
||||
{
|
||||
ngx_http_request_t *sr;
|
||||
|
||||
if (!r->cached || !r->cache->background) {
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (ngx_http_subrequest(r, &r->uri, &r->args, &sr, NULL,
|
||||
NGX_HTTP_SUBREQUEST_CLONE
|
||||
|NGX_HTTP_SUBREQUEST_BACKGROUND)
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
sr->header_only = 1;
|
||||
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_cache_check_range(ngx_http_request_t *r,
|
||||
ngx_http_upstream_t *u)
|
||||
@@ -1174,6 +1233,11 @@ ngx_http_upstream_handler(ngx_event_t *ev)
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
|
||||
"http upstream request: \"%V?%V\"", &r->uri, &r->args);
|
||||
|
||||
if (ev->delayed && ev->timedout) {
|
||||
ev->delayed = 0;
|
||||
ev->timedout = 0;
|
||||
}
|
||||
|
||||
if (ev->write) {
|
||||
u->write_event_handler(r, u);
|
||||
|
||||
@@ -1542,7 +1606,6 @@ static void
|
||||
ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r,
|
||||
ngx_http_upstream_t *u, ngx_connection_t *c)
|
||||
{
|
||||
int tcp_nodelay;
|
||||
ngx_int_t rc;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
|
||||
@@ -1582,22 +1645,10 @@ ngx_http_upstream_ssl_init_connection(ngx_http_request_t *r,
|
||||
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
|
||||
if (clcf->tcp_nodelay && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");
|
||||
|
||||
tcp_nodelay = 1;
|
||||
|
||||
if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
|
||||
(const void *) &tcp_nodelay, sizeof(int)) == -1)
|
||||
{
|
||||
ngx_connection_error(c, ngx_socket_errno,
|
||||
"setsockopt(TCP_NODELAY) failed");
|
||||
ngx_http_upstream_finalize_request(r, u,
|
||||
if (clcf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) {
|
||||
ngx_http_upstream_finalize_request(r, u,
|
||||
NGX_HTTP_INTERNAL_SERVER_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
c->tcp_nodelay = NGX_TCP_NODELAY_SET;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1950,7 +2001,6 @@ static ngx_int_t
|
||||
ngx_http_upstream_send_request_body(ngx_http_request_t *r,
|
||||
ngx_http_upstream_t *u, ngx_uint_t do_write)
|
||||
{
|
||||
int tcp_nodelay;
|
||||
ngx_int_t rc;
|
||||
ngx_chain_t *out, *cl, *ln;
|
||||
ngx_connection_t *c;
|
||||
@@ -1987,20 +2037,8 @@ ngx_http_upstream_send_request_body(ngx_http_request_t *r,
|
||||
c = u->peer.connection;
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
|
||||
if (clcf->tcp_nodelay && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");
|
||||
|
||||
tcp_nodelay = 1;
|
||||
|
||||
if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
|
||||
(const void *) &tcp_nodelay, sizeof(int)) == -1)
|
||||
{
|
||||
ngx_connection_error(c, ngx_socket_errno,
|
||||
"setsockopt(TCP_NODELAY) failed");
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
c->tcp_nodelay = NGX_TCP_NODELAY_SET;
|
||||
if (clcf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
r->read_event_handler = ngx_http_upstream_read_request_handler;
|
||||
@@ -2330,7 +2368,7 @@ ngx_http_upstream_test_next(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
||||
#if (NGX_HTTP_CACHE)
|
||||
|
||||
if (u->cache_status == NGX_HTTP_CACHE_EXPIRED
|
||||
&& (u->conf->cache_use_stale & un->mask))
|
||||
&& ((u->conf->cache_use_stale & un->mask) || r->cache->stale_error))
|
||||
{
|
||||
ngx_int_t rc;
|
||||
|
||||
@@ -2354,14 +2392,17 @@ ngx_http_upstream_test_next(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
||||
&& u->cache_status == NGX_HTTP_CACHE_EXPIRED
|
||||
&& u->conf->cache_revalidate)
|
||||
{
|
||||
time_t now, valid;
|
||||
time_t now, valid, updating, error;
|
||||
ngx_int_t rc;
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http upstream not modified");
|
||||
|
||||
now = ngx_time();
|
||||
|
||||
valid = r->cache->valid_sec;
|
||||
updating = r->cache->updating_sec;
|
||||
error = r->cache->error_sec;
|
||||
|
||||
rc = u->reinit_request(r);
|
||||
|
||||
@@ -2375,6 +2416,8 @@ ngx_http_upstream_test_next(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
||||
|
||||
if (valid == 0) {
|
||||
valid = r->cache->valid_sec;
|
||||
updating = r->cache->updating_sec;
|
||||
error = r->cache->error_sec;
|
||||
}
|
||||
|
||||
if (valid == 0) {
|
||||
@@ -2387,6 +2430,9 @@ ngx_http_upstream_test_next(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
||||
|
||||
if (valid) {
|
||||
r->cache->valid_sec = valid;
|
||||
r->cache->updating_sec = updating;
|
||||
r->cache->error_sec = error;
|
||||
|
||||
r->cache->date = now;
|
||||
|
||||
ngx_http_file_cache_update_header(r);
|
||||
@@ -2750,7 +2796,6 @@ ngx_http_upstream_process_body_in_memory(ngx_http_request_t *r,
|
||||
static void
|
||||
ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
||||
{
|
||||
int tcp_nodelay;
|
||||
ssize_t n;
|
||||
ngx_int_t rc;
|
||||
ngx_event_pipe_t *p;
|
||||
@@ -2831,21 +2876,9 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
||||
return;
|
||||
}
|
||||
|
||||
if (clcf->tcp_nodelay && c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");
|
||||
|
||||
tcp_nodelay = 1;
|
||||
|
||||
if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
|
||||
(const void *) &tcp_nodelay, sizeof(int)) == -1)
|
||||
{
|
||||
ngx_connection_error(c, ngx_socket_errno,
|
||||
"setsockopt(TCP_NODELAY) failed");
|
||||
ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
c->tcp_nodelay = NGX_TCP_NODELAY_SET;
|
||||
if (clcf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) {
|
||||
ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
n = u->buffer.last - u->buffer.pos;
|
||||
@@ -3104,7 +3137,6 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
||||
static void
|
||||
ngx_http_upstream_upgrade(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
||||
{
|
||||
int tcp_nodelay;
|
||||
ngx_connection_t *c;
|
||||
ngx_http_core_loc_conf_t *clcf;
|
||||
|
||||
@@ -3122,37 +3154,15 @@ ngx_http_upstream_upgrade(ngx_http_request_t *r, ngx_http_upstream_t *u)
|
||||
r->write_event_handler = ngx_http_upstream_upgraded_write_downstream;
|
||||
|
||||
if (clcf->tcp_nodelay) {
|
||||
tcp_nodelay = 1;
|
||||
|
||||
if (c->tcp_nodelay == NGX_TCP_NODELAY_UNSET) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");
|
||||
|
||||
if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
|
||||
(const void *) &tcp_nodelay, sizeof(int)) == -1)
|
||||
{
|
||||
ngx_connection_error(c, ngx_socket_errno,
|
||||
"setsockopt(TCP_NODELAY) failed");
|
||||
ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
c->tcp_nodelay = NGX_TCP_NODELAY_SET;
|
||||
if (ngx_tcp_nodelay(c) != NGX_OK) {
|
||||
ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (u->peer.connection->tcp_nodelay == NGX_TCP_NODELAY_UNSET) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, u->peer.connection->log, 0,
|
||||
"tcp_nodelay");
|
||||
|
||||
if (setsockopt(u->peer.connection->fd, IPPROTO_TCP, TCP_NODELAY,
|
||||
(const void *) &tcp_nodelay, sizeof(int)) == -1)
|
||||
{
|
||||
ngx_connection_error(u->peer.connection, ngx_socket_errno,
|
||||
"setsockopt(TCP_NODELAY) failed");
|
||||
ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
u->peer.connection->tcp_nodelay = NGX_TCP_NODELAY_SET;
|
||||
if (ngx_tcp_nodelay(u->peer.connection) != NGX_OK) {
|
||||
ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3670,9 +3680,19 @@ ngx_http_upstream_thread_event_handler(ngx_event_t *ev)
|
||||
r->main->blocked--;
|
||||
r->aio = 0;
|
||||
|
||||
r->write_event_handler(r);
|
||||
if (r->done) {
|
||||
/*
|
||||
* trigger connection event handler if the subrequest was
|
||||
* already finalized; this can happen if the handler is used
|
||||
* for sendfile() in threads
|
||||
*/
|
||||
|
||||
ngx_http_run_posted_requests(c);
|
||||
c->write->handler(c->write);
|
||||
|
||||
} else {
|
||||
r->write_event_handler(r);
|
||||
ngx_http_run_posted_requests(c);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -3720,31 +3740,9 @@ ngx_http_upstream_process_downstream(ngx_http_request_t *r)
|
||||
|
||||
if (wev->timedout) {
|
||||
|
||||
if (wev->delayed) {
|
||||
|
||||
wev->timedout = 0;
|
||||
wev->delayed = 0;
|
||||
|
||||
if (!wev->ready) {
|
||||
ngx_add_timer(wev, p->send_timeout);
|
||||
|
||||
if (ngx_handle_write_event(wev, p->send_lowat) != NGX_OK) {
|
||||
ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (ngx_event_pipe(p, wev->write) == NGX_ABORT) {
|
||||
ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
p->downstream_error = 1;
|
||||
c->timedout = 1;
|
||||
ngx_connection_error(c, NGX_ETIMEDOUT, "client timed out");
|
||||
}
|
||||
p->downstream_error = 1;
|
||||
c->timedout = 1;
|
||||
ngx_connection_error(c, NGX_ETIMEDOUT, "client timed out");
|
||||
|
||||
} else {
|
||||
|
||||
@@ -3789,30 +3787,8 @@ ngx_http_upstream_process_upstream(ngx_http_request_t *r,
|
||||
|
||||
if (rev->timedout) {
|
||||
|
||||
if (rev->delayed) {
|
||||
|
||||
rev->timedout = 0;
|
||||
rev->delayed = 0;
|
||||
|
||||
if (!rev->ready) {
|
||||
ngx_add_timer(rev, p->read_timeout);
|
||||
|
||||
if (ngx_handle_read_event(rev, 0) != NGX_OK) {
|
||||
ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (ngx_event_pipe(p, 0) == NGX_ABORT) {
|
||||
ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
} else {
|
||||
p->upstream_error = 1;
|
||||
ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
|
||||
}
|
||||
p->upstream_error = 1;
|
||||
ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
|
||||
|
||||
} else {
|
||||
|
||||
@@ -4089,6 +4065,10 @@ ngx_http_upstream_next(ngx_http_request_t *r, ngx_http_upstream_t *u,
|
||||
status = NGX_HTTP_NOT_FOUND;
|
||||
break;
|
||||
|
||||
case NGX_HTTP_UPSTREAM_FT_HTTP_429:
|
||||
status = NGX_HTTP_TOO_MANY_REQUESTS;
|
||||
break;
|
||||
|
||||
/*
|
||||
* NGX_HTTP_UPSTREAM_FT_BUSY_LOCK and NGX_HTTP_UPSTREAM_FT_MAX_WAITING
|
||||
* never reach here
|
||||
@@ -4122,7 +4102,7 @@ ngx_http_upstream_next(ngx_http_request_t *r, ngx_http_upstream_t *u,
|
||||
#if (NGX_HTTP_CACHE)
|
||||
|
||||
if (u->cache_status == NGX_HTTP_CACHE_EXPIRED
|
||||
&& (u->conf->cache_use_stale & ft_type))
|
||||
&& ((u->conf->cache_use_stale & ft_type) || r->cache->stale_error))
|
||||
{
|
||||
ngx_int_t rc;
|
||||
|
||||
@@ -4300,6 +4280,8 @@ ngx_http_upstream_finalize_request(ngx_http_request_t *r,
|
||||
u->buffer.last = u->buffer.pos;
|
||||
}
|
||||
|
||||
r->read_event_handler = ngx_http_block_reading;
|
||||
|
||||
if (rc == NGX_DECLINED) {
|
||||
return;
|
||||
}
|
||||
@@ -4497,32 +4479,76 @@ ngx_http_upstream_process_cache_control(ngx_http_request_t *r,
|
||||
offset = 8;
|
||||
}
|
||||
|
||||
if (p == NULL) {
|
||||
return NGX_OK;
|
||||
}
|
||||
if (p) {
|
||||
n = 0;
|
||||
|
||||
n = 0;
|
||||
for (p += offset; p < last; p++) {
|
||||
if (*p == ',' || *p == ';' || *p == ' ') {
|
||||
break;
|
||||
}
|
||||
|
||||
for (p += offset; p < last; p++) {
|
||||
if (*p == ',' || *p == ';' || *p == ' ') {
|
||||
break;
|
||||
if (*p >= '0' && *p <= '9') {
|
||||
n = n * 10 + *p - '0';
|
||||
continue;
|
||||
}
|
||||
|
||||
u->cacheable = 0;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
if (*p >= '0' && *p <= '9') {
|
||||
n = n * 10 + *p - '0';
|
||||
continue;
|
||||
if (n == 0) {
|
||||
u->cacheable = 0;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
u->cacheable = 0;
|
||||
return NGX_OK;
|
||||
r->cache->valid_sec = ngx_time() + n;
|
||||
}
|
||||
|
||||
if (n == 0) {
|
||||
u->cacheable = 0;
|
||||
return NGX_OK;
|
||||
p = ngx_strlcasestrn(start, last, (u_char *) "stale-while-revalidate=",
|
||||
23 - 1);
|
||||
|
||||
if (p) {
|
||||
n = 0;
|
||||
|
||||
for (p += 23; p < last; p++) {
|
||||
if (*p == ',' || *p == ';' || *p == ' ') {
|
||||
break;
|
||||
}
|
||||
|
||||
if (*p >= '0' && *p <= '9') {
|
||||
n = n * 10 + *p - '0';
|
||||
continue;
|
||||
}
|
||||
|
||||
u->cacheable = 0;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
r->cache->updating_sec = n;
|
||||
r->cache->error_sec = n;
|
||||
}
|
||||
|
||||
r->cache->valid_sec = ngx_time() + n;
|
||||
p = ngx_strlcasestrn(start, last, (u_char *) "stale-if-error=", 15 - 1);
|
||||
|
||||
if (p) {
|
||||
n = 0;
|
||||
|
||||
for (p += 15; p < last; p++) {
|
||||
if (*p == ',' || *p == ';' || *p == ' ') {
|
||||
break;
|
||||
}
|
||||
|
||||
if (*p >= '0' && *p <= '9') {
|
||||
n = n * 10 + *p - '0';
|
||||
continue;
|
||||
}
|
||||
|
||||
u->cacheable = 0;
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
r->cache->error_sec = n;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -4809,17 +4835,18 @@ ngx_http_upstream_copy_multi_header_lines(ngx_http_request_t *r,
|
||||
}
|
||||
}
|
||||
|
||||
ph = ngx_array_push(pa);
|
||||
if (ph == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
ho = ngx_list_push(&r->headers_out.headers);
|
||||
if (ho == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*ho = *h;
|
||||
|
||||
ph = ngx_array_push(pa);
|
||||
if (ph == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*ph = ho;
|
||||
|
||||
return NGX_OK;
|
||||
@@ -5391,7 +5418,7 @@ ngx_http_upstream_response_length_variable(ngx_http_request_t *r,
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_header_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
@@ -5406,7 +5433,7 @@ ngx_http_upstream_header_variable(ngx_http_request_t *r,
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_cookie_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
@@ -5442,7 +5469,7 @@ ngx_http_upstream_cookie_variable(ngx_http_request_t *r,
|
||||
|
||||
#if (NGX_HTTP_CACHE)
|
||||
|
||||
ngx_int_t
|
||||
static ngx_int_t
|
||||
ngx_http_upstream_cache_status(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data)
|
||||
{
|
||||
|
||||
@@ -26,10 +26,11 @@
|
||||
#define NGX_HTTP_UPSTREAM_FT_HTTP_504 0x00000080
|
||||
#define NGX_HTTP_UPSTREAM_FT_HTTP_403 0x00000100
|
||||
#define NGX_HTTP_UPSTREAM_FT_HTTP_404 0x00000200
|
||||
#define NGX_HTTP_UPSTREAM_FT_UPDATING 0x00000400
|
||||
#define NGX_HTTP_UPSTREAM_FT_BUSY_LOCK 0x00000800
|
||||
#define NGX_HTTP_UPSTREAM_FT_MAX_WAITING 0x00001000
|
||||
#define NGX_HTTP_UPSTREAM_FT_NON_IDEMPOTENT 0x00002000
|
||||
#define NGX_HTTP_UPSTREAM_FT_HTTP_429 0x00000400
|
||||
#define NGX_HTTP_UPSTREAM_FT_UPDATING 0x00000800
|
||||
#define NGX_HTTP_UPSTREAM_FT_BUSY_LOCK 0x00001000
|
||||
#define NGX_HTTP_UPSTREAM_FT_MAX_WAITING 0x00002000
|
||||
#define NGX_HTTP_UPSTREAM_FT_NON_IDEMPOTENT 0x00004000
|
||||
#define NGX_HTTP_UPSTREAM_FT_NOLIVE 0x40000000
|
||||
#define NGX_HTTP_UPSTREAM_FT_OFF 0x80000000
|
||||
|
||||
@@ -38,7 +39,8 @@
|
||||
|NGX_HTTP_UPSTREAM_FT_HTTP_503 \
|
||||
|NGX_HTTP_UPSTREAM_FT_HTTP_504 \
|
||||
|NGX_HTTP_UPSTREAM_FT_HTTP_403 \
|
||||
|NGX_HTTP_UPSTREAM_FT_HTTP_404)
|
||||
|NGX_HTTP_UPSTREAM_FT_HTTP_404 \
|
||||
|NGX_HTTP_UPSTREAM_FT_HTTP_429)
|
||||
|
||||
#define NGX_HTTP_UPSTREAM_INVALID_HEADER 40
|
||||
|
||||
@@ -55,9 +57,6 @@
|
||||
|
||||
|
||||
typedef struct {
|
||||
ngx_msec_t bl_time;
|
||||
ngx_uint_t bl_state;
|
||||
|
||||
ngx_uint_t status;
|
||||
ngx_msec_t response_time;
|
||||
ngx_msec_t connect_time;
|
||||
@@ -151,7 +150,6 @@ typedef struct {
|
||||
ngx_msec_t connect_timeout;
|
||||
ngx_msec_t send_timeout;
|
||||
ngx_msec_t read_timeout;
|
||||
ngx_msec_t timeout;
|
||||
ngx_msec_t next_upstream_timeout;
|
||||
|
||||
size_t send_lowat;
|
||||
@@ -206,6 +204,7 @@ typedef struct {
|
||||
|
||||
ngx_flag_t cache_revalidate;
|
||||
ngx_flag_t cache_convert_head;
|
||||
ngx_flag_t cache_background_update;
|
||||
|
||||
ngx_array_t *cache_valid;
|
||||
ngx_array_t *cache_bypass;
|
||||
@@ -390,9 +389,6 @@ struct ngx_http_upstream_s {
|
||||
unsigned request_sent:1;
|
||||
unsigned request_body_sent:1;
|
||||
unsigned header_sent:1;
|
||||
|
||||
NGX_COMPAT_BEGIN(1)
|
||||
NGX_COMPAT_END
|
||||
};
|
||||
|
||||
|
||||
@@ -409,11 +405,6 @@ typedef struct {
|
||||
} ngx_http_upstream_param_t;
|
||||
|
||||
|
||||
ngx_int_t ngx_http_upstream_cookie_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
ngx_int_t ngx_http_upstream_header_variable(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
|
||||
ngx_int_t ngx_http_upstream_create(ngx_http_request_t *r);
|
||||
void ngx_http_upstream_init(ngx_http_request_t *r);
|
||||
ngx_http_upstream_srv_conf_t *ngx_http_upstream_add(ngx_conf_t *cf,
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
#include <nginx.h>
|
||||
|
||||
|
||||
static ngx_http_variable_t *ngx_http_add_prefix_variable(ngx_conf_t *cf,
|
||||
ngx_str_t *name, ngx_uint_t flags);
|
||||
|
||||
static ngx_int_t ngx_http_variable_request(ngx_http_request_t *r,
|
||||
ngx_http_variable_value_t *v, uintptr_t data);
|
||||
#if 0
|
||||
@@ -356,6 +359,18 @@ static ngx_http_variable_t ngx_http_core_variables[] = {
|
||||
3, NGX_HTTP_VAR_NOCACHEABLE, 0 },
|
||||
#endif
|
||||
|
||||
{ ngx_string("http_"), NULL, ngx_http_variable_unknown_header_in,
|
||||
0, NGX_HTTP_VAR_PREFIX, 0 },
|
||||
|
||||
{ ngx_string("sent_http_"), NULL, ngx_http_variable_unknown_header_out,
|
||||
0, NGX_HTTP_VAR_PREFIX, 0 },
|
||||
|
||||
{ ngx_string("cookie_"), NULL, ngx_http_variable_cookie,
|
||||
0, NGX_HTTP_VAR_PREFIX, 0 },
|
||||
|
||||
{ ngx_string("arg_"), NULL, ngx_http_variable_argument,
|
||||
0, NGX_HTTP_VAR_NOCACHEABLE|NGX_HTTP_VAR_PREFIX, 0 },
|
||||
|
||||
{ ngx_null_string, NULL, NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
@@ -384,6 +399,10 @@ ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (flags & NGX_HTTP_VAR_PREFIX) {
|
||||
return ngx_http_add_prefix_variable(cf, name, flags);
|
||||
}
|
||||
|
||||
cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
|
||||
|
||||
key = cmcf->variables_keys->keys.elts;
|
||||
@@ -402,6 +421,8 @@ ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
v->flags &= flags | ~NGX_HTTP_VAR_WEAK;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -440,6 +461,59 @@ ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags)
|
||||
}
|
||||
|
||||
|
||||
static ngx_http_variable_t *
|
||||
ngx_http_add_prefix_variable(ngx_conf_t *cf, ngx_str_t *name, ngx_uint_t flags)
|
||||
{
|
||||
ngx_uint_t i;
|
||||
ngx_http_variable_t *v;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
|
||||
cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
|
||||
|
||||
v = cmcf->prefix_variables.elts;
|
||||
for (i = 0; i < cmcf->prefix_variables.nelts; i++) {
|
||||
if (name->len != v[i].name.len
|
||||
|| ngx_strncasecmp(name->data, v[i].name.data, name->len) != 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
v = &v[i];
|
||||
|
||||
if (!(v->flags & NGX_HTTP_VAR_CHANGEABLE)) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"the duplicate \"%V\" variable", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
v->flags &= flags | ~NGX_HTTP_VAR_WEAK;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
v = ngx_array_push(&cmcf->prefix_variables);
|
||||
if (v == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
v->name.len = name->len;
|
||||
v->name.data = ngx_pnalloc(cf->pool, name->len);
|
||||
if (v->name.data == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ngx_strlow(v->name.data, name->data, name->len);
|
||||
|
||||
v->set_handler = NULL;
|
||||
v->get_handler = NULL;
|
||||
v->data = 0;
|
||||
v->flags = flags;
|
||||
v->index = 0;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_get_variable_index(ngx_conf_t *cf, ngx_str_t *name)
|
||||
{
|
||||
@@ -573,6 +647,8 @@ ngx_http_get_flushed_variable(ngx_http_request_t *r, ngx_uint_t index)
|
||||
ngx_http_variable_value_t *
|
||||
ngx_http_get_variable(ngx_http_request_t *r, ngx_str_t *name, ngx_uint_t key)
|
||||
{
|
||||
size_t len;
|
||||
ngx_uint_t i, n;
|
||||
ngx_http_variable_t *v;
|
||||
ngx_http_variable_value_t *vv;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
@@ -610,64 +686,22 @@ ngx_http_get_variable(ngx_http_request_t *r, ngx_str_t *name, ngx_uint_t key)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (name->len >= 5 && ngx_strncmp(name->data, "http_", 5) == 0) {
|
||||
len = 0;
|
||||
|
||||
if (ngx_http_variable_unknown_header_in(r, vv, (uintptr_t) name)
|
||||
== NGX_OK)
|
||||
v = cmcf->prefix_variables.elts;
|
||||
n = cmcf->prefix_variables.nelts;
|
||||
|
||||
for (i = 0; i < cmcf->prefix_variables.nelts; i++) {
|
||||
if (name->len >= v[i].name.len && name->len > len
|
||||
&& ngx_strncmp(name->data, v[i].name.data, v[i].name.len) == 0)
|
||||
{
|
||||
return vv;
|
||||
len = v[i].name.len;
|
||||
n = i;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (name->len >= 10 && ngx_strncmp(name->data, "sent_http_", 10) == 0) {
|
||||
|
||||
if (ngx_http_variable_unknown_header_out(r, vv, (uintptr_t) name)
|
||||
== NGX_OK)
|
||||
{
|
||||
return vv;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (name->len >= 14 && ngx_strncmp(name->data, "upstream_http_", 14) == 0) {
|
||||
|
||||
if (ngx_http_upstream_header_variable(r, vv, (uintptr_t) name)
|
||||
== NGX_OK)
|
||||
{
|
||||
return vv;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (name->len >= 7 && ngx_strncmp(name->data, "cookie_", 7) == 0) {
|
||||
|
||||
if (ngx_http_variable_cookie(r, vv, (uintptr_t) name) == NGX_OK) {
|
||||
return vv;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (name->len >= 16
|
||||
&& ngx_strncmp(name->data, "upstream_cookie_", 16) == 0)
|
||||
{
|
||||
|
||||
if (ngx_http_upstream_cookie_variable(r, vv, (uintptr_t) name)
|
||||
== NGX_OK)
|
||||
{
|
||||
return vv;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (name->len >= 4 && ngx_strncmp(name->data, "arg_", 4) == 0) {
|
||||
|
||||
if (ngx_http_variable_argument(r, vv, (uintptr_t) name) == NGX_OK) {
|
||||
if (n != cmcf->prefix_variables.nelts) {
|
||||
if (v[n].get_handler(r, vv, (uintptr_t) name) == NGX_OK) {
|
||||
return vv;
|
||||
}
|
||||
|
||||
@@ -2502,7 +2536,6 @@ ngx_http_regex_exec(ngx_http_request_t *r, ngx_http_regex_t *re, ngx_str_t *s)
|
||||
ngx_int_t
|
||||
ngx_http_variables_add_core_vars(ngx_conf_t *cf)
|
||||
{
|
||||
ngx_int_t rc;
|
||||
ngx_http_variable_t *cv, *v;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
|
||||
@@ -2523,27 +2556,20 @@ ngx_http_variables_add_core_vars(ngx_conf_t *cf)
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (ngx_array_init(&cmcf->prefix_variables, cf->pool, 8,
|
||||
sizeof(ngx_http_variable_t))
|
||||
!= NGX_OK)
|
||||
{
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
for (cv = ngx_http_core_variables; cv->name.len; cv++) {
|
||||
v = ngx_palloc(cf->pool, sizeof(ngx_http_variable_t));
|
||||
v = ngx_http_add_variable(cf, &cv->name, cv->flags);
|
||||
if (v == NULL) {
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*v = *cv;
|
||||
|
||||
rc = ngx_hash_add_key(cmcf->variables_keys, &v->name, v,
|
||||
NGX_HASH_READONLY_KEY);
|
||||
|
||||
if (rc == NGX_OK) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rc == NGX_BUSY) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"conflicting variable name \"%V\"", &v->name);
|
||||
}
|
||||
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
return NGX_OK;
|
||||
@@ -2553,10 +2579,11 @@ ngx_http_variables_add_core_vars(ngx_conf_t *cf)
|
||||
ngx_int_t
|
||||
ngx_http_variables_init_vars(ngx_conf_t *cf)
|
||||
{
|
||||
size_t len;
|
||||
ngx_uint_t i, n;
|
||||
ngx_hash_key_t *key;
|
||||
ngx_hash_init_t hash;
|
||||
ngx_http_variable_t *v, *av;
|
||||
ngx_http_variable_t *v, *av, *pv;
|
||||
ngx_http_core_main_conf_t *cmcf;
|
||||
|
||||
/* set the handlers for the indexed http variables */
|
||||
@@ -2564,6 +2591,7 @@ ngx_http_variables_init_vars(ngx_conf_t *cf)
|
||||
cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
|
||||
|
||||
v = cmcf->variables.elts;
|
||||
pv = cmcf->prefix_variables.elts;
|
||||
key = cmcf->variables_keys->keys.elts;
|
||||
|
||||
for (i = 0; i < cmcf->variables.nelts; i++) {
|
||||
@@ -2584,7 +2612,9 @@ ngx_http_variables_init_vars(ngx_conf_t *cf)
|
||||
|
||||
av->index = i;
|
||||
|
||||
if (av->get_handler == NULL) {
|
||||
if (av->get_handler == NULL
|
||||
|| (av->flags & NGX_HTTP_VAR_WEAK))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2592,68 +2622,34 @@ ngx_http_variables_init_vars(ngx_conf_t *cf)
|
||||
}
|
||||
}
|
||||
|
||||
if (v[i].name.len >= 5
|
||||
&& ngx_strncmp(v[i].name.data, "http_", 5) == 0)
|
||||
{
|
||||
v[i].get_handler = ngx_http_variable_unknown_header_in;
|
||||
v[i].data = (uintptr_t) &v[i].name;
|
||||
len = 0;
|
||||
av = NULL;
|
||||
|
||||
continue;
|
||||
for (n = 0; n < cmcf->prefix_variables.nelts; n++) {
|
||||
if (v[i].name.len >= pv[n].name.len && v[i].name.len > len
|
||||
&& ngx_strncmp(v[i].name.data, pv[n].name.data, pv[n].name.len)
|
||||
== 0)
|
||||
{
|
||||
av = &pv[n];
|
||||
len = pv[n].name.len;
|
||||
}
|
||||
}
|
||||
|
||||
if (v[i].name.len >= 10
|
||||
&& ngx_strncmp(v[i].name.data, "sent_http_", 10) == 0)
|
||||
{
|
||||
v[i].get_handler = ngx_http_variable_unknown_header_out;
|
||||
if (av) {
|
||||
v[i].get_handler = av->get_handler;
|
||||
v[i].data = (uintptr_t) &v[i].name;
|
||||
v[i].flags = av->flags;
|
||||
|
||||
continue;
|
||||
goto next;
|
||||
}
|
||||
|
||||
if (v[i].name.len >= 14
|
||||
&& ngx_strncmp(v[i].name.data, "upstream_http_", 14) == 0)
|
||||
{
|
||||
v[i].get_handler = ngx_http_upstream_header_variable;
|
||||
v[i].data = (uintptr_t) &v[i].name;
|
||||
v[i].flags = NGX_HTTP_VAR_NOCACHEABLE;
|
||||
if (v[i].get_handler == NULL) {
|
||||
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
||||
"unknown \"%V\" variable", &v[i].name);
|
||||
|
||||
continue;
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
if (v[i].name.len >= 7
|
||||
&& ngx_strncmp(v[i].name.data, "cookie_", 7) == 0)
|
||||
{
|
||||
v[i].get_handler = ngx_http_variable_cookie;
|
||||
v[i].data = (uintptr_t) &v[i].name;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (v[i].name.len >= 16
|
||||
&& ngx_strncmp(v[i].name.data, "upstream_cookie_", 16) == 0)
|
||||
{
|
||||
v[i].get_handler = ngx_http_upstream_cookie_variable;
|
||||
v[i].data = (uintptr_t) &v[i].name;
|
||||
v[i].flags = NGX_HTTP_VAR_NOCACHEABLE;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (v[i].name.len >= 4
|
||||
&& ngx_strncmp(v[i].name.data, "arg_", 4) == 0)
|
||||
{
|
||||
v[i].get_handler = ngx_http_variable_argument;
|
||||
v[i].data = (uintptr_t) &v[i].name;
|
||||
v[i].flags = NGX_HTTP_VAR_NOCACHEABLE;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
|
||||
"unknown \"%V\" variable", &v[i].name);
|
||||
|
||||
return NGX_ERROR;
|
||||
|
||||
next:
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@ typedef ngx_int_t (*ngx_http_get_variable_pt) (ngx_http_request_t *r,
|
||||
#define NGX_HTTP_VAR_NOCACHEABLE 2
|
||||
#define NGX_HTTP_VAR_INDEXED 4
|
||||
#define NGX_HTTP_VAR_NOHASH 8
|
||||
#define NGX_HTTP_VAR_WEAK 16
|
||||
#define NGX_HTTP_VAR_PREFIX 32
|
||||
|
||||
|
||||
struct ngx_http_variable_s {
|
||||
|
||||
@@ -529,29 +529,8 @@ ngx_http_v2_send_output_queue(ngx_http_v2_connection_t *h2c)
|
||||
tcp_nodelay = 1;
|
||||
}
|
||||
|
||||
if (tcp_nodelay
|
||||
&& clcf->tcp_nodelay
|
||||
&& c->tcp_nodelay == NGX_TCP_NODELAY_UNSET)
|
||||
{
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");
|
||||
|
||||
if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
|
||||
(const void *) &tcp_nodelay, sizeof(int))
|
||||
== -1)
|
||||
{
|
||||
#if (NGX_SOLARIS)
|
||||
/* Solaris returns EINVAL if a socket has been shut down */
|
||||
c->log_error = NGX_ERROR_IGNORE_EINVAL;
|
||||
#endif
|
||||
|
||||
ngx_connection_error(c, ngx_socket_errno,
|
||||
"setsockopt(TCP_NODELAY) failed");
|
||||
|
||||
c->log_error = NGX_ERROR_INFO;
|
||||
goto error;
|
||||
}
|
||||
|
||||
c->tcp_nodelay = NGX_TCP_NODELAY_SET;
|
||||
if (tcp_nodelay && clcf->tcp_nodelay && ngx_tcp_nodelay(c) != NGX_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
for ( /* void */ ; out; out = fn) {
|
||||
@@ -783,9 +762,12 @@ ngx_http_v2_state_head(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end)
|
||||
static u_char *
|
||||
ngx_http_v2_state_data(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end)
|
||||
{
|
||||
size_t size;
|
||||
ngx_http_v2_node_t *node;
|
||||
ngx_http_v2_stream_t *stream;
|
||||
|
||||
size = h2c->state.length;
|
||||
|
||||
if (h2c->state.flags & NGX_HTTP_V2_PADDED_FLAG) {
|
||||
|
||||
if (h2c->state.length == 0) {
|
||||
@@ -802,33 +784,33 @@ ngx_http_v2_state_data(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end)
|
||||
}
|
||||
|
||||
h2c->state.padding = *pos++;
|
||||
h2c->state.length--;
|
||||
|
||||
if (h2c->state.padding > h2c->state.length) {
|
||||
if (h2c->state.padding >= size) {
|
||||
ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
|
||||
"client sent padded DATA frame "
|
||||
"with incorrect length: %uz, padding: %uz",
|
||||
h2c->state.length, h2c->state.padding);
|
||||
size, h2c->state.padding);
|
||||
|
||||
return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
|
||||
return ngx_http_v2_connection_error(h2c,
|
||||
NGX_HTTP_V2_PROTOCOL_ERROR);
|
||||
}
|
||||
|
||||
h2c->state.length -= h2c->state.padding;
|
||||
h2c->state.length -= 1 + h2c->state.padding;
|
||||
}
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
|
||||
"http2 DATA frame");
|
||||
|
||||
if (h2c->state.length > h2c->recv_window) {
|
||||
if (size > h2c->recv_window) {
|
||||
ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
|
||||
"client violated connection flow control: "
|
||||
"received DATA frame length %uz, available window %uz",
|
||||
h2c->state.length, h2c->recv_window);
|
||||
size, h2c->recv_window);
|
||||
|
||||
return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_FLOW_CTRL_ERROR);
|
||||
}
|
||||
|
||||
h2c->recv_window -= h2c->state.length;
|
||||
h2c->recv_window -= size;
|
||||
|
||||
if (h2c->recv_window < NGX_HTTP_V2_MAX_WINDOW / 4) {
|
||||
|
||||
@@ -854,11 +836,11 @@ ngx_http_v2_state_data(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end)
|
||||
|
||||
stream = node->stream;
|
||||
|
||||
if (h2c->state.length > stream->recv_window) {
|
||||
if (size > stream->recv_window) {
|
||||
ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
|
||||
"client violated flow control for stream %ui: "
|
||||
"received DATA frame length %uz, available window %uz",
|
||||
node->id, h2c->state.length, stream->recv_window);
|
||||
node->id, size, stream->recv_window);
|
||||
|
||||
if (ngx_http_v2_terminate_stream(h2c, stream,
|
||||
NGX_HTTP_V2_FLOW_CTRL_ERROR)
|
||||
@@ -871,7 +853,7 @@ ngx_http_v2_state_data(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end)
|
||||
return ngx_http_v2_state_skip_padded(h2c, pos, end);
|
||||
}
|
||||
|
||||
stream->recv_window -= h2c->state.length;
|
||||
stream->recv_window -= size;
|
||||
|
||||
if (stream->no_flow_control
|
||||
&& stream->recv_window < NGX_HTTP_V2_MAX_WINDOW / 4)
|
||||
@@ -938,7 +920,7 @@ ngx_http_v2_state_read_data(ngx_http_v2_connection_t *h2c, u_char *pos,
|
||||
|
||||
if (size >= h2c->state.length) {
|
||||
size = h2c->state.length;
|
||||
stream->in_closed = h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG;
|
||||
stream->in_closed = h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG;
|
||||
}
|
||||
|
||||
r = stream->request;
|
||||
@@ -1053,7 +1035,8 @@ ngx_http_v2_state_headers(ngx_http_v2_connection_t *h2c, u_char *pos,
|
||||
"with incorrect length: %uz, padding: %uz",
|
||||
h2c->state.length, h2c->state.padding);
|
||||
|
||||
return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
|
||||
return ngx_http_v2_connection_error(h2c,
|
||||
NGX_HTTP_V2_PROTOCOL_ERROR);
|
||||
}
|
||||
|
||||
h2c->state.length -= h2c->state.padding;
|
||||
@@ -1901,7 +1884,7 @@ ngx_http_v2_state_rst_stream(ngx_http_v2_connection_t *h2c, u_char *pos,
|
||||
|
||||
if (node == NULL || node->stream == NULL) {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
|
||||
"unknown http2 stream");
|
||||
"unknown http2 stream");
|
||||
|
||||
return ngx_http_v2_state_complete(h2c, pos, end);
|
||||
}
|
||||
@@ -2015,6 +1998,7 @@ ngx_http_v2_state_settings_params(ngx_http_v2_connection_t *h2c, u_char *pos,
|
||||
break;
|
||||
|
||||
case NGX_HTTP_V2_MAX_FRAME_SIZE_SETTING:
|
||||
|
||||
if (value > NGX_HTTP_V2_MAX_FRAME_SIZE
|
||||
|| value < NGX_HTTP_V2_DEFAULT_FRAME_SIZE)
|
||||
{
|
||||
@@ -2161,6 +2145,44 @@ ngx_http_v2_state_window_update(ngx_http_v2_connection_t *h2c, u_char *pos,
|
||||
"http2 WINDOW_UPDATE frame sid:%ui window:%uz",
|
||||
h2c->state.sid, window);
|
||||
|
||||
if (window == 0) {
|
||||
if (h2c->state.sid == 0) {
|
||||
ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
|
||||
"client sent WINDOW_UPDATE frame "
|
||||
"with incorrect window increment 0");
|
||||
|
||||
return ngx_http_v2_connection_error(h2c,
|
||||
NGX_HTTP_V2_PROTOCOL_ERROR);
|
||||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
|
||||
"client sent WINDOW_UPDATE frame for stream %ui "
|
||||
"with incorrect window increment 0", h2c->state.sid);
|
||||
|
||||
node = ngx_http_v2_get_node_by_id(h2c, h2c->state.sid, 0);
|
||||
|
||||
if (node && node->stream) {
|
||||
if (ngx_http_v2_terminate_stream(h2c, node->stream,
|
||||
NGX_HTTP_V2_PROTOCOL_ERROR)
|
||||
== NGX_ERROR)
|
||||
{
|
||||
return ngx_http_v2_connection_error(h2c,
|
||||
NGX_HTTP_V2_INTERNAL_ERROR);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (ngx_http_v2_send_rst_stream(h2c, h2c->state.sid,
|
||||
NGX_HTTP_V2_PROTOCOL_ERROR)
|
||||
== NGX_ERROR)
|
||||
{
|
||||
return ngx_http_v2_connection_error(h2c,
|
||||
NGX_HTTP_V2_INTERNAL_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
return ngx_http_v2_state_complete(h2c, pos, end);
|
||||
}
|
||||
|
||||
if (h2c->state.sid) {
|
||||
node = ngx_http_v2_get_node_by_id(h2c, h2c->state.sid, 0);
|
||||
|
||||
@@ -3072,7 +3094,7 @@ ngx_http_v2_pseudo_header(ngx_http_request_t *r, ngx_http_v2_header_t *header)
|
||||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||
"client sent unknown pseudo header \"%V\"",
|
||||
"client sent unknown pseudo-header \":%V\"",
|
||||
&header->name);
|
||||
|
||||
return NGX_DECLINED;
|
||||
@@ -3219,14 +3241,14 @@ ngx_http_v2_parse_scheme(ngx_http_request_t *r, ngx_http_v2_header_t *header)
|
||||
{
|
||||
if (r->schema_start) {
|
||||
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||
"client sent duplicate :schema header");
|
||||
"client sent duplicate :scheme header");
|
||||
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
|
||||
if (header->value.len == 0) {
|
||||
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
|
||||
"client sent empty :schema header");
|
||||
"client sent empty :scheme header");
|
||||
|
||||
return NGX_DECLINED;
|
||||
}
|
||||
@@ -3479,8 +3501,7 @@ ngx_http_v2_run_request(ngx_http_request_t *r)
|
||||
|
||||
|
||||
ngx_int_t
|
||||
ngx_http_v2_read_request_body(ngx_http_request_t *r,
|
||||
ngx_http_client_body_handler_pt post_handler)
|
||||
ngx_http_v2_read_request_body(ngx_http_request_t *r)
|
||||
{
|
||||
off_t len;
|
||||
size_t size;
|
||||
@@ -3493,33 +3514,14 @@ ngx_http_v2_read_request_body(ngx_http_request_t *r,
|
||||
ngx_http_v2_connection_t *h2c;
|
||||
|
||||
stream = r->stream;
|
||||
rb = r->request_body;
|
||||
|
||||
if (stream->skip_data) {
|
||||
r->request_body_no_buffering = 0;
|
||||
post_handler(r);
|
||||
rb->post_handler(r);
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t));
|
||||
if (rb == NULL) {
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
/*
|
||||
* set by ngx_pcalloc():
|
||||
*
|
||||
* rb->bufs = NULL;
|
||||
* rb->buf = NULL;
|
||||
* rb->received = 0;
|
||||
* rb->free = NULL;
|
||||
* rb->busy = NULL;
|
||||
*/
|
||||
|
||||
rb->rest = 1;
|
||||
rb->post_handler = post_handler;
|
||||
|
||||
r->request_body = rb;
|
||||
|
||||
h2scf = ngx_http_get_module_srv_conf(r, ngx_http_v2_module);
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
|
||||
@@ -3569,6 +3571,8 @@ ngx_http_v2_read_request_body(ngx_http_request_t *r,
|
||||
return NGX_HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
rb->rest = 1;
|
||||
|
||||
buf = stream->preread;
|
||||
|
||||
if (stream->in_closed) {
|
||||
@@ -4130,6 +4134,14 @@ ngx_http_v2_handle_connection_handler(ngx_event_t *rev)
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0,
|
||||
"http2 handle connection handler");
|
||||
|
||||
c = rev->data;
|
||||
h2c = c->data;
|
||||
|
||||
if (c->error) {
|
||||
ngx_http_v2_finalize_connection(h2c, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
rev->handler = ngx_http_v2_read_handler;
|
||||
|
||||
if (rev->ready) {
|
||||
@@ -4137,9 +4149,6 @@ ngx_http_v2_handle_connection_handler(ngx_event_t *rev)
|
||||
return;
|
||||
}
|
||||
|
||||
c = rev->data;
|
||||
h2c = c->data;
|
||||
|
||||
if (h2c->last_out && ngx_http_v2_send_output_queue(h2c) == NGX_ERROR) {
|
||||
ngx_http_v2_finalize_connection(h2c, 0);
|
||||
return;
|
||||
@@ -4262,7 +4271,10 @@ ngx_http_v2_finalize_connection(ngx_http_v2_connection_t *h2c,
|
||||
|
||||
if (stream->queued) {
|
||||
stream->queued = 0;
|
||||
|
||||
ev = fc->write;
|
||||
ev->active = 0;
|
||||
ev->ready = 1;
|
||||
|
||||
} else {
|
||||
ev = fc->read;
|
||||
|
||||
@@ -249,8 +249,8 @@ ngx_http_v2_queue_blocked_frame(ngx_http_v2_connection_t *h2c,
|
||||
{
|
||||
ngx_http_v2_out_frame_t **out;
|
||||
|
||||
for (out = &h2c->last_out; *out; out = &(*out)->next)
|
||||
{
|
||||
for (out = &h2c->last_out; *out; out = &(*out)->next) {
|
||||
|
||||
if ((*out)->blocked || (*out)->stream == NULL) {
|
||||
break;
|
||||
}
|
||||
@@ -264,8 +264,7 @@ ngx_http_v2_queue_blocked_frame(ngx_http_v2_connection_t *h2c,
|
||||
void ngx_http_v2_init(ngx_event_t *rev);
|
||||
void ngx_http_v2_request_headers_init(void);
|
||||
|
||||
ngx_int_t ngx_http_v2_read_request_body(ngx_http_request_t *r,
|
||||
ngx_http_client_body_handler_pt post_handler);
|
||||
ngx_int_t ngx_http_v2_read_request_body(ngx_http_request_t *r);
|
||||
ngx_int_t ngx_http_v2_read_unbuffered_request_body(ngx_http_request_t *r);
|
||||
|
||||
void ngx_http_v2_close_stream(ngx_http_v2_stream_t *stream, ngx_int_t rc);
|
||||
|
||||
@@ -148,6 +148,10 @@ ngx_http_v2_header_filter(ngx_http_request_t *r)
|
||||
static size_t nginx_ver_len = ngx_http_v2_literal_size(NGINX_VER);
|
||||
static u_char nginx_ver[ngx_http_v2_literal_size(NGINX_VER)];
|
||||
|
||||
static size_t nginx_ver_build_len =
|
||||
ngx_http_v2_literal_size(NGINX_VER_BUILD);
|
||||
static u_char nginx_ver_build[ngx_http_v2_literal_size(NGINX_VER_BUILD)];
|
||||
|
||||
if (!r->stream) {
|
||||
return ngx_http_next_header_filter(r);
|
||||
}
|
||||
@@ -232,7 +236,16 @@ ngx_http_v2_header_filter(ngx_http_request_t *r)
|
||||
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
|
||||
|
||||
if (r->headers_out.server == NULL) {
|
||||
len += 1 + (clcf->server_tokens ? nginx_ver_len : sizeof(nginx));
|
||||
|
||||
if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_ON) {
|
||||
len += 1 + nginx_ver_len;
|
||||
|
||||
} else if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_BUILD) {
|
||||
len += 1 + nginx_ver_build_len;
|
||||
|
||||
} else {
|
||||
len += 1 + sizeof(nginx);
|
||||
}
|
||||
}
|
||||
|
||||
if (r->headers_out.date == NULL) {
|
||||
@@ -420,13 +433,25 @@ ngx_http_v2_header_filter(ngx_http_request_t *r)
|
||||
}
|
||||
|
||||
if (r->headers_out.server == NULL) {
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
|
||||
"http2 output header: \"server: %s\"",
|
||||
clcf->server_tokens ? NGINX_VER : "nginx");
|
||||
|
||||
if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_ON) {
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
|
||||
"http2 output header: \"server: %s\"",
|
||||
NGINX_VER);
|
||||
|
||||
} else if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_BUILD) {
|
||||
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
|
||||
"http2 output header: \"server: %s\"",
|
||||
NGINX_VER_BUILD);
|
||||
|
||||
} else {
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0,
|
||||
"http2 output header: \"server: nginx\"");
|
||||
}
|
||||
|
||||
*pos++ = ngx_http_v2_inc_indexed(NGX_HTTP_V2_SERVER_INDEX);
|
||||
|
||||
if (clcf->server_tokens) {
|
||||
if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_ON) {
|
||||
if (nginx_ver[0] == '\0') {
|
||||
p = ngx_http_v2_write_value(nginx_ver, (u_char *) NGINX_VER,
|
||||
sizeof(NGINX_VER) - 1, tmp);
|
||||
@@ -435,6 +460,16 @@ ngx_http_v2_header_filter(ngx_http_request_t *r)
|
||||
|
||||
pos = ngx_cpymem(pos, nginx_ver, nginx_ver_len);
|
||||
|
||||
} else if (clcf->server_tokens == NGX_HTTP_SERVER_TOKENS_BUILD) {
|
||||
if (nginx_ver_build[0] == '\0') {
|
||||
p = ngx_http_v2_write_value(nginx_ver_build,
|
||||
(u_char *) NGINX_VER_BUILD,
|
||||
sizeof(NGINX_VER_BUILD) - 1, tmp);
|
||||
nginx_ver_build_len = p - nginx_ver_build;
|
||||
}
|
||||
|
||||
pos = ngx_cpymem(pos, nginx_ver_build, nginx_ver_build_len);
|
||||
|
||||
} else {
|
||||
pos = ngx_cpymem(pos, nginx, sizeof(nginx));
|
||||
}
|
||||
@@ -584,6 +619,8 @@ ngx_http_v2_header_filter(ngx_http_request_t *r)
|
||||
|
||||
ngx_http_v2_queue_blocked_frame(r->stream->connection, frame);
|
||||
|
||||
r->stream->queued = 1;
|
||||
|
||||
cln = ngx_http_cleanup_add(r, 0);
|
||||
if (cln == NULL) {
|
||||
return NGX_ERROR;
|
||||
@@ -592,8 +629,6 @@ ngx_http_v2_header_filter(ngx_http_request_t *r)
|
||||
cln->handler = ngx_http_v2_filter_cleanup;
|
||||
cln->data = r->stream;
|
||||
|
||||
r->stream->queued = 1;
|
||||
|
||||
fc->send_chain = ngx_http_v2_send_chain;
|
||||
fc->need_last_buf = 1;
|
||||
|
||||
@@ -734,6 +769,8 @@ ngx_http_v2_create_headers_frame(ngx_http_request_t *r, u_char *pos,
|
||||
rest -= frame_size;
|
||||
|
||||
if (rest) {
|
||||
frame->length += NGX_HTTP_V2_FRAME_HEADER_SIZE;
|
||||
|
||||
type = NGX_HTTP_V2_CONTINUATION_FRAME;
|
||||
flags = NGX_HTTP_V2_NO_FLAG;
|
||||
continue;
|
||||
@@ -1174,6 +1211,9 @@ ngx_http_v2_headers_frame_handler(ngx_http_v2_connection_t *h2c,
|
||||
"http2:%ui HEADERS frame %p was sent",
|
||||
stream->node->id, frame);
|
||||
|
||||
stream->request->header_size += NGX_HTTP_V2_FRAME_HEADER_SIZE
|
||||
+ frame->length;
|
||||
|
||||
ngx_http_v2_handle_frame(stream, frame);
|
||||
|
||||
ngx_http_v2_handle_stream(h2c, stream);
|
||||
|
||||
@@ -333,6 +333,8 @@ ngx_mail_optimize_servers(ngx_conf_t *cf, ngx_array_t *ports)
|
||||
ls->log.handler = ngx_accept_log_error;
|
||||
|
||||
ls->backlog = addr[i].opt.backlog;
|
||||
ls->rcvbuf = addr[i].opt.rcvbuf;
|
||||
ls->sndbuf = addr[i].opt.sndbuf;
|
||||
|
||||
ls->keepalive = addr[i].opt.so_keepalive;
|
||||
#if (NGX_HAVE_KEEPALIVE_TUNABLE)
|
||||
|
||||
@@ -46,6 +46,8 @@ typedef struct {
|
||||
int tcp_keepcnt;
|
||||
#endif
|
||||
int backlog;
|
||||
int rcvbuf;
|
||||
int sndbuf;
|
||||
} ngx_mail_listen_t;
|
||||
|
||||
|
||||
|
||||
@@ -295,7 +295,7 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_mail_core_srv_conf_t *cscf = conf;
|
||||
|
||||
ngx_str_t *value;
|
||||
ngx_str_t *value, size;
|
||||
ngx_url_t u;
|
||||
ngx_uint_t i, m;
|
||||
ngx_mail_listen_t *ls;
|
||||
@@ -350,6 +350,8 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
|
||||
ls->socklen = u.socklen;
|
||||
ls->backlog = NGX_LISTEN_BACKLOG;
|
||||
ls->rcvbuf = -1;
|
||||
ls->sndbuf = -1;
|
||||
ls->wildcard = u.wildcard;
|
||||
ls->ctx = cf->ctx;
|
||||
|
||||
@@ -398,6 +400,38 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strncmp(value[i].data, "rcvbuf=", 7) == 0) {
|
||||
size.len = value[i].len - 7;
|
||||
size.data = value[i].data + 7;
|
||||
|
||||
ls->rcvbuf = ngx_parse_size(&size);
|
||||
ls->bind = 1;
|
||||
|
||||
if (ls->rcvbuf == NGX_ERROR) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid rcvbuf \"%V\"", &value[i]);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strncmp(value[i].data, "sndbuf=", 7) == 0) {
|
||||
size.len = value[i].len - 7;
|
||||
size.data = value[i].data + 7;
|
||||
|
||||
ls->sndbuf = ngx_parse_size(&size);
|
||||
ls->bind = 1;
|
||||
|
||||
if (ls->sndbuf == NGX_ERROR) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid sndbuf \"%V\"", &value[i]);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strncmp(value[i].data, "ipv6only=o", 10) == 0) {
|
||||
#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
|
||||
size_t len;
|
||||
|
||||
@@ -222,7 +222,7 @@ ngx_mail_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c)
|
||||
ngx_mail_session_t *s;
|
||||
ngx_mail_core_srv_conf_t *cscf;
|
||||
|
||||
if (ngx_ssl_create_connection(ssl, c, 0) == NGX_ERROR) {
|
||||
if (ngx_ssl_create_connection(ssl, c, 0) != NGX_OK) {
|
||||
ngx_mail_close_connection(c);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -185,6 +185,10 @@ ngx_mail_pop3_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED;
|
||||
m <<= 1, i++)
|
||||
{
|
||||
if (ngx_mail_pop3_auth_methods_names[i].len == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m & conf->auth_methods) {
|
||||
size += 1 + ngx_mail_pop3_auth_methods_names[i].len;
|
||||
}
|
||||
@@ -212,6 +216,10 @@ ngx_mail_pop3_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED;
|
||||
m <<= 1, i++)
|
||||
{
|
||||
if (ngx_mail_pop3_auth_methods_names[i].len == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m & conf->auth_methods) {
|
||||
*p++ = ' ';
|
||||
p = ngx_cpymem(p, ngx_mail_pop3_auth_methods_names[i].data,
|
||||
@@ -248,6 +256,10 @@ ngx_mail_pop3_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED;
|
||||
m <<= 1, i++)
|
||||
{
|
||||
if (ngx_mail_pop3_auth_methods_names[i].len == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m & conf->auth_methods) {
|
||||
size += ngx_mail_pop3_auth_methods_names[i].len
|
||||
+ sizeof(CRLF) - 1;
|
||||
@@ -269,6 +281,10 @@ ngx_mail_pop3_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||
m <= NGX_MAIL_AUTH_EXTERNAL_ENABLED;
|
||||
m <<= 1, i++)
|
||||
{
|
||||
if (ngx_mail_pop3_auth_methods_names[i].len == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m & conf->auth_methods) {
|
||||
p = ngx_cpymem(p, ngx_mail_pop3_auth_methods_names[i].data,
|
||||
ngx_mail_pop3_auth_methods_names[i].len);
|
||||
|
||||
@@ -42,6 +42,7 @@ static ngx_conf_bitmask_t ngx_mail_ssl_protocols[] = {
|
||||
{ ngx_string("TLSv1"), NGX_SSL_TLSv1 },
|
||||
{ ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 },
|
||||
{ ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 },
|
||||
{ ngx_string("TLSv1.3"), NGX_SSL_TLSv1_3 },
|
||||
{ ngx_null_string, 0 }
|
||||
};
|
||||
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
#define _NGX_DARWIN_CONFIG_H_INCLUDED_
|
||||
|
||||
|
||||
#define __APPLE_USE_RFC_3542 /* IPV6_PKTINFO */
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -20,8 +20,8 @@ static ssize_t ngx_linux_sendfile(ngx_connection_t *c, ngx_buf_t *file,
|
||||
#error sendfile64() is required!
|
||||
#endif
|
||||
|
||||
static ngx_int_t ngx_linux_sendfile_thread(ngx_connection_t *c, ngx_buf_t *file,
|
||||
size_t size, size_t *sent);
|
||||
static ssize_t ngx_linux_sendfile_thread(ngx_connection_t *c, ngx_buf_t *file,
|
||||
size_t size);
|
||||
static void ngx_linux_sendfile_thread_handler(void *data, ngx_log_t *log);
|
||||
#endif
|
||||
|
||||
@@ -56,10 +56,6 @@ ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
|
||||
ngx_chain_t *cl;
|
||||
ngx_iovec_t header;
|
||||
struct iovec headers[NGX_IOVS_PREALLOCATE];
|
||||
#if (NGX_THREADS)
|
||||
ngx_int_t rc;
|
||||
ngx_uint_t thread_handled, thread_complete;
|
||||
#endif
|
||||
|
||||
wev = c->write;
|
||||
|
||||
@@ -82,10 +78,6 @@ ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
|
||||
|
||||
for ( ;; ) {
|
||||
prev_send = send;
|
||||
#if (NGX_THREADS)
|
||||
thread_handled = 0;
|
||||
thread_complete = 0;
|
||||
#endif
|
||||
|
||||
/* create the iovec and coalesce the neighbouring bufs */
|
||||
|
||||
@@ -179,38 +171,19 @@ ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (NGX_THREADS)
|
||||
if (file->file->thread_handler) {
|
||||
rc = ngx_linux_sendfile_thread(c, file, file_size, &sent);
|
||||
n = ngx_linux_sendfile(c, file, file_size);
|
||||
|
||||
switch (rc) {
|
||||
case NGX_OK:
|
||||
thread_handled = 1;
|
||||
break;
|
||||
|
||||
case NGX_DONE:
|
||||
thread_complete = 1;
|
||||
break;
|
||||
|
||||
case NGX_AGAIN:
|
||||
break;
|
||||
|
||||
default: /* NGX_ERROR */
|
||||
return NGX_CHAIN_ERROR;
|
||||
}
|
||||
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
n = ngx_linux_sendfile(c, file, file_size);
|
||||
|
||||
if (n == NGX_ERROR) {
|
||||
return NGX_CHAIN_ERROR;
|
||||
}
|
||||
|
||||
sent = (n == NGX_AGAIN) ? 0 : n;
|
||||
if (n == NGX_ERROR) {
|
||||
return NGX_CHAIN_ERROR;
|
||||
}
|
||||
|
||||
if (n == NGX_DONE) {
|
||||
/* thread task posted */
|
||||
return in;
|
||||
}
|
||||
|
||||
sent = (n == NGX_AGAIN) ? 0 : n;
|
||||
|
||||
} else {
|
||||
n = ngx_writev(c, &header);
|
||||
|
||||
@@ -225,21 +198,27 @@ ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
|
||||
|
||||
in = ngx_chain_update_sent(in, sent);
|
||||
|
||||
if ((size_t) (send - prev_send) != sent) {
|
||||
#if (NGX_THREADS)
|
||||
if (thread_handled) {
|
||||
return in;
|
||||
}
|
||||
|
||||
if (thread_complete) {
|
||||
send = prev_send + sent;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (n == NGX_AGAIN) {
|
||||
wev->ready = 0;
|
||||
return in;
|
||||
}
|
||||
|
||||
if ((size_t) (send - prev_send) != sent) {
|
||||
|
||||
/*
|
||||
* sendfile() on Linux 4.3+ might be interrupted at any time,
|
||||
* and provides no indication if it was interrupted or not,
|
||||
* so we have to retry till an explicit EAGAIN
|
||||
*
|
||||
* sendfile() in threads can also report less bytes written
|
||||
* than we are prepared to send now, since it was started in
|
||||
* some point in the past, so we again have to retry
|
||||
*/
|
||||
|
||||
send = prev_send + sent;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (send >= limit || in == NULL) {
|
||||
return in;
|
||||
}
|
||||
@@ -258,6 +237,14 @@ ngx_linux_sendfile(ngx_connection_t *c, ngx_buf_t *file, size_t size)
|
||||
ssize_t n;
|
||||
ngx_err_t err;
|
||||
|
||||
#if (NGX_THREADS)
|
||||
|
||||
if (file->file->thread_handler) {
|
||||
return ngx_linux_sendfile_thread(c, file, size);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if (NGX_HAVE_SENDFILE64)
|
||||
offset = file->file_pos;
|
||||
#else
|
||||
@@ -324,9 +311,8 @@ typedef struct {
|
||||
} ngx_linux_sendfile_ctx_t;
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_linux_sendfile_thread(ngx_connection_t *c, ngx_buf_t *file, size_t size,
|
||||
size_t *sent)
|
||||
static ssize_t
|
||||
ngx_linux_sendfile_thread(ngx_connection_t *c, ngx_buf_t *file, size_t size)
|
||||
{
|
||||
ngx_event_t *wev;
|
||||
ngx_thread_task_t *task;
|
||||
@@ -356,10 +342,14 @@ ngx_linux_sendfile_thread(ngx_connection_t *c, ngx_buf_t *file, size_t size,
|
||||
task->event.complete = 0;
|
||||
|
||||
if (ctx->err == NGX_EAGAIN) {
|
||||
*sent = 0;
|
||||
/*
|
||||
* if wev->complete is set, this means that a write event
|
||||
* happened while we were waiting for the thread task, so
|
||||
* we have to retry sending even on EAGAIN
|
||||
*/
|
||||
|
||||
if (wev->complete) {
|
||||
return NGX_DONE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return NGX_AGAIN;
|
||||
@@ -384,13 +374,7 @@ ngx_linux_sendfile_thread(ngx_connection_t *c, ngx_buf_t *file, size_t size,
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*sent = ctx->sent;
|
||||
|
||||
if (ctx->sent == ctx->size || wev->complete) {
|
||||
return NGX_DONE;
|
||||
}
|
||||
|
||||
return NGX_AGAIN;
|
||||
return ctx->sent;
|
||||
}
|
||||
|
||||
if (task->event.active && ctx->file == file) {
|
||||
@@ -399,9 +383,7 @@ ngx_linux_sendfile_thread(ngx_connection_t *c, ngx_buf_t *file, size_t size,
|
||||
* or multiple calls of the next body filter from a filter
|
||||
*/
|
||||
|
||||
*sent = 0;
|
||||
|
||||
return NGX_OK;
|
||||
return NGX_DONE;
|
||||
}
|
||||
|
||||
ctx->file = file;
|
||||
@@ -414,9 +396,7 @@ ngx_linux_sendfile_thread(ngx_connection_t *c, ngx_buf_t *file, size_t size,
|
||||
return NGX_ERROR;
|
||||
}
|
||||
|
||||
*sent = 0;
|
||||
|
||||
return NGX_OK;
|
||||
return NGX_DONE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -15,13 +15,13 @@ typedef struct {
|
||||
int signo;
|
||||
char *signame;
|
||||
char *name;
|
||||
void (*handler)(int signo);
|
||||
void (*handler)(int signo, siginfo_t *siginfo, void *ucontext);
|
||||
} ngx_signal_t;
|
||||
|
||||
|
||||
|
||||
static void ngx_execute_proc(ngx_cycle_t *cycle, void *data);
|
||||
static void ngx_signal_handler(int signo);
|
||||
static void ngx_signal_handler(int signo, siginfo_t *siginfo, void *ucontext);
|
||||
static void ngx_process_get_status(void);
|
||||
static void ngx_unlock_mutexes(ngx_pid_t pid);
|
||||
|
||||
@@ -75,9 +75,9 @@ ngx_signal_t signals[] = {
|
||||
|
||||
{ SIGCHLD, "SIGCHLD", "", ngx_signal_handler },
|
||||
|
||||
{ SIGSYS, "SIGSYS, SIG_IGN", "", SIG_IGN },
|
||||
{ SIGSYS, "SIGSYS, SIG_IGN", "", NULL },
|
||||
|
||||
{ SIGPIPE, "SIGPIPE, SIG_IGN", "", SIG_IGN },
|
||||
{ SIGPIPE, "SIGPIPE, SIG_IGN", "", NULL },
|
||||
|
||||
{ 0, NULL, "", NULL }
|
||||
};
|
||||
@@ -288,7 +288,15 @@ ngx_init_signals(ngx_log_t *log)
|
||||
|
||||
for (sig = signals; sig->signo != 0; sig++) {
|
||||
ngx_memzero(&sa, sizeof(struct sigaction));
|
||||
sa.sa_handler = sig->handler;
|
||||
|
||||
if (sig->handler) {
|
||||
sa.sa_sigaction = sig->handler;
|
||||
sa.sa_flags = SA_SIGINFO;
|
||||
|
||||
} else {
|
||||
sa.sa_handler = SIG_IGN;
|
||||
}
|
||||
|
||||
sigemptyset(&sa.sa_mask);
|
||||
if (sigaction(sig->signo, &sa, NULL) == -1) {
|
||||
#if (NGX_VALGRIND)
|
||||
@@ -306,8 +314,8 @@ ngx_init_signals(ngx_log_t *log)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ngx_signal_handler(int signo)
|
||||
static void
|
||||
ngx_signal_handler(int signo, siginfo_t *siginfo, void *ucontext)
|
||||
{
|
||||
char *action;
|
||||
ngx_int_t ignore;
|
||||
@@ -405,6 +413,7 @@ ngx_signal_handler(int signo)
|
||||
break;
|
||||
}
|
||||
ngx_debug_quit = 1;
|
||||
/* fall through */
|
||||
case ngx_signal_value(NGX_SHUTDOWN_SIGNAL):
|
||||
ngx_quit = 1;
|
||||
action = ", shutting down";
|
||||
@@ -431,8 +440,16 @@ ngx_signal_handler(int signo)
|
||||
break;
|
||||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0,
|
||||
"signal %d (%s) received%s", signo, sig->signame, action);
|
||||
if (siginfo && siginfo->si_pid) {
|
||||
ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0,
|
||||
"signal %d (%s) received from %P%s",
|
||||
signo, sig->signame, siginfo->si_pid, action);
|
||||
|
||||
} else {
|
||||
ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0,
|
||||
"signal %d (%s) received%s",
|
||||
signo, sig->signame, action);
|
||||
}
|
||||
|
||||
if (ignore) {
|
||||
ngx_log_error(NGX_LOG_CRIT, ngx_cycle->log, 0,
|
||||
|
||||
@@ -738,12 +738,8 @@ ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
|
||||
for ( ;; ) {
|
||||
|
||||
if (ngx_exiting) {
|
||||
ngx_event_cancel_timers();
|
||||
|
||||
if (ngx_event_timer_rbtree.root == ngx_event_timer_rbtree.sentinel)
|
||||
{
|
||||
if (ngx_event_no_timers_left() == NGX_OK) {
|
||||
ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");
|
||||
|
||||
ngx_worker_process_exit(cycle);
|
||||
}
|
||||
}
|
||||
@@ -754,7 +750,6 @@ ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
|
||||
|
||||
if (ngx_terminate) {
|
||||
ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting");
|
||||
|
||||
ngx_worker_process_exit(cycle);
|
||||
}
|
||||
|
||||
@@ -766,6 +761,7 @@ ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data)
|
||||
|
||||
if (!ngx_exiting) {
|
||||
ngx_exiting = 1;
|
||||
ngx_set_shutdown_timer(cycle);
|
||||
ngx_close_listening_sockets(cycle);
|
||||
ngx_close_idle_connections(cycle);
|
||||
}
|
||||
|
||||
@@ -203,6 +203,20 @@ ngx_sendmsg(ngx_connection_t *c, ngx_iovec_t *vec)
|
||||
ngx_err_t err;
|
||||
struct msghdr msg;
|
||||
|
||||
#if (NGX_HAVE_MSGHDR_MSG_CONTROL)
|
||||
|
||||
#if (NGX_HAVE_IP_SENDSRCADDR)
|
||||
u_char msg_control[CMSG_SPACE(sizeof(struct in_addr))];
|
||||
#elif (NGX_HAVE_IP_PKTINFO)
|
||||
u_char msg_control[CMSG_SPACE(sizeof(struct in_pktinfo))];
|
||||
#endif
|
||||
|
||||
#if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO)
|
||||
u_char msg_control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
ngx_memzero(&msg, sizeof(struct msghdr));
|
||||
|
||||
if (c->socklen) {
|
||||
@@ -213,6 +227,82 @@ ngx_sendmsg(ngx_connection_t *c, ngx_iovec_t *vec)
|
||||
msg.msg_iov = vec->iovs;
|
||||
msg.msg_iovlen = vec->count;
|
||||
|
||||
#if (NGX_HAVE_MSGHDR_MSG_CONTROL)
|
||||
|
||||
if (c->listening && c->listening->wildcard && c->local_sockaddr) {
|
||||
|
||||
#if (NGX_HAVE_IP_SENDSRCADDR)
|
||||
|
||||
if (c->local_sockaddr->sa_family == AF_INET) {
|
||||
struct cmsghdr *cmsg;
|
||||
struct in_addr *addr;
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
msg.msg_control = &msg_control;
|
||||
msg.msg_controllen = sizeof(msg_control);
|
||||
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
cmsg->cmsg_level = IPPROTO_IP;
|
||||
cmsg->cmsg_type = IP_SENDSRCADDR;
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_addr));
|
||||
|
||||
sin = (struct sockaddr_in *) c->local_sockaddr;
|
||||
|
||||
addr = (struct in_addr *) CMSG_DATA(cmsg);
|
||||
*addr = sin->sin_addr;
|
||||
}
|
||||
|
||||
#elif (NGX_HAVE_IP_PKTINFO)
|
||||
|
||||
if (c->local_sockaddr->sa_family == AF_INET) {
|
||||
struct cmsghdr *cmsg;
|
||||
struct in_pktinfo *pkt;
|
||||
struct sockaddr_in *sin;
|
||||
|
||||
msg.msg_control = &msg_control;
|
||||
msg.msg_controllen = sizeof(msg_control);
|
||||
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
cmsg->cmsg_level = IPPROTO_IP;
|
||||
cmsg->cmsg_type = IP_PKTINFO;
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
|
||||
|
||||
sin = (struct sockaddr_in *) c->local_sockaddr;
|
||||
|
||||
pkt = (struct in_pktinfo *) CMSG_DATA(cmsg);
|
||||
ngx_memzero(pkt, sizeof(struct in_pktinfo));
|
||||
pkt->ipi_spec_dst = sin->sin_addr;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if (NGX_HAVE_INET6 && NGX_HAVE_IPV6_RECVPKTINFO)
|
||||
|
||||
if (c->local_sockaddr->sa_family == AF_INET6) {
|
||||
struct cmsghdr *cmsg;
|
||||
struct in6_pktinfo *pkt6;
|
||||
struct sockaddr_in6 *sin6;
|
||||
|
||||
msg.msg_control = &msg_control6;
|
||||
msg.msg_controllen = sizeof(msg_control6);
|
||||
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
cmsg->cmsg_level = IPPROTO_IPV6;
|
||||
cmsg->cmsg_type = IPV6_PKTINFO;
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
|
||||
|
||||
sin6 = (struct sockaddr_in6 *) c->local_sockaddr;
|
||||
|
||||
pkt6 = (struct in6_pktinfo *) CMSG_DATA(cmsg);
|
||||
ngx_memzero(pkt6, sizeof(struct in6_pktinfo));
|
||||
pkt6->ipi6_addr = sin6->sin6_addr;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
eintr:
|
||||
|
||||
n = sendmsg(c->fd, &msg, 0);
|
||||
|
||||
@@ -494,6 +494,8 @@ ngx_stream_optimize_servers(ngx_conf_t *cf, ngx_array_t *ports)
|
||||
ls->log.handler = ngx_accept_log_error;
|
||||
|
||||
ls->backlog = addr[i].opt.backlog;
|
||||
ls->rcvbuf = addr[i].opt.rcvbuf;
|
||||
ls->sndbuf = addr[i].opt.sndbuf;
|
||||
|
||||
ls->wildcard = addr[i].opt.wildcard;
|
||||
|
||||
|
||||
@@ -62,6 +62,8 @@ typedef struct {
|
||||
int tcp_keepcnt;
|
||||
#endif
|
||||
int backlog;
|
||||
int rcvbuf;
|
||||
int sndbuf;
|
||||
int type;
|
||||
} ngx_stream_listen_t;
|
||||
|
||||
@@ -153,7 +155,8 @@ typedef struct {
|
||||
|
||||
ngx_hash_t variables_hash;
|
||||
|
||||
ngx_array_t variables; /* ngx_stream_variable_t */
|
||||
ngx_array_t variables; /* ngx_stream_variable_t */
|
||||
ngx_array_t prefix_variables; /* ngx_stream_variable_t */
|
||||
ngx_uint_t ncaptures;
|
||||
|
||||
ngx_uint_t variables_hash_max_size;
|
||||
|
||||
@@ -299,28 +299,22 @@ ngx_stream_access_rule(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
ngx_stream_access_rule_un_t *rule_un;
|
||||
#endif
|
||||
|
||||
all = 0;
|
||||
ngx_memzero(&cidr, sizeof(ngx_cidr_t));
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
all = (value[1].len == 3 && ngx_strcmp(value[1].data, "all") == 0);
|
||||
|
||||
if (!all) {
|
||||
if (value[1].len == 3 && ngx_strcmp(value[1].data, "all") == 0) {
|
||||
all = 1;
|
||||
|
||||
#if (NGX_HAVE_UNIX_DOMAIN)
|
||||
|
||||
if (value[1].len == 5 && ngx_strcmp(value[1].data, "unix:") == 0) {
|
||||
cidr.family = AF_UNIX;
|
||||
rc = NGX_OK;
|
||||
|
||||
} else {
|
||||
rc = ngx_ptocidr(&value[1], &cidr);
|
||||
}
|
||||
|
||||
#else
|
||||
rc = ngx_ptocidr(&value[1], &cidr);
|
||||
} else if (value[1].len == 5 && ngx_strcmp(value[1].data, "unix:") == 0) {
|
||||
cidr.family = AF_UNIX;
|
||||
#endif
|
||||
|
||||
} else {
|
||||
rc = ngx_ptocidr(&value[1], &cidr);
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid parameter \"%V\"", &value[1]);
|
||||
|
||||
@@ -309,7 +309,6 @@ ngx_int_t
|
||||
ngx_stream_core_content_phase(ngx_stream_session_t *s,
|
||||
ngx_stream_phase_handler_t *ph)
|
||||
{
|
||||
int tcp_nodelay;
|
||||
ngx_connection_t *c;
|
||||
ngx_stream_core_srv_conf_t *cscf;
|
||||
|
||||
@@ -321,22 +320,10 @@ ngx_stream_core_content_phase(ngx_stream_session_t *s,
|
||||
|
||||
if (c->type == SOCK_STREAM
|
||||
&& cscf->tcp_nodelay
|
||||
&& c->tcp_nodelay == NGX_TCP_NODELAY_UNSET)
|
||||
&& ngx_tcp_nodelay(c) != NGX_OK)
|
||||
{
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0, "tcp_nodelay");
|
||||
|
||||
tcp_nodelay = 1;
|
||||
|
||||
if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
|
||||
(const void *) &tcp_nodelay, sizeof(int)) == -1)
|
||||
{
|
||||
ngx_connection_error(c, ngx_socket_errno,
|
||||
"setsockopt(TCP_NODELAY) failed");
|
||||
ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
c->tcp_nodelay = NGX_TCP_NODELAY_SET;
|
||||
ngx_stream_finalize_session(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
|
||||
return NGX_OK;
|
||||
}
|
||||
|
||||
cscf->handler(s);
|
||||
@@ -582,7 +569,7 @@ ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_stream_core_srv_conf_t *cscf = conf;
|
||||
|
||||
ngx_str_t *value;
|
||||
ngx_str_t *value, size;
|
||||
ngx_url_t u;
|
||||
ngx_uint_t i, backlog;
|
||||
ngx_stream_listen_t *ls, *als;
|
||||
@@ -620,6 +607,8 @@ ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
|
||||
ls->socklen = u.socklen;
|
||||
ls->backlog = NGX_LISTEN_BACKLOG;
|
||||
ls->rcvbuf = -1;
|
||||
ls->sndbuf = -1;
|
||||
ls->type = SOCK_STREAM;
|
||||
ls->wildcard = u.wildcard;
|
||||
ls->ctx = cf->ctx;
|
||||
@@ -659,6 +648,38 @@ ngx_stream_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strncmp(value[i].data, "rcvbuf=", 7) == 0) {
|
||||
size.len = value[i].len - 7;
|
||||
size.data = value[i].data + 7;
|
||||
|
||||
ls->rcvbuf = ngx_parse_size(&size);
|
||||
ls->bind = 1;
|
||||
|
||||
if (ls->rcvbuf == NGX_ERROR) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid rcvbuf \"%V\"", &value[i]);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strncmp(value[i].data, "sndbuf=", 7) == 0) {
|
||||
size.len = value[i].len - 7;
|
||||
size.data = value[i].data + 7;
|
||||
|
||||
ls->sndbuf = ngx_parse_size(&size);
|
||||
ls->bind = 1;
|
||||
|
||||
if (ls->sndbuf == NGX_ERROR) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"invalid sndbuf \"%V\"", &value[i]);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ngx_strncmp(value[i].data, "ipv6only=o", 10) == 0) {
|
||||
#if (NGX_HAVE_INET6 && defined IPV6_V6ONLY)
|
||||
size_t len;
|
||||
|
||||
@@ -443,6 +443,11 @@ ngx_stream_log_script_write(ngx_stream_session_t *s,
|
||||
s->connection->pool)
|
||||
!= NGX_OK)
|
||||
{
|
||||
if (of.err == 0) {
|
||||
/* simulate successful logging */
|
||||
return len;
|
||||
}
|
||||
|
||||
ngx_log_error(NGX_LOG_CRIT, s->connection->log, ngx_errno,
|
||||
"%s \"%s\" failed", of.failed, log.data);
|
||||
/* simulate successful logging */
|
||||
@@ -641,23 +646,10 @@ ngx_stream_log_flush(ngx_open_file_t *file, ngx_log_t *log)
|
||||
static void
|
||||
ngx_stream_log_flush_handler(ngx_event_t *ev)
|
||||
{
|
||||
ngx_open_file_t *file;
|
||||
ngx_stream_log_buf_t *buffer;
|
||||
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ev->log, 0,
|
||||
"stream log buffer flush handler");
|
||||
|
||||
if (ev->timedout) {
|
||||
ngx_stream_log_flush(ev->data, ev->log);
|
||||
return;
|
||||
}
|
||||
|
||||
/* cancel the flush timer for graceful shutdown */
|
||||
|
||||
file = ev->data;
|
||||
buffer = file->data;
|
||||
|
||||
buffer->event = NULL;
|
||||
ngx_stream_log_flush(ev->data, ev->log);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -103,6 +103,7 @@ static ngx_conf_bitmask_t ngx_stream_proxy_ssl_protocols[] = {
|
||||
{ ngx_string("TLSv1"), NGX_SSL_TLSv1 },
|
||||
{ ngx_string("TLSv1.1"), NGX_SSL_TLSv1_1 },
|
||||
{ ngx_string("TLSv1.2"), NGX_SSL_TLSv1_2 },
|
||||
{ ngx_string("TLSv1.3"), NGX_SSL_TLSv1_3 },
|
||||
{ ngx_null_string, 0 }
|
||||
};
|
||||
|
||||
@@ -728,7 +729,6 @@ ngx_stream_proxy_connect(ngx_stream_session_t *s)
|
||||
static void
|
||||
ngx_stream_proxy_init_upstream(ngx_stream_session_t *s)
|
||||
{
|
||||
int tcp_nodelay;
|
||||
u_char *p;
|
||||
ngx_chain_t *cl;
|
||||
ngx_connection_t *c, *pc;
|
||||
@@ -744,22 +744,10 @@ ngx_stream_proxy_init_upstream(ngx_stream_session_t *s)
|
||||
|
||||
if (pc->type == SOCK_STREAM
|
||||
&& cscf->tcp_nodelay
|
||||
&& pc->tcp_nodelay == NGX_TCP_NODELAY_UNSET)
|
||||
&& ngx_tcp_nodelay(pc) != NGX_OK)
|
||||
{
|
||||
ngx_log_debug0(NGX_LOG_DEBUG_STREAM, pc->log, 0, "tcp_nodelay");
|
||||
|
||||
tcp_nodelay = 1;
|
||||
|
||||
if (setsockopt(pc->fd, IPPROTO_TCP, TCP_NODELAY,
|
||||
(const void *) &tcp_nodelay, sizeof(int)) == -1)
|
||||
{
|
||||
ngx_connection_error(pc, ngx_socket_errno,
|
||||
"setsockopt(TCP_NODELAY) failed");
|
||||
ngx_stream_proxy_next_upstream(s);
|
||||
return;
|
||||
}
|
||||
|
||||
pc->tcp_nodelay = NGX_TCP_NODELAY_SET;
|
||||
ngx_stream_proxy_next_upstream(s);
|
||||
return;
|
||||
}
|
||||
|
||||
pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_proxy_module);
|
||||
|
||||
@@ -178,9 +178,15 @@ ngx_stream_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
{
|
||||
ngx_stream_realip_srv_conf_t *rscf = conf;
|
||||
|
||||
ngx_int_t rc;
|
||||
ngx_str_t *value;
|
||||
ngx_cidr_t *cidr;
|
||||
ngx_int_t rc;
|
||||
ngx_str_t *value;
|
||||
ngx_url_t u;
|
||||
ngx_cidr_t c, *cidr;
|
||||
ngx_uint_t i;
|
||||
struct sockaddr_in *sin;
|
||||
#if (NGX_HAVE_INET6)
|
||||
struct sockaddr_in6 *sin6;
|
||||
#endif
|
||||
|
||||
value = cf->args->elts;
|
||||
|
||||
@@ -192,31 +198,78 @@ ngx_stream_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
|
||||
}
|
||||
}
|
||||
|
||||
cidr = ngx_array_push(rscf->from);
|
||||
if (cidr == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
#if (NGX_HAVE_UNIX_DOMAIN)
|
||||
|
||||
if (ngx_strcmp(value[1].data, "unix:") == 0) {
|
||||
cidr = ngx_array_push(rscf->from);
|
||||
if (cidr == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
cidr->family = AF_UNIX;
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
rc = ngx_ptocidr(&value[1], cidr);
|
||||
rc = ngx_ptocidr(&value[1], &c);
|
||||
|
||||
if (rc != NGX_ERROR) {
|
||||
if (rc == NGX_DONE) {
|
||||
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||
"low address bits of %V are meaningless",
|
||||
&value[1]);
|
||||
}
|
||||
|
||||
cidr = ngx_array_push(rscf->from);
|
||||
if (cidr == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
*cidr = c;
|
||||
|
||||
return NGX_CONF_OK;
|
||||
}
|
||||
|
||||
ngx_memzero(&u, sizeof(ngx_url_t));
|
||||
u.host = value[1];
|
||||
|
||||
if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) {
|
||||
if (u.err) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
|
||||
"%s in set_real_ip_from \"%V\"",
|
||||
u.err, &u.host);
|
||||
}
|
||||
|
||||
if (rc == NGX_ERROR) {
|
||||
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"",
|
||||
&value[1]);
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
if (rc == NGX_DONE) {
|
||||
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
|
||||
"low address bits of %V are meaningless", &value[1]);
|
||||
cidr = ngx_array_push_n(rscf->from, u.naddrs);
|
||||
if (cidr == NULL) {
|
||||
return NGX_CONF_ERROR;
|
||||
}
|
||||
|
||||
ngx_memzero(cidr, u.naddrs * sizeof(ngx_cidr_t));
|
||||
|
||||
for (i = 0; i < u.naddrs; i++) {
|
||||
cidr[i].family = u.addrs[i].sockaddr->sa_family;
|
||||
|
||||
switch (cidr[i].family) {
|
||||
|
||||
#if (NGX_HAVE_INET6)
|
||||
case AF_INET6:
|
||||
sin6 = (struct sockaddr_in6 *) u.addrs[i].sockaddr;
|
||||
cidr[i].u.in6.addr = sin6->sin6_addr;
|
||||
ngx_memset(cidr[i].u.in6.mask.s6_addr, 0xff, 16);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default: /* AF_INET */
|
||||
sin = (struct sockaddr_in *) u.addrs[i].sockaddr;
|
||||
cidr[i].u.in.addr = sin->sin_addr.s_addr;
|
||||
cidr[i].u.in.mask = 0xffffffff;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NGX_CONF_OK;
|
||||
|
||||
@@ -222,7 +222,7 @@ ngx_stream_set_complex_value_slot(ngx_conf_t *cf, ngx_command_t *cmd,
|
||||
cv = (ngx_stream_complex_value_t **) (p + cmd->offset);
|
||||
|
||||
if (*cv != NULL) {
|
||||
return "duplicate";
|
||||
return "is duplicate";
|
||||
}
|
||||
|
||||
*cv = ngx_palloc(cf->pool, sizeof(ngx_stream_complex_value_t));
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user