summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2010-06-07 12:41:37 +0000
committerJonathan Kolb <jon@b0g.us>2010-06-07 12:41:37 +0000
commita5d3b2e71a185ce5507e2caf596e919f453c88a7 (patch)
tree4e6d9693be888b506aece9fe46e8f47bfaf99268
parent433704bd188c90b81b2a212ac8c5298583002b32 (diff)
downloadnginx-0.7.66.tar.gz
Changes with nginx 0.7.66 07 Jun 2010v0.7.66
*) Security: now nginx/Windows ignores default file stream name. Thanks to Jose Antonio Vazquez Gonzalez. *) Change: now the charset filter runs before the SSI filter. *) Change: now no message is written in an error log if a variable is not found by $r->variable() method. *) Change: now keepalive connections after POST requests are not disabled for MSIE 7.0+. Thanks to Adam Lounds. *) Feature: the "proxy_no_cache" and "fastcgi_no_cache" directives. *) Feature: now the "rewrite" directive does a redirect automatically if the $scheme variable is used. Thanks to Piotr Sikora. *) Feature: the "chunked_transfer_encoding" directive. *) Feature: the $geoip_city_continent_code, $geoip_latitude, and $geoip_longitude variables. Thanks to Arvind Sundararajan. *) Feature: now the ngx_http_image_filter_module deletes always EXIF and other application specific data if the data consume more than 5% of a JPEG file. *) Feature: now the "msie_padding" directive works for Chrome too. *) Workaround: now keepalive connections are disabled for Safari. Thanks to Joshua Sierles. *) Bugfix: nginx ignored the "private" and "no-store" values in the "Cache-Control" backend response header line. *) Bugfix: an "&" character was not escaped when it was copied in arguments part in a rewrite rule. *) Bugfix: nginx might be terminated abnormally while a signal processing or if the directive "timer_resolution" was used on platforms which do not support kqueue or eventport notification methods. Thanks to George Xie and Maxim Dounin. *) Bugfix: if temporary files and permanent storage area resided at different file systems, then permanent file modification times were incorrect. Thanks to Maxim Dounin. *) Bugfix: ngx_http_memcached_module might issue the error message "memcached sent invalid trailer". Thanks to Maxim Dounin. *) Bugfix: nginx could not built zlib-1.2.4 library using the library sources. Thanks to Maxim Dounin. *) Bugfix: values of the $query_string, $arg_..., etc. variables cached in main request were used by the SSI module in subrequests. *) Bugfix: nginx did not support HTTPS referrers. *) Bugfix: nginx/Windows might not find file if path in configuration was given in other character case; the bug had appeared in 0.7.65. *) Bugfix: the $date_local variable has an incorrect value, if the "%s" format was used. Thanks to Maxim Dounin. *) Bugfix: nginx did not support all ciphers and digests used in client certificates. Thanks to Innocenty Enikeew. *) Bugfix: if ssl_session_cache was not set or was set to "none", then during client certificate verify the error "session id context uninitialized" might occur; the bug had appeared in 0.7.1. *) Bugfix: OpenSSL-1.0.0 compatibility on 64-bit Linux. Thanks to Maxim Dounin. *) Bugfix: a geo range returned default value if the range included two or more /16 networks and did not begin at /16 network boundary. *) Bugfix: the $uid_got variable might not be used in the SSI and perl modules. *) Bugfix: a worker process hung if a FIFO file was requested. Thanks to Vicente Aguilar and Maxim Dounin. *) Bugfix: a variable value was repeatedly encoded after each an "echo" SSI-command output; the bug had appeared in 0.6.14. *) Bugfix: a "stub" parameter of an "include" SSI directive was not used, if empty response has 200 status code. *) Bugfix: a block used in a "stub" parameter of an "include" SSI directive was output with "text/plain" MIME type. *) Bugfix: if a proxied or FastCGI request was internally redirected to another proxied or FastCGI location, then a segmentation fault might occur in a worker process; the bug had appeared in 0.7.65. Thanks to Yichun Zhang. *) Bugfix: IMAP connections may hang until they timed out while talking to Zimbra server. Thanks to Alan Batie. *) Bugfix: nginx did not support chunked transfer encoding for 201 responses. Thanks to Julian Reich.
-rw-r--r--CHANGES115
-rw-r--r--CHANGES.ru122
-rw-r--r--auto/cc/conf1
-rw-r--r--auto/cc/gcc2
-rw-r--r--auto/feature2
-rw-r--r--auto/lib/openssl/conf2
-rw-r--r--auto/lib/openssl/make2
-rw-r--r--auto/lib/openssl/makefile.bcc3
-rw-r--r--auto/lib/openssl/makefile.msvc3
-rw-r--r--auto/lib/zlib/make6
-rw-r--r--auto/modules14
-rwxr-xr-xauto/unix10
-rw-r--r--src/core/nginx.h4
-rw-r--r--src/core/ngx_cycle.c2
-rw-r--r--src/core/ngx_file.c10
-rw-r--r--src/core/ngx_open_file_cache.c9
-rw-r--r--src/core/ngx_string.c4
-rw-r--r--src/core/ngx_times.c82
-rw-r--r--src/core/ngx_times.h3
-rw-r--r--src/event/modules/ngx_devpoll_module.c4
-rw-r--r--src/event/modules/ngx_epoll_module.c4
-rw-r--r--src/event/modules/ngx_eventport_module.c4
-rw-r--r--src/event/modules/ngx_kqueue_module.c6
-rw-r--r--src/event/modules/ngx_poll_module.c4
-rw-r--r--src/event/modules/ngx_rtsig_module.c8
-rw-r--r--src/event/modules/ngx_select_module.c4
-rw-r--r--src/event/modules/ngx_win32_select_module.c2
-rw-r--r--src/event/ngx_event.c2
-rw-r--r--src/event/ngx_event_openssl.c14
-rw-r--r--src/event/ngx_event_openssl.h1
-rw-r--r--src/http/modules/ngx_http_autoindex_module.c4
-rw-r--r--src/http/modules/ngx_http_chunked_filter_module.c12
-rw-r--r--src/http/modules/ngx_http_dav_module.c18
-rw-r--r--src/http/modules/ngx_http_fastcgi_module.c11
-rw-r--r--src/http/modules/ngx_http_flv_module.c4
-rw-r--r--src/http/modules/ngx_http_geo_module.c2
-rw-r--r--src/http/modules/ngx_http_geoip_module.c106
-rw-r--r--src/http/modules/ngx_http_gzip_static_module.c6
-rw-r--r--src/http/modules/ngx_http_image_filter_module.c44
-rw-r--r--src/http/modules/ngx_http_index_module.c4
-rw-r--r--src/http/modules/ngx_http_memcached_module.c11
-rw-r--r--src/http/modules/ngx_http_proxy_module.c24
-rw-r--r--src/http/modules/ngx_http_random_index_module.c4
-rw-r--r--src/http/modules/ngx_http_referer_module.c25
-rw-r--r--src/http/modules/ngx_http_rewrite_module.c11
-rw-r--r--src/http/modules/ngx_http_ssi_filter_module.c38
-rw-r--r--src/http/modules/ngx_http_static_module.c6
-rw-r--r--src/http/modules/ngx_http_userid_filter_module.c2
-rw-r--r--src/http/modules/perl/nginx.pm2
-rw-r--r--src/http/modules/perl/nginx.xs5
-rw-r--r--src/http/modules/perl/ngx_http_perl_module.c10
-rw-r--r--src/http/ngx_http_cache.h5
-rw-r--r--src/http/ngx_http_copy_filter_module.c4
-rw-r--r--src/http/ngx_http_core_module.c35
-rw-r--r--src/http/ngx_http_core_module.h1
-rw-r--r--src/http/ngx_http_file_cache.c70
-rw-r--r--src/http/ngx_http_header_filter_module.c4
-rw-r--r--src/http/ngx_http_parse.c49
-rw-r--r--src/http/ngx_http_request.c29
-rw-r--r--src/http/ngx_http_request.h7
-rw-r--r--src/http/ngx_http_special_response.c24
-rw-r--r--src/http/ngx_http_upstream.c23
-rw-r--r--src/http/ngx_http_upstream.h1
-rw-r--r--src/http/ngx_http_variables.c16
-rw-r--r--src/http/ngx_http_variables.h2
-rw-r--r--src/mail/ngx_mail_pop3_handler.c2
-rw-r--r--src/mail/ngx_mail_proxy_module.c2
-rw-r--r--src/os/unix/ngx_errno.h14
-rw-r--r--src/os/unix/ngx_files.h4
-rw-r--r--src/os/unix/ngx_process.c13
-rw-r--r--src/os/unix/ngx_process_cycle.c6
71 files changed, 809 insertions, 300 deletions
diff --git a/CHANGES b/CHANGES
index d292d381f..6c5bb387f 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,119 @@
+Changes with nginx 0.7.66 07 Jun 2010
+
+ *) Security: now nginx/Windows ignores default file stream name.
+ Thanks to Jose Antonio Vazquez Gonzalez.
+
+ *) Change: now the charset filter runs before the SSI filter.
+
+ *) Change: now no message is written in an error log if a variable is
+ not found by $r->variable() method.
+
+ *) Change: now keepalive connections after POST requests are not
+ disabled for MSIE 7.0+.
+ Thanks to Adam Lounds.
+
+ *) Feature: the "proxy_no_cache" and "fastcgi_no_cache" directives.
+
+ *) Feature: now the "rewrite" directive does a redirect automatically
+ if the $scheme variable is used.
+ Thanks to Piotr Sikora.
+
+ *) Feature: the "chunked_transfer_encoding" directive.
+
+ *) Feature: the $geoip_city_continent_code, $geoip_latitude, and
+ $geoip_longitude variables.
+ Thanks to Arvind Sundararajan.
+
+ *) Feature: now the ngx_http_image_filter_module deletes always EXIF
+ and other application specific data if the data consume more than 5%
+ of a JPEG file.
+
+ *) Feature: now the "msie_padding" directive works for Chrome too.
+
+ *) Workaround: now keepalive connections are disabled for Safari.
+ Thanks to Joshua Sierles.
+
+ *) Bugfix: nginx ignored the "private" and "no-store" values in the
+ "Cache-Control" backend response header line.
+
+ *) Bugfix: an "&" character was not escaped when it was copied in
+ arguments part in a rewrite rule.
+
+ *) Bugfix: nginx might be terminated abnormally while a signal
+ processing or if the directive "timer_resolution" was used on
+ platforms which do not support kqueue or eventport notification
+ methods.
+ Thanks to George Xie and Maxim Dounin.
+
+ *) Bugfix: if temporary files and permanent storage area resided at
+ different file systems, then permanent file modification times were
+ incorrect.
+ Thanks to Maxim Dounin.
+
+ *) Bugfix: ngx_http_memcached_module might issue the error message
+ "memcached sent invalid trailer".
+ Thanks to Maxim Dounin.
+
+ *) Bugfix: nginx could not built zlib-1.2.4 library using the library
+ sources.
+ Thanks to Maxim Dounin.
+
+ *) Bugfix: values of the $query_string, $arg_..., etc. variables cached
+ in main request were used by the SSI module in subrequests.
+
+ *) Bugfix: nginx did not support HTTPS referrers.
+
+ *) Bugfix: nginx/Windows might not find file if path in configuration
+ was given in other character case; the bug had appeared in 0.7.65.
+
+ *) Bugfix: the $date_local variable has an incorrect value, if the "%s"
+ format was used.
+ Thanks to Maxim Dounin.
+
+ *) Bugfix: nginx did not support all ciphers and digests used in client
+ certificates.
+ Thanks to Innocenty Enikeew.
+
+ *) Bugfix: if ssl_session_cache was not set or was set to "none", then
+ during client certificate verify the error "session id context
+ uninitialized" might occur; the bug had appeared in 0.7.1.
+
+ *) Bugfix: OpenSSL-1.0.0 compatibility on 64-bit Linux.
+ Thanks to Maxim Dounin.
+
+ *) Bugfix: a geo range returned default value if the range included two
+ or more /16 networks and did not begin at /16 network boundary.
+
+ *) Bugfix: the $uid_got variable might not be used in the SSI and perl
+ modules.
+
+ *) Bugfix: a worker process hung if a FIFO file was requested.
+ Thanks to Vicente Aguilar and Maxim Dounin.
+
+ *) Bugfix: a variable value was repeatedly encoded after each an "echo"
+ SSI-command output; the bug had appeared in 0.6.14.
+
+ *) Bugfix: a "stub" parameter of an "include" SSI directive was not
+ used, if empty response has 200 status code.
+
+ *) Bugfix: a block used in a "stub" parameter of an "include" SSI
+ directive was output with "text/plain" MIME type.
+
+ *) Bugfix: if a proxied or FastCGI request was internally redirected to
+ another proxied or FastCGI location, then a segmentation fault might
+ occur in a worker process; the bug had appeared in 0.7.65.
+ Thanks to Yichun Zhang.
+
+ *) Bugfix: IMAP connections may hang until they timed out while talking
+ to Zimbra server.
+ Thanks to Alan Batie.
+
+ *) Bugfix: nginx did not support chunked transfer encoding for 201
+ responses.
+ Thanks to Julian Reich.
+
+
Changes with nginx 0.7.65 01 Feb 2010
*) Security: now nginx/Windows ignores trailing spaces in URI.
diff --git a/CHANGES.ru b/CHANGES.ru
index 50dff9985..3845c0157 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,122 @@
+Изменения в nginx 0.7.66 07.06.2010
+
+ *) Безопасность: теперь nginx/Windows игнорирует имя потока файла по
+ умолчанию.
+ Спасибо Jose Antonio Vazquez Gonzalez.
+
+ *) Изменение: теперь charset-фильтр работает до SSI-фильтра.
+
+ *) Изменение: теперь в лог ошибок не пишется сообщение, если переменная
+ не найдена с помощью метода $r->variable().
+
+ *) Изменение: теперь keepalive соединения после запросов POST не
+ запрещаются для MSIE 7.0+.
+ Спасибо Adam Lounds.
+
+ *) Добавление: директивы proxy_no_cache и fastcgi_no_cache.
+
+ *) Добавление: теперь при использовании переменной $scheme в директиве
+ rewrite автоматически делается редирект.
+ Спасибо Piotr Sikora.
+
+ *) Добавление: директива chunked_transfer_encoding.
+
+ *) Добавление: переменные $geoip_city_continent_code, $geoip_latitude и
+ $geoip_longitude.
+ Спасибо Arvind Sundararajan.
+
+ *) Добавление: модуль ngx_http_image_filter_module теперь всегда
+ удаляет EXIF и другие данные, если они занимают больше 5% в
+ JPEG-файле.
+
+ *) Добавление: теперь директива msie_padding работает и для Chrome.
+
+ *) Изменение: теперь keepalive соединения запрещены для Safari.
+ Спасибо Joshua Sierles.
+
+ *) Исправление: nginx игнорировал значения "private" и "no-store" в
+ строке "Cache-Control" в заголовке ответа бэкенда.
+
+ *) Исправление: символ "&" при копировании в аргументы в правилах
+ rewrite не экранировался.
+
+ *) Исправление: nginx мог завершаться аварийно во время обработки
+ сигнала или при использовании директивы timer_resolution на
+ платформах, не поддерживающих методы kqueue или eventport.
+ Спасибо George Xie и Максиму Дунину.
+
+ *) Исправление: если временные файлы и постоянное место хранения
+ располагались на разных файловых системах, то у постоянных файлов
+ время изменения было неверным.
+ Спасибо Максиму Дунину.
+
+ *) Исправление: модуль ngx_http_memcached_module мог выдавать ошибку
+ "memcached sent invalid trailer".
+ Спасибо Максиму Дунину.
+
+ *) Исправление: nginx не мог собрать библиотеку zlib-1.2.4 из исходных
+ текстов.
+ Спасибо Максиму Дунину.
+
+ *) Исправление: модуль SSI в подзапросах использовал закэшированные в
+ основном запросе значения переменных $query_string, $arg_... и им
+ подобных.
+
+ *) Исправление: nginx не поддерживал HTTPS-рефереры.
+
+ *) Исправление: nginx/Windows мог не находить файлы, если путь в
+ конфигурации был задан в другом регистре; ошибка появилась в 0.7.65.
+
+ *) Исправление: переменная $date_local выдавала неверное время, если
+ использовался формат "%s".
+ Спасибо Максиму Дунину.
+
+ *) Исправление: nginx не поддерживал все шифры, используемые в
+ клиентских сертификатах.
+ Спасибо Иннокентию Еникееву.
+
+ *) Исправление: если ssl_session_cache не был установлен или установлен
+ в none, то при проверке клиентского сертификаты могла происходить
+ ошибка "session id context uninitialized"; ошибка появилась в 0.7.1.
+
+ *) Исправление: совместимость с OpenSSL-1.0.0 на 64-битном Linux.
+ Спасибо Максиму Дунину.
+
+ *) Исправление: geo-диапазон возвращал значение по умолчанию, если
+ диапазон включал в себя одну и более сетей размером /16 и не
+ начинался на границе сети размером /16.
+
+ *) Исправление: переменную $uid_got нельзя было использовать в SSI и
+ перловом модулях.
+
+ *) Исправление: рабочий процесс зависал при запросе файла FIFO.
+ Спасибо Vicente Aguilar и Максиму Дунину.
+
+ *) Исправление: значение переменной повторно экранировалось после
+ каждого вывода SSI-команды echo; ошибка появилась в 0.6.14.
+
+ *) Исправление: параметр stub в SSI-директиве include не использовался,
+ если пустой ответ имел код 200.
+
+ *) Исправление: блок, используемый в параметре stub в SSI-директиве
+ include, выводился с MIME-типом "text/plain".
+
+ *) Исправление: если проксированный или FastCGI запрос внутренне
+ перенаправлялся в другой проксированный или FastCGI location, то в
+ рабочем процессе мог произойти segmentation fault; ошибка появилась
+ в 0.7.65.
+ Спасибо Yichun Zhang.
+
+ *) Исправление: соединения IMAP к серверу Zimbra могло зависнуть до
+ таймаута.
+ Спасибо Alan Batie.
+
+ *) Исправление: nginx не поддерживал передачу chunk'ами для 201-ых
+ ответов.
+ Спасибо Julian Reich.
+
+
Изменения в nginx 0.7.65 01.02.2010
*) Безопасность: теперь nginx/Windows игнорирует пробелы в конце URI.
@@ -178,7 +296,7 @@
*) Добавление: директивы limit_req_log_level и limit_conn_log_level.
- *) Исправление: Теперь директива limit_req соответствует алгоритму
+ *) Исправление: теперь директива limit_req соответствует алгоритму
leaky bucket.
Спасибо Максиму Дунину.
@@ -1648,7 +1766,7 @@
Спасибо Андрею Нигматулину.
*) Исправление: ngx_http_memcached_module не устанавливал
- upstream_response_time.
+ $upstream_response_time.
Спасибо Максиму Дунину.
*) Исправление: рабочий процесс мог зациклиться при использовании
diff --git a/auto/cc/conf b/auto/cc/conf
index 482390029..dacb079c7 100644
--- a/auto/cc/conf
+++ b/auto/cc/conf
@@ -104,6 +104,7 @@ else
fi
CFLAGS="$CFLAGS $NGX_CC_OPT"
+NGX_TEST_LD_OPT="$NGX_LD_OPT"
if [ "$NGX_PLATFORM" != win32 ]; then
diff --git a/auto/cc/gcc b/auto/cc/gcc
index 8e5422e08..772b92582 100644
--- a/auto/cc/gcc
+++ b/auto/cc/gcc
@@ -51,8 +51,6 @@ esac
#NGX_GCC_OPT="-Os"
NGX_GCC_OPT="-O"
-CFLAGS="$CFLAGS $NGX_GCC_OPT"
-
#CFLAGS="$CFLAGS -fomit-frame-pointer"
case $CPU in
diff --git a/auto/feature b/auto/feature
index cd71e27b1..1bd334551 100644
--- a/auto/feature
+++ b/auto/feature
@@ -39,7 +39,7 @@ END
ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS $ngx_feature_inc_path \
- -o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_LD_OPT $ngx_feature_libs"
+ -o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_TEST_LD_OPT $ngx_feature_libs"
ngx_feature_inc_path=
diff --git a/auto/lib/openssl/conf b/auto/lib/openssl/conf
index 64f2ce02f..c57a7c830 100644
--- a/auto/lib/openssl/conf
+++ b/auto/lib/openssl/conf
@@ -19,6 +19,8 @@ if [ $OPENSSL != NONE ]; then
# libeay32.lib requires gdi32.lib
CORE_LIBS="$CORE_LIBS gdi32.lib"
+ # OpenSSL 1.0.0 requires crypt32.lib
+ CORE_LIBS="$CORE_LIBS crypt32.lib"
;;
*)
diff --git a/auto/lib/openssl/make b/auto/lib/openssl/make
index d497d88e1..a2025bbd6 100644
--- a/auto/lib/openssl/make
+++ b/auto/lib/openssl/make
@@ -57,7 +57,7 @@ $OPENSSL/.openssl/include/openssl/ssl.h: $NGX_MAKEFILE
&& \$(MAKE) clean \\
&& ./config --prefix=$ngx_prefix no-shared $OPENSSL_OPT \\
&& \$(MAKE) \\
- && \$(MAKE) install
+ && \$(MAKE) install LIBDIR=lib
END
diff --git a/auto/lib/openssl/makefile.bcc b/auto/lib/openssl/makefile.bcc
index 679e7fe4a..5938cbf6b 100644
--- a/auto/lib/openssl/makefile.bcc
+++ b/auto/lib/openssl/makefile.bcc
@@ -5,8 +5,7 @@
all:
cd $(OPENSSL)
- perl Configure BC-32 no-shared --prefix=openssl -DNO_SYS_TYPES_H \
- $(OPENSSL_OPT)
+ perl Configure BC-32 no-shared --prefix=openssl $(OPENSSL_OPT)
ms\do_nasm
diff --git a/auto/lib/openssl/makefile.msvc b/auto/lib/openssl/makefile.msvc
index 0e45c487f..379b95dc0 100644
--- a/auto/lib/openssl/makefile.msvc
+++ b/auto/lib/openssl/makefile.msvc
@@ -5,8 +5,7 @@
all:
cd $(OPENSSL)
- perl Configure VC-WIN32 no-shared --prefix=openssl -DNO_SYS_TYPES_H \
- $(OPENSSL_OPT)
+ perl Configure VC-WIN32 no-shared --prefix=openssl $(OPENSSL_OPT)
ms\do_ms
diff --git a/auto/lib/zlib/make b/auto/lib/zlib/make
index 4d62b757f..b874b04ad 100644
--- a/auto/lib/zlib/make
+++ b/auto/lib/zlib/make
@@ -53,7 +53,7 @@ END
$ZLIB/libz.a: $NGX_MAKEFILE
cd $ZLIB \\
- && \$(MAKE) clean \\
+ && \$(MAKE) distclean \\
&& cp contrib/asm586/match.S . \\
&& CFLAGS="$ZLIB_OPT -DASMV" CC="\$(CC)" \\
./configure \\
@@ -70,7 +70,7 @@ END
$ZLIB/libz.a: $NGX_MAKEFILE
cd $ZLIB \\
- && \$(MAKE) clean \\
+ && \$(MAKE) distclean \\
&& cp contrib/asm686/match.S . \\
&& CFLAGS="$ZLIB_OPT -DASMV" CC="\$(CC)" \\
./configure \\
@@ -103,7 +103,7 @@ if [ $done = NO ]; then
$ZLIB/libz.a: $NGX_MAKEFILE
cd $ZLIB \\
- && \$(MAKE) clean \\
+ && \$(MAKE) distclean \\
&& CFLAGS="$ZLIB_OPT" CC="\$(CC)" \\
./configure \\
&& \$(MAKE) libz.a
diff --git a/auto/modules b/auto/modules
index 01951c738..d19eda1db 100644
--- a/auto/modules
+++ b/auto/modules
@@ -101,8 +101,8 @@ fi
# ngx_http_range_header_filter
# ngx_http_gzip_filter
# ngx_http_postpone_filter
-# ngx_http_charset_filter
# ngx_http_ssi_filter
+# ngx_http_charset_filter
# ngx_http_xslt_filter
# ngx_http_image_filter_filter
# ngx_http_sub_filter
@@ -130,12 +130,6 @@ if [ $HTTP_POSTPONE = YES ]; then
HTTP_SRCS="$HTTP_SRCS $HTTP_POSTPONE_FILTER_SRCS"
fi
-if [ $HTTP_CHARSET = YES ]; then
- have=NGX_HTTP_CHARSET . auto/have
- HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_CHARSET_FILTER_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_CHARSET_SRCS"
-fi
-
if [ $HTTP_SSI = YES ]; then
have=NGX_HTTP_SSI . auto/have
HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_SSI_FILTER_MODULE"
@@ -143,6 +137,12 @@ if [ $HTTP_SSI = YES ]; then
HTTP_SRCS="$HTTP_SRCS $HTTP_SSI_SRCS"
fi
+if [ $HTTP_CHARSET = YES ]; then
+ have=NGX_HTTP_CHARSET . auto/have
+ HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_CHARSET_FILTER_MODULE"
+ HTTP_SRCS="$HTTP_SRCS $HTTP_CHARSET_SRCS"
+fi
+
if [ $HTTP_XSLT = YES ]; then
USE_LIBXSLT=YES
HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_XSLT_FILTER_MODULE"
diff --git a/auto/unix b/auto/unix
index 687a23a88..728b116d2 100755
--- a/auto/unix
+++ b/auto/unix
@@ -133,6 +133,16 @@ ngx_feature_test="char buf[1024]; long n; n = strerror_r(1, buf, 1024);
. auto/feature
+ngx_feature="sys_errlist[]"
+ngx_feature_name="NGX_HAVE_SYS_ERRLIST"
+ngx_feature_run=yes
+ngx_feature_incs="#include <stdio.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="int n = sys_nerr; const char *p = sys_errlist[1];"
+. auto/feature
+
+
ngx_feature="localtime_r()"
ngx_feature_name="NGX_HAVE_LOCALTIME_R"
ngx_feature_run=no
diff --git a/src/core/nginx.h b/src/core/nginx.h
index c444f473d..86c943465 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,8 +8,8 @@
#define _NGINX_H_INCLUDED_
-#define nginx_version 7065
-#define NGINX_VERSION "0.7.65"
+#define nginx_version 7066
+#define NGINX_VERSION "0.7.66"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c
index cd9efbee7..cb551e945 100644
--- a/src/core/ngx_cycle.c
+++ b/src/core/ngx_cycle.c
@@ -63,7 +63,7 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
tp = ngx_timeofday();
tp->sec = 0;
- ngx_time_update(0, 0);
+ ngx_time_update();
log = old_cycle->log;
diff --git a/src/core/ngx_file.c b/src/core/ngx_file.c
index 6844849ad..b5160f3ea 100644
--- a/src/core/ngx_file.c
+++ b/src/core/ngx_file.c
@@ -762,10 +762,12 @@ ngx_copy_file(u_char *from, u_char *to, ngx_copy_file_t *cf)
size -= n;
}
- if (ngx_set_file_time(to, nfd, cf->time) != NGX_OK) {
- ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
- ngx_set_file_time_n " \"%s\" failed", to);
- goto failed;
+ if (cf->time != -1) {
+ if (ngx_set_file_time(to, nfd, cf->time) != NGX_OK) {
+ ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
+ ngx_set_file_time_n " \"%s\" failed", to);
+ goto failed;
+ }
}
rc = NGX_OK;
diff --git a/src/core/ngx_open_file_cache.c b/src/core/ngx_open_file_cache.c
index 5f6e0b263..034bf3b60 100644
--- a/src/core/ngx_open_file_cache.c
+++ b/src/core/ngx_open_file_cache.c
@@ -487,7 +487,14 @@ ngx_open_and_stat_file(u_char *name, ngx_open_file_info_t *of, ngx_log_t *log)
}
if (!of->log) {
- fd = ngx_open_file(name, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);
+
+ /*
+ * Use non-blocking open() not to hang on FIFO files, etc.
+ * This flag has no effect on a regular files.
+ */
+
+ fd = ngx_open_file(name, NGX_FILE_RDONLY|NGX_FILE_NONBLOCK,
+ NGX_FILE_OPEN, 0);
} else {
fd = ngx_open_file(name, NGX_FILE_APPEND, NGX_FILE_CREATE_OR_OPEN,
diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c
index f8b165731..9068bd9ea 100644
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -1277,13 +1277,13 @@ ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
};
- /* " ", "#", "%", "+", "?", %00-%1F, %7F-%FF */
+ /* " ", "#", "%", "&", "+", "?", %00-%1F, %7F-%FF */
static uint32_t args[] = {
0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
/* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
- 0x80000829, /* 1000 0000 0000 0000 0000 1000 0010 1001 */
+ 0x80000869, /* 1000 0000 0000 0000 0000 1000 0110 1001 */
/* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
diff --git a/src/core/ngx_times.c b/src/core/ngx_times.c
index 3105beb47..50501246a 100644
--- a/src/core/ngx_times.c
+++ b/src/core/ngx_times.c
@@ -28,6 +28,17 @@ volatile ngx_str_t ngx_cached_err_log_time;
volatile ngx_str_t ngx_cached_http_time;
volatile ngx_str_t ngx_cached_http_log_time;
+#if !(NGX_WIN32)
+
+/*
+ * locatime() and localtime_r() are not Async-Signal-Safe functions, therefore,
+ * they must not be called by a signal handler, so we use the cached
+ * GMT offset value. Fortunately the value is changed only two times a year.
+ */
+
+static ngx_int_t cached_gmtoff;
+#endif
+
static ngx_time_t cached_time[NGX_TIME_SLOTS];
static u_char cached_err_log_time[NGX_TIME_SLOTS]
[sizeof("1970/09/28 12:00:00")];
@@ -50,15 +61,17 @@ ngx_time_init(void)
ngx_cached_time = &cached_time[0];
- ngx_time_update(0, 0);
+ ngx_time_update();
}
void
-ngx_time_update(time_t sec, ngx_uint_t msec)
+ngx_time_update(void)
{
u_char *p0, *p1, *p2;
ngx_tm_t tm, gmt;
+ time_t sec;
+ ngx_uint_t msec;
ngx_time_t *tp;
struct timeval tv;
@@ -66,12 +79,10 @@ ngx_time_update(time_t sec, ngx_uint_t msec)
return;
}
- if (sec == 0) {
- ngx_gettimeofday(&tv);
+ ngx_gettimeofday(&tv);
- sec = tv.tv_sec;
- msec = tv.tv_usec / 1000;
- }
+ sec = tv.tv_sec;
+ msec = tv.tv_usec / 1000;
ngx_current_msec = (ngx_msec_t) sec * 1000 + msec;
@@ -112,12 +123,14 @@ ngx_time_update(time_t sec, ngx_uint_t msec)
#elif (NGX_HAVE_GMTOFF)
ngx_localtime(sec, &tm);
- tp->gmtoff = (ngx_int_t) (tm.ngx_tm_gmtoff / 60);
+ cached_gmtoff = (ngx_int_t) (tm.ngx_tm_gmtoff / 60);
+ tp->gmtoff = cached_gmtoff;
#else
ngx_localtime(sec, &tm);
- tp->gmtoff = ngx_timezone(tm.ngx_tm_isdst);
+ cached_gmtoff = ngx_timezone(tm.ngx_tm_isdst);
+ tp->gmtoff = cached_gmtoff;
#endif
@@ -151,6 +164,57 @@ ngx_time_update(time_t sec, ngx_uint_t msec)
}
+#if !(NGX_WIN32)
+
+void
+ngx_time_sigsafe_update(void)
+{
+ u_char *p;
+ ngx_tm_t tm;
+ time_t sec;
+ ngx_time_t *tp;
+ struct timeval tv;
+
+ if (!ngx_trylock(&ngx_time_lock)) {
+ return;
+ }
+
+ ngx_gettimeofday(&tv);
+
+ sec = tv.tv_sec;
+
+ tp = &cached_time[slot];
+
+ if (tp->sec == sec) {
+ ngx_unlock(&ngx_time_lock);
+ return;
+ }
+
+ if (slot == NGX_TIME_SLOTS - 1) {
+ slot = 0;
+ } else {
+ slot++;
+ }
+
+ ngx_gmtime(sec + cached_gmtoff * 60, &tm);
+
+ p = &cached_err_log_time[slot][0];
+
+ (void) ngx_sprintf(p, "%4d/%02d/%02d %02d:%02d:%02d",
+ tm.ngx_tm_year, tm.ngx_tm_mon,
+ tm.ngx_tm_mday, tm.ngx_tm_hour,
+ tm.ngx_tm_min, tm.ngx_tm_sec);
+
+ ngx_memory_barrier();
+
+ ngx_cached_err_log_time.data = p;
+
+ ngx_unlock(&ngx_time_lock);
+}
+
+#endif
+
+
u_char *
ngx_http_time(u_char *buf, time_t t)
{
diff --git a/src/core/ngx_times.h b/src/core/ngx_times.h
index 8363ca136..4e31f00a0 100644
--- a/src/core/ngx_times.h
+++ b/src/core/ngx_times.h
@@ -20,7 +20,8 @@ typedef struct {
void ngx_time_init(void);
-void ngx_time_update(time_t sec, ngx_uint_t msec);
+void ngx_time_update(void);
+void ngx_time_sigsafe_update(void);
u_char *ngx_http_time(u_char *buf, time_t t);
u_char *ngx_http_cookie_time(u_char *buf, time_t t);
void ngx_gmtime(time_t t, ngx_tm_t *tp);
diff --git a/src/event/modules/ngx_devpoll_module.c b/src/event/modules/ngx_devpoll_module.c
index 657886268..b12badf33 100644
--- a/src/event/modules/ngx_devpoll_module.c
+++ b/src/event/modules/ngx_devpoll_module.c
@@ -375,8 +375,8 @@ ngx_devpoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
err = 0;
}
- if (flags & NGX_UPDATE_TIME) {
- ngx_time_update(0, 0);
+ if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
+ ngx_time_update();
}
if (err) {
diff --git a/src/event/modules/ngx_epoll_module.c b/src/event/modules/ngx_epoll_module.c
index b3267b37d..1a7215fb4 100644
--- a/src/event/modules/ngx_epoll_module.c
+++ b/src/event/modules/ngx_epoll_module.c
@@ -407,8 +407,8 @@ ngx_epoll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
err = 0;
}
- if (flags & NGX_UPDATE_TIME) {
- ngx_time_update(0, 0);
+ if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
+ ngx_time_update();
}
if (err) {
diff --git a/src/event/modules/ngx_eventport_module.c b/src/event/modules/ngx_eventport_module.c
index 842d631af..f4f0119a5 100644
--- a/src/event/modules/ngx_eventport_module.c
+++ b/src/event/modules/ngx_eventport_module.c
@@ -405,7 +405,7 @@ ngx_eventport_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
err = ngx_errno;
if (flags & NGX_UPDATE_TIME) {
- ngx_time_update(0, 0);
+ ngx_time_update();
}
if (n == -1) {
@@ -439,7 +439,7 @@ ngx_eventport_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
for (i = 0; i < events; i++) {
if (event_list[i].portev_source == PORT_SOURCE_TIMER) {
- ngx_time_update(0, 0);
+ ngx_time_update();
continue;
}
diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c
index a84fc8fe1..fac647408 100644
--- a/src/event/modules/ngx_kqueue_module.c
+++ b/src/event/modules/ngx_kqueue_module.c
@@ -543,8 +543,8 @@ ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
err = 0;
}
- if (flags & NGX_UPDATE_TIME) {
- ngx_time_update(0, 0);
+ if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
+ ngx_time_update();
}
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
@@ -595,7 +595,7 @@ ngx_kqueue_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
#if (NGX_HAVE_TIMER_EVENT)
if (event_list[i].filter == EVFILT_TIMER) {
- ngx_time_update(0, 0);
+ ngx_time_update();
continue;
}
diff --git a/src/event/modules/ngx_poll_module.c b/src/event/modules/ngx_poll_module.c
index db9c41945..958ea3ede 100644
--- a/src/event/modules/ngx_poll_module.c
+++ b/src/event/modules/ngx_poll_module.c
@@ -266,8 +266,8 @@ ngx_poll_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
err = 0;
}
- if (flags & NGX_UPDATE_TIME) {
- ngx_time_update(0, 0);
+ if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
+ ngx_time_update();
}
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
diff --git a/src/event/modules/ngx_rtsig_module.c b/src/event/modules/ngx_rtsig_module.c
index 926be0de3..4b011007b 100644
--- a/src/event/modules/ngx_rtsig_module.c
+++ b/src/event/modules/ngx_rtsig_module.c
@@ -323,7 +323,7 @@ ngx_rtsig_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
"rtsig signo:%d", signo);
if (flags & NGX_UPDATE_TIME) {
- ngx_time_update(0, 0);
+ ngx_time_update();
}
if (err == NGX_EAGAIN) {
@@ -349,7 +349,7 @@ ngx_rtsig_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
signo, si.si_fd, si.si_band);
if (flags & NGX_UPDATE_TIME) {
- ngx_time_update(0, 0);
+ ngx_time_update();
}
rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module);
@@ -419,7 +419,7 @@ ngx_rtsig_process_events(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags)
} else if (signo == SIGALRM) {
- ngx_time_update(0, 0);
+ ngx_time_update();
return NGX_OK;
@@ -671,7 +671,7 @@ ngx_rtsig_process_overflow(ngx_cycle_t *cycle, ngx_msec_t timer,
}
if (flags & NGX_UPDATE_TIME) {
- ngx_time_update(0, 0);
+ ngx_time_update();
}
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
diff --git a/src/event/modules/ngx_select_module.c b/src/event/modules/ngx_select_module.c
index a09712bfa..8015c5175 100644
--- a/src/event/modules/ngx_select_module.c
+++ b/src/event/modules/ngx_select_module.c
@@ -266,8 +266,8 @@ ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
err = 0;
}
- if (flags & NGX_UPDATE_TIME) {
- ngx_time_update(0, 0);
+ if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
+ ngx_time_update();
}
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
diff --git a/src/event/modules/ngx_win32_select_module.c b/src/event/modules/ngx_win32_select_module.c
index 768c60ccb..cefe05929 100644
--- a/src/event/modules/ngx_win32_select_module.c
+++ b/src/event/modules/ngx_win32_select_module.c
@@ -273,7 +273,7 @@ ngx_select_process_events(ngx_cycle_t *cycle, ngx_msec_t timer,
}
if (flags & NGX_UPDATE_TIME) {
- ngx_time_update(0, 0);
+ ngx_time_update();
}
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c
index 9c13eac47..3922b0e20 100644
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -562,8 +562,6 @@ ngx_timer_signal_handler(int signo)
{
ngx_event_timer_alarm = 1;
- ngx_time_update(0, 0);
-
#if 1
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, "timer signal");
#endif
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index d4b5683d6..5eab4affb 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -106,6 +106,8 @@ ngx_ssl_init(ngx_log_t *log)
ENGINE_load_builtin_engines();
+ OpenSSL_add_all_algorithms();
+
ngx_ssl_connection_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
if (ngx_ssl_connection_index == -1) {
@@ -559,6 +561,9 @@ ngx_ssl_handshake(ngx_connection_t *c)
#if (NGX_DEBUG)
{
char buf[129], *s, *d;
+#if OPENSSL_VERSION_NUMBER >= 0x1000000fL
+ const
+#endif
SSL_CIPHER *cipher;
cipher = SSL_get_current_cipher(c->ssl->connection);
@@ -1308,10 +1313,14 @@ ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
/* handshake failures */
if (n == SSL_R_DIGEST_CHECK_FAILED /* 149 */
+ || n == SSL_R_LENGTH_MISMATCH /* 159 */
|| n == SSL_R_NO_CIPHERS_PASSED /* 182 */
+ || n == SSL_R_NO_CIPHERS_SPECIFIED /* 183 */
|| n == SSL_R_NO_SHARED_CIPHER /* 193 */
+ || n == SSL_R_RECORD_LENGTH_MISMATCH /* 213 */
|| n == SSL_R_UNEXPECTED_MESSAGE /* 244 */
|| n == SSL_R_UNEXPECTED_RECORD /* 245 */
+ || n == SSL_R_UNKNOWN_ALERT_TYPE /* 246 */
|| n == SSL_R_UNKNOWN_PROTOCOL /* 252 */
|| n == SSL_R_WRONG_VERSION_NUMBER /* 267 */
|| n == SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC /* 281 */
@@ -1424,6 +1433,8 @@ ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
return NGX_OK;
}
+ SSL_CTX_set_session_id_context(ssl->ctx, sess_ctx->data, sess_ctx->len);
+
if (builtin_session_cache == NGX_SSL_NONE_SCACHE) {
/*
@@ -1455,8 +1466,6 @@ ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
SSL_CTX_set_session_cache_mode(ssl->ctx, cache_mode);
- SSL_CTX_set_session_id_context(ssl->ctx, sess_ctx->data, sess_ctx->len);
-
if (builtin_session_cache != NGX_SSL_NO_BUILTIN_SCACHE) {
if (builtin_session_cache != NGX_SSL_DFLT_BUILTIN_SCACHE) {
@@ -2311,5 +2320,6 @@ ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
static void
ngx_openssl_exit(ngx_cycle_t *cycle)
{
+ EVP_cleanup();
ENGINE_cleanup();
}
diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h
index f3b5a2558..a8f9d8757 100644
--- a/src/event/ngx_event_openssl.h
+++ b/src/event/ngx_event_openssl.h
@@ -15,6 +15,7 @@
#include <openssl/err.h>
#include <openssl/conf.h>
#include <openssl/engine.h>
+#include <openssl/evp.h>
#define NGX_SSL_NAME "OpenSSL"
diff --git a/src/http/modules/ngx_http_autoindex_module.c b/src/http/modules/ngx_http_autoindex_module.c
index 698b7636c..bd2de4d77 100644
--- a/src/http/modules/ngx_http_autoindex_module.c
+++ b/src/http/modules/ngx_http_autoindex_module.c
@@ -160,10 +160,6 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
return NGX_DECLINED;
}
- if (r->zero_in_uri) {
- return NGX_DECLINED;
- }
-
if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
return NGX_DECLINED;
}
diff --git a/src/http/modules/ngx_http_chunked_filter_module.c b/src/http/modules/ngx_http_chunked_filter_module.c
index 846053ff4..9c4c5de14 100644
--- a/src/http/modules/ngx_http_chunked_filter_module.c
+++ b/src/http/modules/ngx_http_chunked_filter_module.c
@@ -50,9 +50,10 @@ static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
static ngx_int_t
ngx_http_chunked_header_filter(ngx_http_request_t *r)
{
+ ngx_http_core_loc_conf_t *clcf;
+
if (r->headers_out.status == NGX_HTTP_NOT_MODIFIED
|| r->headers_out.status == NGX_HTTP_NO_CONTENT
- || r->headers_out.status == NGX_HTTP_CREATED
|| r != r->main
|| (r->method & NGX_HTTP_HEAD))
{
@@ -64,7 +65,14 @@ ngx_http_chunked_header_filter(ngx_http_request_t *r)
r->keepalive = 0;
} else {
- r->chunked = 1;
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+ if (clcf->chunked_transfer_encoding) {
+ r->chunked = 1;
+
+ } else {
+ r->keepalive = 0;
+ }
}
}
diff --git a/src/http/modules/ngx_http_dav_module.c b/src/http/modules/ngx_http_dav_module.c
index 2948eec06..3d34a4009 100644
--- a/src/http/modules/ngx_http_dav_module.c
+++ b/src/http/modules/ngx_http_dav_module.c
@@ -146,10 +146,6 @@ ngx_http_dav_handler(ngx_http_request_t *r)
ngx_int_t rc;
ngx_http_dav_loc_conf_t *dlcf;
- if (r->zero_in_uri) {
- return NGX_DECLINED;
- }
-
dlcf = ngx_http_get_module_loc_conf(r, ngx_http_dav_module);
if (!(r->method & dlcf->methods)) {
@@ -325,13 +321,13 @@ ok:
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http delete filename: \"%s\"", path.data);
- if (ngx_file_info(path.data, &fi) == NGX_FILE_ERROR) {
+ if (ngx_link_info(path.data, &fi) == NGX_FILE_ERROR) {
err = ngx_errno;
rc = (err == NGX_ENOTDIR) ? NGX_HTTP_CONFLICT : NGX_HTTP_NOT_FOUND;
return ngx_http_dav_error(r->connection->log, err,
- rc, ngx_file_info_n, path.data);
+ rc, ngx_link_info_n, path.data);
}
if (ngx_is_dir(&fi)) {
@@ -358,7 +354,7 @@ ok:
/*
* we do not need to test (r->uri.data[r->uri.len - 1] == '/')
- * because ngx_file_info("/file/") returned NGX_ENOTDIR above
+ * because ngx_link_info("/file/") returned NGX_ENOTDIR above
*/
depth = ngx_http_dav_depth(r, 0);
@@ -685,12 +681,12 @@ overwrite_done:
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http copy to: \"%s\"", copy.path.data);
- if (ngx_file_info(copy.path.data, &fi) == NGX_FILE_ERROR) {
+ if (ngx_link_info(copy.path.data, &fi) == NGX_FILE_ERROR) {
err = ngx_errno;
if (err != NGX_ENOENT) {
return ngx_http_dav_error(r->connection->log, err,
- NGX_HTTP_NOT_FOUND, ngx_file_info_n,
+ NGX_HTTP_NOT_FOUND, ngx_link_info_n,
copy.path.data);
}
@@ -719,9 +715,9 @@ overwrite_done:
dir = ngx_is_dir(&fi);
}
- if (ngx_file_info(path.data, &fi) == NGX_FILE_ERROR) {
+ if (ngx_link_info(path.data, &fi) == NGX_FILE_ERROR) {
return ngx_http_dav_error(r->connection->log, ngx_errno,
- NGX_HTTP_NOT_FOUND, ngx_file_info_n,
+ NGX_HTTP_NOT_FOUND, ngx_link_info_n,
path.data);
}
diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c
index a4a62e4cc..95079ca28 100644
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -333,6 +333,13 @@ static ngx_command_t ngx_http_fastcgi_commands[] = {
0,
&ngx_http_fastcgi_module },
+ { ngx_string("fastcgi_no_cache"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
+ ngx_http_no_cache_set_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_fastcgi_loc_conf_t, upstream.no_cache),
+ NULL },
+
{ ngx_string("fastcgi_cache_valid"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
ngx_http_file_cache_valid_set_slot,
@@ -1890,6 +1897,7 @@ ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf)
#if (NGX_HTTP_CACHE)
conf->upstream.cache = NGX_CONF_UNSET_PTR;
conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT;
+ conf->upstream.no_cache = NGX_CONF_UNSET_PTR;
conf->upstream.cache_valid = NGX_CONF_UNSET_PTR;
#endif
@@ -2111,6 +2119,9 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
conf->upstream.cache_methods |= NGX_HTTP_GET|NGX_HTTP_HEAD;
+ ngx_conf_merge_ptr_value(conf->upstream.no_cache,
+ prev->upstream.no_cache, NULL);
+
ngx_conf_merge_ptr_value(conf->upstream.cache_valid,
prev->upstream.cache_valid, NULL);
diff --git a/src/http/modules/ngx_http_flv_module.c b/src/http/modules/ngx_http_flv_module.c
index 2afeb2809..956333e87 100644
--- a/src/http/modules/ngx_http_flv_module.c
+++ b/src/http/modules/ngx_http_flv_module.c
@@ -80,10 +80,6 @@ ngx_http_flv_handler(ngx_http_request_t *r)
return NGX_DECLINED;
}
- if (r->zero_in_uri) {
- return NGX_DECLINED;
- }
-
rc = ngx_http_discard_request_body(r);
if (rc != NGX_OK) {
diff --git a/src/http/modules/ngx_http_geo_module.c b/src/http/modules/ngx_http_geo_module.c
index 0ec8d093b..a184a7ae3 100644
--- a/src/http/modules/ngx_http_geo_module.c
+++ b/src/http/modules/ngx_http_geo_module.c
@@ -589,7 +589,7 @@ ngx_http_geo_add_range(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
ngx_array_t *a;
ngx_http_geo_range_t *range;
- for (n = start; n <= end; n += 0x10000) {
+ for (n = start; n <= end; n = (n + 0x10000) & 0xffff0000) {
h = n >> 16;
diff --git a/src/http/modules/ngx_http_geoip_module.c b/src/http/modules/ngx_http_geoip_module.c
index 81b872efb..2c50909f6 100644
--- a/src/http/modules/ngx_http_geoip_module.c
+++ b/src/http/modules/ngx_http_geoip_module.c
@@ -30,6 +30,9 @@ static ngx_int_t ngx_http_geoip_country_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_geoip_city_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
+static ngx_int_t ngx_http_geoip_city_float_variable(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data);
+static GeoIPRecord *ngx_http_geoip_get_city_record(ngx_http_request_t *r);
static ngx_int_t ngx_http_geoip_add_variables(ngx_conf_t *cf);
static void *ngx_http_geoip_create_conf(ngx_conf_t *cf);
@@ -93,23 +96,32 @@ ngx_module_t ngx_http_geoip_module = {
static ngx_http_variable_t ngx_http_geoip_vars[] = {
- { ngx_string("geoip_country_code"), NULL, ngx_http_geoip_country_variable,
+ { ngx_string("geoip_country_code"), NULL,
+ ngx_http_geoip_country_variable,
(uintptr_t) GeoIP_country_code_by_ipnum, 0, 0 },
- { ngx_string("geoip_country_code3"), NULL, ngx_http_geoip_country_variable,
+ { ngx_string("geoip_country_code3"), NULL,
+ ngx_http_geoip_country_variable,
(uintptr_t) GeoIP_country_code3_by_ipnum, 0, 0 },
- { ngx_string("geoip_country_name"), NULL, ngx_http_geoip_country_variable,
+ { ngx_string("geoip_country_name"), NULL,
+ ngx_http_geoip_country_variable,
(uintptr_t) GeoIP_country_name_by_ipnum, 0, 0 },
- { ngx_string("geoip_city_country_code"), NULL, ngx_http_geoip_city_variable,
+ { ngx_string("geoip_city_continent_code"), NULL,
+ ngx_http_geoip_city_variable,
+ offsetof(GeoIPRecord, continent_code), 0, 0 },
+
+ { ngx_string("geoip_city_country_code"), NULL,
+ ngx_http_geoip_city_variable,
offsetof(GeoIPRecord, country_code), 0, 0 },
{ ngx_string("geoip_city_country_code3"), NULL,
ngx_http_geoip_city_variable,
offsetof(GeoIPRecord, country_code3), 0, 0 },
- { ngx_string("geoip_city_country_name"), NULL, ngx_http_geoip_city_variable,
+ { ngx_string("geoip_city_country_name"), NULL,
+ ngx_http_geoip_city_variable,
offsetof(GeoIPRecord, country_name), 0, 0 },
{ ngx_string("geoip_region"), NULL,
@@ -124,6 +136,14 @@ static ngx_http_variable_t ngx_http_geoip_vars[] = {
ngx_http_geoip_city_variable,
offsetof(GeoIPRecord, postal_code), 0, 0 },
+ { ngx_string("geoip_latitude"), NULL,
+ ngx_http_geoip_city_float_variable,
+ offsetof(GeoIPRecord, latitude), 0, 0 },
+
+ { ngx_string("geoip_longitude"), NULL,
+ ngx_http_geoip_city_float_variable,
+ offsetof(GeoIPRecord, longitude), 0, 0 },
+
{ ngx_null_string, NULL, NULL, 0, 0, 0 }
};
@@ -179,34 +199,16 @@ static ngx_int_t
ngx_http_geoip_city_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data)
{
- u_long addr;
- char *val;
- size_t len;
- GeoIPRecord *gr;
- struct sockaddr_in *sin;
- ngx_http_geoip_conf_t *gcf;
-
- gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module);
-
- if (gcf->city == NULL) {
- goto not_found;
- }
-
- if (r->connection->sockaddr->sa_family != AF_INET) {
- goto not_found;
- }
-
- sin = (struct sockaddr_in *) r->connection->sockaddr;
- addr = ntohl(sin->sin_addr.s_addr);
-
- gr = GeoIP_record_by_ipnum(gcf->city, addr);
+ char *val;
+ size_t len;
+ GeoIPRecord *gr;
+ gr = ngx_http_geoip_get_city_record(r);
if (gr == NULL) {
goto not_found;
}
val = *(char **) ((char *) gr + data);
-
if (val == NULL) {
goto no_value;
}
@@ -243,6 +245,56 @@ not_found:
static ngx_int_t
+ngx_http_geoip_city_float_variable(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data)
+{
+ float val;
+ GeoIPRecord *gr;
+
+ gr = ngx_http_geoip_get_city_record(r);
+ if (gr == NULL) {
+ v->not_found = 1;
+ return NGX_OK;
+ }
+
+ v->data = ngx_pnalloc(r->pool, NGX_INT64_LEN + 5);
+ if (v->data == NULL) {
+ GeoIPRecord_delete(gr);
+ return NGX_ERROR;
+ }
+
+ val = *(float *) ((char *) gr + data);
+
+ v->len = ngx_sprintf(v->data, "%.4f", val) - v->data;
+
+ GeoIPRecord_delete(gr);
+
+ return NGX_OK;
+}
+
+
+static GeoIPRecord *
+ngx_http_geoip_get_city_record(ngx_http_request_t *r)
+{
+ u_long addr;
+ struct sockaddr_in *sin;
+ ngx_http_geoip_conf_t *gcf;
+
+ gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module);
+
+ if (gcf->city && r->connection->sockaddr->sa_family == AF_INET) {
+
+ sin = (struct sockaddr_in *) r->connection->sockaddr;
+ addr = ntohl(sin->sin_addr.s_addr);
+
+ return GeoIP_record_by_ipnum(gcf->city, addr);
+ }
+
+ return NULL;
+}
+
+
+static ngx_int_t
ngx_http_geoip_add_variables(ngx_conf_t *cf)
{
ngx_http_variable_t *var, *v;
diff --git a/src/http/modules/ngx_http_gzip_static_module.c b/src/http/modules/ngx_http_gzip_static_module.c
index 29874a33a..5d87985ab 100644
--- a/src/http/modules/ngx_http_gzip_static_module.c
+++ b/src/http/modules/ngx_http_gzip_static_module.c
@@ -89,10 +89,6 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r)
return NGX_DECLINED;
}
- if (r->zero_in_uri) {
- return NGX_DECLINED;
- }
-
gzcf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_static_module);
if (!gzcf->enable) {
@@ -179,7 +175,7 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r)
#if !(NGX_WIN32) /* the not regular files are probably Unix specific */
if (!of.is_file) {
- ngx_log_error(NGX_LOG_CRIT, log, ngx_errno,
+ ngx_log_error(NGX_LOG_CRIT, log, 0,
"\"%s\" is not a regular file", path.data);
return NGX_HTTP_NOT_FOUND;
diff --git a/src/http/modules/ngx_http_image_filter_module.c b/src/http/modules/ngx_http_image_filter_module.c
index 9a4dafe05..6511317c6 100644
--- a/src/http/modules/ngx_http_image_filter_module.c
+++ b/src/http/modules/ngx_http_image_filter_module.c
@@ -63,6 +63,7 @@ typedef struct {
ngx_uint_t phase;
ngx_uint_t type;
+ ngx_uint_t force;
} ngx_http_image_filter_ctx_t;
@@ -501,7 +502,8 @@ ngx_http_image_process(ngx_http_request_t *r)
if (rc == NGX_OK
&& ctx->width <= ctx->max_width
- && ctx->height <= ctx->max_height)
+ && ctx->height <= ctx->max_height
+ && !ctx->force)
{
return ngx_http_image_asis(r, ctx);
}
@@ -601,6 +603,7 @@ static ngx_int_t
ngx_http_image_size(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
{
u_char *p, *last;
+ size_t len, app;
ngx_uint_t width, height;
p = ctx->image;
@@ -611,26 +614,38 @@ ngx_http_image_size(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
p += 2;
last = ctx->image + ctx->length - 10;
+ width = 0;
+ height = 0;
+ app = 0;
while (p < last) {
if (p[0] == 0xff && p[1] != 0xff) {
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "JPEG: %02xd %02xd", *p, *(p + 1));
+ "JPEG: %02xd %02xd", p[0], p[1]);
p++;
- if (*p == 0xc0 || *p == 0xc1 || *p == 0xc2 || *p == 0xc3
- || *p == 0xc9 || *p == 0xca || *p == 0xcb)
+ if ((*p == 0xc0 || *p == 0xc1 || *p == 0xc2 || *p == 0xc3
+ || *p == 0xc9 || *p == 0xca || *p == 0xcb)
+ && (width == 0 || height == 0))
{
- goto found;
+ width = p[6] * 256 + p[7];
+ height = p[4] * 256 + p[5];
}
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"JPEG: %02xd %02xd", p[1], p[2]);
- p += p[1] * 256 + p[2];
+ len = p[1] * 256 + p[2];
+
+ if (*p >= 0xe1 && *p <= 0xef) {
+ /* application data, e.g., EXIF, Adobe XMP, etc. */
+ app += len;
+ }
+
+ p += len;
continue;
}
@@ -638,12 +653,16 @@ ngx_http_image_size(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
p++;
}
- return NGX_DECLINED;
-
- found:
+ if (width == 0 || height == 0) {
+ return NGX_DECLINED;
+ }
- width = p[6] * 256 + p[7];
- height = p[4] * 256 + p[5];
+ if (ctx->length / 20 < app) {
+ /* force conversion if application data consume more than 5% */
+ ctx->force = 1;
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "app data size: %uz", app);
+ }
break;
@@ -708,7 +727,8 @@ ngx_http_image_resize(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module);
- if ((ngx_uint_t) sx <= ctx->max_width
+ if (!ctx->force
+ && (ngx_uint_t) sx <= ctx->max_width
&& (ngx_uint_t) sy <= ctx->max_height)
{
gdImageDestroy(src);
diff --git a/src/http/modules/ngx_http_index_module.c b/src/http/modules/ngx_http_index_module.c
index b58aa97c2..3e2113c49 100644
--- a/src/http/modules/ngx_http_index_module.c
+++ b/src/http/modules/ngx_http_index_module.c
@@ -116,10 +116,6 @@ ngx_http_index_handler(ngx_http_request_t *r)
return NGX_DECLINED;
}
- if (r->zero_in_uri) {
- return NGX_DECLINED;
- }
-
ilcf = ngx_http_get_module_loc_conf(r, ngx_http_index_module);
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
diff --git a/src/http/modules/ngx_http_memcached_module.c b/src/http/modules/ngx_http_memcached_module.c
index dc7c76719..4b2af10a9 100644
--- a/src/http/modules/ngx_http_memcached_module.c
+++ b/src/http/modules/ngx_http_memcached_module.c
@@ -423,15 +423,20 @@ ngx_http_memcached_filter(void *data, ssize_t bytes)
if (ngx_strncmp(b->last,
ngx_http_memcached_end + NGX_HTTP_MEMCACHED_END - ctx->rest,
- ctx->rest)
+ bytes)
!= 0)
{
ngx_log_error(NGX_LOG_ERR, ctx->request->connection->log, 0,
"memcached sent invalid trailer");
+
+ u->length = 0;
+ ctx->rest = 0;
+
+ return NGX_OK;
}
- u->length = 0;
- ctx->rest = 0;
+ u->length -= bytes;
+ ctx->rest -= bytes;
return NGX_OK;
}
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index 19dbd5cfc..518bf85d6 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -357,6 +357,13 @@ static ngx_command_t ngx_http_proxy_commands[] = {
0,
&ngx_http_proxy_module },
+ { ngx_string("proxy_no_cache"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
+ ngx_http_no_cache_set_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_proxy_loc_conf_t, upstream.no_cache),
+ NULL },
+
{ ngx_string("proxy_cache_valid"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
ngx_http_file_cache_valid_set_slot,
@@ -630,6 +637,7 @@ ngx_http_proxy_handler(ngx_http_request_t *r)
u->process_header = ngx_http_proxy_process_status_line;
u->abort_request = ngx_http_proxy_abort_request;
u->finalize_request = ngx_http_proxy_finalize_request;
+ r->state = 0;
if (plcf->redirects) {
u->rewrite_redirect = ngx_http_proxy_rewrite_redirect;
@@ -1191,6 +1199,7 @@ ngx_http_proxy_reinit_request(ngx_http_request_t *r)
ctx->status_end = NULL;
r->upstream->process_header = ngx_http_proxy_process_status_line;
+ r->state = 0;
return NGX_OK;
}
@@ -1906,7 +1915,7 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
* conf->body_set_len = NULL;
* conf->body_set = NULL;
* conf->body_source = { 0, NULL };
- * conf->rewrite_locations = NULL;
+ * conf->redirects = NULL;
*/
conf->upstream.store = NGX_CONF_UNSET;
@@ -1931,6 +1940,7 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
#if (NGX_HTTP_CACHE)
conf->upstream.cache = NGX_CONF_UNSET_PTR;
conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT;
+ conf->upstream.no_cache = NGX_CONF_UNSET_PTR;
conf->upstream.cache_valid = NGX_CONF_UNSET_PTR;
#endif
@@ -2155,6 +2165,9 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
|NGX_HTTP_UPSTREAM_FT_OFF;
}
+ ngx_conf_merge_ptr_value(conf->upstream.no_cache,
+ prev->upstream.no_cache, NULL);
+
ngx_conf_merge_ptr_value(conf->upstream.cache_valid,
prev->upstream.cache_valid, NULL);
@@ -2747,9 +2760,16 @@ ngx_http_proxy_redirect(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
if (ngx_strcmp(value[1].data, "default") == 0) {
+ if (plcf->proxy_lengths) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "\"proxy_redirect default\" may not be used "
+ "with \"proxy_pass\" directive with variables");
+ return NGX_CONF_ERROR;
+ }
+
if (plcf->url.data == NULL) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"proxy_rewrite_location default\" must go "
+ "\"proxy_redirect default\" must go "
"after the \"proxy_pass\" directive");
return NGX_CONF_ERROR;
}
diff --git a/src/http/modules/ngx_http_random_index_module.c b/src/http/modules/ngx_http_random_index_module.c
index 7b0ec503c..02bdc45f9 100644
--- a/src/http/modules/ngx_http_random_index_module.c
+++ b/src/http/modules/ngx_http_random_index_module.c
@@ -86,10 +86,6 @@ ngx_http_random_index_handler(ngx_http_request_t *r)
return NGX_DECLINED;
}
- if (r->zero_in_uri) {
- return NGX_DECLINED;
- }
-
if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD|NGX_HTTP_POST))) {
return NGX_DECLINED;
}
diff --git a/src/http/modules/ngx_http_referer_module.c b/src/http/modules/ngx_http_referer_module.c
index 8daa399bd..a62b6d461 100644
--- a/src/http/modules/ngx_http_referer_module.c
+++ b/src/http/modules/ngx_http_referer_module.c
@@ -124,18 +124,27 @@ ngx_http_referer_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
len = r->headers_in.referer->value.len;
ref = r->headers_in.referer->value.data;
- if (len < sizeof("http://i.ru") - 1
- || (ngx_strncasecmp(ref, (u_char *) "http://", 7) != 0))
- {
- if (rlcf->blocked_referer) {
- goto valid;
+ if (len >= sizeof("http://i.ru") - 1) {
+ last = ref + len;
+
+ if (ngx_strncasecmp(ref, (u_char *) "http://", 7) == 0) {
+ ref += 7;
+ goto valid_scheme;
+
+ } else if (ngx_strncasecmp(ref, (u_char *) "https://", 8) == 0) {
+ ref += 8;
+ goto valid_scheme;
}
+ }
- goto invalid;
+ if (rlcf->blocked_referer) {
+ goto valid;
}
- last = ref + len;
- ref += 7;
+ goto invalid;
+
+valid_scheme:
+
i = 0;
key = 0;
diff --git a/src/http/modules/ngx_http_rewrite_module.c b/src/http/modules/ngx_http_rewrite_module.c
index 1f98cf829..61090317b 100644
--- a/src/http/modules/ngx_http_rewrite_module.c
+++ b/src/http/modules/ngx_http_rewrite_module.c
@@ -340,13 +340,10 @@ ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
last = 0;
- if (ngx_strncmp(value[2].data, "http://", sizeof("http://") - 1) == 0) {
- regex->status = NGX_HTTP_MOVED_TEMPORARILY;
- regex->redirect = 1;
- last = 1;
- }
-
- if (ngx_strncmp(value[2].data, "https://", sizeof("https://") - 1) == 0) {
+ if (ngx_strncmp(value[2].data, "http://", sizeof("http://") - 1) == 0
+ || ngx_strncmp(value[2].data, "https://", sizeof("https://") - 1) == 0
+ || ngx_strncmp(value[2].data, "$scheme", sizeof("$scheme") - 1) == 0)
+ {
regex->status = NGX_HTTP_MOVED_TEMPORARILY;
regex->redirect = 1;
last = 1;
diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c
index d03e58407..ced8f6843 100644
--- a/src/http/modules/ngx_http_ssi_filter_module.c
+++ b/src/http/modules/ngx_http_ssi_filter_module.c
@@ -14,7 +14,6 @@
#define NGX_HTTP_SSI_ADD_PREFIX 1
#define NGX_HTTP_SSI_ADD_ZERO 2
-#define NGX_HTTP_SSI_EXPR_TEST 4
typedef struct {
@@ -1701,8 +1700,7 @@ ngx_http_ssi_evaluate_string(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
val = ngx_http_ssi_get_variable(r, &var, key);
if (val == NULL) {
- vv = ngx_http_get_variable(r, &var, key,
- flags & NGX_HTTP_SSI_EXPR_TEST);
+ vv = ngx_http_get_variable(r, &var, key);
if (vv == NULL) {
return NGX_ERROR;
}
@@ -2061,9 +2059,9 @@ ngx_http_ssi_stub_output(ngx_http_request_t *r, void *data, ngx_int_t rc)
out = data;
if (!r->header_sent) {
- if (ngx_http_set_content_type(r) != NGX_OK) {
- return NGX_ERROR;
- }
+ r->headers_out.content_type_len =
+ r->parent->headers_out.content_type_len;
+ r->headers_out.content_type = r->parent->headers_out.content_type;
if (ngx_http_send_header(r) == NGX_ERROR) {
return NGX_ERROR;
@@ -2110,7 +2108,7 @@ ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
value = ngx_http_ssi_get_variable(r, var, key);
if (value == NULL) {
- vv = ngx_http_get_variable(r, var, key, 1);
+ vv = ngx_http_get_variable(r, var, key);
if (vv == NULL) {
return NGX_HTTP_SSI_ERROR;
@@ -2161,10 +2159,9 @@ ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
}
}
- switch (ctx->encoding) {
+ p = value->data;
- case NGX_HTTP_SSI_NO_ENCODING:
- break;
+ switch (ctx->encoding) {
case NGX_HTTP_SSI_URL_ENCODING:
len = 2 * ngx_escape_uri(NULL, value->data, value->len,
@@ -2177,11 +2174,9 @@ ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
}
(void) ngx_escape_uri(p, value->data, value->len, NGX_ESCAPE_HTML);
-
- value->len += len;
- value->data = p;
}
+ len += value->len;
break;
case NGX_HTTP_SSI_ENTITY_ENCODING:
@@ -2194,11 +2189,13 @@ ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
}
(void) ngx_escape_html(p, value->data, value->len);
-
- value->len += len;
- value->data = p;
}
+ len += value->len;
+ break;
+
+ default: /* NGX_HTTP_SSI_NO_ENCODING */
+ len = value->len;
break;
}
@@ -2213,8 +2210,8 @@ ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
}
b->memory = 1;
- b->pos = value->data;
- b->last = value->data + value->len;
+ b->pos = p;
+ b->last = p + len;
cl->buf = b;
cl->next = NULL;
@@ -2362,7 +2359,7 @@ ngx_http_ssi_if(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
p++;
}
- flags = (p == last) ? NGX_HTTP_SSI_EXPR_TEST : 0;
+ flags = 0;
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"left: \"%V\"", &left);
@@ -2614,8 +2611,7 @@ ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r,
return NGX_ERROR;
}
- v->len = ngx_sprintf(v->data, "%T", tp->sec + (gmt ? 0 : tp->gmtoff))
- - v->data;
+ v->len = ngx_sprintf(v->data, "%T", tp->sec) - v->data;
return NGX_OK;
}
diff --git a/src/http/modules/ngx_http_static_module.c b/src/http/modules/ngx_http_static_module.c
index bc46b84a7..41ebc2162 100644
--- a/src/http/modules/ngx_http_static_module.c
+++ b/src/http/modules/ngx_http_static_module.c
@@ -66,10 +66,6 @@ ngx_http_static_handler(ngx_http_request_t *r)
return NGX_DECLINED;
}
- if (r->zero_in_uri) {
- return NGX_DECLINED;
- }
-
log = r->connection->log;
/*
@@ -188,7 +184,7 @@ ngx_http_static_handler(ngx_http_request_t *r)
#if !(NGX_WIN32) /* the not regular files are probably Unix specific */
if (!of.is_file) {
- ngx_log_error(NGX_LOG_CRIT, log, ngx_errno,
+ ngx_log_error(NGX_LOG_CRIT, log, 0,
"\"%s\" is not a regular file", path.data);
return NGX_HTTP_NOT_FOUND;
diff --git a/src/http/modules/ngx_http_userid_filter_module.c b/src/http/modules/ngx_http_userid_filter_module.c
index 9997274a6..c5a148737 100644
--- a/src/http/modules/ngx_http_userid_filter_module.c
+++ b/src/http/modules/ngx_http_userid_filter_module.c
@@ -545,7 +545,7 @@ ngx_http_userid_add_variables(ngx_conf_t *cf)
{
ngx_http_variable_t *var;
- var = ngx_http_add_variable(cf, &ngx_http_userid_got, NGX_HTTP_VAR_NOHASH);
+ var = ngx_http_add_variable(cf, &ngx_http_userid_got, 0);
if (var == NULL) {
return NGX_ERROR;
}
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index 8108a0fd4..91eeadde1 100644
--- a/src/http/modules/perl/nginx.pm
+++ b/src/http/modules/perl/nginx.pm
@@ -47,7 +47,7 @@ our @EXPORT = qw(
HTTP_INSUFFICIENT_STORAGE
);
-our $VERSION = '0.7.65';
+our $VERSION = '0.7.66';
require XSLoader;
XSLoader::load('nginx', $VERSION);
diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs
index 077cf0ddf..2ce5af2db 100644
--- a/src/http/modules/perl/nginx.xs
+++ b/src/http/modules/perl/nginx.xs
@@ -847,7 +847,7 @@ variable(r, name, value = NULL)
#endif
- vv = ngx_http_get_variable(r, &var, hash, 1);
+ vv = ngx_http_get_variable(r, &var, hash);
if (vv == NULL) {
XSRETURN_UNDEF;
}
@@ -901,9 +901,6 @@ variable(r, name, value = NULL)
XSRETURN_UNDEF;
}
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "variable \"%V\" not found", &var);
-
XSRETURN_UNDEF;
}
diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c
index 6ba5a4d9e..8ab066925 100644
--- a/src/http/modules/perl/ngx_http_perl_module.c
+++ b/src/http/modules/perl/ngx_http_perl_module.c
@@ -30,12 +30,6 @@ typedef struct {
} ngx_http_perl_variable_t;
-typedef struct {
- SV *sv;
- PerlInterpreter *perl;
-} ngx_http_perl_cleanup_t;
-
-
#if (NGX_HTTP_SSI)
static ngx_int_t ngx_http_perl_ssi(ngx_http_request_t *r,
ngx_http_ssi_ctx_t *ssi_ctx, ngx_str_t **params);
@@ -174,10 +168,6 @@ ngx_http_perl_xs_init(pTHX)
static ngx_int_t
ngx_http_perl_handler(ngx_http_request_t *r)
{
- if (r->zero_in_uri) {
- return NGX_HTTP_NOT_FOUND;
- }
-
ngx_http_perl_handle_request(r);
return NGX_DONE;
diff --git a/src/http/ngx_http_cache.h b/src/http/ngx_http_cache.h
index 6ac6fd876..41d12b0f3 100644
--- a/src/http/ngx_http_cache.h
+++ b/src/http/ngx_http_cache.h
@@ -133,6 +133,11 @@ char *ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
char *ngx_http_file_cache_valid_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
+ngx_int_t ngx_http_cache(ngx_http_request_t *r, ngx_array_t *no_cache);
+char *ngx_http_no_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
+
+
extern ngx_str_t ngx_http_cache_status[];
diff --git a/src/http/ngx_http_copy_filter_module.c b/src/http/ngx_http_copy_filter_module.c
index c7f6be29d..97cd846a1 100644
--- a/src/http/ngx_http_copy_filter_module.c
+++ b/src/http/ngx_http_copy_filter_module.c
@@ -104,7 +104,9 @@ ngx_http_copy_filter(ngx_http_request_t *r, ngx_chain_t *in)
ctx->output_filter = (ngx_output_chain_filter_pt) ngx_http_next_filter;
ctx->filter_ctx = r;
- r->request_output = 1;
+ if (in && in->buf && ngx_buf_size(in->buf)) {
+ r->request_output = 1;
+ }
}
rc = ngx_output_chain(ctx, in);
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 7bb3ad25c..479592a85 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -560,6 +560,13 @@ static ngx_command_t ngx_http_core_commands[] = {
offsetof(ngx_http_core_loc_conf_t, if_modified_since),
&ngx_http_core_if_modified_since },
+ { ngx_string("chunked_transfer_encoding"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_flag_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_core_loc_conf_t, chunked_transfer_encoding),
+ NULL },
+
{ ngx_string("error_page"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
|NGX_CONF_2MORE,
@@ -744,14 +751,24 @@ ngx_http_handler(ngx_http_request_t *r)
break;
}
- if (r->keepalive && r->headers_in.msie && r->method == NGX_HTTP_POST) {
+ if (r->keepalive) {
- /*
- * MSIE may wait for some time if an response for
- * a POST request was sent over a keepalive connection
- */
+ if (r->headers_in.msie6) {
+ if (r->method == NGX_HTTP_POST) {
+ /*
+ * MSIE may wait for some time if an response for
+ * a POST request was sent over a keepalive connection
+ */
+ r->keepalive = 0;
+ }
- r->keepalive = 0;
+ } else if (r->headers_in.safari) {
+ /*
+ * Safari may send a POST request to a closed keepalive
+ * connection and stalls for some time
+ */
+ r->keepalive = 0;
+ }
}
if (r->headers_in.content_length_n > 0) {
@@ -1288,7 +1305,7 @@ ngx_http_core_content_phase(ngx_http_request_t *r,
/* no content handler was found */
- if (r->uri.data[r->uri.len - 1] == '/' && !r->zero_in_uri) {
+ if (r->uri.data[r->uri.len - 1] == '/') {
if (ngx_http_map_uri_to_path(r, &path, &root, 0) != NULL) {
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
@@ -2076,7 +2093,6 @@ ngx_http_subrequest(ngx_http_request_t *r,
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
"http subrequest \"%V?%V\"", uri, &sr->args);
- sr->zero_in_uri = (flags & NGX_HTTP_ZERO_IN_URI) != 0;
sr->subrequest_in_memory = (flags & NGX_HTTP_SUBREQUEST_IN_MEMORY) != 0;
sr->waited = (flags & NGX_HTTP_SUBREQUEST_WAITED) != 0;
@@ -2944,6 +2960,7 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf)
lcf->log_subrequest = NGX_CONF_UNSET;
lcf->recursive_error_pages = NGX_CONF_UNSET;
lcf->server_tokens = NGX_CONF_UNSET;
+ lcf->chunked_transfer_encoding = NGX_CONF_UNSET;
lcf->types_hash_max_size = NGX_CONF_UNSET_UINT;
lcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT;
@@ -3181,6 +3198,8 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_value(conf->recursive_error_pages,
prev->recursive_error_pages, 0);
ngx_conf_merge_value(conf->server_tokens, prev->server_tokens, 1);
+ ngx_conf_merge_value(conf->chunked_transfer_encoding,
+ prev->chunked_transfer_encoding, 1);
ngx_conf_merge_ptr_value(conf->open_file_cache,
prev->open_file_cache, NULL);
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index 71d5b953c..e55c433bf 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -358,6 +358,7 @@ struct ngx_http_core_loc_conf_s {
ngx_flag_t log_subrequest; /* log_subrequest */
ngx_flag_t recursive_error_pages; /* recursive_error_pages */
ngx_flag_t server_tokens; /* server_tokens */
+ ngx_flag_t chunked_transfer_encoding; /* chunked_transfer_encoding */
#if (NGX_HTTP_GZIP)
ngx_flag_t gzip_vary; /* gzip_vary */
diff --git a/src/http/ngx_http_file_cache.c b/src/http/ngx_http_file_cache.c
index c02bc7740..3fa5826c4 100644
--- a/src/http/ngx_http_file_cache.c
+++ b/src/http/ngx_http_file_cache.c
@@ -1128,7 +1128,7 @@ ngx_http_file_cache_manager_sleep(ngx_http_file_cache_t *cache)
if (cache->files++ > 100) {
- ngx_time_update(0, 0);
+ ngx_time_update();
elapsed = ngx_abs((ngx_msec_int_t) (ngx_current_msec - cache->last));
@@ -1145,7 +1145,7 @@ ngx_http_file_cache_manager_sleep(ngx_http_file_cache_t *cache)
ngx_msleep(200);
- ngx_time_update(0, 0);
+ ngx_time_update();
}
cache->last = ngx_current_msec;
@@ -1604,3 +1604,69 @@ ngx_http_file_cache_valid_set_slot(ngx_conf_t *cf, ngx_command_t *cmd,
return NGX_CONF_OK;
}
+
+
+ngx_int_t
+ngx_http_cache(ngx_http_request_t *r, ngx_array_t *no_cache)
+{
+ ngx_str_t val;
+ ngx_uint_t i;
+ ngx_http_complex_value_t *cv;
+
+ cv = no_cache->elts;
+
+ for (i = 0; i < no_cache->nelts; i++) {
+ if (ngx_http_complex_value(r, &cv[i], &val) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ if (val.len && val.data[0] != '0') {
+ return NGX_DECLINED;
+ }
+ }
+
+ return NGX_OK;
+}
+
+
+char *
+ngx_http_no_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ char *p = conf;
+
+ ngx_str_t *value;
+ ngx_uint_t i;
+ ngx_array_t **a;
+ ngx_http_complex_value_t *cv;
+ ngx_http_compile_complex_value_t ccv;
+
+ a = (ngx_array_t **) (p + cmd->offset);
+
+ if (*a == NGX_CONF_UNSET_PTR) {
+ *a = ngx_array_create(cf->pool, 1, sizeof(ngx_http_complex_value_t));
+ if (*a == NULL) {
+ return NGX_CONF_ERROR;
+ }
+ }
+
+ value = cf->args->elts;
+
+ for (i = 1; i < cf->args->nelts; i++) {
+ cv = ngx_array_push(*a);
+ if (cv == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
+
+ ccv.cf = cf;
+ ccv.value = &value[i];
+ ccv.complex_value = cv;
+
+ if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+ }
+
+ return NGX_CONF_OK;
+}
diff --git a/src/http/ngx_http_header_filter_module.c b/src/http/ngx_http_header_filter_module.c
index 0f6f1731a..237911154 100644
--- a/src/http/ngx_http_header_filter_module.c
+++ b/src/http/ngx_http_header_filter_module.c
@@ -538,8 +538,8 @@ ngx_http_header_filter(ngx_http_request_t *r)
r->headers_out.location->value.len = b->last - p;
r->headers_out.location->value.data = p;
- r->headers_out.location->key.len = sizeof("Location: ") - 1;
- r->headers_out.location->key.data = (u_char *) "Location: ";
+ r->headers_out.location->key.len = sizeof("Location") - 1;
+ r->headers_out.location->key.data = (u_char *) "Location";
*b->last++ = CR; *b->last++ = LF;
}
diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c
index b638f86fc..2952e02ea 100644
--- a/src/http/ngx_http_parse.c
+++ b/src/http/ngx_http_parse.c
@@ -438,8 +438,7 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
r->plus_in_uri = 1;
break;
case '\0':
- r->zero_in_uri = 1;
- break;
+ return NGX_HTTP_PARSE_INVALID_REQUEST;
default:
state = sw_check_uri;
break;
@@ -496,8 +495,7 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
r->plus_in_uri = 1;
break;
case '\0':
- r->zero_in_uri = 1;
- break;
+ return NGX_HTTP_PARSE_INVALID_REQUEST;
}
break;
@@ -526,8 +524,7 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
r->complex_uri = 1;
break;
case '\0':
- r->zero_in_uri = 1;
- break;
+ return NGX_HTTP_PARSE_INVALID_REQUEST;
}
break;
@@ -1202,7 +1199,7 @@ ngx_http_parse_complex_uri(ngx_http_request_t *r, ngx_uint_t merge_slashes)
ch = *p++;
} else if (ch == '\0') {
- r->zero_in_uri = 1;
+ return NGX_HTTP_PARSE_INVALID_REQUEST;
}
state = quoted_state;
@@ -1304,8 +1301,7 @@ ngx_http_parse_unsafe_uri(ngx_http_request_t *r, ngx_str_t *uri,
}
if (ch == '\0') {
- *flags |= NGX_HTTP_ZERO_IN_URI;
- continue;
+ goto unsafe;
}
if (ngx_path_separator(ch) && len > 2) {
@@ -1449,34 +1445,19 @@ ngx_http_arg(ngx_http_request_t *r, u_char *name, size_t len, ngx_str_t *value)
void
ngx_http_split_args(ngx_http_request_t *r, ngx_str_t *uri, ngx_str_t *args)
{
- u_char ch, *p, *last;
-
- p = uri->data;
-
- last = p + uri->len;
-
- args->len = 0;
-
- while (p < last) {
-
- ch = *p++;
+ u_char *p, *last;
- if (ch == '?') {
- args->len = last - p;
- args->data = p;
+ last = uri->data + uri->len;
- uri->len = p - 1 - uri->data;
+ p = ngx_strlchr(uri->data, last, '?');
- if (ngx_strlchr(p, last, '\0') != NULL) {
- r->zero_in_uri = 1;
- }
+ if (p) {
+ uri->len = p - uri->data;
+ p++;
+ args->len = last - p;
+ args->data = p;
- return;
- }
-
- if (ch == '\0') {
- r->zero_in_uri = 1;
- continue;
- }
+ } else {
+ args->len = 0;
}
}
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index c239b9d34..5710c699f 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -784,16 +784,31 @@ ngx_http_process_request_line(ngx_event_t *rev)
p = r->uri.data + r->uri.len - 1;
- if (*p == '.' || *p == ' ') {
+ while (p > r->uri.data) {
- while (--p > r->uri.data && (*p == '.' || *p == ' ')) {
- /* void */
+ if (*p == ' ') {
+ p--;
+ continue;
}
- r->uri.len = p + 1 - r->uri.data;
+ if (*p == '.') {
+ p--;
+ continue;
+ }
+
+ if (ngx_strncasecmp(p - 6, (u_char *) "::$data", 7) == 0) {
+ p -= 7;
+ continue;
+ }
+ break;
+ }
+
+ if (p != r->uri.data + r->uri.len - 1) {
+ r->uri.len = p + 1 - r->uri.data;
ngx_http_set_exten(r);
}
+
}
#endif
@@ -1443,6 +1458,12 @@ ngx_http_process_user_agent(ngx_http_request_t *r, ngx_table_elt_t *h,
if (ngx_strstrn(user_agent, "Gecko/", 6 - 1)) {
r->headers_in.gecko = 1;
+ } else if (ngx_strstrn(user_agent, "Chrome/", 7 - 1)) {
+ r->headers_in.chrome = 1;
+
+ } else if (ngx_strstrn(user_agent, "Safari/", 7 - 1)) {
+ r->headers_in.safari = 1;
+
} else if (ngx_strstrn(user_agent, "Konqueror", 9 - 1)) {
r->headers_in.konqueror = 1;
}
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
index 974020ef8..73b950848 100644
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -57,7 +57,7 @@
#define NGX_HTTP_PARSE_INVALID_HEADER 13
-#define NGX_HTTP_ZERO_IN_URI 1
+/* unused 1 */
#define NGX_HTTP_SUBREQUEST_IN_MEMORY 2
#define NGX_HTTP_SUBREQUEST_WAITED 4
#define NGX_HTTP_LOG_UNSAFE 8
@@ -220,6 +220,8 @@ typedef struct {
unsigned msie6:1;
unsigned opera:1;
unsigned gecko:1;
+ unsigned chrome:1;
+ unsigned safari:1;
unsigned konqueror:1;
} ngx_http_headers_in_t;
@@ -428,9 +430,6 @@ struct ngx_http_request_s {
/* URI with "+" */
unsigned plus_in_uri:1;
- /* URI with "\0" or "%00" */
- unsigned zero_in_uri:1;
-
unsigned invalid_header:1;
unsigned valid_location:1;
diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c
index 62f71a3ef..6e51fd6d7 100644
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -31,13 +31,13 @@ static u_char ngx_http_error_tail[] =
;
-static u_char ngx_http_msie_stub[] =
-"<!-- The padding to disable MSIE's friendly error page -->" CRLF
-"<!-- The padding to disable MSIE's friendly error page -->" CRLF
-"<!-- The padding to disable MSIE's friendly error page -->" CRLF
-"<!-- The padding to disable MSIE's friendly error page -->" CRLF
-"<!-- The padding to disable MSIE's friendly error page -->" CRLF
-"<!-- The padding to disable MSIE's friendly error page -->" CRLF
+static u_char ngx_http_msie_padding[] =
+"<!-- a padding to disable MSIE and Chrome friendly error page -->" CRLF
+"<!-- a padding to disable MSIE and Chrome friendly error page -->" CRLF
+"<!-- a padding to disable MSIE and Chrome friendly error page -->" CRLF
+"<!-- a padding to disable MSIE and Chrome friendly error page -->" CRLF
+"<!-- a padding to disable MSIE and Chrome friendly error page -->" CRLF
+"<!-- a padding to disable MSIE and Chrome friendly error page -->" CRLF
;
@@ -517,8 +517,6 @@ ngx_http_send_error_page(ngx_http_request_t *r, ngx_http_err_page_t *err_page)
r->err_status = overwrite;
- r->zero_in_uri = 0;
-
if (ngx_http_complex_value(r, &err_page->value, &uri) != NGX_OK) {
return NGX_ERROR;
}
@@ -598,12 +596,12 @@ ngx_http_send_special_response(ngx_http_request_t *r,
r->headers_out.content_length_n = ngx_http_error_pages[err].len
+ len;
if (clcf->msie_padding
- && r->headers_in.msie
+ && (r->headers_in.msie || r->headers_in.chrome)
&& r->http_version >= NGX_HTTP_VERSION_10
&& err >= NGX_HTTP_LEVEL_300)
{
r->headers_out.content_length_n +=
- sizeof(ngx_http_msie_stub) - 1;
+ sizeof(ngx_http_msie_padding) - 1;
msie_padding = 1;
}
@@ -671,8 +669,8 @@ ngx_http_send_special_response(ngx_http_request_t *r,
}
b->memory = 1;
- b->pos = ngx_http_msie_stub;
- b->last = ngx_http_msie_stub + sizeof(ngx_http_msie_stub) - 1;
+ b->pos = ngx_http_msie_padding;
+ b->last = ngx_http_msie_padding + sizeof(ngx_http_msie_padding) - 1;
out[1].next = &out[2];
out[2].buf = b;
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index 2deec4819..4e3c3ed76 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -363,8 +363,6 @@ ngx_http_upstream_create(ngx_http_request_t *r)
if (u && u->cleanup) {
ngx_http_upstream_cleanup(r);
- *u->cleanup = NULL;
- u->cleanup = NULL;
}
u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t));
@@ -587,6 +585,13 @@ ngx_http_upstream_cache(ngx_http_request_t *r, ngx_http_upstream_t *u)
ngx_int_t rc;
ngx_http_cache_t *c;
+ if (u->conf->no_cache) {
+ rc = ngx_http_cache(r, u->conf->no_cache);
+ if (rc != NGX_OK) {
+ return rc;
+ }
+ }
+
if (!(r->method & u->conf->cache_methods)) {
return NGX_DECLINED;
}
@@ -1775,10 +1780,6 @@ ngx_http_upstream_process_headers(ngx_http_request_t *r, ngx_http_upstream_t *u)
return NGX_DONE;
}
- if (flags & NGX_HTTP_ZERO_IN_URI) {
- r->zero_in_uri = 1;
- }
-
if (r->method != NGX_HTTP_HEAD) {
r->method = NGX_HTTP_GET;
}
@@ -3004,16 +3005,18 @@ ngx_http_upstream_process_cache_control(ngx_http_request_t *r,
return NGX_OK;
}
- last = h->value.data + h->value.len;
+ p = h->value.data;
+ last = p + h->value.len;
- if (ngx_strlcasestrn(h->value.data, last, (u_char *) "no-cache", 8 - 1)
- != NULL)
+ if (ngx_strlcasestrn(p, last, (u_char *) "no-cache", 8 - 1) != NULL
+ || ngx_strlcasestrn(p, last, (u_char *) "no-store", 8 - 1) != NULL
+ || ngx_strlcasestrn(p, last, (u_char *) "private", 7 - 1) != NULL)
{
u->cacheable = 0;
return NGX_OK;
}
- p = ngx_strlcasestrn(h->value.data, last, (u_char *) "max-age=", 8 - 1);
+ p = ngx_strlcasestrn(p, last, (u_char *) "max-age=", 8 - 1);
if (p == NULL) {
return NGX_OK;
diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h
index ac2682d6f..38bd7df82 100644
--- a/src/http/ngx_http_upstream.h
+++ b/src/http/ngx_http_upstream.h
@@ -160,6 +160,7 @@ typedef struct {
ngx_uint_t cache_methods;
ngx_array_t *cache_valid;
+ ngx_array_t *no_cache; /* ngx_http_complex_value_t */
#endif
ngx_array_t *store_lengths;
diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c
index fc8ca9b02..79b9b3d1d 100644
--- a/src/http/ngx_http_variables.c
+++ b/src/http/ngx_http_variables.c
@@ -196,7 +196,8 @@ static ngx_http_variable_t ngx_http_core_variables[] = {
{ ngx_string("server_name"), NULL, ngx_http_variable_server_name, 0, 0, 0 },
{ ngx_string("request_method"), NULL,
- ngx_http_variable_request_method, 0, 0, 0 },
+ ngx_http_variable_request_method, 0,
+ NGX_HTTP_VAR_NOCACHEABLE, 0 },
{ ngx_string("remote_user"), NULL, ngx_http_variable_remote_user, 0, 0, 0 },
@@ -440,8 +441,7 @@ ngx_http_get_flushed_variable(ngx_http_request_t *r, ngx_uint_t index)
ngx_http_variable_value_t *
-ngx_http_get_variable(ngx_http_request_t *r, ngx_str_t *name, ngx_uint_t key,
- ngx_uint_t nowarn)
+ngx_http_get_variable(ngx_http_request_t *r, ngx_str_t *name, ngx_uint_t key)
{
ngx_http_variable_t *v;
ngx_http_variable_value_t *vv;
@@ -453,7 +453,7 @@ ngx_http_get_variable(ngx_http_request_t *r, ngx_str_t *name, ngx_uint_t key,
if (v) {
if (v->flags & NGX_HTTP_VAR_INDEXED) {
- return ngx_http_get_indexed_variable(r, v->index);
+ return ngx_http_get_flushed_variable(r, v->index);
} else {
@@ -494,7 +494,7 @@ ngx_http_get_variable(ngx_http_request_t *r, ngx_str_t *name, ngx_uint_t key,
return NULL;
}
- if (ngx_strncmp(name->data, "upstream_http_", 10) == 0) {
+ if (ngx_strncmp(name->data, "upstream_http_", 14) == 0) {
if (ngx_http_upstream_header_variable(r, vv, (uintptr_t) name)
== NGX_OK)
@@ -525,11 +525,6 @@ ngx_http_get_variable(ngx_http_request_t *r, ngx_str_t *name, ngx_uint_t key,
vv->not_found = 1;
- if (nowarn == 0) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "unknown \"%V\" variable", name);
- }
-
return vv;
}
@@ -1781,6 +1776,7 @@ ngx_http_variables_init_vars(ngx_conf_t *cf)
if (ngx_strncmp(v[i].name.data, "arg_", 4) == 0) {
v[i].get_handler = ngx_http_variable_argument;
v[i].data = (uintptr_t) &v[i].name;
+ v[i].flags = NGX_HTTP_VAR_NOCACHEABLE;
continue;
}
diff --git a/src/http/ngx_http_variables.h b/src/http/ngx_http_variables.h
index 0e86aaf3d..b922d282c 100644
--- a/src/http/ngx_http_variables.h
+++ b/src/http/ngx_http_variables.h
@@ -50,7 +50,7 @@ ngx_http_variable_value_t *ngx_http_get_flushed_variable(ngx_http_request_t *r,
ngx_uint_t index);
ngx_http_variable_value_t *ngx_http_get_variable(ngx_http_request_t *r,
- ngx_str_t *name, ngx_uint_t key, ngx_uint_t nowarn);
+ ngx_str_t *name, ngx_uint_t key);
ngx_int_t ngx_http_variable_unknown_header(ngx_http_variable_value_t *v,
ngx_str_t *var, ngx_list_part_t *part, size_t prefix);
diff --git a/src/mail/ngx_mail_pop3_handler.c b/src/mail/ngx_mail_pop3_handler.c
index aed662919..d22ba5ebf 100644
--- a/src/mail/ngx_mail_pop3_handler.c
+++ b/src/mail/ngx_mail_pop3_handler.c
@@ -188,7 +188,6 @@ ngx_mail_pop3_auth_state(ngx_event_t *rev)
default:
rc = NGX_MAIL_PARSE_INVALID_COMMAND;
- s->mail_state = ngx_pop3_start;
break;
}
@@ -215,7 +214,6 @@ ngx_mail_pop3_auth_state(ngx_event_t *rev)
default:
rc = NGX_MAIL_PARSE_INVALID_COMMAND;
- s->mail_state = ngx_pop3_start;
break;
}
diff --git a/src/mail/ngx_mail_proxy_module.c b/src/mail/ngx_mail_proxy_module.c
index b408ed7d3..3a9a6bec5 100644
--- a/src/mail/ngx_mail_proxy_module.c
+++ b/src/mail/ngx_mail_proxy_module.c
@@ -726,7 +726,7 @@ ngx_mail_proxy_read_response(ngx_mail_session_t *s, ngx_uint_t state)
b->last += n;
- if (b->last - b->pos < 5) {
+ if (b->last - b->pos < 4) {
return NGX_AGAIN;
}
diff --git a/src/os/unix/ngx_errno.h b/src/os/unix/ngx_errno.h
index 379f36777..ddc2b2761 100644
--- a/src/os/unix/ngx_errno.h
+++ b/src/os/unix/ngx_errno.h
@@ -64,10 +64,22 @@ u_char *ngx_strerror_r(int err, u_char *errstr, size_t size);
/* Solaris and Tru64 UNIX have thread-safe strerror() */
-#define ngx_strerror_r(err, errstr, size) \
+#define ngx_strerror_r(err, errstr, size) \
ngx_cpystrn(errstr, (u_char *) strerror(err), size)
#endif
+#if (NGX_HAVE_SYS_ERRLIST)
+
+#define ngx_sigsafe_strerror(err) \
+ (err > 0 && err < sys_nerr) ? sys_errlist[err] : "Unknown error"
+
+#else
+
+#define ngx_sigsafe_strerror(err) ""
+
+#endif
+
+
#endif /* _NGX_ERRNO_H_INCLUDED_ */
diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h
index c9144f31b..7e9b143ef 100644
--- a/src/os/unix/ngx_files.h
+++ b/src/os/unix/ngx_files.h
@@ -64,6 +64,7 @@ typedef struct {
#define NGX_FILE_OPEN 0
#define NGX_FILE_TRUNCATE O_CREAT|O_TRUNC
#define NGX_FILE_APPEND O_WRONLY|O_APPEND
+#define NGX_FILE_NONBLOCK O_NONBLOCK
#define NGX_FILE_DEFAULT_ACCESS 0644
#define NGX_FILE_OWNER_ACCESS 0600
@@ -138,6 +139,9 @@ ngx_int_t ngx_set_file_time(u_char *name, ngx_fd_t fd, time_t s);
#define ngx_fd_info(fd, sb) fstat(fd, sb)
#define ngx_fd_info_n "fstat()"
+#define ngx_link_info(file, sb) lstat((const char *) file, sb)
+#define ngx_link_info_n "lstat()"
+
#define ngx_is_dir(sb) (S_ISDIR((sb)->st_mode))
#define ngx_is_file(sb) (S_ISREG((sb)->st_mode))
#define ngx_is_link(sb) (S_ISLNK((sb)->st_mode))
diff --git a/src/os/unix/ngx_process.c b/src/os/unix/ngx_process.c
index 21a92f178..5e230f5bb 100644
--- a/src/os/unix/ngx_process.c
+++ b/src/os/unix/ngx_process.c
@@ -315,7 +315,7 @@ ngx_signal_handler(int signo)
}
}
- ngx_time_update(0, 0);
+ ngx_time_sigsafe_update();
action = "";
@@ -476,16 +476,17 @@ ngx_process_get_status(void)
*/
if (err == NGX_ECHILD) {
- ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, errno,
- "waitpid() failed");
+ ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, 0,
+ "waitpid() failed (%d: %s)",
+ err, ngx_sigsafe_strerror(err));
return;
}
#endif
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, errno,
- "waitpid() failed");
-
+ ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
+ "waitpid() failed (%d: %s)",
+ err, ngx_sigsafe_strerror(err));
return;
}
diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c
index e3b054834..812b36fc4 100644
--- a/src/os/unix/ngx_process_cycle.c
+++ b/src/os/unix/ngx_process_cycle.c
@@ -168,7 +168,7 @@ ngx_master_process_cycle(ngx_cycle_t *cycle)
sigsuspend(&set);
- ngx_time_update(0, 0);
+ ngx_time_update();
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"wake up, sigio %i", sigio);
@@ -1337,7 +1337,7 @@ ngx_cache_manager_process_handler(ngx_event_t *ev)
next = (n <= next) ? n : next;
- ngx_time_update(0, 0);
+ ngx_time_update();
}
}
@@ -1367,7 +1367,7 @@ ngx_cache_loader_process_handler(ngx_event_t *ev)
if (path[i]->loader) {
path[i]->loader(path[i]->data);
- ngx_time_update(0, 0);
+ ngx_time_update();
}
}