summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornginx <nginx@nginx.org>2013-09-17 13:36:21 +0000
committerJon Kolb <jon@b0g.us>2013-09-17 13:36:21 +0000
commitc6e358d8a8b9773f4244cca3fb0f4dff1a93c838 (patch)
treed521395e241ea7525b0743b76c97913319c6fda8
parentb4f0587460c1cec132bbf547b658057a674aa94e (diff)
downloadnginx-c6e358d8a8b9773f4244cca3fb0f4dff1a93c838.tar.gz
Changes with nginx 1.5.5 17 Sep 2013v1.5.5
*) Change: now nginx assumes HTTP/1.0 by default if it is not able to detect protocol reliably. *) Feature: the "disable_symlinks" directive now uses O_PATH on Linux. *) Feature: now nginx uses EPOLLRDHUP events to detect premature connection close by clients if the "epoll" method is used. *) Bugfix: in the "valid_referers" directive if the "server_names" parameter was used. *) Bugfix: the $request_time variable did not work in nginx/Windows. *) Bugfix: in the "image_filter" directive. Thanks to Lanshun Zhou. *) Bugfix: OpenSSL 1.0.1f compatibility. Thanks to Piotr Sikora.
-rw-r--r--CHANGES22
-rw-r--r--CHANGES.ru23
-rw-r--r--auto/cc/conf23
-rw-r--r--auto/cc/owc8
-rw-r--r--auto/lib/openssl/conf4
-rw-r--r--auto/lib/pcre/conf5
-rw-r--r--auto/lib/pcre/make19
-rw-r--r--auto/lib/pcre/makefile.bcc4
-rw-r--r--auto/lib/pcre/makefile.owc2
-rw-r--r--auto/lib/zlib/make23
-rw-r--r--auto/modules1
-rw-r--r--auto/os/linux32
-rw-r--r--auto/os/win3213
-rwxr-xr-xauto/unix2
-rw-r--r--src/core/nginx.h4
-rw-r--r--src/core/ngx_connection.c6
-rw-r--r--src/core/ngx_cycle.c6
-rw-r--r--src/core/ngx_file.c17
-rw-r--r--src/core/ngx_open_file_cache.c66
-rw-r--r--src/core/ngx_resolver.c2
-rw-r--r--src/core/ngx_slab.c3
-rw-r--r--src/core/ngx_string.c2
-rw-r--r--src/event/modules/ngx_epoll_module.c18
-rw-r--r--src/event/modules/ngx_select_module.c2
-rw-r--r--src/event/modules/ngx_win32_select_module.c4
-rw-r--r--src/event/ngx_event.h13
-rw-r--r--src/event/ngx_event_accept.c4
-rw-r--r--src/event/ngx_event_connect.c2
-rw-r--r--src/event/ngx_event_openssl.c16
-rw-r--r--src/event/ngx_event_pipe.c10
-rw-r--r--src/http/modules/ngx_http_image_filter_module.c7
-rw-r--r--src/http/modules/ngx_http_log_module.c2
-rw-r--r--src/http/modules/ngx_http_map_module.c6
-rw-r--r--src/http/modules/ngx_http_memcached_module.c2
-rw-r--r--src/http/modules/ngx_http_mp4_module.c12
-rw-r--r--src/http/modules/ngx_http_proxy_module.c4
-rw-r--r--src/http/modules/ngx_http_referer_module.c199
-rw-r--r--src/http/modules/ngx_http_upstream_ip_hash_module.c2
-rw-r--r--src/http/modules/perl/ngx_http_perl_module.c4
-rw-r--r--src/http/ngx_http_file_cache.c2
-rw-r--r--src/http/ngx_http_header_filter_module.c11
-rw-r--r--src/http/ngx_http_request.c35
-rw-r--r--src/http/ngx_http_request_body.c8
-rw-r--r--src/http/ngx_http_upstream.c55
-rw-r--r--src/http/ngx_http_variables.c2
-rw-r--r--src/os/unix/ngx_errno.h1
-rw-r--r--src/os/unix/ngx_files.h3
-rw-r--r--src/os/unix/ngx_readv_chain.c1
-rw-r--r--src/os/unix/ngx_recv.c1
49 files changed, 553 insertions, 160 deletions
diff --git a/CHANGES b/CHANGES
index 57c6146b7..ae7c79e10 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,26 @@
+Changes with nginx 1.5.5 17 Sep 2013
+
+ *) Change: now nginx assumes HTTP/1.0 by default if it is not able to
+ detect protocol reliably.
+
+ *) Feature: the "disable_symlinks" directive now uses O_PATH on Linux.
+
+ *) Feature: now nginx uses EPOLLRDHUP events to detect premature
+ connection close by clients if the "epoll" method is used.
+
+ *) Bugfix: in the "valid_referers" directive if the "server_names"
+ parameter was used.
+
+ *) Bugfix: the $request_time variable did not work in nginx/Windows.
+
+ *) Bugfix: in the "image_filter" directive.
+ Thanks to Lanshun Zhou.
+
+ *) Bugfix: OpenSSL 1.0.1f compatibility.
+ Thanks to Piotr Sikora.
+
+
Changes with nginx 1.5.4 27 Aug 2013
*) Change: the "js" extension MIME type has been changed to
diff --git a/CHANGES.ru b/CHANGES.ru
index bbc8b908c..de89fa996 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,27 @@
+Изменения в nginx 1.5.5 17.09.2013
+
+ *) Изменение: теперь nginx по умолчанию использует HTTP/1.0, если точно
+ определить протокол не удалось.
+
+ *) Добавление: директива disable_symlinks теперь использует O_PATH на
+ Linux.
+
+ *) Добавление: для определения того, что клиент закрыл соединение, при
+ использовании метода epoll теперь используются события EPOLLRDHUP.
+
+ *) Исправление: в директиве valid_referers при использовании параметра
+ server_names.
+
+ *) Исправление: переменная $request_time не работала в nginx/Windows.
+
+ *) Исправление: в директиве image_filter.
+ Спасибо Lanshun Zhou.
+
+ *) Исправление: совместимость с OpenSSL 1.0.1f.
+ Спасибо Piotr Sikora.
+
+
Изменения в nginx 1.5.4 27.08.2013
*) Изменение: MIME-тип для расширения js изменён на
diff --git a/auto/cc/conf b/auto/cc/conf
index 8027b9805..edc6d74dd 100644
--- a/auto/cc/conf
+++ b/auto/cc/conf
@@ -43,6 +43,29 @@ if test -n "$CFLAGS"; then
ngx_include_opt="-I"
;;
+ sunc)
+
+ case "$NGX_MACHINE" in
+
+ i86pc)
+ NGX_AUX=" src/os/unix/ngx_sunpro_x86.il"
+ ;;
+
+ sun4u | sun4v)
+ NGX_AUX=" src/os/unix/ngx_sunpro_sparc64.il"
+ ;;
+
+ esac
+
+ case $CPU in
+
+ amd64)
+ NGX_AUX=" src/os/unix/ngx_sunpro_amd64.il"
+ ;;
+
+ esac
+ ;;
+
esac
else
diff --git a/auto/cc/owc b/auto/cc/owc
index 22eb4c125..a063aa341 100644
--- a/auto/cc/owc
+++ b/auto/cc/owc
@@ -65,10 +65,10 @@ have=NGX_HAVE_C99_VARIADIC_MACROS . auto/have
# the precompiled headers
-CORE_DEPS="$CORE_DEPS $NGX_OBJS/ngx_config.pch"
-NGX_PCH="$NGX_OBJS/ngx_config.pch"
-NGX_BUILD_PCH="-fhq=$NGX_OBJS/ngx_config.pch"
-NGX_USE_PCH="-fh=$NGX_OBJS/ngx_config.pch"
+#CORE_DEPS="$CORE_DEPS $NGX_OBJS/ngx_config.pch"
+#NGX_PCH="$NGX_OBJS/ngx_config.pch"
+#NGX_BUILD_PCH="-fhq=$NGX_OBJS/ngx_config.pch"
+#NGX_USE_PCH="-fh=$NGX_OBJS/ngx_config.pch"
# the link flags, built target is NT GUI mode application
diff --git a/auto/lib/openssl/conf b/auto/lib/openssl/conf
index 528ee1794..a65815f63 100644
--- a/auto/lib/openssl/conf
+++ b/auto/lib/openssl/conf
@@ -33,6 +33,10 @@ if [ $OPENSSL != NONE ]; then
CORE_LIBS="$CORE_LIBS $OPENSSL/.openssl/lib/libssl.a"
CORE_LIBS="$CORE_LIBS $OPENSSL/.openssl/lib/libcrypto.a"
CORE_LIBS="$CORE_LIBS $NGX_LIBDL"
+
+ if [ "$NGX_PLATFORM" = win32 ]; then
+ CORE_LIBS="$CORE_LIBS -lgdi32 -lcrypt32 -lws2_32"
+ fi
;;
esac
diff --git a/auto/lib/pcre/conf b/auto/lib/pcre/conf
index 345860053..939f01b77 100644
--- a/auto/lib/pcre/conf
+++ b/auto/lib/pcre/conf
@@ -73,6 +73,11 @@ if [ $PCRE != NONE ]; then
*)
have=NGX_PCRE . auto/have
+
+ if [ "$NGX_PLATFORM" = win32 ]; then
+ have=PCRE_STATIC . auto/have
+ fi
+
CORE_DEPS="$CORE_DEPS $PCRE/pcre.h"
LINK_DEPS="$LINK_DEPS $PCRE/.libs/libpcre.a"
CORE_LIBS="$CORE_LIBS $PCRE/.libs/libpcre.a"
diff --git a/auto/lib/pcre/make b/auto/lib/pcre/make
index c50d12f9f..0a27a112c 100644
--- a/auto/lib/pcre/make
+++ b/auto/lib/pcre/make
@@ -23,14 +23,16 @@ case "$NGX_CC_NAME" in
ngx_pcre=`echo \-DPCRE=\"$PCRE\" | sed -e "s/\//$ngx_regex_dirsep/g"`
;;
-esac
+ *)
+ ngx_makefile=
+ ;;
+esac
-case "$NGX_PLATFORM" in
- win32)
+if [ -n "$ngx_makefile" ]; then
- cat << END >> $NGX_MAKEFILE
+ cat << END >> $NGX_MAKEFILE
`echo "$PCRE/pcre.lib: $PCRE/pcre.h $NGX_MAKEFILE" \
| sed -e "s/\//$ngx_regex_dirsep/g"`
@@ -41,10 +43,9 @@ case "$NGX_PLATFORM" in
END
- ;;
+else
- *)
- cat << END >> $NGX_MAKEFILE
+ cat << END >> $NGX_MAKEFILE
$PCRE/pcre.h: $PCRE/Makefile
@@ -60,6 +61,4 @@ $PCRE/.libs/libpcre.a: $PCRE/Makefile
END
- ;;
-
-esac
+fi
diff --git a/auto/lib/pcre/makefile.bcc b/auto/lib/pcre/makefile.bcc
index 7230f3205..7a0f2beaf 100644
--- a/auto/lib/pcre/makefile.bcc
+++ b/auto/lib/pcre/makefile.bcc
@@ -13,8 +13,8 @@ pcre.lib:
bcc32 -c $(CFLAGS) -I. $(PCREFLAGS) pcre_*.c
- > pcre.lst
- for %n in (*.obj) do @echo +%n & >> pcre.lst
+ copy /y nul pcre.lst
+ for %n in (*.obj) do @echo +%n ^^& >> pcre.lst
echo + >> pcre.lst
tlib pcre.lib @pcre.lst
diff --git a/auto/lib/pcre/makefile.owc b/auto/lib/pcre/makefile.owc
index 78f5257b3..122fd5b27 100644
--- a/auto/lib/pcre/makefile.owc
+++ b/auto/lib/pcre/makefile.owc
@@ -4,7 +4,7 @@
CFLAGS = -c -zq -bt=nt -ot -op -oi -oe -s -bm $(CPU_OPT)
-PCREFLAGS = -DHAVE_CONFIG_H -DPCRE_STATIC -DPOSIX_MALLOC_THRESHOLD=10 \
+PCREFLAGS = -DHAVE_CONFIG_H -DPCRE_STATIC -DPOSIX_MALLOC_THRESHOLD=10 &
-DSUPPORT_PCRE8 -DHAVE_MEMMOVE
diff --git a/auto/lib/zlib/make b/auto/lib/zlib/make
index 9401a1d1a..7875ef67f 100644
--- a/auto/lib/zlib/make
+++ b/auto/lib/zlib/make
@@ -24,6 +24,10 @@ case "$NGX_CC_NAME" in
ngx_zlib=`echo \-DZLIB=\"$ZLIB\" | sed -e "s/\//$ngx_regex_dirsep/g"`
;;
+ *)
+ ngx_makefile=
+ ;;
+
esac
@@ -33,13 +37,30 @@ done=NO
case "$NGX_PLATFORM" in
win32)
- cat << END >> $NGX_MAKEFILE
+
+ if [ -n "$ngx_makefile" ]; then
+ cat << END >> $NGX_MAKEFILE
`echo "$ZLIB/zlib.lib: $NGX_MAKEFILE" | sed -e "s/\//$ngx_regex_dirsep/g"`
\$(MAKE) -f auto/lib/zlib/$ngx_makefile $ngx_opt $ngx_zlib
END
+ else
+
+ cat << END >> $NGX_MAKEFILE
+
+$ZLIB/libz.a: $NGX_MAKEFILE
+ cd $ZLIB \\
+ && \$(MAKE) distclean \\
+ && \$(MAKE) -f win32/Makefile.gcc \\
+ CFLAGS="$ZLIB_OPT" CC="\$(CC)" \\
+ libz.a
+
+END
+
+ fi
+
done=YES
;;
diff --git a/auto/modules b/auto/modules
index e710ae0ff..3feaf53e1 100644
--- a/auto/modules
+++ b/auto/modules
@@ -42,6 +42,7 @@ fi
if [ $NGX_TEST_BUILD_EPOLL = YES ]; then
have=NGX_HAVE_EPOLL . auto/have
+ have=NGX_HAVE_EPOLLRDHUP . auto/have
have=NGX_HAVE_EVENTFD . auto/have
have=NGX_TEST_BUILD_EPOLL . auto/have
EVENT_MODULES="$EVENT_MODULES $EPOLL_MODULE"
diff --git a/auto/os/linux b/auto/os/linux
index c506d3dc3..19bf832ce 100644
--- a/auto/os/linux
+++ b/auto/os/linux
@@ -65,9 +65,41 @@ if [ $ngx_found = yes ]; then
CORE_SRCS="$CORE_SRCS $EPOLL_SRCS"
EVENT_MODULES="$EVENT_MODULES $EPOLL_MODULE"
EVENT_FOUND=YES
+
+
+ # EPOLLRDHUP appeared in Linux 2.6.17, glibc 2.8
+
+ ngx_feature="EPOLLRDHUP"
+ ngx_feature_name="NGX_HAVE_EPOLLRDHUP"
+ ngx_feature_run=no
+ ngx_feature_incs="#include <sys/epoll.h>"
+ ngx_feature_path=
+ ngx_feature_libs=
+ ngx_feature_test="int efd = 0, fd = 0;
+ struct epoll_event ee;
+ ee.events = EPOLLIN|EPOLLRDHUP|EPOLLET;
+ ee.data.ptr = NULL;
+ epoll_ctl(efd, EPOLL_CTL_ADD, fd, &ee)"
+ . auto/feature
fi
+# O_PATH and AT_EMPTY_PATH were introduced in 2.6.39, glibc 2.14
+
+ngx_feature="O_PATH"
+ngx_feature_name="NGX_HAVE_O_PATH"
+ngx_feature_run=no
+ngx_feature_incs="#include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="int fd; struct stat sb;
+ fd = openat(AT_FDCWD, \".\", O_PATH|O_DIRECTORY|O_NOFOLLOW);
+ if (fstatat(fd, \"\", &sb, AT_EMPTY_PATH) != 0) return 1"
+. auto/feature
+
+
# sendfile()
CC_AUX_FLAGS="$cc_aux_flags -D_GNU_SOURCE"
diff --git a/auto/os/win32 b/auto/os/win32
index 21a54ba11..0b9b46187 100644
--- a/auto/os/win32
+++ b/auto/os/win32
@@ -9,10 +9,21 @@ CORE_INCS="$WIN32_INCS"
CORE_DEPS="$WIN32_DEPS"
CORE_SRCS="$WIN32_SRCS $IOCP_SRCS"
OS_CONFIG="$WIN32_CONFIG"
-CORE_LIBS="$CORE_LIBS advapi32.lib ws2_32.lib"
NGX_ICONS="$NGX_WIN32_ICONS"
SELECT_SRCS=$WIN32_SELECT_SRCS
+case "$NGX_CC_NAME" in
+
+ gcc)
+ CORE_LIBS="$CORE_LIBS -ladvapi32 -lws2_32"
+ ;;
+
+ *)
+ CORE_LIBS="$CORE_LIBS advapi32.lib ws2_32.lib"
+ ;;
+
+esac
+
EVENT_MODULES="$EVENT_MODULES $IOCP_MODULE"
EVENT_FOUND=YES
diff --git a/auto/unix b/auto/unix
index cd4209e7b..4dbdbe0c0 100755
--- a/auto/unix
+++ b/auto/unix
@@ -330,7 +330,7 @@ ngx_feature_test="setsockopt(0, IPPROTO_TCP, TCP_DEFER_ACCEPT, NULL, 0)"
. auto/feature
-ngx_feature="TCP_KEEPIDLE, TCP_KEEPINTVL, TCP_KEEPCNT"
+ngx_feature="TCP_KEEPIDLE"
ngx_feature_name="NGX_HAVE_KEEPALIVE_TUNABLE"
ngx_feature_run=no
ngx_feature_incs="#include <sys/socket.h>
diff --git a/src/core/nginx.h b/src/core/nginx.h
index c2ecbfd86..7117a03ad 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -9,8 +9,8 @@
#define _NGINX_H_INCLUDED_
-#define nginx_version 1005004
-#define NGINX_VERSION "1.5.4"
+#define nginx_version 1005005
+#define NGINX_VERSION "1.5.5"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c
index e12d3efc0..28bf6ba06 100644
--- a/src/core/ngx_connection.c
+++ b/src/core/ngx_connection.c
@@ -297,7 +297,7 @@ ngx_open_listening_sockets(ngx_cycle_t *cycle)
continue;
}
- if (ls[i].fd != -1) {
+ if (ls[i].fd != (ngx_socket_t) -1) {
continue;
}
@@ -312,7 +312,7 @@ ngx_open_listening_sockets(ngx_cycle_t *cycle)
s = ngx_socket(ls[i].sockaddr->sa_family, ls[i].type, 0);
- if (s == -1) {
+ if (s == (ngx_socket_t) -1) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno,
ngx_socket_n " %V failed", &ls[i].addr_text);
return NGX_ERROR;
@@ -863,7 +863,7 @@ ngx_close_connection(ngx_connection_t *c)
ngx_uint_t log_error, level;
ngx_socket_t fd;
- if (c->fd == -1) {
+ if (c->fd == (ngx_socket_t) -1) {
ngx_log_error(NGX_LOG_ALERT, c->log, 0, "connection already closed");
return;
}
diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c
index 2c006bcb2..eb39ab253 100644
--- a/src/core/ngx_cycle.c
+++ b/src/core/ngx_cycle.c
@@ -543,7 +543,7 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
}
}
- if (nls[n].fd == -1) {
+ if (nls[n].fd == (ngx_socket_t) -1) {
nls[n].open = 1;
}
}
@@ -649,7 +649,7 @@ old_shm_zone_done:
ls = old_cycle->listening.elts;
for (i = 0; i < old_cycle->listening.nelts; i++) {
- if (ls[i].remain || ls[i].fd == -1) {
+ if (ls[i].remain || ls[i].fd == (ngx_socket_t) -1) {
continue;
}
@@ -813,7 +813,7 @@ failed:
ls = cycle->listening.elts;
for (i = 0; i < cycle->listening.nelts; i++) {
- if (ls[i].fd == -1 || !ls[i].open) {
+ if (ls[i].fd == (ngx_socket_t) -1 || !ls[i].open) {
continue;
}
diff --git a/src/core/ngx_file.c b/src/core/ngx_file.c
index 28e8871ec..7e6e921a3 100644
--- a/src/core/ngx_file.c
+++ b/src/core/ngx_file.c
@@ -359,9 +359,6 @@ ngx_conf_set_path_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NULL;
}
- path->len = 0;
- path->manager = NULL;
- path->loader = NULL;
path->conf_file = cf->conf_file->file.name.data;
path->line = cf->conf_file->line;
@@ -402,7 +399,7 @@ ngx_conf_merge_path_value(ngx_conf_t *cf, ngx_path_t **path, ngx_path_t *prev,
return NGX_CONF_OK;
}
- *path = ngx_palloc(cf->pool, sizeof(ngx_path_t));
+ *path = ngx_pcalloc(cf->pool, sizeof(ngx_path_t));
if (*path == NULL) {
return NGX_CONF_ERROR;
}
@@ -421,10 +418,6 @@ ngx_conf_merge_path_value(ngx_conf_t *cf, ngx_path_t **path, ngx_path_t *prev,
+ init->level[1] + (init->level[1] ? 1 : 0)
+ init->level[2] + (init->level[2] ? 1 : 0);
- (*path)->manager = NULL;
- (*path)->loader = NULL;
- (*path)->conf_file = NULL;
-
if (ngx_add_path(cf, path) != NGX_OK) {
return NGX_CONF_ERROR;
}
@@ -508,6 +501,14 @@ ngx_add_path(ngx_conf_t *cf, ngx_path_t **slot)
if (p[i]->name.len == path->name.len
&& ngx_strcmp(p[i]->name.data, path->name.data) == 0)
{
+ if (p[i]->data != path->data) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "the same path name \"%V\" "
+ "used in %s:%ui and",
+ &p[i]->name, p[i]->conf_file, p[i]->line);
+ return NGX_ERROR;
+ }
+
for (n = 0; n < 3; n++) {
if (p[i]->level[n] != path->level[n]) {
if (path->conf_file == NULL) {
diff --git a/src/core/ngx_open_file_cache.c b/src/core/ngx_open_file_cache.c
index b72af5ea0..4df2134b2 100644
--- a/src/core/ngx_open_file_cache.c
+++ b/src/core/ngx_open_file_cache.c
@@ -25,6 +25,10 @@ static void ngx_open_file_cache_cleanup(void *data);
#if (NGX_HAVE_OPENAT)
static ngx_fd_t ngx_openat_file_owner(ngx_fd_t at_fd, const u_char *name,
ngx_int_t mode, ngx_int_t create, ngx_int_t access, ngx_log_t *log);
+#if (NGX_HAVE_O_PATH)
+static ngx_int_t ngx_file_o_path_info(ngx_fd_t fd, ngx_file_info_t *fi,
+ ngx_log_t *log);
+#endif
#endif
static ngx_fd_t ngx_open_file_wrapper(ngx_str_t *name,
ngx_open_file_info_t *of, ngx_int_t mode, ngx_int_t create,
@@ -517,10 +521,17 @@ ngx_openat_file_owner(ngx_fd_t at_fd, const u_char *name,
goto failed;
}
+#if (NGX_HAVE_O_PATH)
+ if (ngx_file_o_path_info(fd, &fi, log) == NGX_ERROR) {
+ err = ngx_errno;
+ goto failed;
+ }
+#else
if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) {
err = ngx_errno;
goto failed;
}
+#endif
if (fi.st_uid != atfi.st_uid) {
err = NGX_ELOOP;
@@ -541,8 +552,63 @@ failed:
return NGX_INVALID_FILE;
}
+
+#if (NGX_HAVE_O_PATH)
+
+static ngx_int_t
+ngx_file_o_path_info(ngx_fd_t fd, ngx_file_info_t *fi, ngx_log_t *log)
+{
+ static ngx_uint_t use_fstat = 1;
+
+ /*
+ * In Linux 2.6.39 the O_PATH flag was introduced that allows to obtain
+ * a descriptor without actually opening file or directory. It requires
+ * less permissions for path components, but till Linux 3.6 fstat() returns
+ * EBADF on such descriptors, and fstatat() with the AT_EMPTY_PATH flag
+ * should be used instead.
+ *
+ * Three scenarios are handled in this function:
+ *
+ * 1) The kernel is newer than 3.6 or fstat() with O_PATH support was
+ * backported by vendor. Then fstat() is used.
+ *
+ * 2) The kernel is newer than 2.6.39 but older than 3.6. In this case
+ * the first call of fstat() returns EBADF and we fallback to fstatat()
+ * with AT_EMPTY_PATH which was introduced at the same time as O_PATH.
+ *
+ * 3) The kernel is older than 2.6.39 but nginx was build with O_PATH
+ * support. Since descriptors are opened with O_PATH|O_RDONLY flags
+ * and O_PATH is ignored by the kernel then the O_RDONLY flag is
+ * actually used. In this case fstat() just works.
+ */
+
+ if (use_fstat) {
+ if (ngx_fd_info(fd, fi) != NGX_FILE_ERROR) {
+ return NGX_OK;
+ }
+
+ if (ngx_errno != NGX_EBADF) {
+ return NGX_ERROR;
+ }
+
+ ngx_log_error(NGX_LOG_NOTICE, log, 0,
+ "fstat(O_PATH) failed with EBADF, "
+ "switching to fstatat(AT_EMPTY_PATH)");
+
+ use_fstat = 0;
+ }
+
+ if (ngx_file_at_info(fd, "", fi, AT_EMPTY_PATH) != NGX_FILE_ERROR) {
+ return NGX_OK;
+ }
+
+ return NGX_ERROR;
+}
+
#endif
+#endif /* NGX_HAVE_OPENAT */
+
static ngx_fd_t
ngx_open_file_wrapper(ngx_str_t *name, ngx_open_file_info_t *of,
diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c
index d59d0c471..d94477a9c 100644
--- a/src/core/ngx_resolver.c
+++ b/src/core/ngx_resolver.c
@@ -2221,7 +2221,7 @@ ngx_udp_connect(ngx_udp_connection_t *uc)
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, &uc->log, 0, "UDP socket %d", s);
- if (s == -1) {
+ if (s == (ngx_socket_t) -1) {
ngx_log_error(NGX_LOG_ALERT, &uc->log, ngx_socket_errno,
ngx_socket_n " failed");
return NGX_ERROR;
diff --git a/src/core/ngx_slab.c b/src/core/ngx_slab.c
index ae9d6f3fc..6d18abb72 100644
--- a/src/core/ngx_slab.c
+++ b/src/core/ngx_slab.c
@@ -440,7 +440,8 @@ ngx_slab_free_locked(ngx_slab_pool_t *pool, void *p)
n = ((uintptr_t) p & (ngx_pagesize - 1)) >> shift;
m = (uintptr_t) 1 << (n & (sizeof(uintptr_t) * 8 - 1));
n /= (sizeof(uintptr_t) * 8);
- bitmap = (uintptr_t *) ((uintptr_t) p & ~(ngx_pagesize - 1));
+ bitmap = (uintptr_t *)
+ ((uintptr_t) p & ~((uintptr_t) ngx_pagesize - 1));
if (bitmap[n] & m) {
diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c
index 3b392f7b2..d3ff36855 100644
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -486,7 +486,7 @@ ngx_sprintf_num(u_char *buf, u_char *last, uint64_t ui64, u_char zero,
if (hexadecimal == 0) {
- if (ui64 <= NGX_MAX_UINT32_VALUE) {
+ if (ui64 <= (uint64_t) NGX_MAX_UINT32_VALUE) {
/*
* To divide 64-bit numbers and to find remainders
diff --git a/src/event/modules/ngx_epoll_module.c b/src/event/modules/ngx_epoll_module.c
index ee77d8e4a..f5f663179 100644
--- a/src/event/modules/ngx_epoll_module.c
+++ b/src/event/modules/ngx_epoll_module.c
@@ -25,6 +25,8 @@
#define EPOLLERR 0x008
#define EPOLLHUP 0x010
+#define EPOLLRDHUP 0x2000
+
#define EPOLLET 0x80000000
#define EPOLLONESHOT 0x40000000
@@ -396,13 +398,13 @@ ngx_epoll_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
if (event == NGX_READ_EVENT) {
e = c->write;
prev = EPOLLOUT;
-#if (NGX_READ_EVENT != EPOLLIN)
- events = EPOLLIN;
+#if (NGX_READ_EVENT != EPOLLIN|EPOLLRDHUP)
+ events = EPOLLIN|EPOLLRDHUP;
#endif
} else {
e = c->read;
- prev = EPOLLIN;
+ prev = EPOLLIN|EPOLLRDHUP;
#if (NGX_WRITE_EVENT != EPOLLOUT)
events = EPOLLOUT;
#endif
@@ -466,7 +468,7 @@ ngx_epoll_del_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
} else {
e = c->read;
- prev = EPOLLIN;
+ prev = EPOLLIN|EPOLLRDHUP;
}
if (e->active) {
@@ -501,7 +503,7 @@ ngx_epoll_add_connection(ngx_connection_t *c)
{
struct epoll_event ee;
- ee.events = EPOLLIN|EPOLLOUT|EPOLLET;
+ ee.events = EPOLLIN|EPOLLOUT|EPOLLET|EPOLLRDHUP;
ee.data.ptr = (void *) ((uintptr_t) c | c->read->instance);
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, c->log, 0,
@@ -666,6 +668,12 @@ ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
if ((revents & EPOLLIN) && rev->active) {
+#if (NGX_HAVE_EPOLLRDHUP)
+ if (revents & EPOLLRDHUP) {
+ rev->pending_eof = 1;
+ }
+#endif
+
if ((flags & NGX_POST_THREAD_EVENTS) && !rev->accept) {
rev->posted_ready = 1;
diff --git a/src/event/modules/ngx_select_module.c b/src/event/modules/ngx_select_module.c
index ed71368e9..51690558e 100644
--- a/src/event/modules/ngx_select_module.c
+++ b/src/event/modules/ngx_select_module.c
@@ -288,7 +288,7 @@ ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
ngx_log_error(level, cycle->log, err, "select() failed");
- if (err == EBADF) {
+ if (err == NGX_EBADF) {
ngx_select_repair_fd_sets(cycle);
}
diff --git a/src/event/modules/ngx_win32_select_module.c b/src/event/modules/ngx_win32_select_module.c
index 0a02ffca0..eb5382d4e 100644
--- a/src/event/modules/ngx_win32_select_module.c
+++ b/src/event/modules/ngx_win32_select_module.c
@@ -148,8 +148,8 @@ ngx_select_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags)
return NGX_ERROR;
}
- if ((event == NGX_READ_EVENT) && (max_read >= FD_SETSIZE)
- || (event == NGX_WRITE_EVENT) && (max_write >= FD_SETSIZE))
+ if ((event == NGX_READ_EVENT && max_read >= FD_SETSIZE)
+ || (event == NGX_WRITE_EVENT && max_write >= FD_SETSIZE))
{
ngx_log_error(NGX_LOG_ERR, ev->log, 0,
"maximum number of descriptors "
diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h
index 93c457c7b..530c9486c 100644
--- a/src/event/ngx_event.h
+++ b/src/event/ngx_event.h
@@ -69,13 +69,9 @@ struct ngx_event_s {
unsigned delayed:1;
- unsigned read_discarded:1;
-
- unsigned unexpected_eof:1;
-
unsigned deferred_accept:1;
- /* the pending eof reported by kqueue or in aio chain operation */
+ /* the pending eof reported by kqueue, epoll or in aio chain operation */
unsigned pending_eof:1;
#if !(NGX_THREADS)
@@ -353,6 +349,11 @@ extern ngx_event_actions_t ngx_event_actions;
#define NGX_VNODE_EVENT 0
+#if (NGX_HAVE_EPOLL) && !(NGX_HAVE_EPOLLRDHUP)
+#define EPOLLRDHUP 0
+#endif
+
+
#if (NGX_HAVE_KQUEUE)
#define NGX_READ_EVENT EVFILT_READ
@@ -396,7 +397,7 @@ extern ngx_event_actions_t ngx_event_actions;
#elif (NGX_HAVE_EPOLL)
-#define NGX_READ_EVENT EPOLLIN
+#define NGX_READ_EVENT (EPOLLIN|EPOLLRDHUP)
#define NGX_WRITE_EVENT EPOLLOUT
#define NGX_LEVEL_EVENT 0
diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c
index e3f828da8..b1145446a 100644
--- a/src/event/ngx_event_accept.c
+++ b/src/event/ngx_event_accept.c
@@ -70,7 +70,7 @@ ngx_event_accept(ngx_event_t *ev)
s = accept(lc->fd, (struct sockaddr *) sa, &socklen);
#endif
- if (s == -1) {
+ if (s == (ngx_socket_t) -1) {
err = ngx_socket_errno;
if (err == NGX_EAGAIN) {
@@ -297,7 +297,7 @@ ngx_event_accept(ngx_event_t *ev)
cidr = ecf->debug_connection.elts;
for (i = 0; i < ecf->debug_connection.nelts; i++) {
- if (cidr[i].family != c->sockaddr->sa_family) {
+ if (cidr[i].family != (ngx_uint_t) c->sockaddr->sa_family) {
goto next;
}
diff --git a/src/event/ngx_event_connect.c b/src/event/ngx_event_connect.c
index e6ae6564e..fddad0a92 100644
--- a/src/event/ngx_event_connect.c
+++ b/src/event/ngx_event_connect.c
@@ -31,7 +31,7 @@ ngx_event_connect_peer(ngx_peer_connection_t *pc)
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, pc->log, 0, "socket %d", s);
- if (s == -1) {
+ if (s == (ngx_socket_t) -1) {
ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno,
ngx_socket_n " failed");
return NGX_ERROR;
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index 50746e7ac..fedb604de 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -185,8 +185,10 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data)
SSL_CTX_set_options(ssl->ctx, SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG);
SSL_CTX_set_options(ssl->ctx, SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER);
+#ifdef SSL_OP_MSIE_SSLV2_RSA_PADDING
/* this option allow a potential SSL 2.0 rollback (CAN-2005-2969) */
SSL_CTX_set_options(ssl->ctx, SSL_OP_MSIE_SSLV2_RSA_PADDING);
+#endif
SSL_CTX_set_options(ssl->ctx, SSL_OP_SSLEAY_080_CLIENT_DH_BUG);
SSL_CTX_set_options(ssl->ctx, SSL_OP_TLS_D5_BUG);
@@ -363,6 +365,13 @@ ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
return NGX_ERROR;
}
+ /*
+ * SSL_CTX_load_verify_locations() may leave errors in the error queue
+ * while returning success
+ */
+
+ ERR_clear_error();
+
list = SSL_load_client_CA_file((char *) cert->data);
if (list == NULL) {
@@ -407,6 +416,13 @@ ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
return NGX_ERROR;
}
+ /*
+ * SSL_CTX_load_verify_locations() may leave errors in the error queue
+ * while returning success
+ */
+
+ ERR_clear_error();
+
return NGX_OK;
}
diff --git a/src/event/ngx_event_pipe.c b/src/event/ngx_event_pipe.c
index 4dfb88f6d..6f685a9ed 100644
--- a/src/event/ngx_event_pipe.c
+++ b/src/event/ngx_event_pipe.c
@@ -57,7 +57,7 @@ ngx_event_pipe(ngx_event_pipe_t *p, ngx_int_t do_write)
do_write = 1;
}
- if (p->upstream->fd != -1) {
+ if (p->upstream->fd != (ngx_socket_t) -1) {
rev = p->upstream->read;
flags = (rev->eof || rev->error) ? NGX_CLOSE_EVENT : 0;
@@ -74,7 +74,9 @@ ngx_event_pipe(ngx_event_pipe_t *p, ngx_int_t do_write)
}
}
- if (p->downstream->fd != -1 && p->downstream->data == p->output_ctx) {
+ if (p->downstream->fd != (ngx_socket_t) -1
+ && p->downstream->data == p->output_ctx)
+ {
wev = p->downstream->write;
if (ngx_handle_write_event(wev, p->send_lowat) != NGX_OK) {
return NGX_ABORT;
@@ -220,8 +222,8 @@ ngx_event_pipe_read_upstream(ngx_event_pipe_t *p)
{
/*
- * if it is allowed, then save some bufs from r->in
- * to a temporary file, and add them to a r->out chain
+ * if it is allowed, then save some bufs from p->in
+ * to a temporary file, and add them to a p->out chain
*/
rc = ngx_event_pipe_write_chain_to_temp_file(p);
diff --git a/src/http/modules/ngx_http_image_filter_module.c b/src/http/modules/ngx_http_image_filter_module.c
index 6d3f47dcb..cc41ef0d5 100644
--- a/src/http/modules/ngx_http_image_filter_module.c
+++ b/src/http/modules/ngx_http_image_filter_module.c
@@ -478,7 +478,12 @@ ngx_http_image_read(ngx_http_request_t *r, ngx_chain_t *in)
"image buf: %uz", size);
rest = ctx->image + ctx->length - p;
- size = (rest < size) ? rest : size;
+
+ if (size > rest) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "image filter: too big response");
+ return NGX_ERROR;
+ }
p = ngx_cpymem(p, b->pos, size);
b->pos += size;
diff --git a/src/http/modules/ngx_http_log_module.c b/src/http/modules/ngx_http_log_module.c
index aa6a3fcee..7eb29b38a 100644
--- a/src/http/modules/ngx_http_log_module.c
+++ b/src/http/modules/ngx_http_log_module.c
@@ -780,7 +780,7 @@ ngx_http_log_request_time(ngx_http_request_t *r, u_char *buf,
((tp->sec - r->start_sec) * 1000 + (tp->msec - r->start_msec));
ms = ngx_max(ms, 0);
- return ngx_sprintf(buf, "%T.%03M", ms / 1000, ms % 1000);
+ return ngx_sprintf(buf, "%T.%03M", (time_t) ms / 1000, ms % 1000);
}
diff --git a/src/http/modules/ngx_http_map_module.c b/src/http/modules/ngx_http_map_module.c
index 13c8b97ff..3245e0413 100644
--- a/src/http/modules/ngx_http_map_module.c
+++ b/src/http/modules/ngx_http_map_module.c
@@ -131,7 +131,7 @@ ngx_http_map_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
}
if (!value->valid) {
- value = ngx_http_get_flushed_variable(r, (ngx_uint_t) value->data);
+ value = ngx_http_get_flushed_variable(r, (uintptr_t) value->data);
if (value == NULL || value->not_found) {
value = &ngx_http_variable_null_value;
@@ -414,7 +414,7 @@ ngx_http_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
var = ctx->var_values.elts;
for (i = 0; i < ctx->var_values.nelts; i++) {
- if (index == (ngx_int_t) var[i].data) {
+ if (index == (intptr_t) var[i].data) {
var = &var[i];
goto found;
}
@@ -429,7 +429,7 @@ ngx_http_map(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
var->no_cacheable = 0;
var->not_found = 0;
var->len = 0;
- var->data = (u_char *) index;
+ var->data = (u_char *) (intptr_t) index;
goto found;
}
diff --git a/src/http/modules/ngx_http_memcached_module.c b/src/http/modules/ngx_http_memcached_module.c
index bfff1bfc2..aaa047e8f 100644
--- a/src/http/modules/ngx_http_memcached_module.c
+++ b/src/http/modules/ngx_http_memcached_module.c
@@ -520,7 +520,7 @@ ngx_http_memcached_filter(void *data, ssize_t bytes)
return NGX_OK;
}
- last += u->length - NGX_HTTP_MEMCACHED_END;
+ last += (size_t) (u->length - NGX_HTTP_MEMCACHED_END);
if (ngx_strncmp(last, ngx_http_memcached_end, b->last - last) != 0) {
ngx_log_error(NGX_LOG_ERR, ctx->request->connection->log, 0,
diff --git a/src/http/modules/ngx_http_mp4_module.c b/src/http/modules/ngx_http_mp4_module.c
index f9281a371..c44dc52c9 100644
--- a/src/http/modules/ngx_http_mp4_module.c
+++ b/src/http/modules/ngx_http_mp4_module.c
@@ -157,7 +157,11 @@ typedef struct {
#define ngx_mp4_atom_header(mp4) (mp4->buffer_pos - 8)
#define ngx_mp4_atom_data(mp4) mp4->buffer_pos
#define ngx_mp4_atom_data_size(t) (uint64_t) (sizeof(t) - 8)
-#define ngx_mp4_atom_next(mp4, n) mp4->buffer_pos += n; mp4->offset += n
+
+
+#define ngx_mp4_atom_next(mp4, n) \
+ mp4->buffer_pos += (size_t) n; \
+ mp4->offset += n
#define ngx_mp4_set_atom_name(p, n1, n2, n3, n4) \
@@ -956,7 +960,7 @@ ngx_http_mp4_read_ftyp_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "mp4 ftyp atom");
if (atom_data_size > 1024
- || ngx_mp4_atom_data(mp4) + atom_data_size > mp4->buffer_end)
+ || ngx_mp4_atom_data(mp4) + (size_t) atom_data_size > mp4->buffer_end)
{
ngx_log_error(NGX_LOG_ERR, mp4->file.log, 0,
"\"%s\" mp4 ftyp atom is too large:%uL",
@@ -1129,7 +1133,7 @@ ngx_http_mp4_update_mdat_atom(ngx_http_mp4_file_t *mp4, off_t start_offset)
atom_header = mp4->mdat_atom_header;
- if ((uint64_t) atom_data_size > 0xffffffff) {
+ if ((uint64_t) atom_data_size > (uint64_t) 0xffffffff) {
atom_size = 1;
atom_header_size = sizeof(ngx_mp4_atom_header64_t);
ngx_mp4_set_64value(atom_header + sizeof(ngx_mp4_atom_header_t),
@@ -1304,7 +1308,7 @@ ngx_http_mp4_read_trak_atom(ngx_http_mp4_file_t *mp4, uint64_t atom_data_size)
trak->out[NGX_HTTP_MP4_TRAK_ATOM].buf = atom;
- atom_end = mp4->buffer_pos + atom_data_size;
+ atom_end = mp4->buffer_pos + (size_t) atom_data_size;
atom_file_end = mp4->offset + atom_data_size;
rc = ngx_http_mp4_read_atom(mp4, ngx_http_mp4_trak_atoms, atom_data_size);
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index a22ed0fcb..f5fd83d14 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -1712,7 +1712,7 @@ ngx_http_proxy_chunked_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
if (buf->last - buf->pos >= ctx->chunked.size) {
- buf->pos += ctx->chunked.size;
+ buf->pos += (size_t) ctx->chunked.size;
b->last = buf->pos;
ctx->chunked.size = 0;
@@ -1875,7 +1875,7 @@ ngx_http_proxy_non_buffered_chunked_filter(void *data, ssize_t bytes)
b->tag = u->output.tag;
if (buf->last - buf->pos >= ctx->chunked.size) {
- buf->pos += ctx->chunked.size;
+ buf->pos += (size_t) ctx->chunked.size;
b->last = buf->pos;
ctx->chunked.size = 0;
diff --git a/src/http/modules/ngx_http_referer_module.c b/src/http/modules/ngx_http_referer_module.c
index 85b75ab3d..b417eb227 100644
--- a/src/http/modules/ngx_http_referer_module.c
+++ b/src/http/modules/ngx_http_referer_module.c
@@ -12,22 +12,18 @@
#define NGX_HTTP_REFERER_NO_URI_PART ((void *) 4)
-#if !(NGX_PCRE)
-
-#define ngx_regex_t void
-
-#endif
-
typedef struct {
ngx_hash_combined_t hash;
#if (NGX_PCRE)
ngx_array_t *regex;
+ ngx_array_t *server_name_regex;
#endif
ngx_flag_t no_referer;
ngx_flag_t blocked_referer;
+ ngx_flag_t server_names;
ngx_hash_keys_arrays_t *keys;
@@ -41,10 +37,14 @@ static char * ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent,
void *child);
static char *ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
-static char *ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
- ngx_str_t *value, ngx_str_t *uri);
-static char *ngx_http_add_regex_referer(ngx_conf_t *cf,
- ngx_http_referer_conf_t *rlcf, ngx_str_t *name, ngx_regex_t *regex);
+static ngx_int_t ngx_http_add_referer(ngx_conf_t *cf,
+ ngx_hash_keys_arrays_t *keys, ngx_str_t *value, ngx_str_t *uri);
+static ngx_int_t ngx_http_add_regex_referer(ngx_conf_t *cf,
+ ngx_http_referer_conf_t *rlcf, ngx_str_t *name);
+#if (NGX_PCRE)
+static ngx_int_t ngx_http_add_regex_server_name(ngx_conf_t *cf,
+ ngx_http_referer_conf_t *rlcf, ngx_http_regex_t *regex);
+#endif
static int ngx_libc_cdecl ngx_http_cmp_referer_wildcards(const void *one,
const void *two);
@@ -117,6 +117,10 @@ ngx_http_referer_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
ngx_uint_t i, key;
ngx_http_referer_conf_t *rlcf;
u_char buf[256];
+#if (NGX_PCRE)
+ ngx_int_t rc;
+ ngx_str_t referer;
+#endif
rlcf = ngx_http_get_module_loc_conf(r, ngx_http_referer_module);
@@ -125,6 +129,7 @@ ngx_http_referer_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
&& rlcf->hash.wc_tail == NULL
#if (NGX_PCRE)
&& rlcf->regex == NULL
+ && rlcf->server_name_regex == NULL
#endif
)
{
@@ -173,12 +178,12 @@ valid_scheme:
break;
}
- buf[i] = ngx_tolower(*p);
- key = ngx_hash(key, buf[i++]);
-
if (i == 256) {
goto invalid;
}
+
+ buf[i] = ngx_tolower(*p);
+ key = ngx_hash(key, buf[i++]);
}
uri = ngx_hash_find_combined(&rlcf->hash, key, buf, p - ref);
@@ -189,10 +194,25 @@ valid_scheme:
#if (NGX_PCRE)
- if (rlcf->regex) {
- ngx_int_t rc;
- ngx_str_t referer;
+ if (rlcf->server_name_regex) {
+ referer.len = p - ref;
+ referer.data = buf;
+
+ rc = ngx_regex_exec_array(rlcf->server_name_regex, &referer,
+ r->connection->log);
+
+ if (rc == NGX_OK) {
+ goto valid;
+ }
+
+ if (rc == NGX_ERROR) {
+ return rc;
+ }
+
+ /* NGX_DECLINED */
+ }
+ if (rlcf->regex) {
referer.len = len;
referer.data = ref;
@@ -253,8 +273,17 @@ ngx_http_referer_create_conf(ngx_conf_t *cf)
return NULL;
}
+ /*
+ * set by ngx_pcalloc():
+ *
+ * conf->hash = { NULL };
+ * conf->server_names = 0;
+ * conf->keys = NULL;
+ */
+
#if (NGX_PCRE)
conf->regex = NGX_CONF_UNSET_PTR;
+ conf->server_name_regex = NGX_CONF_UNSET_PTR;
#endif
conf->no_referer = NGX_CONF_UNSET;
@@ -272,13 +301,18 @@ ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_http_referer_conf_t *prev = parent;
ngx_http_referer_conf_t *conf = child;
- ngx_hash_init_t hash;
+ ngx_uint_t n;
+ ngx_hash_init_t hash;
+ ngx_http_server_name_t *sn;
+ ngx_http_core_srv_conf_t *cscf;
if (conf->keys == NULL) {
conf->hash = prev->hash;
#if (NGX_PCRE)
ngx_conf_merge_ptr_value(conf->regex, prev->regex, NULL);
+ ngx_conf_merge_ptr_value(conf->server_name_regex,
+ prev->server_name_regex, NULL);
#endif
ngx_conf_merge_value(conf->no_referer, prev->no_referer, 0);
ngx_conf_merge_value(conf->blocked_referer, prev->blocked_referer, 0);
@@ -290,6 +324,33 @@ ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, void *child)
return NGX_CONF_OK;
}
+ if (conf->server_names == 1) {
+ cscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_core_module);
+
+ sn = cscf->server_names.elts;
+ for (n = 0; n < cscf->server_names.nelts; n++) {
+
+#if (NGX_PCRE)
+ if (sn[n].regex) {
+
+ if (ngx_http_add_regex_server_name(cf, conf, sn[n].regex)
+ != NGX_OK)
+ {
+ return NGX_CONF_ERROR;
+ }
+
+ continue;
+ }
+#endif
+
+ if (ngx_http_add_referer(cf, conf->keys, &sn[n].name, NULL)
+ != NGX_OK)
+ {
+ return NGX_CONF_ERROR;
+ }
+ }
+ }
+
if ((conf->no_referer == 1 || conf->blocked_referer == 1)
&& conf->keys->keys.nelts == 0
&& conf->keys->dns_wc_head.nelts == 0
@@ -368,6 +429,8 @@ ngx_http_referer_merge_conf(ngx_conf_t *cf, void *parent, void *child)
#if (NGX_PCRE)
ngx_conf_merge_ptr_value(conf->regex, prev->regex, NULL);
+ ngx_conf_merge_ptr_value(conf->server_name_regex, prev->server_name_regex,
+ NULL);
#endif
if (conf->no_referer == NGX_CONF_UNSET) {
@@ -391,10 +454,8 @@ ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
u_char *p;
ngx_str_t *value, uri, name;
- ngx_uint_t i, n;
+ ngx_uint_t i;
ngx_http_variable_t *var;
- ngx_http_server_name_t *sn;
- ngx_http_core_srv_conf_t *cscf;
ngx_str_set(&name, "invalid_referer");
@@ -438,48 +499,21 @@ ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
continue;
}
- ngx_str_null(&uri);
-
if (ngx_strcmp(value[i].data, "server_names") == 0) {
-
- cscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_core_module);
-
- sn = cscf->server_names.elts;
- for (n = 0; n < cscf->server_names.nelts; n++) {
-
-#if (NGX_PCRE)
- if (sn[n].regex) {
-
- if (ngx_http_add_regex_referer(cf, rlcf, &sn[n].name,
- sn[n].regex->regex)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- continue;
- }
-#endif
-
- if (ngx_http_add_referer(cf, rlcf->keys, &sn[n].name, &uri)
- != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
- }
-
+ rlcf->server_names = 1;
continue;
}
if (value[i].data[0] == '~') {
- if (ngx_http_add_regex_referer(cf, rlcf, &value[i], NULL) != NGX_OK)
- {
+ if (ngx_http_add_regex_referer(cf, rlcf, &value[i]) != NGX_OK) {
return NGX_CONF_ERROR;
}
continue;
}
+ ngx_str_null(&uri);
+
p = (u_char *) ngx_strchr(value[i].data, '/');
if (p) {
@@ -497,20 +531,20 @@ ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
-static char *
+static ngx_int_t
ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
ngx_str_t *value, ngx_str_t *uri)
{
ngx_int_t rc;
ngx_str_t *u;
- if (uri->len == 0) {
+ if (uri == NULL || uri->len == 0) {
u = NGX_HTTP_REFERER_NO_URI_PART;
} else {
u = ngx_palloc(cf->pool, sizeof(ngx_str_t));
if (u == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
*u = *uri;
@@ -519,7 +553,7 @@ ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
rc = ngx_hash_add_key(keys, value, u, NGX_HASH_WILDCARD_KEY);
if (rc == NGX_OK) {
- return NGX_CONF_OK;
+ return NGX_OK;
}
if (rc == NGX_DECLINED) {
@@ -532,13 +566,13 @@ ngx_http_add_referer(ngx_conf_t *cf, ngx_hash_keys_arrays_t *keys,
"conflicting parameter \"%V\"", value);
}
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
-static char *
+static ngx_int_t
ngx_http_add_regex_referer(ngx_conf_t *cf, ngx_http_referer_conf_t *rlcf,
- ngx_str_t *name, ngx_regex_t *regex)
+ ngx_str_t *name)
{
#if (NGX_PCRE)
ngx_regex_elt_t *re;
@@ -547,26 +581,19 @@ ngx_http_add_regex_referer(ngx_conf_t *cf, ngx_http_referer_conf_t *rlcf,
if (name->len == 1) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "empty regex in \"%V\"", name);
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
if (rlcf->regex == NGX_CONF_UNSET_PTR) {
rlcf->regex = ngx_array_create(cf->pool, 2, sizeof(ngx_regex_elt_t));
if (rlcf->regex == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
}
re = ngx_array_push(rlcf->regex);
if (re == NULL) {
- return NGX_CONF_ERROR;
- }
-
- if (regex) {
- re->regex = regex;
- re->name = name->data;
-
- return NGX_CONF_OK;
+ return NGX_ERROR;
}
name->len--;
@@ -582,13 +609,13 @@ ngx_http_add_regex_referer(ngx_conf_t *cf, ngx_http_referer_conf_t *rlcf,
if (ngx_regex_compile(&rc) != NGX_OK) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc.err);
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
re->regex = rc.regex;
re->name = name->data;
- return NGX_CONF_OK;
+ return NGX_OK;
#else
@@ -596,12 +623,42 @@ ngx_http_add_regex_referer(ngx_conf_t *cf, ngx_http_referer_conf_t *rlcf,
"the using of the regex \"%V\" requires PCRE library",
name);
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
#endif
}
+#if (NGX_PCRE)
+
+static ngx_int_t
+ngx_http_add_regex_server_name(ngx_conf_t *cf, ngx_http_referer_conf_t *rlcf,
+ ngx_http_regex_t *regex)
+{
+ ngx_regex_elt_t *re;
+
+ if (rlcf->server_name_regex == NGX_CONF_UNSET_PTR) {
+ rlcf->server_name_regex = ngx_array_create(cf->pool, 2,
+ sizeof(ngx_regex_elt_t));
+ if (rlcf->server_name_regex == NULL) {
+ return NGX_ERROR;
+ }
+ }
+
+ re = ngx_array_push(rlcf->server_name_regex);
+ if (re == NULL) {
+ return NGX_ERROR;
+ }
+
+ re->regex = regex->regex;
+ re->name = regex->name.data;
+
+ return NGX_OK;
+}
+
+#endif
+
+
static int ngx_libc_cdecl
ngx_http_cmp_referer_wildcards(const void *one, const void *two)
{
diff --git a/src/http/modules/ngx_http_upstream_ip_hash_module.c b/src/http/modules/ngx_http_upstream_ip_hash_module.c
index 29c74fd54..0e5cf416a 100644
--- a/src/http/modules/ngx_http_upstream_ip_hash_module.c
+++ b/src/http/modules/ngx_http_upstream_ip_hash_module.c
@@ -174,7 +174,7 @@ ngx_http_upstream_get_ip_hash_peer(ngx_peer_connection_t *pc, void *data)
for ( ;; ) {
- for (i = 0; i < iphp->addrlen; i++) {
+ for (i = 0; i < (ngx_uint_t) iphp->addrlen; i++) {
hash = (hash * 113 + iphp->addr[i]) % 6271;
}
diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c
index 90e32e80e..bf4d1fe9a 100644
--- a/src/http/modules/perl/ngx_http_perl_module.c
+++ b/src/http/modules/perl/ngx_http_perl_module.c
@@ -421,7 +421,7 @@ ngx_http_perl_ssi(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ssi_ctx,
return NGX_ERROR;
}
- asv[0] = (SV *) i;
+ asv[0] = (SV *) (uintptr_t) i;
for (i = 0; args[i]; i++) {
asv[i + 1] = newSVpvn((char *) args[i]->data, args[i]->len);
@@ -692,7 +692,7 @@ ngx_http_perl_call_handler(pTHX_ ngx_http_request_t *r, HV *nginx, SV *sub,
if (args) {
EXTEND(sp, (intptr_t) args[0]);
- for (i = 1; i <= (ngx_uint_t) args[0]; i++) {
+ for (i = 1; i <= (uintptr_t) args[0]; i++) {
PUSHs(sv_2mortal(args[i]));
}
}
diff --git a/src/http/ngx_http_file_cache.c b/src/http/ngx_http_file_cache.c
index cf27683e6..7e46d1295 100644
--- a/src/http/ngx_http_file_cache.c
+++ b/src/http/ngx_http_file_cache.c
@@ -503,7 +503,7 @@ ngx_http_file_cache_read(ngx_http_request_t *r, ngx_http_cache_t *c)
return NGX_DECLINED;
}
- if (h->body_start > c->body_start) {
+ if ((size_t) h->body_start > c->body_start) {
ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0,
"cache file \"%s\" has too long header",
c->file.name.data);
diff --git a/src/http/ngx_http_header_filter_module.c b/src/http/ngx_http_header_filter_module.c
index 707a81313..fc54836f6 100644
--- a/src/http/ngx_http_header_filter_module.c
+++ b/src/http/ngx_http_header_filter_module.c
@@ -92,10 +92,7 @@ static ngx_str_t ngx_http_status_lines[] = {
ngx_string("411 Length Required"),
ngx_string("412 Precondition Failed"),
ngx_string("413 Request Entity Too Large"),
- ngx_null_string, /* "414 Request-URI Too Large", but we never send it
- * because we treat such requests as the HTTP/0.9
- * requests and send only a body without a header
- */
+ ngx_string("414 Request-URI Too Large"),
ngx_string("415 Unsupported Media Type"),
ngx_string("416 Requested Range Not Satisfiable"),
@@ -270,6 +267,12 @@ ngx_http_header_filter(ngx_http_request_t *r)
len += NGX_INT_T_LEN;
status_line = NULL;
}
+
+ if (status_line && status_line->len == 0) {
+ status = r->headers_out.status;
+ len += NGX_INT_T_LEN;
+ status_line = NULL;
+ }
}
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index ca738cbb6..1f6d246bc 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -571,6 +571,7 @@ ngx_http_create_request(ngx_connection_t *c)
r->start_msec = tp->msec;
r->method = NGX_HTTP_UNKNOWN;
+ r->http_version = NGX_HTTP_VERSION_10;
r->headers_in.content_length_n = -1;
r->headers_in.keep_alive_n = -1;
@@ -2693,6 +2694,33 @@ ngx_http_test_reading(ngx_http_request_t *r)
#endif
+#if (NGX_HAVE_EPOLLRDHUP)
+
+ if ((ngx_event_flags & NGX_USE_EPOLL_EVENT) && rev->pending_eof) {
+ socklen_t len;
+
+ rev->eof = 1;
+ c->error = 1;
+
+ err = 0;
+ len = sizeof(ngx_err_t);
+
+ /*
+ * BSDs and Linux return 0 and set a pending error in err
+ * Solaris returns -1 and sets errno
+ */
+
+ if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len)
+ == -1)
+ {
+ err = ngx_errno;
+ }
+
+ goto closed;
+ }
+
+#endif
+
n = recv(c->fd, buf, 1, MSG_PEEK);
if (n == 0) {
@@ -3342,10 +3370,15 @@ ngx_http_free_request(ngx_http_request_t *r, ngx_int_t rc)
return;
}
- for (cln = r->cleanup; cln; cln = cln->next) {
+ cln = r->cleanup;
+ r->cleanup = NULL;
+
+ while (cln) {
if (cln->handler) {
cln->handler(cln->data);
}
+
+ cln = cln->next;
}
#if (NGX_STAT_STUB)
diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c
index fc3a1800d..dc1fcde1c 100644
--- a/src/http/ngx_http_request_body.c
+++ b/src/http/ngx_http_request_body.c
@@ -714,7 +714,7 @@ ngx_http_discard_request_body_filter(ngx_http_request_t *r, ngx_buf_t *b)
size = b->last - b->pos;
if ((off_t) size > rb->chunked->size) {
- b->pos += rb->chunked->size;
+ b->pos += (size_t) rb->chunked->size;
rb->chunked->size = 0;
} else {
@@ -753,7 +753,7 @@ ngx_http_discard_request_body_filter(ngx_http_request_t *r, ngx_buf_t *b)
size = b->last - b->pos;
if ((off_t) size > r->headers_in.content_length_n) {
- b->pos += r->headers_in.content_length_n;
+ b->pos += (size_t) r->headers_in.content_length_n;
r->headers_in.content_length_n = 0;
} else {
@@ -866,7 +866,7 @@ ngx_http_request_body_length_filter(ngx_http_request_t *r, ngx_chain_t *in)
rb->rest -= size;
} else {
- cl->buf->pos += rb->rest;
+ cl->buf->pos += (size_t) rb->rest;
rb->rest = 0;
b->last = cl->buf->pos;
b->last_buf = 1;
@@ -972,7 +972,7 @@ ngx_http_request_body_chunked_filter(ngx_http_request_t *r, ngx_chain_t *in)
size = cl->buf->last - cl->buf->pos;
if ((off_t) size > rb->chunked->size) {
- cl->buf->pos += rb->chunked->size;
+ cl->buf->pos += (size_t) rb->chunked->size;
r->headers_in.content_length_n += rb->chunked->size;
rb->chunked->size = 0;
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index 652222f8f..2321f6e97 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -1070,6 +1070,55 @@ ngx_http_upstream_check_broken_connection(ngx_http_request_t *r,
#endif
+#if (NGX_HAVE_EPOLLRDHUP)
+
+ if ((ngx_event_flags & NGX_USE_EPOLL_EVENT) && ev->pending_eof) {
+ socklen_t len;
+
+ ev->eof = 1;
+ c->error = 1;
+
+ err = 0;
+ len = sizeof(ngx_err_t);
+
+ /*
+ * BSDs and Linux return 0 and set a pending error in err
+ * Solaris returns -1 and sets errno
+ */
+
+ if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len)
+ == -1)
+ {
+ err = ngx_errno;
+ }
+
+ if (err) {
+ ev->error = 1;
+ }
+
+ if (!u->cacheable && u->peer.connection) {
+ ngx_log_error(NGX_LOG_INFO, ev->log, err,
+ "epoll_wait() reported that client prematurely closed "
+ "connection, so upstream connection is closed too");
+ ngx_http_upstream_finalize_request(r, u,
+ NGX_HTTP_CLIENT_CLOSED_REQUEST);
+ return;
+ }
+
+ ngx_log_error(NGX_LOG_INFO, ev->log, err,
+ "epoll_wait() reported that client prematurely closed "
+ "connection");
+
+ if (u->peer.connection == NULL) {
+ ngx_http_upstream_finalize_request(r, u,
+ NGX_HTTP_CLIENT_CLOSED_REQUEST);
+ }
+
+ return;
+ }
+
+#endif
+
n = recv(c->fd, buf, 1, MSG_PEEK);
err = ngx_socket_errno;
@@ -2105,6 +2154,8 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
return;
}
+ u->header_sent = 1;
+
if (u->upgrade) {
ngx_http_upstream_upgrade(r, u);
return;
@@ -2131,8 +2182,6 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
}
}
- u->header_sent = 1;
-
if (r->request_body && r->request_body->temp_file) {
ngx_pool_run_cleanup_file(r->pool, r->request_body->temp_file->file.fd);
r->request_body->temp_file->file.fd = NGX_INVALID_FILE;
@@ -4309,7 +4358,7 @@ ngx_http_upstream_response_time_variable(ngx_http_request_t *r,
ms = (ngx_msec_int_t)
(state[i].response_sec * 1000 + state[i].response_msec);
ms = ngx_max(ms, 0);
- p = ngx_sprintf(p, "%d.%03d", ms / 1000, ms % 1000);
+ p = ngx_sprintf(p, "%T.%03M", (time_t) ms / 1000, ms % 1000);
} else {
*p++ = '-';
diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c
index 4138bda42..3ec038aef 100644
--- a/src/http/ngx_http_variables.c
+++ b/src/http/ngx_http_variables.c
@@ -1992,7 +1992,7 @@ ngx_http_variable_request_time(ngx_http_request_t *r,
((tp->sec - r->start_sec) * 1000 + (tp->msec - r->start_msec));
ms = ngx_max(ms, 0);
- v->len = ngx_sprintf(p, "%T.%03M", ms / 1000, ms % 1000) - p;
+ v->len = ngx_sprintf(p, "%T.%03M", (time_t) ms / 1000, ms % 1000) - p;
v->valid = 1;
v->no_cacheable = 0;
v->not_found = 0;
diff --git a/src/os/unix/ngx_errno.h b/src/os/unix/ngx_errno.h
index 1497c5f2f..6d1a4889a 100644
--- a/src/os/unix/ngx_errno.h
+++ b/src/os/unix/ngx_errno.h
@@ -50,6 +50,7 @@ typedef int ngx_err_t;
#define NGX_EILSEQ EILSEQ
#define NGX_ENOMOREFILES 0
#define NGX_ELOOP ELOOP
+#define NGX_EBADF EBADF
#if (NGX_HAVE_OPENAT)
#define NGX_EMLINK EMLINK
diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h
index 4e3ed7db4..df759df52 100644
--- a/src/os/unix/ngx_files.h
+++ b/src/os/unix/ngx_files.h
@@ -91,6 +91,9 @@ typedef struct {
#elif defined(O_EXEC)
#define NGX_FILE_SEARCH (O_EXEC|NGX_FILE_DIRECTORY)
+#elif (NGX_HAVE_O_PATH)
+#define NGX_FILE_SEARCH (O_PATH|O_RDONLY|NGX_FILE_DIRECTORY)
+
#else
#define NGX_FILE_SEARCH (O_RDONLY|NGX_FILE_DIRECTORY)
#endif
diff --git a/src/os/unix/ngx_readv_chain.c b/src/os/unix/ngx_readv_chain.c
index c2c21b407..8836c817d 100644
--- a/src/os/unix/ngx_readv_chain.c
+++ b/src/os/unix/ngx_readv_chain.c
@@ -129,6 +129,7 @@ ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *chain)
"%d available bytes", rev->available);
#endif
+ rev->ready = 0;
rev->eof = 1;
rev->available = 0;
}
diff --git a/src/os/unix/ngx_recv.c b/src/os/unix/ngx_recv.c
index 1640cdb27..86675dfdd 100644
--- a/src/os/unix/ngx_recv.c
+++ b/src/os/unix/ngx_recv.c
@@ -80,6 +80,7 @@ ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size)
* even if kqueue reported about available data
*/
+ rev->ready = 0;
rev->eof = 1;
rev->available = 0;
}