summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNGINX team <nginx@nginx.org>2012-03-28 14:00:08 +0000
committerJon Kolb <jon@b0g.us>2012-03-28 14:00:08 +0000
commit60a50f7b445d1ac18ea0b1ff140745b6844c6794 (patch)
treeb2edd9e3a38a3e58a0b348b6988e55f7f8be7cd0
parent3e2cd7431101761df65f2242c667c037599aa0c4 (diff)
downloadnginx-1.1.18.tar.gz
Changes with nginx 1.1.18 28 Mar 2012v1.1.18
*) Change: keepalive connections are no longer disabled for Safari by default. *) Feature: the $connection_requests variable. *) Feature: $tcpinfo_rtt, $tcpinfo_rttvar, $tcpinfo_snd_cwnd and $tcpinfo_rcv_space variables. *) Feature: the "worker_cpu_affinity" directive now works on FreeBSD. *) Feature: the "xslt_param" and "xslt_string_param" directives. Thanks to Samuel Behan. *) Bugfix: in configure tests. Thanks to Piotr Sikora. *) Bugfix: in the ngx_http_xslt_filter_module. *) Bugfix: nginx could not be built on Debian GNU/Hurd.
-rw-r--r--CHANGES23
-rw-r--r--CHANGES.ru23
-rw-r--r--auto/lib/pcre/conf4
-rw-r--r--auto/os/freebsd8
-rw-r--r--auto/os/linux9
-rw-r--r--auto/os/solaris3
-rw-r--r--auto/sources2
-rw-r--r--auto/types/sizeof3
-rw-r--r--auto/types/typedef2
-rw-r--r--auto/types/uintptr_t11
-rwxr-xr-xauto/unix75
-rw-r--r--src/core/nginx.c18
-rw-r--r--src/core/nginx.h4
-rw-r--r--src/core/ngx_cycle.h4
-rw-r--r--src/core/ngx_resolver.c6
-rw-r--r--src/http/modules/ngx_http_headers_filter_module.c44
-rw-r--r--src/http/modules/ngx_http_log_module.c14
-rw-r--r--src/http/modules/ngx_http_realip_module.c14
-rw-r--r--src/http/modules/ngx_http_split_clients_module.c19
-rw-r--r--src/http/modules/ngx_http_xslt_filter_module.c208
-rw-r--r--src/http/modules/perl/nginx.pm2
-rw-r--r--src/http/ngx_http_copy_filter_module.c7
-rw-r--r--src/http/ngx_http_core_module.c14
-rw-r--r--src/http/ngx_http_parse.c1
-rw-r--r--src/http/ngx_http_postpone_filter_module.c8
-rw-r--r--src/http/ngx_http_request.c4
-rw-r--r--src/http/ngx_http_upstream.c4
-rw-r--r--src/http/ngx_http_variables.c97
-rw-r--r--src/os/unix/ngx_files.h13
-rw-r--r--src/os/unix/ngx_freebsd_config.h1
-rw-r--r--src/os/unix/ngx_posix_config.h1
-rw-r--r--src/os/unix/ngx_process.h1
-rw-r--r--src/os/unix/ngx_process_cycle.c17
-rw-r--r--src/os/unix/ngx_setaffinity.c69
-rw-r--r--src/os/unix/ngx_setaffinity.h23
-rw-r--r--src/os/unix/ngx_solaris_config.h1
36 files changed, 597 insertions, 160 deletions
diff --git a/CHANGES b/CHANGES
index ce993c874..57eab3f40 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,27 @@
+Changes with nginx 1.1.18 28 Mar 2012
+
+ *) Change: keepalive connections are no longer disabled for Safari by
+ default.
+
+ *) Feature: the $connection_requests variable.
+
+ *) Feature: $tcpinfo_rtt, $tcpinfo_rttvar, $tcpinfo_snd_cwnd and
+ $tcpinfo_rcv_space variables.
+
+ *) Feature: the "worker_cpu_affinity" directive now works on FreeBSD.
+
+ *) Feature: the "xslt_param" and "xslt_string_param" directives.
+ Thanks to Samuel Behan.
+
+ *) Bugfix: in configure tests.
+ Thanks to Piotr Sikora.
+
+ *) Bugfix: in the ngx_http_xslt_filter_module.
+
+ *) Bugfix: nginx could not be built on Debian GNU/Hurd.
+
+
Changes with nginx 1.1.17 15 Mar 2012
*) Security: content of previously freed memory might be sent to a
diff --git a/CHANGES.ru b/CHANGES.ru
index 67122567b..cdca077a9 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,27 @@
+Изменения в nginx 1.1.18 28.03.2012
+
+ *) Изменение: теперь keepalive соединения не запрещены для Safari по
+ умолчанию.
+
+ *) Добавление: переменная $connection_requests.
+
+ *) Добавление: переменные $tcpinfo_rtt, $tcpinfo_rttvar,
+ $tcpinfo_snd_cwnd и $tcpinfo_rcv_space.
+
+ *) Добавление: директива worker_cpu_affinity теперь работает на FreeBSD.
+
+ *) Добавление: директивы xslt_param и xslt_string_param.
+ Спасибо Samuel Behan.
+
+ *) Исправление: в configure.
+ Спасибо Piotr Sikora.
+
+ *) Исправление: в модуле ngx_http_xslt_filter_module.
+
+ *) Исправление: nginx не собирался на Debian GNU/Hurd.
+
+
Изменения в nginx 1.1.17 15.03.2012
*) Безопасность: содержимое ранее освобождённой памяти могло быть
diff --git a/auto/lib/pcre/conf b/auto/lib/pcre/conf
index c56848d5d..6a8c326c4 100644
--- a/auto/lib/pcre/conf
+++ b/auto/lib/pcre/conf
@@ -98,7 +98,9 @@ else
ngx_feature_incs="#include <pcre.h>"
ngx_feature_path=
ngx_feature_libs="-lpcre"
- ngx_feature_test="pcre *re; re = pcre_compile(NULL, 0, NULL, 0, NULL)"
+ ngx_feature_test="pcre *re;
+ re = pcre_compile(NULL, 0, NULL, 0, NULL);
+ if (re == NULL) return 1"
. auto/feature
if [ $ngx_found = no ]; then
diff --git a/auto/os/freebsd b/auto/os/freebsd
index 88654ba60..6aa823f92 100644
--- a/auto/os/freebsd
+++ b/auto/os/freebsd
@@ -134,3 +134,11 @@ END
exit 1
fi
fi
+
+
+# cpuset_setaffinity()
+
+if [ $version -ge 701000 ]; then
+ echo " + cpuset_setaffinity() found"
+ have=NGX_HAVE_CPUSET_SETAFFINITY . auto/have
+fi
diff --git a/auto/os/linux b/auto/os/linux
index 0b2173cae..c506d3dc3 100644
--- a/auto/os/linux
+++ b/auto/os/linux
@@ -52,7 +52,7 @@ ngx_feature_run=yes
ngx_feature_incs="#include <sys/epoll.h>"
ngx_feature_path=
ngx_feature_libs=
-ngx_feature_test="int efd = 0, fd = 1, n;
+ngx_feature_test="int efd = 0;
struct epoll_event ee;
ee.events = EPOLLIN|EPOLLOUT|EPOLLET;
ee.data.ptr = NULL;
@@ -128,8 +128,9 @@ ngx_feature_run=no
ngx_feature_incs="#include <sched.h>"
ngx_feature_path=
ngx_feature_libs=
-ngx_feature_test="long mask = 0;
- sched_setaffinity(0, 32, (cpu_set_t *) &mask)"
+ngx_feature_test="cpu_set_t mask;
+ CPU_ZERO(&mask);
+ sched_setaffinity(0, sizeof(cpu_set_t), &mask)"
. auto/feature
@@ -142,7 +143,7 @@ ngx_feature_incs="#include <crypt.h>"
ngx_feature_path=
ngx_feature_libs=-lcrypt
ngx_feature_test="struct crypt_data cd;
- crypt_r(NULL, NULL, &cd);"
+ crypt_r(\"key\", \"salt\", &cd);"
. auto/feature
diff --git a/auto/os/solaris b/auto/os/solaris
index 16da4b3fd..d39df0bf7 100644
--- a/auto/os/solaris
+++ b/auto/os/solaris
@@ -35,7 +35,8 @@ ngx_feature_path=
ngx_feature_libs="-lsendfile"
ngx_feature_test="int fd = 1; sendfilevec_t vec[1];
size_t sent; ssize_t n;
- n = sendfilev(fd, vec, 1, &sent)"
+ n = sendfilev(fd, vec, 1, &sent);
+ if (n == -1) return 1"
. auto/feature
diff --git a/auto/sources b/auto/sources
index c48c3adf4..374ad667c 100644
--- a/auto/sources
+++ b/auto/sources
@@ -145,6 +145,7 @@ UNIX_DEPS="$CORE_DEPS $EVENT_DEPS \
src/os/unix/ngx_channel.h \
src/os/unix/ngx_shmem.h \
src/os/unix/ngx_process.h \
+ src/os/unix/ngx_setaffinity.h \
src/os/unix/ngx_setproctitle.h \
src/os/unix/ngx_atomic.h \
src/os/unix/ngx_gcc_atomic_x86.h \
@@ -179,6 +180,7 @@ UNIX_SRCS="$CORE_SRCS $EVENT_SRCS \
src/os/unix/ngx_shmem.c \
src/os/unix/ngx_process.c \
src/os/unix/ngx_daemon.c \
+ src/os/unix/ngx_setaffinity.c \
src/os/unix/ngx_setproctitle.c \
src/os/unix/ngx_posix_init.c \
src/os/unix/ngx_user.c \
diff --git a/auto/types/sizeof b/auto/types/sizeof
index e84a0905e..e1d405c65 100644
--- a/auto/types/sizeof
+++ b/auto/types/sizeof
@@ -20,12 +20,13 @@ cat << END > $NGX_AUTOTEST.c
#include <sys/time.h>
$NGX_INCLUDE_UNISTD_H
#include <signal.h>
+#include <stdio.h>
#include <sys/resource.h>
$NGX_INCLUDE_INTTYPES_H
$NGX_INCLUDE_AUTO_CONFIG_H
int main() {
- printf("%d", sizeof($ngx_type));
+ printf("%d", (int) sizeof($ngx_type));
return 0;
}
diff --git a/auto/types/typedef b/auto/types/typedef
index f121e8fc2..d81229331 100644
--- a/auto/types/typedef
+++ b/auto/types/typedef
@@ -29,7 +29,7 @@ $NGX_INCLUDE_INTTYPES_H
int main() {
$ngx_try i = 0;
- return 0;
+ return (int) i;
}
END
diff --git a/auto/types/uintptr_t b/auto/types/uintptr_t
index 07f7e7d7d..2f1908035 100644
--- a/auto/types/uintptr_t
+++ b/auto/types/uintptr_t
@@ -4,8 +4,8 @@
echo $ngx_n "checking for uintptr_t ...$ngx_c"
-echo >> $NGX_ERR
-echo "checking for uintptr_t" >> $NGX_ERR
+echo >> $NGX_AUTOCONF_ERR
+echo "checking for uintptr_t" >> $NGX_AUTOCONF_ERR
found=no
@@ -16,12 +16,15 @@ $NGX_INTTYPES_H
int main() {
uintptr_t i = 0;
- return 0;
+ return (int) i;
}
END
-eval "$CC -o $NGX_AUTOTEST $NGX_AUTOTEST.c >> $NGX_ERR 2>&1"
+ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS \
+ -o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_LD_OPT"
+
+eval "$ngx_test >> $NGX_AUTOCONF_ERR 2>&1"
if [ -x $NGX_AUTOTEST ]; then
echo " uintptr_t found"
diff --git a/auto/unix b/auto/unix
index d786bb433..783219e2d 100755
--- a/auto/unix
+++ b/auto/unix
@@ -33,12 +33,12 @@ ngx_feature_run=no
ngx_feature_incs="#include <poll.h>"
ngx_feature_path=
ngx_feature_libs=
-ngx_feature_test="int n, dp; struct pollfd pl;
- dp = 0;
+ngx_feature_test="int n; struct pollfd pl;
pl.fd = 0;
pl.events = 0;
pl.revents = 0;
- n = poll(&pl, 1, 0)"
+ n = poll(&pl, 1, 0);
+ if (n == -1) return 1"
. auto/feature
if [ $ngx_found = no ]; then
@@ -57,7 +57,8 @@ ngx_feature_test="int n, dp; struct dvpoll dvp;
dvp.dp_fds = NULL;
dvp.dp_nfds = 0;
dvp.dp_timeout = 0;
- n = ioctl(dp, DP_POLL, &dvp)"
+ n = ioctl(dp, DP_POLL, &dvp);
+ if (n == -1) return 1"
. auto/feature
if [ $ngx_found = yes ]; then
@@ -237,7 +238,7 @@ ngx_feature_incs="$NGX_INCLUDE_SYS_PARAM_H
ngx_feature_path=
ngx_feature_libs=
ngx_feature_test="struct statfs fs;
- statfs(NULL, &fs);"
+ statfs(\".\", &fs);"
. auto/feature
@@ -249,7 +250,7 @@ ngx_feature_incs="#include <sys/types.h>
ngx_feature_path=
ngx_feature_libs=
ngx_feature_test="struct statvfs fs;
- statvfs(NULL, &fs);"
+ statvfs(\".\", &fs);"
. auto/feature
@@ -343,6 +344,24 @@ ngx_feature_test="setsockopt(0, IPPROTO_TCP, TCP_KEEPIDLE, NULL, 0);
. auto/feature
+ngx_feature="TCP_INFO"
+ngx_feature_name="NGX_HAVE_TCP_INFO"
+ngx_feature_run=no
+ngx_feature_incs="#include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <netinet/tcp.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="socklen_t optlen = sizeof(struct tcp_info);
+ struct tcp_info ti;
+ ti.tcpi_rtt = 0;
+ ti.tcpi_rttvar = 0;
+ ti.tcpi_snd_cwnd = 0;
+ ti.tcpi_rcv_space = 0;
+ getsockopt(0, IPPROTO_TCP, TCP_INFO, &ti, &optlen)"
+. auto/feature
+
+
ngx_feature="accept4()"
ngx_feature_name="NGX_HAVE_ACCEPT4"
ngx_feature_run=no
@@ -481,7 +500,7 @@ fi
ngx_feature="setproctitle()"
ngx_feature_name="NGX_HAVE_SETPROCTITLE"
ngx_feature_run=no
-ngx_feature_incs=
+ngx_feature_incs="#include <stdlib.h>"
ngx_feature_path=
ngx_feature_libs=$NGX_SETPROCTITLE_LIB
ngx_feature_test="setproctitle(\"test\");"
@@ -494,7 +513,8 @@ ngx_feature_run=no
ngx_feature_incs=
ngx_feature_path=
ngx_feature_libs=
-ngx_feature_test="char buf[1]; ssize_t n; n = pread(0, buf, 1, 0)"
+ngx_feature_test="char buf[1]; ssize_t n; n = pread(0, buf, 1, 0);
+ if (n == -1) return 1"
. auto/feature
@@ -504,7 +524,8 @@ ngx_feature_run=no
ngx_feature_incs=
ngx_feature_path=
ngx_feature_libs=
-ngx_feature_test="char buf[1]; ssize_t n; n = pwrite(1, buf, 1, 0)"
+ngx_feature_test="char buf[1]; ssize_t n; n = pwrite(1, buf, 1, 0);
+ if (n == -1) return 1"
. auto/feature
@@ -578,17 +599,20 @@ ngx_feature_run=no
ngx_feature_incs="#include <stdlib.h>"
ngx_feature_path=
ngx_feature_libs=
-ngx_feature_test="void *p; int n; n = posix_memalign(&p, 4096, 4096)"
+ngx_feature_test="void *p; int n; n = posix_memalign(&p, 4096, 4096);
+ if (n != 0) return 1"
. auto/feature
ngx_feature="memalign()"
ngx_feature_name="NGX_HAVE_MEMALIGN"
ngx_feature_run=no
-ngx_feature_incs="#include <stdlib.h>"
+ngx_feature_incs="#include <stdlib.h>
+ #include <malloc.h>"
ngx_feature_path=
ngx_feature_libs=
-ngx_feature_test="void *p; p = memalign(4096, 4096)"
+ngx_feature_test="void *p; p = memalign(4096, 4096);
+ if (p == NULL) return 1"
. auto/feature
@@ -675,10 +699,12 @@ fi
ngx_feature="struct msghdr.msg_control"
ngx_feature_name="NGX_HAVE_MSGHDR_MSG_CONTROL"
ngx_feature_run=no
-ngx_feature_incs="#include <sys/socket.h>"
+ngx_feature_incs="#include <sys/socket.h>
+ #include <stdio.h>"
ngx_feature_path=
ngx_feature_libs=
-ngx_feature_test="struct msghdr msg; msg.msg_control = NULL"
+ngx_feature_test="struct msghdr msg;
+ printf(\"%d\", (int) sizeof(msg.msg_control))"
. auto/feature
@@ -686,40 +712,47 @@ ngx_feature="ioctl(FIONBIO)"
ngx_feature_name="NGX_HAVE_FIONBIO"
ngx_feature_run=no
ngx_feature_incs="#include <sys/ioctl.h>
+ #include <stdio.h>
$NGX_INCLUDE_SYS_FILIO_H"
ngx_feature_path=
ngx_feature_libs=
-ngx_feature_test="int i; i = FIONBIO"
+ngx_feature_test="int i = FIONBIO; printf(\"%d\", i)"
. auto/feature
ngx_feature="struct tm.tm_gmtoff"
ngx_feature_name="NGX_HAVE_GMTOFF"
ngx_feature_run=no
-ngx_feature_incs="#include <time.h>"
+ngx_feature_incs="#include <time.h>
+ #include <stdio.h>"
ngx_feature_path=
ngx_feature_libs=
-ngx_feature_test="struct tm tm; tm.tm_gmtoff = 0"
+ngx_feature_test="struct tm tm; tm.tm_gmtoff = 0;
+ printf(\"%d\", (int) tm.tm_gmtoff)"
. auto/feature
ngx_feature="struct dirent.d_namlen"
ngx_feature_name="NGX_HAVE_D_NAMLEN"
ngx_feature_run=no
-ngx_feature_incs="#include <dirent.h>"
+ngx_feature_incs="#include <dirent.h>
+ #include <stdio.h>"
ngx_feature_path=
ngx_feature_libs=
-ngx_feature_test="struct dirent dir; dir.d_namlen = 0"
+ngx_feature_test="struct dirent dir; dir.d_namlen = 0;
+ printf(\"%d\", (int) dir.d_namlen)"
. auto/feature
ngx_feature="struct dirent.d_type"
ngx_feature_name="NGX_HAVE_D_TYPE"
ngx_feature_run=no
-ngx_feature_incs="#include <dirent.h>"
+ngx_feature_incs="#include <dirent.h>
+ #include <stdio.h>"
ngx_feature_path=
ngx_feature_libs=
-ngx_feature_test="struct dirent dir; dir.d_type = DT_REG"
+ngx_feature_test="struct dirent dir; dir.d_type = DT_REG;
+ printf(\"%d\", (int) dir.d_type)"
. auto/feature
diff --git a/src/core/nginx.c b/src/core/nginx.c
index e8fcbaeba..19feb0700 100644
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -983,15 +983,15 @@ ngx_core_module_init_conf(ngx_cycle_t *cycle, void *conf)
ngx_conf_init_value(ccf->worker_processes, 1);
ngx_conf_init_value(ccf->debug_points, 0);
-#if (NGX_HAVE_SCHED_SETAFFINITY)
+#if (NGX_HAVE_CPU_AFFINITY)
if (ccf->cpu_affinity_n
&& ccf->cpu_affinity_n != 1
&& ccf->cpu_affinity_n != (ngx_uint_t) ccf->worker_processes)
{
ngx_log_error(NGX_LOG_WARN, cycle->log, 0,
- "number of the \"worker_processes\" is not equal to "
- "the number of the \"worker_cpu_affinity\" mask, "
+ "the number of \"worker_processes\" is not equal to "
+ "the number of \"worker_cpu_affinity\" masks, "
"using last mask for remaining worker processes");
}
@@ -1242,11 +1242,11 @@ ngx_set_priority(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
static char *
ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
-#if (NGX_HAVE_SCHED_SETAFFINITY)
+#if (NGX_HAVE_CPU_AFFINITY)
ngx_core_conf_t *ccf = conf;
u_char ch;
- u_long *mask;
+ uint64_t *mask;
ngx_str_t *value;
ngx_uint_t i, n;
@@ -1254,7 +1254,7 @@ ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return "is duplicate";
}
- mask = ngx_palloc(cf->pool, (cf->args->nelts - 1) * sizeof(long));
+ mask = ngx_palloc(cf->pool, (cf->args->nelts - 1) * sizeof(uint64_t));
if (mask == NULL) {
return NGX_CONF_ERROR;
}
@@ -1266,9 +1266,9 @@ ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
for (n = 1; n < cf->args->nelts; n++) {
- if (value[n].len > 32) {
+ if (value[n].len > 64) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"worker_cpu_affinity\" supports up to 32 CPU only");
+ "\"worker_cpu_affinity\" supports up to 64 CPUs only");
return NGX_CONF_ERROR;
}
@@ -1311,7 +1311,7 @@ ngx_set_cpu_affinity(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
-u_long
+uint64_t
ngx_get_cpu_affinity(ngx_uint_t n)
{
ngx_core_conf_t *ccf;
diff --git a/src/core/nginx.h b/src/core/nginx.h
index cd27398dd..f23bbf4d0 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -9,8 +9,8 @@
#define _NGINX_H_INCLUDED_
-#define nginx_version 1001017
-#define NGINX_VERSION "1.1.17"
+#define nginx_version 1001018
+#define NGINX_VERSION "1.1.18"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
diff --git a/src/core/ngx_cycle.h b/src/core/ngx_cycle.h
index dbc6e195e..551b6288e 100644
--- a/src/core/ngx_cycle.h
+++ b/src/core/ngx_cycle.h
@@ -86,7 +86,7 @@ typedef struct {
int priority;
ngx_uint_t cpu_affinity_n;
- u_long *cpu_affinity;
+ uint64_t *cpu_affinity;
char *username;
ngx_uid_t user;
@@ -124,7 +124,7 @@ ngx_int_t ngx_signal_process(ngx_cycle_t *cycle, char *sig);
void ngx_reopen_files(ngx_cycle_t *cycle, ngx_uid_t user);
char **ngx_set_environment(ngx_cycle_t *cycle, ngx_uint_t *last);
ngx_pid_t ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv);
-u_long ngx_get_cpu_affinity(ngx_uint_t n);
+uint64_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);
diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c
index 2e3047135..02c484da6 100644
--- a/src/core/ngx_resolver.c
+++ b/src/core/ngx_resolver.c
@@ -1840,7 +1840,7 @@ ngx_resolver_create_name_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
len++;
} else {
- if (len == 0) {
+ if (len == 0 || len > 255) {
return NGX_DECLINED;
}
@@ -1851,6 +1851,10 @@ ngx_resolver_create_name_query(ngx_resolver_node_t *rn, ngx_resolver_ctx_t *ctx)
p--;
}
+ if (len == 0 || len > 255) {
+ return NGX_DECLINED;
+ }
+
*p = (u_char) len;
return NGX_OK;
diff --git a/src/http/modules/ngx_http_headers_filter_module.c b/src/http/modules/ngx_http_headers_filter_module.c
index e6cf3f423..938993434 100644
--- a/src/http/modules/ngx_http_headers_filter_module.c
+++ b/src/http/modules/ngx_http_headers_filter_module.c
@@ -25,23 +25,25 @@ typedef struct {
struct ngx_http_header_val_s {
ngx_http_complex_value_t value;
- ngx_uint_t hash;
ngx_str_t key;
ngx_http_set_header_pt handler;
ngx_uint_t offset;
};
-#define NGX_HTTP_EXPIRES_OFF 0
-#define NGX_HTTP_EXPIRES_EPOCH 1
-#define NGX_HTTP_EXPIRES_MAX 2
-#define NGX_HTTP_EXPIRES_ACCESS 3
-#define NGX_HTTP_EXPIRES_MODIFIED 4
-#define NGX_HTTP_EXPIRES_DAILY 5
+typedef enum {
+ NGX_HTTP_EXPIRES_OFF,
+ NGX_HTTP_EXPIRES_EPOCH,
+ NGX_HTTP_EXPIRES_MAX,
+ NGX_HTTP_EXPIRES_ACCESS,
+ NGX_HTTP_EXPIRES_MODIFIED,
+ NGX_HTTP_EXPIRES_DAILY,
+ NGX_HTTP_EXPIRES_UNSET
+} ngx_http_expires_t;
typedef struct {
- ngx_uint_t expires;
+ ngx_http_expires_t expires;
time_t expires_time;
ngx_array_t *headers;
} ngx_http_headers_conf_t;
@@ -51,6 +53,8 @@ static ngx_int_t ngx_http_set_expires(ngx_http_request_t *r,
ngx_http_headers_conf_t *conf);
static ngx_int_t ngx_http_add_cache_control(ngx_http_request_t *r,
ngx_http_header_val_t *hv, ngx_str_t *value);
+static ngx_int_t ngx_http_add_header(ngx_http_request_t *r,
+ ngx_http_header_val_t *hv, ngx_str_t *value);
static ngx_int_t ngx_http_set_last_modified(ngx_http_request_t *r,
ngx_http_header_val_t *hv, ngx_str_t *value);
@@ -313,7 +317,7 @@ ngx_http_add_header(ngx_http_request_t *r, ngx_http_header_val_t *hv,
return NGX_ERROR;
}
- h->hash = hv->hash;
+ h->hash = 1;
h->key = hv->key;
h->value = *value;
}
@@ -366,16 +370,11 @@ ngx_http_set_last_modified(ngx_http_request_t *r, ngx_http_header_val_t *hv,
{
ngx_table_elt_t *h, **old;
- if (hv->offset) {
- old = (ngx_table_elt_t **) ((char *) &r->headers_out + hv->offset);
-
- } else {
- old = NULL;
- }
+ old = (ngx_table_elt_t **) ((char *) &r->headers_out + hv->offset);
r->headers_out.last_modified_time = -1;
- if (old == NULL || *old == NULL) {
+ if (*old == NULL) {
if (value->len == 0) {
return NGX_OK;
@@ -386,6 +385,8 @@ ngx_http_set_last_modified(ngx_http_request_t *r, ngx_http_header_val_t *hv,
return NGX_ERROR;
}
+ *old = h;
+
} else {
h = *old;
@@ -395,7 +396,7 @@ ngx_http_set_last_modified(ngx_http_request_t *r, ngx_http_header_val_t *hv,
}
}
- h->hash = hv->hash;
+ h->hash = 1;
h->key = hv->key;
h->value = *value;
@@ -420,7 +421,7 @@ ngx_http_headers_create_conf(ngx_conf_t *cf)
* conf->expires_time = 0;
*/
- conf->expires = NGX_CONF_UNSET_UINT;
+ conf->expires = NGX_HTTP_EXPIRES_UNSET;
return conf;
}
@@ -432,11 +433,11 @@ ngx_http_headers_merge_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_http_headers_conf_t *prev = parent;
ngx_http_headers_conf_t *conf = child;
- if (conf->expires == NGX_CONF_UNSET_UINT) {
+ if (conf->expires == NGX_HTTP_EXPIRES_UNSET) {
conf->expires = prev->expires;
conf->expires_time = prev->expires_time;
- if (conf->expires == NGX_CONF_UNSET_UINT) {
+ if (conf->expires == NGX_HTTP_EXPIRES_UNSET) {
conf->expires = NGX_HTTP_EXPIRES_OFF;
}
}
@@ -467,7 +468,7 @@ ngx_http_headers_expires(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_uint_t minus, n;
ngx_str_t *value;
- if (hcf->expires != NGX_CONF_UNSET_UINT) {
+ if (hcf->expires != NGX_HTTP_EXPIRES_UNSET) {
return "is duplicate";
}
@@ -576,7 +577,6 @@ ngx_http_headers_add(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}
- hv->hash = 1;
hv->key = value[1];
hv->handler = ngx_http_add_header;
hv->offset = 0;
diff --git a/src/http/modules/ngx_http_log_module.c b/src/http/modules/ngx_http_log_module.c
index 2452f23b3..2d412853b 100644
--- a/src/http/modules/ngx_http_log_module.c
+++ b/src/http/modules/ngx_http_log_module.c
@@ -80,6 +80,8 @@ static ssize_t ngx_http_log_script_write(ngx_http_request_t *r,
static u_char *ngx_http_log_connection(ngx_http_request_t *r, u_char *buf,
ngx_http_log_op_t *op);
+static u_char *ngx_http_log_connection_requests(ngx_http_request_t *r,
+ u_char *buf, ngx_http_log_op_t *op);
static u_char *ngx_http_log_pipe(ngx_http_request_t *r, u_char *buf,
ngx_http_log_op_t *op);
static u_char *ngx_http_log_time(ngx_http_request_t *r, u_char *buf,
@@ -193,6 +195,8 @@ static ngx_str_t ngx_http_combined_fmt =
static ngx_http_log_var_t ngx_http_log_vars[] = {
{ ngx_string("connection"), NGX_ATOMIC_T_LEN, ngx_http_log_connection },
+ { ngx_string("connection_requests"), NGX_INT_T_LEN,
+ ngx_http_log_connection_requests },
{ ngx_string("pipe"), 1, ngx_http_log_pipe },
{ ngx_string("time_local"), sizeof("28/Sep/1970:12:00:00 +0600") - 1,
ngx_http_log_time },
@@ -501,7 +505,15 @@ static u_char *
ngx_http_log_connection(ngx_http_request_t *r, u_char *buf,
ngx_http_log_op_t *op)
{
- return ngx_sprintf(buf, "%ui", r->connection->number);
+ return ngx_sprintf(buf, "%uA", r->connection->number);
+}
+
+
+static u_char *
+ngx_http_log_connection_requests(ngx_http_request_t *r, u_char *buf,
+ ngx_http_log_op_t *op)
+{
+ return ngx_sprintf(buf, "%ui", r->connection->requests);
}
diff --git a/src/http/modules/ngx_http_realip_module.c b/src/http/modules/ngx_http_realip_module.c
index bb606beb7..c54c2ffa1 100644
--- a/src/http/modules/ngx_http_realip_module.c
+++ b/src/http/modules/ngx_http_realip_module.c
@@ -16,13 +16,7 @@
typedef struct {
- in_addr_t mask;
- in_addr_t addr;
-} ngx_http_realip_from_t;
-
-
-typedef struct {
- ngx_array_t *from; /* array of ngx_http_realip_from_t */
+ ngx_array_t *from; /* array of ngx_in_cidr_t */
ngx_uint_t type;
ngx_uint_t hash;
ngx_str_t header;
@@ -114,9 +108,9 @@ ngx_http_realip_handler(ngx_http_request_t *r)
ngx_list_part_t *part;
ngx_table_elt_t *header;
struct sockaddr_in *sin;
+ ngx_in_cidr_t *from;
ngx_connection_t *c;
ngx_http_realip_ctx_t *ctx;
- ngx_http_realip_from_t *from;
ngx_http_realip_loc_conf_t *rlcf;
ctx = ngx_http_get_module_ctx(r, ngx_http_realip_module);
@@ -317,7 +311,7 @@ ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_int_t rc;
ngx_str_t *value;
ngx_cidr_t cidr;
- ngx_http_realip_from_t *from;
+ ngx_in_cidr_t *from;
value = cf->args->elts;
@@ -332,7 +326,7 @@ ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
if (rlcf->from == NULL) {
rlcf->from = ngx_array_create(cf->pool, 2,
- sizeof(ngx_http_realip_from_t));
+ sizeof(ngx_in_cidr_t));
if (rlcf->from == NULL) {
return NGX_CONF_ERROR;
}
diff --git a/src/http/modules/ngx_http_split_clients_module.c b/src/http/modules/ngx_http_split_clients_module.c
index f2160b149..6b1a8155a 100644
--- a/src/http/modules/ngx_http_split_clients_module.c
+++ b/src/http/modules/ngx_http_split_clients_module.c
@@ -97,7 +97,7 @@ ngx_http_split_clients_variable(ngx_http_request_t *r,
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http split: %uD %uD", hash, part[i].percent);
- if (hash < part[i].percent) {
+ if (hash < part[i].percent || part[i].percent == 0) {
*v = part[i].value;
return NGX_OK;
}
@@ -111,8 +111,9 @@ static char *
ngx_conf_split_clients_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
char *rv;
+ uint32_t sum, last;
ngx_str_t *value, name;
- ngx_uint_t i, sum, last;
+ ngx_uint_t i;
ngx_conf_t save;
ngx_http_variable_t *var;
ngx_http_split_clients_ctx_t *ctx;
@@ -175,19 +176,15 @@ ngx_conf_split_clients_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
for (i = 0; i < ctx->parts.nelts; i++) {
sum = part[i].percent ? sum + part[i].percent : 10000;
if (sum > 10000) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "percent sum is more than 100%%");
- return NGX_CONF_ERROR;
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "percent sum is more than 100%%");
+ return NGX_CONF_ERROR;
}
if (part[i].percent) {
- part[i].percent = (uint32_t)
- (last + 0xffffffff / 10000 * part[i].percent);
- } else {
- part[i].percent = 0xffffffff;
+ last += part[i].percent * (uint64_t) 0xffffffff / 10000;
+ part[i].percent = last;
}
-
- last = part[i].percent;
}
return rv;
diff --git a/src/http/modules/ngx_http_xslt_filter_module.c b/src/http/modules/ngx_http_xslt_filter_module.c
index f86c30381..4309a4489 100644
--- a/src/http/modules/ngx_http_xslt_filter_module.c
+++ b/src/http/modules/ngx_http_xslt_filter_module.c
@@ -14,6 +14,7 @@
#include <libxslt/xslt.h>
#include <libxslt/xsltInternals.h>
#include <libxslt/transform.h>
+#include <libxslt/variables.h>
#include <libxslt/xsltutils.h>
#if (NGX_HAVE_EXSLT)
@@ -27,38 +28,47 @@
typedef struct {
- u_char *name;
- void *data;
+ u_char *name;
+ void *data;
} ngx_http_xslt_file_t;
typedef struct {
- ngx_array_t dtd_files; /* ngx_http_xslt_file_t */
- ngx_array_t sheet_files; /* ngx_http_xslt_file_t */
+ ngx_array_t dtd_files; /* ngx_http_xslt_file_t */
+ ngx_array_t sheet_files; /* ngx_http_xslt_file_t */
} ngx_http_xslt_filter_main_conf_t;
typedef struct {
- xsltStylesheetPtr stylesheet;
- ngx_array_t params; /* ngx_http_complex_value_t */
+ u_char *name;
+ ngx_http_complex_value_t value;
+ ngx_uint_t quote; /* unsigned quote:1; */
+} ngx_http_xslt_param_t;
+
+
+typedef struct {
+ xsltStylesheetPtr stylesheet;
+ ngx_array_t params; /* ngx_http_xslt_param_t */
} ngx_http_xslt_sheet_t;
typedef struct {
- xmlDtdPtr dtd;
- ngx_array_t sheets; /* ngx_http_xslt_sheet_t */
- ngx_hash_t types;
- ngx_array_t *types_keys;
+ xmlDtdPtr dtd;
+ ngx_array_t sheets; /* ngx_http_xslt_sheet_t */
+ ngx_hash_t types;
+ ngx_array_t *types_keys;
+ ngx_array_t *params; /* ngx_http_xslt_param_t */
} ngx_http_xslt_filter_loc_conf_t;
typedef struct {
- xmlDocPtr doc;
- xmlParserCtxtPtr ctxt;
- ngx_http_request_t *request;
- ngx_array_t params;
+ xmlDocPtr doc;
+ xmlParserCtxtPtr ctxt;
+ xsltTransformContextPtr transform;
+ ngx_http_request_t *request;
+ ngx_array_t params;
- ngx_uint_t done; /* unsigned done:1; */
+ ngx_uint_t done; /* unsigned done:1; */
} ngx_http_xslt_filter_ctx_t;
@@ -76,7 +86,7 @@ static void ngx_cdecl ngx_http_xslt_sax_error(void *data, const char *msg, ...);
static ngx_buf_t *ngx_http_xslt_apply_stylesheet(ngx_http_request_t *r,
ngx_http_xslt_filter_ctx_t *ctx);
static ngx_int_t ngx_http_xslt_params(ngx_http_request_t *r,
- ngx_http_xslt_filter_ctx_t *ctx, ngx_array_t *params);
+ ngx_http_xslt_filter_ctx_t *ctx, ngx_array_t *params, ngx_uint_t final);
static u_char *ngx_http_xslt_content_type(xsltStylesheetPtr s);
static u_char *ngx_http_xslt_encoding(xsltStylesheetPtr s);
static void ngx_http_xslt_cleanup(void *data);
@@ -85,6 +95,8 @@ static char *ngx_http_xslt_entities(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char *ngx_http_xslt_stylesheet(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
+static char *ngx_http_xslt_param(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
static void ngx_http_xslt_cleanup_dtd(void *data);
static void ngx_http_xslt_cleanup_stylesheet(void *data);
static void *ngx_http_xslt_filter_create_main_conf(ngx_conf_t *cf);
@@ -117,6 +129,20 @@ static ngx_command_t ngx_http_xslt_filter_commands[] = {
0,
NULL },
+ { ngx_string("xslt_param"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
+ ngx_http_xslt_param,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ 0,
+ NULL },
+
+ { ngx_string("xslt_string_param"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
+ ngx_http_xslt_param,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ 0,
+ (void *) 1 },
+
{ ngx_string("xslt_types"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
ngx_http_types_slot,
@@ -336,15 +362,14 @@ ngx_http_xslt_add_chunk(ngx_http_request_t *r, ngx_http_xslt_filter_ctx_t *ctx,
"xmlCreatePushParserCtxt() failed");
return NGX_ERROR;
}
+ xmlCtxtUseOptions(ctxt, XML_PARSE_NOENT|XML_PARSE_DTDLOAD
+ |XML_PARSE_NOWARNING);
ctxt->sax->externalSubset = ngx_http_xslt_sax_external_subset;
ctxt->sax->setDocumentLocator = NULL;
- ctxt->sax->warning = NULL;
ctxt->sax->error = ngx_http_xslt_sax_error;
ctxt->sax->fatalError = ngx_http_xslt_sax_error;
ctxt->sax->_private = ctx;
- ctxt->replaceEntities = 1;
- ctxt->loadsubset = 1;
ctx->ctxt = ctxt;
ctx->request = r;
@@ -469,13 +494,31 @@ ngx_http_xslt_apply_stylesheet(ngx_http_request_t *r,
for (i = 0; i < conf->sheets.nelts; i++) {
- if (ngx_http_xslt_params(r, ctx, &sheet[i].params) != NGX_OK) {
+ ctx->transform = xsltNewTransformContext(sheet[i].stylesheet, doc);
+ if (ctx->transform == NULL) {
xmlFreeDoc(doc);
return NULL;
}
- res = xsltApplyStylesheet(sheet[i].stylesheet, doc, ctx->params.elts);
+ if (conf->params
+ && ngx_http_xslt_params(r, ctx, conf->params, 0) != NGX_OK)
+ {
+ xsltFreeTransformContext(ctx->transform);
+ xmlFreeDoc(doc);
+ return NULL;
+ }
+ if (ngx_http_xslt_params(r, ctx, &sheet[i].params, 1) != NGX_OK) {
+ xsltFreeTransformContext(ctx->transform);
+ xmlFreeDoc(doc);
+ return NULL;
+ }
+
+ res = xsltApplyStylesheetUser(sheet[i].stylesheet, doc,
+ ctx->params.elts, NULL, NULL,
+ ctx->transform);
+
+ xsltFreeTransformContext(ctx->transform);
xmlFreeDoc(doc);
if (res == NULL) {
@@ -565,27 +608,68 @@ ngx_http_xslt_apply_stylesheet(ngx_http_request_t *r,
static ngx_int_t
ngx_http_xslt_params(ngx_http_request_t *r, ngx_http_xslt_filter_ctx_t *ctx,
- ngx_array_t *params)
+ ngx_array_t *params, ngx_uint_t final)
{
- u_char *p, *last, *value, *dst, *src, **s;
- size_t len;
- ngx_uint_t i;
- ngx_str_t string;
- ngx_http_complex_value_t *param;
+ u_char *p, *last, *value, *dst, *src, **s;
+ size_t len;
+ ngx_uint_t i;
+ ngx_str_t string;
+ ngx_http_xslt_param_t *param;
param = params->elts;
for (i = 0; i < params->nelts; i++) {
- if (ngx_http_complex_value(r, &param[i], &string) != NGX_OK) {
+ if (ngx_http_complex_value(r, &param[i].value, &string) != NGX_OK) {
return NGX_ERROR;
}
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"xslt filter param: \"%s\"", string.data);
+ if (param[i].name) {
+
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "xslt filter param name: \"%s\"", param[i].name);
+
+ if (param[i].quote) {
+ if (xsltQuoteOneUserParam(ctx->transform, param[i].name,
+ string.data)
+ != 0)
+ {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "xsltQuoteOneUserParam(\"%s\", \"%s\") failed",
+ param[i].name, string.data);
+ return NGX_ERROR;
+ }
+
+ continue;
+ }
+
+ s = ngx_array_push(&ctx->params);
+ if (s == NULL) {
+ return NGX_ERROR;
+ }
+
+ *s = param[i].name;
+
+ s = ngx_array_push(&ctx->params);
+ if (s == NULL) {
+ return NGX_ERROR;
+ }
+
+ *s = string.data;
+
+ continue;
+ }
+
+ /*
+ * parse param1=value1:param2=value2 syntax as used by parameters
+ * specified in xslt_stylesheet directives
+ */
+
p = string.data;
- last = string.data + string.len - 1;
+ last = string.data + string.len;
while (p && *p) {
@@ -641,12 +725,14 @@ ngx_http_xslt_params(ngx_http_request_t *r, ngx_http_xslt_filter_ctx_t *ctx,
}
}
- s = ngx_array_push(&ctx->params);
- if (s == NULL) {
- return NGX_ERROR;
- }
+ if (final) {
+ s = ngx_array_push(&ctx->params);
+ if (s == NULL) {
+ return NGX_ERROR;
+ }
- *s = NULL;
+ *s = NULL;
+ }
return NGX_OK;
}
@@ -768,7 +854,7 @@ ngx_http_xslt_stylesheet(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_pool_cleanup_t *cln;
ngx_http_xslt_file_t *file;
ngx_http_xslt_sheet_t *sheet;
- ngx_http_complex_value_t *param;
+ ngx_http_xslt_param_t *param;
ngx_http_compile_complex_value_t ccv;
ngx_http_xslt_filter_main_conf_t *xmcf;
@@ -837,7 +923,7 @@ found:
}
if (ngx_array_init(&sheet->params, cf->pool, n - 2,
- sizeof(ngx_http_complex_value_t))
+ sizeof(ngx_http_xslt_param_t))
!= NGX_OK)
{
return NGX_CONF_ERROR;
@@ -850,11 +936,12 @@ found:
return NGX_CONF_ERROR;
}
+ ngx_memzero(param, sizeof(ngx_http_xslt_param_t));
ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
ccv.cf = cf;
ccv.value = &value[i];
- ccv.complex_value = param;
+ ccv.complex_value = &param->value;
ccv.zero = 1;
if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
@@ -866,6 +953,48 @@ found:
}
+static char *
+ngx_http_xslt_param(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_http_xslt_filter_loc_conf_t *xlcf = conf;
+
+ ngx_http_xslt_param_t *param;
+ ngx_http_compile_complex_value_t ccv;
+ ngx_str_t *value;
+
+ value = cf->args->elts;
+
+ if (xlcf->params == NULL) {
+ xlcf->params = ngx_array_create(cf->pool, 2,
+ sizeof(ngx_http_xslt_param_t));
+ if (xlcf->params == NULL) {
+ return NGX_CONF_ERROR;
+ }
+ }
+
+ param = ngx_array_push(xlcf->params);
+ if (param == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ param->name = value[1].data;
+ param->quote = (cmd->post == NULL) ? 0 : 1;
+
+ ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
+
+ ccv.cf = cf;
+ ccv.value = &value[2];
+ ccv.complex_value = &param->value;
+ ccv.zero = 1;
+
+ if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ return NGX_CONF_OK;
+}
+
+
static void
ngx_http_xslt_cleanup_dtd(void *data)
{
@@ -925,6 +1054,7 @@ ngx_http_xslt_filter_create_conf(ngx_conf_t *cf)
* conf->sheets = { NULL };
* conf->types = { NULL };
* conf->types_keys = NULL;
+ * conf->params = NULL;
*/
return conf;
@@ -945,6 +1075,10 @@ ngx_http_xslt_filter_merge_conf(ngx_conf_t *cf, void *parent, void *child)
conf->sheets = prev->sheets;
}
+ if (conf->params == NULL) {
+ conf->params = prev->params;
+ }
+
if (ngx_http_merge_types(cf, &conf->types_keys, &conf->types,
&prev->types_keys, &prev->types,
ngx_http_xslt_default_types)
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index 7a9cd4ed7..364f70897 100644
--- a/src/http/modules/perl/nginx.pm
+++ b/src/http/modules/perl/nginx.pm
@@ -50,7 +50,7 @@ our @EXPORT = qw(
HTTP_INSUFFICIENT_STORAGE
);
-our $VERSION = '1.1.17';
+our $VERSION = '1.1.18';
require XSLoader;
XSLoader::load('nginx', $VERSION);
diff --git a/src/http/ngx_http_copy_filter_module.c b/src/http/ngx_http_copy_filter_module.c
index d52fbebe8..95bc0b835 100644
--- a/src/http/ngx_http_copy_filter_module.c
+++ b/src/http/ngx_http_copy_filter_module.c
@@ -74,7 +74,7 @@ ngx_module_t ngx_http_copy_filter_module = {
};
-static ngx_http_output_body_filter_pt ngx_http_next_filter;
+static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
static ngx_int_t
@@ -115,7 +115,8 @@ ngx_http_copy_filter(ngx_http_request_t *r, ngx_chain_t *in)
ctx->bufs = conf->bufs;
ctx->tag = (ngx_buf_tag_t) &ngx_http_copy_filter_module;
- ctx->output_filter = (ngx_output_chain_filter_pt) ngx_http_next_filter;
+ ctx->output_filter = (ngx_output_chain_filter_pt)
+ ngx_http_next_body_filter;
ctx->filter_ctx = r;
#if (NGX_HAVE_FILE_AIO)
@@ -292,7 +293,7 @@ ngx_http_copy_filter_merge_conf(ngx_conf_t *cf, void *parent, void *child)
static ngx_int_t
ngx_http_copy_filter_init(ngx_conf_t *cf)
{
- ngx_http_next_filter = ngx_http_top_body_filter;
+ ngx_http_next_body_filter = ngx_http_top_body_filter;
ngx_http_top_body_filter = ngx_http_copy_filter;
return NGX_OK;
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 7504a2c64..f0ba7c705 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -3568,8 +3568,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_bitmask_value(conf->keepalive_disable,
prev->keepalive_disable,
(NGX_CONF_BITMASK_SET
- |NGX_HTTP_KEEPALIVE_DISABLE_MSIE6
- |NGX_HTTP_KEEPALIVE_DISABLE_SAFARI));
+ |NGX_HTTP_KEEPALIVE_DISABLE_MSIE6));
ngx_conf_merge_uint_value(conf->satisfy, prev->satisfy,
NGX_HTTP_SATISFY_ALL);
ngx_conf_merge_uint_value(conf->if_modified_since, prev->if_modified_since,
@@ -4647,7 +4646,7 @@ ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_core_loc_conf_t *clcf = conf;
- ngx_str_t *value;
+ ngx_str_t *value, name;
if (clcf->error_log) {
return "is duplicate";
@@ -4655,7 +4654,14 @@ ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
value = cf->args->elts;
- clcf->error_log = ngx_log_create(cf->cycle, &value[1]);
+ if (ngx_strcmp(value[1].data, "stderr") == 0) {
+ ngx_str_null(&name);
+
+ } else {
+ name = value[1];
+ }
+
+ clcf->error_log = ngx_log_create(cf->cycle, &name);
if (clcf->error_log == NULL) {
return NGX_CONF_ERROR;
}
diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c
index 876a437af..ace6cfe9a 100644
--- a/src/http/ngx_http_parse.c
+++ b/src/http/ngx_http_parse.c
@@ -1153,6 +1153,7 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r, ngx_uint_t merge_slashes)
break;
case '+':
r->plus_in_uri = 1;
+ /* fall through */
default:
*u++ = ch;
break;
diff --git a/src/http/ngx_http_postpone_filter_module.c b/src/http/ngx_http_postpone_filter_module.c
index cf49b2fa8..85c4b84d0 100644
--- a/src/http/ngx_http_postpone_filter_module.c
+++ b/src/http/ngx_http_postpone_filter_module.c
@@ -46,7 +46,7 @@ ngx_module_t ngx_http_postpone_filter_module = {
};
-static ngx_http_output_body_filter_pt ngx_http_next_filter;
+static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
static ngx_int_t
@@ -80,7 +80,7 @@ ngx_http_postpone_filter(ngx_http_request_t *r, ngx_chain_t *in)
if (r->postponed == NULL) {
if (in || c->buffered) {
- return ngx_http_next_filter(r->main, in);
+ return ngx_http_next_body_filter(r->main, in);
}
return NGX_OK;
@@ -116,7 +116,7 @@ ngx_http_postpone_filter(ngx_http_request_t *r, ngx_chain_t *in)
"http postpone filter output \"%V?%V\"",
&r->uri, &r->args);
- if (ngx_http_next_filter(r->main, pr->out) == NGX_ERROR) {
+ if (ngx_http_next_body_filter(r->main, pr->out) == NGX_ERROR) {
return NGX_ERROR;
}
}
@@ -171,7 +171,7 @@ found:
static ngx_int_t
ngx_http_postpone_filter_init(ngx_conf_t *cf)
{
- ngx_http_next_filter = ngx_http_top_body_filter;
+ ngx_http_next_body_filter = ngx_http_top_body_filter;
ngx_http_top_body_filter = ngx_http_postpone_filter;
return NGX_OK;
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index a8515f376..441517ea4 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -1493,7 +1493,9 @@ ngx_http_process_user_agent(ngx_http_request_t *r, ngx_table_elt_t *h,
} else if (ngx_strstrn(user_agent, "Chrome/", 7 - 1)) {
r->headers_in.chrome = 1;
- } else if (ngx_strstrn(user_agent, "Safari/", 7 - 1)) {
+ } else if (ngx_strstrn(user_agent, "Safari/", 7 - 1)
+ && ngx_strstrn(user_agent, "Mac OS X", 8 - 1))
+ {
r->headers_in.safari = 1;
} else if (ngx_strstrn(user_agent, "Konqueror", 9 - 1)) {
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index 7e368c1c1..a5ed15c42 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -3312,6 +3312,8 @@ ngx_http_upstream_process_accel_expires(ngx_http_request_t *r,
switch (n) {
case 0:
u->cacheable = 0;
+ /* fall through */
+
case NGX_ERROR:
return NGX_OK;
@@ -4460,6 +4462,8 @@ ngx_http_upstream_bind_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
case NGX_DECLINED:
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"invalid address \"%V\"", &value[1]);
+ /* fall through */
+
default:
return NGX_CONF_ERROR;
}
diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c
index 78cfa234a..744bd0b68 100644
--- a/src/http/ngx_http_variables.c
+++ b/src/http/ngx_http_variables.c
@@ -34,6 +34,10 @@ static ngx_int_t ngx_http_variable_cookie(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_variable_argument(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
+#if (NGX_HAVE_TCP_INFO)
+static ngx_int_t ngx_http_variable_tcpinfo(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data);
+#endif
static ngx_int_t ngx_http_variable_host(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
@@ -259,6 +263,20 @@ static ngx_http_variable_t ngx_http_core_variables[] = {
{ ngx_string("pid"), NULL, ngx_http_variable_pid,
0, 0, 0 },
+#if (NGX_HAVE_TCP_INFO)
+ { ngx_string("tcpinfo_rtt"), NULL, ngx_http_variable_tcpinfo,
+ 0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
+
+ { ngx_string("tcpinfo_rttvar"), NULL, ngx_http_variable_tcpinfo,
+ 1, NGX_HTTP_VAR_NOCACHEABLE, 0 },
+
+ { ngx_string("tcpinfo_snd_cwnd"), NULL, ngx_http_variable_tcpinfo,
+ 2, NGX_HTTP_VAR_NOCACHEABLE, 0 },
+
+ { ngx_string("tcpinfo_rcv_space"), NULL, ngx_http_variable_tcpinfo,
+ 3, NGX_HTTP_VAR_NOCACHEABLE, 0 },
+#endif
+
{ ngx_null_string, NULL, NULL, 0, 0, 0 }
};
@@ -384,7 +402,7 @@ ngx_http_get_variable_index(ngx_conf_t *cf, ngx_str_t *name)
v->flags = 0;
v->index = cmcf->variables.nelts - 1;
- return cmcf->variables.nelts - 1;
+ return v->index;
}
@@ -884,6 +902,61 @@ ngx_http_variable_argument(ngx_http_request_t *r, ngx_http_variable_value_t *v,
}
+#if (NGX_HAVE_TCP_INFO)
+
+static ngx_int_t
+ngx_http_variable_tcpinfo(ngx_http_request_t *r, ngx_http_variable_value_t *v,
+ uintptr_t data)
+{
+ struct tcp_info ti;
+ socklen_t len;
+ uint32_t value;
+
+ len = sizeof(struct tcp_info);
+ if (getsockopt(r->connection->fd, IPPROTO_TCP, TCP_INFO, &ti, &len) == -1) {
+ v->not_found = 1;
+ return NGX_OK;
+ }
+
+ v->data = ngx_pnalloc(r->pool, NGX_INT32_LEN);
+ if (v->data == NULL) {
+ return NGX_ERROR;
+ }
+
+ switch (data) {
+ case 0:
+ value = ti.tcpi_rtt;
+ break;
+
+ case 1:
+ value = ti.tcpi_rttvar;
+ break;
+
+ case 2:
+ value = ti.tcpi_snd_cwnd;
+ break;
+
+ case 3:
+ value = ti.tcpi_rcv_space;
+ break;
+
+ /* suppress warning */
+ default:
+ value = 0;
+ break;
+ }
+
+ v->len = ngx_sprintf(v->data, "%uD", value) - v->data;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+
+ return NGX_OK;
+}
+
+#endif
+
+
static ngx_int_t
ngx_http_variable_host(ngx_http_request_t *r, ngx_http_variable_value_t *v,
uintptr_t data)
@@ -1200,10 +1273,13 @@ static ngx_int_t
ngx_http_variable_realpath_root(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{
+ u_char *real;
size_t len;
ngx_str_t path;
ngx_http_core_loc_conf_t *clcf;
- u_char real[NGX_MAX_PATH];
+#if (NGX_HAVE_MAX_PATH)
+ u_char buffer[NGX_MAX_PATH];
+#endif
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
@@ -1225,7 +1301,15 @@ ngx_http_variable_realpath_root(ngx_http_request_t *r,
}
}
- if (ngx_realpath(path.data, real) == NULL) {
+#if (NGX_HAVE_MAX_PATH)
+ real = buffer;
+#else
+ real = NULL;
+#endif
+
+ real = ngx_realpath(path.data, real);
+
+ if (real == NULL) {
ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
ngx_realpath_n " \"%s\" failed", path.data);
return NGX_ERROR;
@@ -1235,6 +1319,9 @@ ngx_http_variable_realpath_root(ngx_http_request_t *r,
v->data = ngx_pnalloc(r->pool, len);
if (v->data == NULL) {
+#if !(NGX_HAVE_MAX_PATH)
+ ngx_free(real);
+#endif
return NGX_ERROR;
}
@@ -1245,6 +1332,10 @@ ngx_http_variable_realpath_root(ngx_http_request_t *r,
ngx_memcpy(v->data, real, len);
+#if !(NGX_HAVE_MAX_PATH)
+ ngx_free(real);
+#endif
+
return NGX_OK;
}
diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h
index ffe732c47..9c97e2bb7 100644
--- a/src/os/unix/ngx_files.h
+++ b/src/os/unix/ngx_files.h
@@ -200,14 +200,25 @@ void ngx_close_file_mapping(ngx_file_mapping_t *fm);
#endif
-#define ngx_realpath(p, r) realpath((char *) p, (char *) r)
+#define ngx_realpath(p, r) (u_char *) realpath((char *) p, (char *) r)
#define ngx_realpath_n "realpath()"
#define ngx_getcwd(buf, size) (getcwd((char *) buf, size) != NULL)
#define ngx_getcwd_n "getcwd()"
#define ngx_path_separator(c) ((c) == '/')
+
+#if defined(PATH_MAX)
+
+#define NGX_HAVE_MAX_PATH 1
#define NGX_MAX_PATH PATH_MAX
+#else
+
+#define NGX_MAX_PATH 4096
+
+#endif
+
+
#define NGX_DIR_MASK_LEN 0
diff --git a/src/os/unix/ngx_freebsd_config.h b/src/os/unix/ngx_freebsd_config.h
index 460581a7b..5b3ff278c 100644
--- a/src/os/unix/ngx_freebsd_config.h
+++ b/src/os/unix/ngx_freebsd_config.h
@@ -23,6 +23,7 @@
#include <grp.h>
#include <dirent.h>
#include <glob.h>
+#include <time.h>
#include <sys/param.h> /* ALIGN() */
#include <sys/mount.h> /* statfs() */
diff --git a/src/os/unix/ngx_posix_config.h b/src/os/unix/ngx_posix_config.h
index a0a2c8ce8..4d432a7e3 100644
--- a/src/os/unix/ngx_posix_config.h
+++ b/src/os/unix/ngx_posix_config.h
@@ -45,6 +45,7 @@
#include <grp.h>
#include <dirent.h>
#include <glob.h>
+#include <time.h>
#if (NGX_HAVE_SYS_PARAM_H)
#include <sys/param.h> /* statfs() */
#endif
diff --git a/src/os/unix/ngx_process.h b/src/os/unix/ngx_process.h
index bd0252bd8..7b5e8c0c2 100644
--- a/src/os/unix/ngx_process.h
+++ b/src/os/unix/ngx_process.h
@@ -9,6 +9,7 @@
#define _NGX_PROCESS_H_INCLUDED_
+#include <ngx_setaffinity.h>
#include <ngx_setproctitle.h>
diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c
index 2b6f4c72a..82cf8e6ca 100644
--- a/src/os/unix/ngx_process_cycle.c
+++ b/src/os/unix/ngx_process_cycle.c
@@ -62,7 +62,7 @@ ngx_int_t ngx_threads_n;
#endif
-u_long cpu_affinity;
+uint64_t cpu_affinity;
static u_char master_process[] = "master process";
@@ -913,23 +913,10 @@ ngx_worker_process_init(ngx_cycle_t *cycle, ngx_uint_t priority)
}
}
-#if (NGX_HAVE_SCHED_SETAFFINITY)
-
if (cpu_affinity) {
- ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0,
- "sched_setaffinity(0x%08Xl)", cpu_affinity);
-
- if (sched_setaffinity(0, sizeof(cpu_affinity),
- (cpu_set_t *) &cpu_affinity)
- == -1)
- {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "sched_setaffinity(0x%08Xl) failed", cpu_affinity);
- }
+ ngx_setaffinity(cpu_affinity, cycle->log);
}
-#endif
-
#if (NGX_HAVE_PR_SET_DUMPABLE)
/* allow coredump after setuid() in Linux 2.4.x */
diff --git a/src/os/unix/ngx_setaffinity.c b/src/os/unix/ngx_setaffinity.c
new file mode 100644
index 000000000..8f6cf3594
--- /dev/null
+++ b/src/os/unix/ngx_setaffinity.c
@@ -0,0 +1,69 @@
+
+/*
+ * Copyright (C) Nginx, Inc.
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+
+
+#if (NGX_HAVE_CPUSET_SETAFFINITY)
+
+#include <sys/cpuset.h>
+
+void
+ngx_setaffinity(uint64_t cpu_affinity, ngx_log_t *log)
+{
+ cpuset_t mask;
+ ngx_uint_t i;
+
+ ngx_log_error(NGX_LOG_NOTICE, log, 0,
+ "cpuset_setaffinity(0x%08Xl)", cpu_affinity);
+
+ CPU_ZERO(&mask);
+ i = 0;
+ do {
+ if (cpu_affinity & 1) {
+ CPU_SET(i, &mask);
+ }
+ i++;
+ cpu_affinity >>= 1;
+ } while (cpu_affinity);
+
+ if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1,
+ sizeof(cpuset_t), &mask) == -1)
+ {
+ ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+ "cpuset_setaffinity() failed");
+ }
+}
+
+#elif (NGX_HAVE_SCHED_SETAFFINITY)
+
+void
+ngx_setaffinity(uint64_t cpu_affinity, ngx_log_t *log)
+{
+ cpu_set_t mask;
+ ngx_uint_t i;
+
+ ngx_log_error(NGX_LOG_NOTICE, log, 0,
+ "sched_setaffinity(0x%08Xl)", cpu_affinity);
+
+ CPU_ZERO(&mask);
+ i = 0;
+ do {
+ if (cpu_affinity & 1) {
+ CPU_SET(i, &mask);
+ }
+ i++;
+ cpu_affinity >>= 1;
+ } while (cpu_affinity);
+
+ if (sched_setaffinity(0, sizeof(cpu_set_t), &mask) == -1) {
+ ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
+ "sched_setaffinity() failed");
+ }
+}
+
+#endif
diff --git a/src/os/unix/ngx_setaffinity.h b/src/os/unix/ngx_setaffinity.h
new file mode 100644
index 000000000..33f5835de
--- /dev/null
+++ b/src/os/unix/ngx_setaffinity.h
@@ -0,0 +1,23 @@
+
+/*
+ * Copyright (C) Nginx, Inc.
+ */
+
+#ifndef _NGX_SETAFFINITY_H_INCLUDED_
+#define _NGX_SETAFFINITY_H_INCLUDED_
+
+
+#if (NGX_HAVE_SCHED_SETAFFINITY || NGX_HAVE_CPUSET_SETAFFINITY)
+
+#define NGX_HAVE_CPU_AFFINITY 1
+
+void ngx_setaffinity(uint64_t cpu_affinity, ngx_log_t *log);
+
+#else
+
+#define ngx_setaffinity(cpu_affinity, log)
+
+#endif
+
+
+#endif /* _NGX_SETAFFINITY_H_INCLUDED_ */
diff --git a/src/os/unix/ngx_solaris_config.h b/src/os/unix/ngx_solaris_config.h
index 8a86fe610..e664ba826 100644
--- a/src/os/unix/ngx_solaris_config.h
+++ b/src/os/unix/ngx_solaris_config.h
@@ -29,6 +29,7 @@
#include <grp.h>
#include <dirent.h>
#include <glob.h>
+#include <time.h>
#include <sys/statvfs.h> /* statvfs() */
#include <sys/filio.h> /* FIONBIO */