summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2009-10-26 17:57:42 +0000
committerJonathan Kolb <jon@b0g.us>2009-10-26 17:57:42 +0000
commit8da401f429b4061ce19e26cc7d01a3c045826d7c (patch)
treed7e9a60322d76883788234cba5e1b9145c56d3a2
parent8a41cb8620c2f1ee221a787d601de0766fa7ae2e (diff)
downloadnginx-8da401f429b4061ce19e26cc7d01a3c045826d7c.tar.gz
Changes with nginx 0.7.63 26 Oct 2009v0.7.63
*) Security: now "/../" are disabled in "Destination" request header line. *) Change: minimum supported OpenSSL version is 0.9.7. *) Change: the "ask" parameter of the "ssl_verify_client" directive was changed to the "optional" parameter and now it checks a client certificate if it was offered. Thanks to Brice Figureau. *) Feature: now the "-V" switch shows TLS SNI support. *) Feature: the $ssl_client_verify variable. Thanks to Brice Figureau. *) Feature: the "ssl_crl" directive. Thanks to Brice Figureau. *) Bugfix: the $ssl_client_cert variable usage corrupted memory; the bug had appeared in 0.7.7. Thanks to Sergey Zhuravlev. *) Feature: now the start cache loader runs in a separate process; this should improve large caches handling. *) Feature: now temporary files and permanent storage area may reside at different file systems. *) Bugfix: nginx counted incorrectly disk cache size. *) Change: now directive "gzip_disable msie6" does not disable gzipping for MSIE 6.0 SV1. *) Bugfix: nginx always added "Vary: Accept-Encoding" response header line, if both "gzip_static" and "gzip_vary" were on. *) Feature: the "proxy" parameter of the "geo" directive. *) Feature: the ngx_http_geoip_module. *) Feature: the "limit_rate_after" directive. Thanks to Ivan Debnar. *) Feature: the "limit_req_log_level" and "limit_conn_log_level" directives. *) Bugfix: now "limit_req" directive conforms to the leaky bucket algorithm. Thanks to Maxim Dounin. *) Bugfix: in ngx_http_limit_req_module. Thanks to Maxim Dounin. *) Bugfix: now nginx allows underscores in a request method. *) Bugfix: "proxy_pass_header" and "fastcgi_pass_header" directives did not pass to a client the "X-Accel-Redirect", "X-Accel-Limit-Rate", "X-Accel-Buffering", and "X-Accel-Charset" lines from backend response header. Thanks to Maxim Dounin. *) Bugfix: in handling "Last-Modified" and "Accept-Ranges" backend response header lines; the bug had appeared in 0.7.44. Thanks to Maxim Dounin. *) Feature: the "image_filter_transparency" directive. *) Feature: the "image_filter" directive supports variables for setting size. *) Bugfix: in PNG alpha-channel support in the ngx_http_image_filter_module. *) Bugfix: in transparency support in the ngx_http_image_filter_module. *) Feature: now several "perl_modules" directives may be used. *) Bugfix: ngx_http_perl_module responses did not work in subrequests. *) Bugfix: nginx sent '0' in a "Location" response header line on MKCOL request. Thanks to Xie Zhenye. *) Bugfix: an "error_page" directive did not redirect a 413 error; the bug had appeared in 0.6.10. *) Bugfix: in memory allocation error handling. Thanks to Maxim Dounin and Kirill A. Korinskiy.
-rw-r--r--CHANGES92
-rw-r--r--CHANGES.ru95
-rw-r--r--auto/lib/conf3
-rw-r--r--auto/lib/geoip/conf78
-rw-r--r--auto/modules6
-rw-r--r--auto/options3
-rw-r--r--auto/sources4
-rw-r--r--src/core/nginx.c7
-rw-r--r--src/core/nginx.h4
-rw-r--r--src/core/ngx_cycle.c9
-rw-r--r--src/core/ngx_file.c229
-rw-r--r--src/core/ngx_file.h21
-rw-r--r--src/core/ngx_hash.c4
-rw-r--r--src/core/ngx_output_chain.c3
-rw-r--r--src/core/ngx_string.c23
-rw-r--r--src/event/modules/ngx_devpoll_module.c2
-rw-r--r--src/event/modules/ngx_epoll_module.c2
-rw-r--r--src/event/modules/ngx_eventport_module.c2
-rw-r--r--src/event/modules/ngx_kqueue_module.c2
-rw-r--r--src/event/modules/ngx_rtsig_module.c2
-rw-r--r--src/event/ngx_event.c38
-rw-r--r--src/event/ngx_event_openssl.c99
-rw-r--r--src/event/ngx_event_openssl.h7
-rw-r--r--src/http/modules/ngx_http_access_module.c2
-rw-r--r--src/http/modules/ngx_http_addition_filter_module.c2
-rw-r--r--src/http/modules/ngx_http_auth_basic_module.c2
-rw-r--r--src/http/modules/ngx_http_autoindex_module.c16
-rw-r--r--src/http/modules/ngx_http_browser_module.c2
-rw-r--r--src/http/modules/ngx_http_charset_filter_module.c394
-rw-r--r--src/http/modules/ngx_http_dav_module.c136
-rw-r--r--src/http/modules/ngx_http_fastcgi_module.c23
-rw-r--r--src/http/modules/ngx_http_geo_module.c159
-rw-r--r--src/http/modules/ngx_http_geoip_module.c376
-rw-r--r--src/http/modules/ngx_http_gzip_filter_module.c2
-rw-r--r--src/http/modules/ngx_http_gzip_static_module.c13
-rw-r--r--src/http/modules/ngx_http_headers_filter_module.c2
-rw-r--r--src/http/modules/ngx_http_image_filter_module.c243
-rw-r--r--src/http/modules/ngx_http_index_module.c2
-rw-r--r--src/http/modules/ngx_http_limit_req_module.c63
-rw-r--r--src/http/modules/ngx_http_limit_zone_module.c25
-rw-r--r--src/http/modules/ngx_http_log_module.c12
-rw-r--r--src/http/modules/ngx_http_map_module.c2
-rw-r--r--src/http/modules/ngx_http_memcached_module.c19
-rw-r--r--src/http/modules/ngx_http_proxy_module.c15
-rw-r--r--src/http/modules/ngx_http_random_index_module.c2
-rw-r--r--src/http/modules/ngx_http_realip_module.c2
-rw-r--r--src/http/modules/ngx_http_referer_module.c2
-rw-r--r--src/http/modules/ngx_http_rewrite_module.c6
-rw-r--r--src/http/modules/ngx_http_secure_link_module.c2
-rw-r--r--src/http/modules/ngx_http_ssi_filter_module.c9
-rw-r--r--src/http/modules/ngx_http_ssl_module.c59
-rw-r--r--src/http/modules/ngx_http_ssl_module.h1
-rw-r--r--src/http/modules/ngx_http_sub_filter_module.c2
-rw-r--r--src/http/modules/ngx_http_userid_filter_module.c2
-rw-r--r--src/http/modules/ngx_http_xslt_filter_module.c6
-rw-r--r--src/http/modules/perl/nginx.pm2
-rw-r--r--src/http/modules/perl/ngx_http_perl_module.c138
-rw-r--r--src/http/ngx_http_cache.h1
-rw-r--r--src/http/ngx_http_core_module.c24
-rw-r--r--src/http/ngx_http_core_module.h1
-rw-r--r--src/http/ngx_http_file_cache.c106
-rw-r--r--src/http/ngx_http_parse.c10
-rw-r--r--src/http/ngx_http_request.c50
-rw-r--r--src/http/ngx_http_request.h4
-rw-r--r--src/http/ngx_http_script.c2
-rw-r--r--src/http/ngx_http_upstream.c58
-rw-r--r--src/http/ngx_http_upstream.h1
-rw-r--r--src/http/ngx_http_write_filter_module.c23
-rw-r--r--src/mail/ngx_mail_auth_http_module.c2
-rw-r--r--src/mail/ngx_mail_core_module.c6
-rw-r--r--src/mail/ngx_mail_proxy_module.c2
-rw-r--r--src/mail/ngx_mail_ssl_module.c34
-rw-r--r--src/os/unix/ngx_errno.h1
-rw-r--r--src/os/unix/ngx_files.h12
-rw-r--r--src/os/unix/ngx_process.c18
-rw-r--r--src/os/unix/ngx_process.h9
-rw-r--r--src/os/unix/ngx_process_cycle.c167
-rw-r--r--src/os/unix/ngx_process_cycle.h7
78 files changed, 2167 insertions, 849 deletions
diff --git a/CHANGES b/CHANGES
index 7938a05a2..89e0c380f 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,96 @@
+Changes with nginx 0.7.63 26 Oct 2009
+
+ *) Security: now "/../" are disabled in "Destination" request header
+ line.
+
+ *) Change: minimum supported OpenSSL version is 0.9.7.
+
+ *) Change: the "ask" parameter of the "ssl_verify_client" directive was
+ changed to the "optional" parameter and now it checks a client
+ certificate if it was offered.
+ Thanks to Brice Figureau.
+
+ *) Feature: now the "-V" switch shows TLS SNI support.
+
+ *) Feature: the $ssl_client_verify variable.
+ Thanks to Brice Figureau.
+
+ *) Feature: the "ssl_crl" directive.
+ Thanks to Brice Figureau.
+
+ *) Bugfix: the $ssl_client_cert variable usage corrupted memory; the
+ bug had appeared in 0.7.7.
+ Thanks to Sergey Zhuravlev.
+
+ *) Feature: now the start cache loader runs in a separate process; this
+ should improve large caches handling.
+
+ *) Feature: now temporary files and permanent storage area may reside
+ at different file systems.
+
+ *) Bugfix: nginx counted incorrectly disk cache size.
+
+ *) Change: now directive "gzip_disable msie6" does not disable gzipping
+ for MSIE 6.0 SV1.
+
+ *) Bugfix: nginx always added "Vary: Accept-Encoding" response header
+ line, if both "gzip_static" and "gzip_vary" were on.
+
+ *) Feature: the "proxy" parameter of the "geo" directive.
+
+ *) Feature: the ngx_http_geoip_module.
+
+ *) Feature: the "limit_rate_after" directive.
+ Thanks to Ivan Debnar.
+
+ *) Feature: the "limit_req_log_level" and "limit_conn_log_level"
+ directives.
+
+ *) Bugfix: now "limit_req" directive conforms to the leaky bucket
+ algorithm.
+ Thanks to Maxim Dounin.
+
+ *) Bugfix: in ngx_http_limit_req_module.
+ Thanks to Maxim Dounin.
+
+ *) Bugfix: now nginx allows underscores in a request method.
+
+ *) Bugfix: "proxy_pass_header" and "fastcgi_pass_header" directives did
+ not pass to a client the "X-Accel-Redirect", "X-Accel-Limit-Rate",
+ "X-Accel-Buffering", and "X-Accel-Charset" lines from backend
+ response header.
+ Thanks to Maxim Dounin.
+
+ *) Bugfix: in handling "Last-Modified" and "Accept-Ranges" backend
+ response header lines; the bug had appeared in 0.7.44.
+ Thanks to Maxim Dounin.
+
+ *) Feature: the "image_filter_transparency" directive.
+
+ *) Feature: the "image_filter" directive supports variables for setting
+ size.
+
+ *) Bugfix: in PNG alpha-channel support in the
+ ngx_http_image_filter_module.
+
+ *) Bugfix: in transparency support in the ngx_http_image_filter_module.
+
+ *) Feature: now several "perl_modules" directives may be used.
+
+ *) Bugfix: ngx_http_perl_module responses did not work in subrequests.
+
+ *) Bugfix: nginx sent '\0' in a "Location" response header line on
+ MKCOL request.
+ Thanks to Xie Zhenye.
+
+ *) Bugfix: an "error_page" directive did not redirect a 413 error; the
+ bug had appeared in 0.6.10.
+
+ *) Bugfix: in memory allocation error handling.
+ Thanks to Maxim Dounin and Kirill A. Korinskiy.
+
+
Changes with nginx 0.7.62 14 Sep 2009
*) Security: a segmentation fault might occur in worker process while
diff --git a/CHANGES.ru b/CHANGES.ru
index a789b0e39..b19ab0636 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,99 @@
+Изменения в nginx 0.7.63 26.10.2009
+
+ *) Безопасность: теперь символы "/../" запрещены в строке "Destination"
+ в заголовке запроса.
+
+ *) Изменение: минимальная поддерживаемая версия OpenSSL - 0.9.7.
+
+ *) Изменение: параметр ask директивы ssl_verify_client изменён на
+ параметр optional и теперь он проверяет клиентский сертификат, если
+ он был предложен.
+ Спасибо Brice Figureau.
+
+ *) Добавление: теперь ключ -V показывает статус поддержки TLS SNI.
+
+ *) Добавление: переменная $ssl_client_verify.
+ Спасибо Brice Figureau.
+
+ *) Добавление: директива ssl_crl.
+ Спасибо Brice Figureau.
+
+ *) Исправление: использование переменной $ssl_client_cert портило
+ память; ошибка появилась в 0.7.7.
+ Спасибо Сергею Журавлёву.
+
+ *) Добавление: теперь стартовый загрузчик кэша работает в отдельном
+ процесс; это должно улучшить обработку больших кэшей.
+
+ *) Добавление: теперь временные файлы и постоянное место хранения могут
+ располагаться на разных файловых системах.
+
+ *) Исправление: nginx неверно считал размер кэша на диске.
+
+ *) Изменение: теперь директива "gzip_disable msie6" не запрещает сжатие
+ для MSIE 6.0 SV1.
+
+ *) Исправление: nginx всегда добавлял строку "Vary: Accept-Encoding" в
+ заголовок ответа, если обе директивы gzip_static и gzip_vary были
+ включены.
+
+ *) Добавление: параметр proxy директивы geo.
+
+ *) Добавление: модуль ngx_http_geoip_module.
+
+ *) Добавление: директива limit_rate_after.
+ Спасибо Ivan Debnar.
+
+ *) Добавление: директивы limit_req_log_level и limit_conn_log_level.
+
+ *) Исправление: Теперь директива limit_req соответствует алгоритму
+ leaky bucket.
+ Спасибо Максиму Дунину.
+
+ *) Исправление: в модуле ngx_http_limit_req_module.
+ Спасибо Максиму Дунину.
+
+ *) Исправление: теперь nginx разрешает подчёркивания в методе запроса.
+
+ *) Исправление: директивы proxy_pass_header и fastcgi_pass_header" не
+ передавали клиенту строки "X-Accel-Redirect", "X-Accel-Limit-Rate",
+ "X-Accel-Buffering" и "X-Accel-Charset" из заголовка ответа
+ бэкенда.
+ Спасибо Максиму Дунину.
+
+ *) Исправление: в обработке строк "Last-Modified" и "Accept-Ranges" в
+ заголовке ответа бэкенда; ошибка появилась в 0.7.44
+ Спасибо Максиму Дунину.
+
+ *) Добавление: директива image_filter_transparency.
+
+ *) Добавление: директива image_filter поддерживает переменные для
+ задания размеров.
+
+ *) Исправление: в поддержке альфа-канала PNG в модуле
+ ngx_http_image_filter_module.
+
+ *) Исправление: в поддержке прозрачности в модуле
+ ngx_http_image_filter_module.
+
+ *) Добавление: теперь можно использовать несколько директив
+ perl_modules.
+
+ *) Исправление: ответы модуля ngx_http_perl_module не работали в
+ подзапросах.
+
+ *) Исправление: nginx слал символ '\0' в строке "Location" в заголовке
+ в ответе на запрос MKCOL.
+ Спасибо Xie Zhenye.
+
+ *) Исправление: директива error_page не перенаправляла ошибку 413;
+ ошибка появилась в 0.6.10.
+
+ *) Исправление: в обработке ошибок выделения памяти.
+ Спасибо Максиму Дунину и Кириллу Коринскому.
+
+
Изменения в nginx 0.7.62 14.09.2009
*) Безопасность: при обработке специально созданного запроса в рабочем
diff --git a/auto/lib/conf b/auto/lib/conf
index f52c90492..edb15bc3b 100644
--- a/auto/lib/conf
+++ b/auto/lib/conf
@@ -67,6 +67,9 @@ if [ $USE_PERL = YES ]; then
. auto/lib/perl/conf
fi
+if [ $HTTP_GEOIP = YES ]; then
+ . auto/lib/geoip/conf
+fi
if [ $NGX_GOOGLE_PERFTOOLS = YES ]; then
. auto/lib/google-perftools/conf
fi
diff --git a/auto/lib/geoip/conf b/auto/lib/geoip/conf
new file mode 100644
index 000000000..5647e9167
--- /dev/null
+++ b/auto/lib/geoip/conf
@@ -0,0 +1,78 @@
+
+# Copyright (C) Igor Sysoev
+
+
+ ngx_feature="GeoIP library"
+ ngx_feature_name=
+ ngx_feature_run=no
+ ngx_feature_incs=
+ ngx_feature_path=
+ ngx_feature_libs="-lGeoIP"
+ ngx_feature_test="GeoIP_open(NULL, 0)"
+ . auto/feature
+
+
+if [ $ngx_found = no ]; then
+
+ # FreeBSD port
+
+ ngx_feature="GeoIP library in /usr/local/"
+
+ if [ $NGX_RPATH = YES ]; then
+ ngx_feature_libs="-R/usr/local/lib -L/usr/local/lib -lGeoIP"
+ else
+ ngx_feature_libs="-L/usr/local/lib -lGeoIP"
+ fi
+
+ . auto/feature
+fi
+
+
+if [ $ngx_found = no ]; then
+
+ # NetBSD port
+
+ ngx_feature="GeoIP library in /usr/pkg/"
+ ngx_feature_path="/usr/pkg/include/"
+
+ if [ $NGX_RPATH = YES ]; then
+ ngx_feature_libs="-R/usr/pkg/lib -L/usr/pkg/lib -lGeoIP"
+ else
+ ngx_feature_libs="-L/usr/pkg/lib -lGeoIP"
+ fi
+
+ . auto/feature
+fi
+
+
+if [ $ngx_found = no ]; then
+
+ # MacPorts
+
+ ngx_feature="GeoIP library in /opt/local/"
+ ngx_feature_path="/opt/local/include"
+
+ if [ $NGX_RPATH = YES ]; then
+ ngx_feature_libs="-R/opt/local/lib -L/opt/local/lib -lGeoIP"
+ else
+ ngx_feature_libs="-L/opt/local/lib -lGeoIP"
+ fi
+
+ . auto/feature
+fi
+
+
+if [ $ngx_found = yes ]; then
+ CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
+
+else
+
+cat << END
+
+$0: error: the GeoIP module requires the GeoIP library.
+You can either do not enable the module or install the library.
+
+END
+
+ exit 1
+fi
diff --git a/auto/modules b/auto/modules
index 9bc2e04db..01951c738 100644
--- a/auto/modules
+++ b/auto/modules
@@ -240,6 +240,12 @@ if [ $HTTP_GEO = YES ]; then
HTTP_SRCS="$HTTP_SRCS $HTTP_GEO_SRCS"
fi
+if [ $HTTP_GEOIP = YES ]; then
+ have=NGX_HTTP_GEOIP . auto/have
+ HTTP_MODULES="$HTTP_MODULES $HTTP_GEOIP_MODULE"
+ HTTP_SRCS="$HTTP_SRCS $HTTP_GEOIP_SRCS"
+fi
+
if [ $HTTP_MAP = YES ]; then
have=NGX_HTTP_MAP . auto/have
HTTP_MODULES="$HTTP_MODULES $HTTP_MAP_MODULE"
diff --git a/auto/options b/auto/options
index aca314b93..bc9e80917 100644
--- a/auto/options
+++ b/auto/options
@@ -71,6 +71,7 @@ HTTP_AUTOINDEX=YES
HTTP_RANDOM_INDEX=NO
HTTP_STATUS=NO
HTTP_GEO=YES
+HTTP_GEOIP=NO
HTTP_MAP=YES
HTTP_REFERER=YES
HTTP_REWRITE=YES
@@ -184,6 +185,7 @@ do
--with-http_addition_module) HTTP_ADDITION=YES ;;
--with-http_xslt_module) HTTP_XSLT=YES ;;
--with-http_image_filter_module) HTTP_IMAGE_FILTER=YES ;;
+ --with-http_geoip_module) HTTP_GEOIP=YES ;;
--with-http_sub_module) HTTP_SUB=YES ;;
--with-http_dav_module) HTTP_DAV=YES ;;
--with-http_flv_module) HTTP_FLV=YES ;;
@@ -310,6 +312,7 @@ cat << END
--with-http_addition_module enable ngx_http_addition_module
--with-http_xslt_module enable ngx_http_xslt_module
--with-http_image_filter_module enable ngx_http_image_filter_module
+ --with-http_geoip_module enable ngx_http_geoip_module
--with-http_sub_module enable ngx_http_sub_module
--with-http_dav_module enable ngx_http_dav_module
--with-http_flv_module enable ngx_http_flv_module
diff --git a/auto/sources b/auto/sources
index e4649b030..616b9f11e 100644
--- a/auto/sources
+++ b/auto/sources
@@ -377,6 +377,10 @@ HTTP_GEO_MODULE=ngx_http_geo_module
HTTP_GEO_SRCS=src/http/modules/ngx_http_geo_module.c
+HTTP_GEOIP_MODULE=ngx_http_geoip_module
+HTTP_GEOIP_SRCS=src/http/modules/ngx_http_geoip_module.c
+
+
HTTP_MAP_MODULE=ngx_http_map_module
HTTP_MAP_SRCS=src/http/modules/ngx_http_map_module.c
diff --git a/src/core/nginx.c b/src/core/nginx.c
index ff7a9f848..a9951d3a2 100644
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -239,6 +239,13 @@ main(int argc, char *const *argv)
#ifdef NGX_COMPILER
ngx_log_stderr(0, "built by " NGX_COMPILER);
#endif
+#if (NGX_SSL)
+#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
+ ngx_log_stderr(0, "TLS SNI support enabled");
+#else
+ ngx_log_stderr(0, "TLS SNI support disabled");
+#endif
+#endif
ngx_log_stderr(0, "configure arguments:" NGX_CONFIGURE);
}
diff --git a/src/core/nginx.h b/src/core/nginx.h
index 83bafc613..fd894a3a9 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,8 +8,8 @@
#define _NGINX_H_INCLUDED_
-#define nginx_version 7062
-#define NGINX_VERSION "0.7.62"
+#define nginx_version 7063
+#define NGINX_VERSION "0.7.63"
#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 1e846f85d..cd9efbee7 100644
--- a/src/core/ngx_cycle.c
+++ b/src/core/ngx_cycle.c
@@ -216,7 +216,7 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
if (module->create_conf) {
rv = module->create_conf(cycle);
- if (rv == NGX_CONF_ERROR) {
+ if (rv == NULL) {
ngx_destroy_pool(pool);
return NULL;
}
@@ -255,11 +255,13 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
#endif
if (ngx_conf_param(&conf) != NGX_CONF_OK) {
+ environ = senv;
ngx_destroy_cycle_pools(&conf);
return NULL;
}
if (ngx_conf_parse(&conf, &cycle->conf_file) != NGX_CONF_OK) {
+ environ = senv;
ngx_destroy_cycle_pools(&conf);
return NULL;
}
@@ -280,6 +282,7 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
if (module->init_conf(cycle, cycle->conf_ctx[ngx_modules[i]->index])
== NGX_CONF_ERROR)
{
+ environ = senv;
ngx_destroy_cycle_pools(&conf);
return NULL;
}
@@ -698,8 +701,8 @@ old_shm_zone_done:
if (ngx_process == NGX_PROCESS_MASTER || ngx_is_init_cycle(old_cycle)) {
/*
- * perl_destruct() frees environ if it is not the same as it was at
- * perl_construct() time. So we have saved an previous cycle
+ * perl_destruct() frees environ, if it is not the same as it was at
+ * perl_construct() time, therefore we save the previous cycle
* environment before ngx_conf_parse() where it will be changed.
*/
diff --git a/src/core/ngx_file.c b/src/core/ngx_file.c
index 3f47fc98b..45bb4ca4f 100644
--- a/src/core/ngx_file.c
+++ b/src/core/ngx_file.c
@@ -8,8 +8,9 @@
#include <ngx_core.h>
-static ngx_atomic_uint_t ngx_temp_number;
-static ngx_atomic_uint_t ngx_random_number;
+static ngx_atomic_t temp_number = 0;
+ngx_atomic_t *ngx_temp_number = &temp_number;
+ngx_atomic_int_t ngx_random_number = 123456;
ssize_t
@@ -99,13 +100,7 @@ ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path, ngx_pool_t *pool,
continue;
}
- if ((path->level[0] == 0)
- || (err != NGX_ENOENT
-#if (NGX_WIN32)
- && err != NGX_ENOTDIR
-#endif
- ))
- {
+ if ((path->level[0] == 0) || (err != NGX_ENOPATH)) {
ngx_log_error(NGX_LOG_CRIT, file->log, err,
ngx_open_tempfile_n " \"%s\" failed",
file->name.data);
@@ -211,22 +206,16 @@ ngx_create_full_path(u_char *dir, ngx_uint_t access)
}
-void
-ngx_init_temp_number(void)
-{
- ngx_temp_number = 0;
- ngx_random_number = 123456;
-}
-
-
ngx_atomic_uint_t
ngx_next_temp_number(ngx_uint_t collision)
{
- if (collision) {
- ngx_temp_number += ngx_random_number;
- }
+ ngx_atomic_uint_t n, add;
+
+ add = collision ? ngx_random_number : 1;
- return ngx_temp_number++;
+ n = ngx_atomic_fetch_add(ngx_temp_number, add);
+
+ return n + add;
}
@@ -264,7 +253,8 @@ ngx_conf_set_path_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
path->len = 0;
- path->manager = (ngx_path_manager_pt) cmd->post;
+ path->manager = NULL;
+ path->loader = NULL;
path->conf_file = cf->conf_file->file.name.data;
path->line = cf->conf_file->line;
@@ -325,6 +315,7 @@ ngx_conf_merge_path_value(ngx_conf_t *cf, ngx_path_t **path, ngx_path_t *prev,
+ 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) {
@@ -528,7 +519,9 @@ ngx_create_pathes(ngx_cycle_t *cycle, ngx_uid_t user)
ngx_int_t
ngx_ext_rename_file(ngx_str_t *src, ngx_str_t *to, ngx_ext_rename_file_t *ext)
{
- ngx_err_t err;
+ u_char *name;
+ ngx_err_t err;
+ ngx_copy_file_t cf;
#if !(NGX_WIN32)
@@ -558,14 +551,8 @@ ngx_ext_rename_file(ngx_str_t *src, ngx_str_t *to, ngx_ext_rename_file_t *ext)
err = ngx_errno;
- if (err
-#if (NGX_WIN32)
- == ERROR_PATH_NOT_FOUND
-#else
- == NGX_ENOENT
-#endif
- )
- {
+ if (err == NGX_ENOPATH) {
+
if (!ext->create_path) {
goto failed;
}
@@ -584,7 +571,6 @@ ngx_ext_rename_file(ngx_str_t *src, ngx_str_t *to, ngx_ext_rename_file_t *ext)
}
err = ngx_errno;
- goto failed;
}
#if (NGX_WIN32)
@@ -605,6 +591,53 @@ ngx_ext_rename_file(ngx_str_t *src, ngx_str_t *to, ngx_ext_rename_file_t *ext)
#endif
+ if (err == NGX_EXDEV) {
+
+ cf.size = -1;
+ cf.buf_size = 0;
+ cf.access = ext->access;
+ cf.time = ext->time;
+ cf.log = ext->log;
+
+ name = ngx_alloc(to->len + 1 + 10 + 1, ext->log);
+ if (name == NULL) {
+ return NGX_ERROR;
+ }
+
+ (void) ngx_sprintf(name, "%*s.%010uD%Z", to->len, to->data,
+ (uint32_t) ngx_next_temp_number(0));
+
+ if (ngx_copy_file(src->data, name, &cf) == NGX_OK) {
+
+ if (ngx_rename_file(name, to->data) != NGX_FILE_ERROR) {
+ ngx_free(name);
+
+ if (ngx_delete_file(src->data) == NGX_FILE_ERROR) {
+ ngx_log_error(NGX_LOG_CRIT, ext->log, ngx_errno,
+ ngx_delete_file_n " \"%s\" failed",
+ src->data);
+ return NGX_ERROR;
+ }
+
+ return NGX_OK;
+ }
+
+ ngx_log_error(NGX_LOG_CRIT, ext->log, ngx_errno,
+ ngx_rename_file_n " \"%s\" to \"%s\" failed",
+ name, to->data);
+
+ if (ngx_delete_file(name) == NGX_FILE_ERROR) {
+ ngx_log_error(NGX_LOG_CRIT, ext->log, ngx_errno,
+ ngx_delete_file_n " \"%s\" failed", name);
+
+ }
+ }
+
+ ngx_free(name);
+
+ err = 0;
+ }
+
failed:
if (ext->delete_file) {
@@ -614,18 +647,144 @@ failed:
}
}
- if (err && ext->log_rename_error) {
+ if (err) {
ngx_log_error(NGX_LOG_CRIT, ext->log, err,
ngx_rename_file_n " \"%s\" to \"%s\" failed",
src->data, to->data);
}
- ext->rename_error = err;
-
return NGX_ERROR;
}
+ngx_int_t
+ngx_copy_file(u_char *from, u_char *to, ngx_copy_file_t *cf)
+{
+ char *buf;
+ off_t size;
+ size_t len;
+ ssize_t n;
+ ngx_fd_t fd, nfd;
+ ngx_int_t rc;
+ ngx_file_info_t fi;
+
+ rc = NGX_ERROR;
+ buf = NULL;
+ nfd = NGX_INVALID_FILE;
+
+ fd = ngx_open_file(from, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);
+
+ if (fd == NGX_INVALID_FILE) {
+ ngx_log_error(NGX_LOG_CRIT, cf->log, ngx_errno,
+ ngx_open_file_n " \"%s\" failed", from);
+ goto failed;
+ }
+
+ if (cf->size != -1) {
+ size = cf->size;
+
+ } else {
+ if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) {
+ ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
+ ngx_fd_info_n " \"%s\" failed", from);
+
+ goto failed;
+ }
+
+ size = ngx_file_size(&fi);
+ }
+
+ len = cf->buf_size ? cf->buf_size : 65536;
+
+ if ((off_t) len > size) {
+ len = (size_t) size;
+ }
+
+ buf = ngx_alloc(len, cf->log);
+ if (buf == NULL) {
+ goto failed;
+ }
+
+ nfd = ngx_open_file(to, NGX_FILE_WRONLY, NGX_FILE_CREATE_OR_OPEN,
+ cf->access);
+
+ if (nfd == NGX_INVALID_FILE) {
+ ngx_log_error(NGX_LOG_CRIT, cf->log, ngx_errno,
+ ngx_open_file_n " \"%s\" failed", to);
+ goto failed;
+ }
+
+ while (size > 0) {
+
+ if ((off_t) len > size) {
+ len = (size_t) size;
+ }
+
+ n = ngx_read_fd(fd, buf, len);
+
+ if (n == NGX_FILE_ERROR) {
+ ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
+ ngx_read_fd_n " \"%s\" failed", from);
+ goto failed;
+ }
+
+ if ((size_t) n != len) {
+ ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
+ ngx_read_fd_n " has read only %z of %uz from %s",
+ n, size, from);
+ goto failed;
+ }
+
+ n = ngx_write_fd(nfd, buf, len);
+
+ if (n == NGX_FILE_ERROR) {
+ ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
+ ngx_write_fd_n " \"%s\" failed", to);
+ goto failed;
+ }
+
+ if ((size_t) n != len) {
+ ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
+ ngx_write_fd_n " has written only %z of %uz to %s",
+ n, size, to);
+ goto failed;
+ }
+
+ 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;
+ }
+
+ rc = NGX_OK;
+
+failed:
+
+ if (nfd != NGX_INVALID_FILE) {
+ if (ngx_close_file(nfd) == NGX_FILE_ERROR) {
+ ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
+ ngx_close_file_n " \"%s\" failed", to);
+ }
+ }
+
+ if (fd != NGX_INVALID_FILE) {
+ if (ngx_close_file(fd) == NGX_FILE_ERROR) {
+ ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno,
+ ngx_close_file_n " \"%s\" failed", from);
+ }
+ }
+
+ if (buf) {
+ ngx_free(buf);
+ }
+
+ return rc;
+}
+
+
/*
* ctx->init_handler() - see ctx->alloc
* ctx->file_handler() - file handler
diff --git a/src/core/ngx_file.h b/src/core/ngx_file.h
index 264ba391b..56315433b 100644
--- a/src/core/ngx_file.h
+++ b/src/core/ngx_file.h
@@ -30,6 +30,7 @@ struct ngx_file_s {
typedef time_t (*ngx_path_manager_pt) (void *data);
+typedef void (*ngx_path_loader_pt) (void *data);
typedef struct {
@@ -38,6 +39,7 @@ typedef struct {
size_t level[3];
ngx_path_manager_pt manager;
+ ngx_path_loader_pt loader;
void *data;
u_char *conf_file;
@@ -71,16 +73,25 @@ typedef struct {
ngx_uint_t path_access;
time_t time;
ngx_fd_t fd;
- ngx_err_t rename_error;
unsigned create_path:1;
unsigned delete_file:1;
- unsigned log_rename_error:1;
ngx_log_t *log;
} ngx_ext_rename_file_t;
+typedef struct {
+ off_t size;
+ size_t buf_size;
+
+ ngx_uint_t access;
+ time_t time;
+
+ ngx_log_t *log;
+} ngx_copy_file_t;
+
+
typedef struct ngx_tree_ctx_s ngx_tree_ctx_t;
typedef ngx_int_t (*ngx_tree_init_handler_pt) (void *ctx, void *prev);
@@ -115,9 +126,9 @@ ngx_int_t ngx_add_path(ngx_conf_t *cf, ngx_path_t **slot);
ngx_int_t ngx_create_pathes(ngx_cycle_t *cycle, ngx_uid_t user);
ngx_int_t ngx_ext_rename_file(ngx_str_t *src, ngx_str_t *to,
ngx_ext_rename_file_t *ext);
+ngx_int_t ngx_copy_file(u_char *from, u_char *to, ngx_copy_file_t *cf);
ngx_int_t ngx_walk_tree(ngx_tree_ctx_t *ctx, ngx_str_t *tree);
-void ngx_init_temp_number(void);
ngx_atomic_uint_t ngx_next_temp_number(ngx_uint_t collision);
char *ngx_conf_set_path_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
@@ -126,4 +137,8 @@ char *ngx_conf_merge_path_value(ngx_conf_t *cf, ngx_path_t **path,
char *ngx_conf_set_access_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
+extern ngx_atomic_t *ngx_temp_number;
+extern ngx_atomic_int_t ngx_random_number;
+
+
#endif /* _NGX_FILE_H_INCLUDED_ */
diff --git a/src/core/ngx_hash.c b/src/core/ngx_hash.c
index 2eadbf3e3..2a5b0adc7 100644
--- a/src/core/ngx_hash.c
+++ b/src/core/ngx_hash.c
@@ -534,7 +534,7 @@ ngx_hash_wildcard_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names,
next_name->key.len = names[n].key.len - len;
next_name->key.data = names[n].key.data + len;
- next_name->key_hash= 0;
+ next_name->key_hash = 0;
next_name->value = names[n].value;
#if 0
@@ -562,7 +562,7 @@ ngx_hash_wildcard_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names,
next_name->key.len = names[i].key.len - dot_len;
next_name->key.data = names[i].key.data + dot_len;
- next_name->key_hash= 0;
+ next_name->key_hash = 0;
next_name->value = names[i].value;
#if 0
diff --git a/src/core/ngx_output_chain.c b/src/core/ngx_output_chain.c
index ee23e8fe1..6d6d241c1 100644
--- a/src/core/ngx_output_chain.c
+++ b/src/core/ngx_output_chain.c
@@ -314,12 +314,11 @@ ngx_output_chain_add_copy(ngx_pool_t *pool, ngx_chain_t **chain,
#endif
+ cl->next = NULL;
*ll = cl;
ll = &cl->next;
}
- *ll = NULL;
-
return NGX_OK;
}
diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c
index e73dc41d8..c0bcc1d12 100644
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -30,12 +30,15 @@ ngx_cpystrn(u_char *dst, u_char *src, size_t n)
return dst;
}
- for ( /* void */ ; --n; dst++, src++) {
+ while (--n) {
*dst = *src;
if (*dst == '\0') {
return dst;
}
+
+ dst++;
+ src++;
}
*dst = '\0';
@@ -565,8 +568,8 @@ ngx_strcasecmp(u_char *s1, u_char *s2)
c1 = (ngx_uint_t) *s1++;
c2 = (ngx_uint_t) *s2++;
- c1 = (c1 >= 'A' && c1 <= 'Z') ? (c1 | 0x20) : c1;
- c2 = (c2 >= 'A' && c2 <= 'Z') ? (c2 | 0x20) : c2;
+ c1 = (c1 >= 'A' && c1 <= 'Z') ? (c1 | 0x20) : c1;
+ c2 = (c2 >= 'A' && c2 <= 'Z') ? (c2 | 0x20) : c2;
if (c1 == c2) {
@@ -591,8 +594,8 @@ ngx_strncasecmp(u_char *s1, u_char *s2, size_t n)
c1 = (ngx_uint_t) *s1++;
c2 = (ngx_uint_t) *s2++;
- c1 = (c1 >= 'A' && c1 <= 'Z') ? (c1 | 0x20) : c1;
- c2 = (c2 >= 'A' && c2 <= 'Z') ? (c2 | 0x20) : c2;
+ c1 = (c1 >= 'A' && c1 <= 'Z') ? (c1 | 0x20) : c1;
+ c2 = (c2 >= 'A' && c2 <= 'Z') ? (c2 | 0x20) : c2;
if (c1 == c2) {
@@ -680,7 +683,7 @@ ngx_strcasestrn(u_char *s1, char *s2, size_t n)
ngx_uint_t c1, c2;
c2 = (ngx_uint_t) *s2++;
- c2 = (c2 >= 'A' && c2 <= 'Z') ? (c2 | 0x20) : c2;
+ c2 = (c2 >= 'A' && c2 <= 'Z') ? (c2 | 0x20) : c2;
do {
do {
@@ -690,7 +693,7 @@ ngx_strcasestrn(u_char *s1, char *s2, size_t n)
return NULL;
}
- c1 = (c1 >= 'A' && c1 <= 'Z') ? (c1 | 0x20) : c1;
+ c1 = (c1 >= 'A' && c1 <= 'Z') ? (c1 | 0x20) : c1;
} while (c1 != c2);
@@ -712,7 +715,7 @@ ngx_strlcasestrn(u_char *s1, u_char *last, u_char *s2, size_t n)
ngx_uint_t c1, c2;
c2 = (ngx_uint_t) *s2++;
- c2 = (c2 >= 'A' && c2 <= 'Z') ? (c2 | 0x20) : c2;
+ c2 = (c2 >= 'A' && c2 <= 'Z') ? (c2 | 0x20) : c2;
last -= n;
do {
@@ -723,7 +726,7 @@ ngx_strlcasestrn(u_char *s1, u_char *last, u_char *s2, size_t n)
c1 = (ngx_uint_t) *s1++;
- c1 = (c1 >= 'A' && c1 <= 'Z') ? (c1 | 0x20) : c1;
+ c1 = (c1 >= 'A' && c1 <= 'Z') ? (c1 | 0x20) : c1;
} while (c1 != c2);
@@ -1337,7 +1340,7 @@ ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
/* find the number of the characters to be escaped */
- n = 0;
+ n = 0;
for (i = 0; i < size; i++) {
if (escape[*src >> 5] & (1 << (*src & 0x1f))) {
diff --git a/src/event/modules/ngx_devpoll_module.c b/src/event/modules/ngx_devpoll_module.c
index 903efe6b5..657886268 100644
--- a/src/event/modules/ngx_devpoll_module.c
+++ b/src/event/modules/ngx_devpoll_module.c
@@ -550,7 +550,7 @@ ngx_devpoll_create_conf(ngx_cycle_t *cycle)
dpcf = ngx_palloc(cycle->pool, sizeof(ngx_devpoll_conf_t));
if (dpcf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
dpcf->changes = NGX_CONF_UNSET;
diff --git a/src/event/modules/ngx_epoll_module.c b/src/event/modules/ngx_epoll_module.c
index 71d847107..b3267b37d 100644
--- a/src/event/modules/ngx_epoll_module.c
+++ b/src/event/modules/ngx_epoll_module.c
@@ -552,7 +552,7 @@ ngx_epoll_create_conf(ngx_cycle_t *cycle)
epcf = ngx_palloc(cycle->pool, sizeof(ngx_epoll_conf_t));
if (epcf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
epcf->events = NGX_CONF_UNSET;
diff --git a/src/event/modules/ngx_eventport_module.c b/src/event/modules/ngx_eventport_module.c
index 4becf75d0..842d631af 100644
--- a/src/event/modules/ngx_eventport_module.c
+++ b/src/event/modules/ngx_eventport_module.c
@@ -581,7 +581,7 @@ ngx_eventport_create_conf(ngx_cycle_t *cycle)
epcf = ngx_palloc(cycle->pool, sizeof(ngx_eventport_conf_t));
if (epcf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
epcf->events = NGX_CONF_UNSET;
diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c
index 1ad2d8d5a..a84fc8fe1 100644
--- a/src/event/modules/ngx_kqueue_module.c
+++ b/src/event/modules/ngx_kqueue_module.c
@@ -768,7 +768,7 @@ ngx_kqueue_create_conf(ngx_cycle_t *cycle)
kcf = ngx_palloc(cycle->pool, sizeof(ngx_kqueue_conf_t));
if (kcf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
kcf->changes = NGX_CONF_UNSET;
diff --git a/src/event/modules/ngx_rtsig_module.c b/src/event/modules/ngx_rtsig_module.c
index 6020936b7..926be0de3 100644
--- a/src/event/modules/ngx_rtsig_module.c
+++ b/src/event/modules/ngx_rtsig_module.c
@@ -691,7 +691,7 @@ ngx_rtsig_create_conf(ngx_cycle_t *cycle)
rtscf = ngx_palloc(cycle->pool, sizeof(ngx_rtsig_conf_t));
if (rtscf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
rtscf->signo = NGX_CONF_UNSET;
diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c
index e30c5636a..9c13eac47 100644
--- a/src/event/ngx_event.c
+++ b/src/event/ngx_event.c
@@ -43,7 +43,7 @@ ngx_uint_t ngx_event_flags;
ngx_event_actions_t ngx_event_actions;
-ngx_atomic_t connection_counter = 1;
+static ngx_atomic_t connection_counter = 1;
ngx_atomic_t *ngx_connection_counter = &connection_counter;
@@ -429,6 +429,7 @@ ngx_event_module_init(ngx_cycle_t *cycle)
u_char *shared;
size_t size, cl;
ngx_shm_t shm;
+ ngx_time_t *tp;
ngx_core_conf_t *ccf;
ngx_event_conf_t *ecf;
@@ -492,7 +493,8 @@ ngx_event_module_init(ngx_cycle_t *cycle)
cl = 128;
size = cl /* ngx_accept_mutex */
- + cl; /* ngx_connection_counter */
+ + cl /* ngx_connection_counter */
+ + cl; /* ngx_temp_number */
#if (NGX_STAT_STUB)
@@ -526,23 +528,29 @@ ngx_event_module_init(ngx_cycle_t *cycle)
ngx_connection_counter = (ngx_atomic_t *) (shared + 1 * cl);
-#if (NGX_STAT_STUB)
-
- ngx_stat_accepted = (ngx_atomic_t *) (shared + 2 * cl);
- ngx_stat_handled = (ngx_atomic_t *) (shared + 3 * cl);
- ngx_stat_requests = (ngx_atomic_t *) (shared + 4 * cl);
- ngx_stat_active = (ngx_atomic_t *) (shared + 5 * cl);
- ngx_stat_reading = (ngx_atomic_t *) (shared + 6 * cl);
- ngx_stat_writing = (ngx_atomic_t *) (shared + 7 * cl);
-
-#endif
-
(void) ngx_atomic_cmp_set(ngx_connection_counter, 0, 1);
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"counter: %p, %d",
ngx_connection_counter, *ngx_connection_counter);
+ ngx_temp_number = (ngx_atomic_t *) (shared + 2 * cl);
+
+ tp = ngx_timeofday();
+
+ ngx_random_number = (tp->msec << 16) + ngx_pid;
+
+#if (NGX_STAT_STUB)
+
+ ngx_stat_accepted = (ngx_atomic_t *) (shared + 3 * cl);
+ ngx_stat_handled = (ngx_atomic_t *) (shared + 4 * cl);
+ ngx_stat_requests = (ngx_atomic_t *) (shared + 5 * cl);
+ ngx_stat_active = (ngx_atomic_t *) (shared + 6 * cl);
+ ngx_stat_reading = (ngx_atomic_t *) (shared + 7 * cl);
+ ngx_stat_writing = (ngx_atomic_t *) (shared + 8 * cl);
+
+#endif
+
return NGX_OK;
}
@@ -1113,7 +1121,7 @@ ngx_event_create_conf(ngx_cycle_t *cycle)
ecf = ngx_palloc(cycle->pool, sizeof(ngx_event_conf_t));
if (ecf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
ecf->connections = NGX_CONF_UNSET_UINT;
@@ -1128,7 +1136,7 @@ ngx_event_create_conf(ngx_cycle_t *cycle)
if (ngx_array_init(&ecf->debug_connection, cycle->pool, 4,
sizeof(ngx_event_debug_t)) == NGX_ERROR)
{
- return NGX_CONF_ERROR;
+ return NULL;
}
#endif
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index 23a4fbec4..846114077 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -97,16 +97,12 @@ int ngx_ssl_session_cache_index;
ngx_int_t
ngx_ssl_init(ngx_log_t *log)
{
-#if OPENSSL_VERSION_NUMBER >= 0x00907000
OPENSSL_config(NULL);
-#endif
SSL_library_init();
SSL_load_error_strings();
-#if (NGX_SSL_ENGINE)
ENGINE_load_builtin_engines();
-#endif
ngx_ssl_connection_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
@@ -169,9 +165,7 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data)
SSL_CTX_set_options(ssl->ctx, SSL_OP_TLS_D5_BUG);
SSL_CTX_set_options(ssl->ctx, SSL_OP_TLS_BLOCK_PADDING_BUG);
-#ifdef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
SSL_CTX_set_options(ssl->ctx, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
-#endif
SSL_CTX_set_options(ssl->ctx, SSL_OP_SINGLE_DH_USE);
@@ -267,6 +261,51 @@ ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert,
}
+ngx_int_t
+ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl)
+{
+ X509_STORE *store;
+ X509_LOOKUP *lookup;
+
+ if (crl->len == 0) {
+ return NGX_OK;
+ }
+
+ if (ngx_conf_full_name(cf->cycle, crl, 1) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ store = SSL_CTX_get_cert_store(ssl->ctx);
+
+ if (store == NULL) {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "SSL_CTX_get_cert_store() failed");
+ return NGX_ERROR;
+ }
+
+ lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
+
+ if (lookup == NULL) {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "X509_STORE_add_lookup() failed");
+ return NGX_ERROR;
+ }
+
+ if (X509_LOOKUP_load_file(lookup, (char *) crl->data, X509_FILETYPE_PEM)
+ == 0)
+ {
+ ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
+ "X509_LOOKUP_load_file(\"%s\") failed", crl->data);
+ return NGX_ERROR;
+ }
+
+ X509_STORE_set_flags(store,
+ X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL);
+
+ return NGX_OK;
+}
+
+
static int
ngx_http_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store)
{
@@ -1201,9 +1240,7 @@ ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
if (err == NGX_ECONNRESET
|| err == NGX_EPIPE
|| err == NGX_ENOTCONN
-#if !(NGX_CRIT_ETIMEDOUT)
|| err == NGX_ETIMEDOUT
-#endif
|| err == NGX_ECONNREFUSED
|| err == NGX_ENETDOWN
|| err == NGX_ENETUNREACH
@@ -1974,7 +2011,7 @@ ngx_ssl_get_certificate(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
p = s->data;
- for (i = 0; i < len; i++) {
+ for (i = 0; i < cert.len - 1; i++) {
*p++ = cert.data[i];
if (cert.data[i] == LF) {
*p++ = '\t';
@@ -2108,6 +2145,35 @@ ngx_ssl_get_serial_number(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
}
+ngx_int_t
+ngx_ssl_get_client_verify(ngx_connection_t *c, ngx_pool_t *pool, ngx_str_t *s)
+{
+ X509 *cert;
+
+ if (SSL_get_verify_result(c->ssl->connection) != X509_V_OK) {
+ s->len = sizeof("FAILED") - 1;
+ s->data = (u_char *) "FAILED";
+
+ return NGX_OK;
+ }
+
+ cert = SSL_get_peer_certificate(c->ssl->connection);
+
+ if (cert) {
+ s->len = sizeof("SUCCESS") - 1;
+ s->data = (u_char *) "SUCCESS";
+
+ } else {
+ s->len = sizeof("NONE") - 1;
+ s->data = (u_char *) "NONE";
+ }
+
+ X509_free(cert);
+
+ return NGX_OK;
+}
+
+
static void *
ngx_openssl_create_conf(ngx_cycle_t *cycle)
{
@@ -2115,7 +2181,7 @@ ngx_openssl_create_conf(ngx_cycle_t *cycle)
oscf = ngx_pcalloc(cycle->pool, sizeof(ngx_openssl_conf_t));
if (oscf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
/*
@@ -2131,7 +2197,6 @@ ngx_openssl_create_conf(ngx_cycle_t *cycle)
static char *
ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
-#if (NGX_SSL_ENGINE)
ngx_openssl_conf_t *oscf = conf;
ENGINE *engine;
@@ -2166,23 +2231,11 @@ ngx_openssl_engine(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ENGINE_free(engine);
return NGX_CONF_OK;
-
-#else
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"ssl_engine\" directive is available only in "
- "OpenSSL 0.9.7 and higher,");
-
- return NGX_CONF_ERROR;
-
-#endif
}
static void
ngx_openssl_exit(ngx_cycle_t *cycle)
{
-#if (NGX_SSL_ENGINE)
ENGINE_cleanup();
-#endif
}
diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h
index 1e83606fd..2b9dd284e 100644
--- a/src/event/ngx_event_openssl.h
+++ b/src/event/ngx_event_openssl.h
@@ -13,12 +13,8 @@
#include <openssl/ssl.h>
#include <openssl/err.h>
-
-#if OPENSSL_VERSION_NUMBER >= 0x00907000
#include <openssl/conf.h>
#include <openssl/engine.h>
-#define NGX_SSL_ENGINE 1
-#endif
#define NGX_SSL_NAME "OpenSSL"
@@ -100,6 +96,7 @@ ngx_int_t ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
ngx_str_t *cert, ngx_str_t *key);
ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl,
ngx_str_t *cert, ngx_int_t depth);
+ngx_int_t ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl);
ngx_int_t ngx_ssl_generate_rsa512_key(ngx_ssl_t *ssl);
ngx_int_t ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file);
ngx_int_t ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
@@ -131,6 +128,8 @@ ngx_int_t ngx_ssl_get_issuer_dn(ngx_connection_t *c, ngx_pool_t *pool,
ngx_str_t *s);
ngx_int_t ngx_ssl_get_serial_number(ngx_connection_t *c, ngx_pool_t *pool,
ngx_str_t *s);
+ngx_int_t ngx_ssl_get_client_verify(ngx_connection_t *c, ngx_pool_t *pool,
+ ngx_str_t *s);
ngx_int_t ngx_ssl_handshake(ngx_connection_t *c);
diff --git a/src/http/modules/ngx_http_access_module.c b/src/http/modules/ngx_http_access_module.c
index 78b8a6a10..405aad4ef 100644
--- a/src/http/modules/ngx_http_access_module.c
+++ b/src/http/modules/ngx_http_access_module.c
@@ -201,7 +201,7 @@ ngx_http_access_create_loc_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_access_loc_conf_t));
if (conf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
return conf;
diff --git a/src/http/modules/ngx_http_addition_filter_module.c b/src/http/modules/ngx_http_addition_filter_module.c
index eb6a4b168..4076c5374 100644
--- a/src/http/modules/ngx_http_addition_filter_module.c
+++ b/src/http/modules/ngx_http_addition_filter_module.c
@@ -212,7 +212,7 @@ ngx_http_addition_create_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_addition_conf_t));
if (conf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
/*
diff --git a/src/http/modules/ngx_http_auth_basic_module.c b/src/http/modules/ngx_http_auth_basic_module.c
index 1d2d75e73..c9ce694ef 100644
--- a/src/http/modules/ngx_http_auth_basic_module.c
+++ b/src/http/modules/ngx_http_auth_basic_module.c
@@ -372,7 +372,7 @@ ngx_http_auth_basic_create_loc_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_auth_basic_loc_conf_t));
if (conf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
return conf;
diff --git a/src/http/modules/ngx_http_autoindex_module.c b/src/http/modules/ngx_http_autoindex_module.c
index 6215da21f..698b7636c 100644
--- a/src/http/modules/ngx_http_autoindex_module.c
+++ b/src/http/modules/ngx_http_autoindex_module.c
@@ -145,7 +145,7 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
ngx_int_t rc, size;
ngx_str_t path;
ngx_dir_t dir;
- ngx_uint_t i, level;
+ ngx_uint_t i, level, utf8;
ngx_pool_t *pool;
ngx_time_t *tp;
ngx_chain_t out;
@@ -252,6 +252,16 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
filename = path.data;
filename[path.len] = '/';
+ if (r->headers_out.charset.len == 5
+ && ngx_strncasecmp(r->headers_out.charset.data, (u_char *) "utf-8", 5)
+ == 0)
+ {
+ utf8 = 1;
+
+ } else {
+ utf8 = 0;
+ }
+
for ( ;; ) {
ngx_set_errno(0);
@@ -335,7 +345,7 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
entry->escape = 2 * ngx_escape_uri(NULL, ngx_de_name(&dir), len,
NGX_ESCAPE_HTML);
- if (r->utf8) {
+ if (utf8) {
entry->utf_len = ngx_utf8_length(entry->name.data, entry->name.len);
} else {
entry->utf_len = len;
@@ -622,7 +632,7 @@ ngx_http_autoindex_create_loc_conf(ngx_conf_t *cf)
conf = ngx_palloc(cf->pool, sizeof(ngx_http_autoindex_loc_conf_t));
if (conf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
conf->enable = NGX_CONF_UNSET;
diff --git a/src/http/modules/ngx_http_browser_module.c b/src/http/modules/ngx_http_browser_module.c
index e0710c1bf..d400fec7f 100644
--- a/src/http/modules/ngx_http_browser_module.c
+++ b/src/http/modules/ngx_http_browser_module.c
@@ -423,7 +423,7 @@ ngx_http_browser_create_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_browser_conf_t));
if (conf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
/*
diff --git a/src/http/modules/ngx_http_charset_filter_module.c b/src/http/modules/ngx_http_charset_filter_module.c
index 4efbce76d..a76499181 100644
--- a/src/http/modules/ngx_http_charset_filter_module.c
+++ b/src/http/modules/ngx_http_charset_filter_module.c
@@ -9,8 +9,9 @@
#include <ngx_http.h>
-#define NGX_HTTP_NO_CHARSET -2
-#define NGX_HTTP_CHARSET_VAR 0x10000
+#define NGX_HTTP_CHARSET_OFF -2
+#define NGX_HTTP_NO_CHARSET -3
+#define NGX_HTTP_CHARSET_VAR 0x10000
/* 1 byte length and up to 3 bytes for the UTF-8 encoding of the UCS-2 */
#define NGX_UTF_LEN 4
@@ -61,6 +62,7 @@ typedef struct {
typedef struct {
u_char *table;
ngx_int_t charset;
+ ngx_str_t charset_name;
ngx_chain_t *busy;
ngx_chain_t *free_bufs;
@@ -82,9 +84,16 @@ typedef struct {
} ngx_http_charset_conf_ctx_t;
-static ngx_int_t ngx_http_charset_get_charset(ngx_http_charset_t *charsets,
- ngx_uint_t n, ngx_str_t *charset);
-static ngx_int_t ngx_http_charset_set_charset(ngx_http_request_t *r,
+static ngx_int_t ngx_http_destination_charset(ngx_http_request_t *r,
+ ngx_str_t *name);
+static ngx_int_t ngx_http_main_request_charset(ngx_http_request_t *r,
+ ngx_str_t *name);
+static ngx_int_t ngx_http_source_charset(ngx_http_request_t *r,
+ ngx_str_t *name);
+static ngx_int_t ngx_http_get_charset(ngx_http_request_t *r, ngx_str_t *name);
+static ngx_inline void ngx_http_set_charset(ngx_http_request_t *r,
+ ngx_str_t *charset);
+static ngx_int_t ngx_http_charset_ctx(ngx_http_request_t *r,
ngx_http_charset_t *charsets, ngx_int_t charset, ngx_int_t source_charset);
static ngx_uint_t ngx_http_charset_recode(ngx_buf_t *b, u_char *table);
static ngx_chain_t *ngx_http_charset_recode_from_utf8(ngx_pool_t *pool,
@@ -207,207 +216,264 @@ static ngx_int_t
ngx_http_charset_header_filter(ngx_http_request_t *r)
{
ngx_int_t charset, source_charset;
- ngx_str_t *mc, *from, *to, s;
- ngx_uint_t n;
+ ngx_str_t dst, src;
ngx_http_charset_t *charsets;
- ngx_http_charset_ctx_t *ctx;
- ngx_http_variable_value_t *vv;
- ngx_http_charset_loc_conf_t *lcf, *mlcf;
ngx_http_charset_main_conf_t *mcf;
- mcf = ngx_http_get_module_main_conf(r, ngx_http_charset_filter_module);
+ if (r == r->main) {
+ charset = ngx_http_destination_charset(r, &dst);
- charsets = mcf->charsets.elts;
- n = mcf->charsets.nelts;
+ } else {
+ charset = ngx_http_main_request_charset(r, &dst);
+ }
- /* destination charset */
+ if (charset == NGX_ERROR) {
+ return NGX_ERROR;
+ }
- if (r == r->main) {
+ if (charset == NGX_DECLINED) {
+ return ngx_http_next_header_filter(r);
+ }
+
+ /* charset: charset index or NGX_HTTP_NO_CHARSET */
+
+ source_charset = ngx_http_source_charset(r, &src);
+
+ if (source_charset == NGX_ERROR) {
+ return NGX_ERROR;
+ }
+
+ /*
+ * source_charset: charset index, NGX_HTTP_NO_CHARSET,
+ * or NGX_HTTP_CHARSET_OFF
+ */
+
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "charset: \"%V\" > \"%V\"", &src, &dst);
- if (!r->ignore_content_encoding
- && r->headers_out.content_encoding
- && r->headers_out.content_encoding->value.len)
+ if (source_charset == NGX_HTTP_CHARSET_OFF) {
+ ngx_http_set_charset(r, &dst);
+
+ return ngx_http_next_header_filter(r);
+ }
+
+ if (charset == NGX_HTTP_NO_CHARSET
+ || source_charset == NGX_HTTP_NO_CHARSET)
+ {
+ if (source_charset != charset
+ || ngx_strncasecmp(dst.data, src.data, dst.len) != 0)
{
- return ngx_http_next_header_filter(r);
+ goto no_charset_map;
}
- if (r->headers_out.content_type.len == 0) {
- return ngx_http_next_header_filter(r);
- }
+ ngx_http_set_charset(r, &dst);
- if (r->headers_out.override_charset
- && r->headers_out.override_charset->len)
- {
- charset = ngx_http_charset_get_charset(charsets, n,
- r->headers_out.override_charset);
+ return ngx_http_next_header_filter(r);
+ }
- if (charset == NGX_HTTP_NO_CHARSET) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "unknown charset \"%V\" to override",
- r->headers_out.override_charset);
+ mcf = ngx_http_get_module_main_conf(r, ngx_http_charset_filter_module);
+ charsets = mcf->charsets.elts;
- return ngx_http_next_header_filter(r);
- }
+ if (source_charset != charset
+ && (charsets[source_charset].tables == NULL
+ || charsets[source_charset].tables[charset] == NULL))
+ {
+ goto no_charset_map;
+ }
- } else {
- mlcf = ngx_http_get_module_loc_conf(r,
- ngx_http_charset_filter_module);
- charset = mlcf->charset;
+ r->headers_out.content_type.len = r->headers_out.content_type_len;
- if (charset == NGX_HTTP_NO_CHARSET) {
- return ngx_http_next_header_filter(r);
- }
+ ngx_http_set_charset(r, &dst);
- if (r->headers_out.charset.len) {
- if (mlcf->override_charset == 0) {
- return ngx_http_next_header_filter(r);
- }
+ if (source_charset != charset) {
+ return ngx_http_charset_ctx(r, charsets, charset, source_charset);
+ }
- } else {
- if (ngx_http_test_content_type(r, &mlcf->types) == NULL) {
- return ngx_http_next_header_filter(r);
- }
- }
+ return ngx_http_next_header_filter(r);
- if (charset >= NGX_HTTP_CHARSET_VAR) {
- vv = ngx_http_get_indexed_variable(r,
- charset - NGX_HTTP_CHARSET_VAR);
+no_charset_map:
- if (vv == NULL || vv->not_found) {
- return NGX_ERROR;
- }
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "no \"charset_map\" between the charsets \"%V\" and \"%V\"",
+ &src, &dst);
- s.len = vv->len;
- s.data = vv->data;
+ return ngx_http_next_header_filter(r);
+}
- charset = ngx_http_charset_get_charset(charsets, n, &s);
- }
- }
- } else {
- ctx = ngx_http_get_module_ctx(r->main, ngx_http_charset_filter_module);
+static ngx_int_t
+ngx_http_destination_charset(ngx_http_request_t *r, ngx_str_t *name)
+{
+ ngx_int_t charset;
+ ngx_http_charset_t *charsets;
+ ngx_http_variable_value_t *vv;
+ ngx_http_charset_loc_conf_t *mlcf;
+ ngx_http_charset_main_conf_t *mcf;
- if (ctx == NULL) {
+ if (!r->ignore_content_encoding
+ && r->headers_out.content_encoding
+ && r->headers_out.content_encoding->value.len)
+ {
+ return NGX_DECLINED;
+ }
- mc = &r->main->headers_out.charset;
+ if (r->headers_out.content_type.len == 0) {
+ return NGX_DECLINED;
+ }
- if (mc->len == 0) {
- return ngx_http_next_header_filter(r);
- }
+ if (r->headers_out.override_charset
+ && r->headers_out.override_charset->len)
+ {
+ *name = *r->headers_out.override_charset;
- ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_charset_ctx_t));
- if (ctx == NULL) {
- return NGX_ERROR;
- }
+ charset = ngx_http_get_charset(r, name);
- ngx_http_set_ctx(r->main, ctx, ngx_http_charset_filter_module);
+ if (charset != NGX_HTTP_NO_CHARSET) {
+ return charset;
+ }
+
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "unknown charset \"%V\" to override", name);
+
+ return NGX_DECLINED;
+ }
- charset = ngx_http_charset_get_charset(charsets, n, mc);
+ mlcf = ngx_http_get_module_loc_conf(r, ngx_http_charset_filter_module);
+ charset = mlcf->charset;
- ctx->charset = charset;
+ if (charset == NGX_HTTP_CHARSET_OFF) {
+ return NGX_DECLINED;
+ }
- } else {
- charset = ctx->charset;
+ if (r->headers_out.charset.len) {
+ if (mlcf->override_charset == 0) {
+ return NGX_DECLINED;
}
+
+ } else {
+ if (ngx_http_test_content_type(r, &mlcf->types) == NULL) {
+ return NGX_DECLINED;
+ }
+ }
+
+ if (charset < NGX_HTTP_CHARSET_VAR) {
+ mcf = ngx_http_get_module_main_conf(r, ngx_http_charset_filter_module);
+ charsets = mcf->charsets.elts;
+ *name = charsets[charset].name;
+ return charset;
}
- /* source charset */
+ vv = ngx_http_get_indexed_variable(r, charset - NGX_HTTP_CHARSET_VAR);
- if (r->headers_out.charset.len == 0) {
- lcf = ngx_http_get_module_loc_conf(r, ngx_http_charset_filter_module);
+ if (vv == NULL || vv->not_found) {
+ return NGX_ERROR;
+ }
- source_charset = lcf->source_charset;
+ name->len = vv->len;
+ name->data = vv->data;
- if (source_charset >= NGX_HTTP_CHARSET_VAR) {
- vv = ngx_http_get_indexed_variable(r,
- source_charset - NGX_HTTP_CHARSET_VAR);
+ return ngx_http_get_charset(r, name);
+}
- if (vv == NULL || vv->not_found) {
- return NGX_ERROR;
- }
- s.len = vv->len;
- s.data = vv->data;
+static ngx_int_t
+ngx_http_main_request_charset(ngx_http_request_t *r, ngx_str_t *src)
+{
+ ngx_int_t charset;
+ ngx_str_t *main_charset;
+ ngx_http_charset_ctx_t *ctx;
- source_charset = ngx_http_charset_get_charset(charsets, n, &s);
- }
+ ctx = ngx_http_get_module_ctx(r->main, ngx_http_charset_filter_module);
- if (charset != NGX_HTTP_NO_CHARSET) {
- return ngx_http_charset_set_charset(r, mcf->charsets.elts, charset,
- source_charset);
- }
+ if (ctx) {
+ *src = ctx->charset_name;
+ return ctx->charset;
+ }
- if (source_charset == NGX_CONF_UNSET) {
- return ngx_http_next_header_filter(r);
- }
+ main_charset = &r->main->headers_out.charset;
- from = &charsets[source_charset].name;
- to = &r->main->headers_out.charset;
+ if (main_charset->len == 0) {
+ return NGX_DECLINED;
+ }
- goto no_charset_map;
+ ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_charset_ctx_t));
+ if (ctx == NULL) {
+ return NGX_ERROR;
}
- source_charset = ngx_http_charset_get_charset(charsets, n,
- &r->headers_out.charset);
+ ngx_http_set_ctx(r->main, ctx, ngx_http_charset_filter_module);
- if (charset == NGX_HTTP_NO_CHARSET
- || source_charset == NGX_HTTP_NO_CHARSET)
- {
- if (charset != source_charset
- || ngx_strcasecmp(r->main->headers_out.charset.data,
- r->headers_out.charset.data)
- != 0)
- {
- from = &r->headers_out.charset;
- to = (charset == NGX_HTTP_NO_CHARSET) ?
- &r->main->headers_out.charset:
- &charsets[charset].name;
+ charset = ngx_http_get_charset(r, main_charset);
- goto no_charset_map;
- }
+ ctx->charset = charset;
+ ctx->charset_name = *main_charset;
+ *src = *main_charset;
- return ngx_http_next_header_filter(r);
+ return charset;
+}
+
+
+static ngx_int_t
+ngx_http_source_charset(ngx_http_request_t *r, ngx_str_t *name)
+{
+ ngx_int_t charset;
+ ngx_http_charset_t *charsets;
+ ngx_http_variable_value_t *vv;
+ ngx_http_charset_loc_conf_t *lcf;
+ ngx_http_charset_main_conf_t *mcf;
+
+ if (r->headers_out.charset.len) {
+ *name = r->headers_out.charset;
+ return ngx_http_get_charset(r, name);
}
- if (source_charset != charset
- && (charsets[source_charset].tables == NULL
- || charsets[source_charset].tables[charset] == NULL))
- {
- from = &charsets[source_charset].name;
- to = &charsets[charset].name;
+ lcf = ngx_http_get_module_loc_conf(r, ngx_http_charset_filter_module);
- goto no_charset_map;
+ charset = lcf->source_charset;
+
+ if (charset == NGX_HTTP_CHARSET_OFF) {
+ name->len = 0;
+ return charset;
}
- r->headers_out.content_type.len = r->headers_out.content_type_len;
+ if (charset < NGX_HTTP_CHARSET_VAR) {
+ mcf = ngx_http_get_module_main_conf(r, ngx_http_charset_filter_module);
+ charsets = mcf->charsets.elts;
+ *name = charsets[charset].name;
+ return charset;
+ }
- return ngx_http_charset_set_charset(r, mcf->charsets.elts, charset,
- source_charset);
+ vv = ngx_http_get_indexed_variable(r, charset - NGX_HTTP_CHARSET_VAR);
-no_charset_map:
+ if (vv == NULL || vv->not_found) {
+ return NGX_ERROR;
+ }
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "no \"charset_map\" between the charsets \"%V\" and \"%V\"",
- from, to);
+ name->len = vv->len;
+ name->data = vv->data;
- return ngx_http_next_header_filter(r);
+ return ngx_http_get_charset(r, name);
}
static ngx_int_t
-ngx_http_charset_get_charset(ngx_http_charset_t *charsets, ngx_uint_t n,
- ngx_str_t *charset)
+ngx_http_get_charset(ngx_http_request_t *r, ngx_str_t *name)
{
- ngx_uint_t i;
+ ngx_uint_t i, n;
+ ngx_http_charset_t *charset;
+ ngx_http_charset_main_conf_t *mcf;
+
+ mcf = ngx_http_get_module_main_conf(r, ngx_http_charset_filter_module);
+
+ charset = mcf->charsets.elts;
+ n = mcf->charsets.nelts;
for (i = 0; i < n; i++) {
- if (charsets[i].name.len != charset->len) {
+ if (charset[i].name.len != name->len) {
continue;
}
- if (ngx_strncasecmp(charsets[i].name.data, charset->data, charset->len)
- == 0)
- {
+ if (ngx_strncasecmp(charset[i].name.data, name->data, name->len) == 0) {
return i;
}
}
@@ -416,11 +482,12 @@ ngx_http_charset_get_charset(ngx_http_charset_t *charsets, ngx_uint_t n,
}
-static ngx_int_t
-ngx_http_charset_set_charset(ngx_http_request_t *r,
- ngx_http_charset_t *charsets, ngx_int_t charset, ngx_int_t source_charset)
+static ngx_inline void
+ngx_http_set_charset(ngx_http_request_t *r, ngx_str_t *charset)
{
- ngx_http_charset_ctx_t *ctx;
+ if (r != r->main) {
+ return;
+ }
if (r->headers_out.status == NGX_HTTP_MOVED_PERMANENTLY
|| r->headers_out.status == NGX_HTTP_MOVED_TEMPORARILY)
@@ -431,16 +498,18 @@ ngx_http_charset_set_charset(ngx_http_request_t *r,
*/
r->headers_out.charset.len = 0;
-
- return ngx_http_next_header_filter(r);
+ return;
}
- r->headers_out.charset = charsets[charset].name;
- r->utf8 = charsets[charset].utf8;
+ r->headers_out.charset = *charset;
+}
- if (source_charset == NGX_CONF_UNSET || source_charset == charset) {
- return ngx_http_next_header_filter(r);
- }
+
+static ngx_int_t
+ngx_http_charset_ctx(ngx_http_request_t *r, ngx_http_charset_t *charsets,
+ ngx_int_t charset, ngx_int_t source_charset)
+{
+ ngx_http_charset_ctx_t *ctx;
ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_charset_ctx_t));
if (ctx == NULL) {
@@ -451,6 +520,7 @@ ngx_http_charset_set_charset(ngx_http_request_t *r,
ctx->table = charsets[source_charset].tables[charset];
ctx->charset = charset;
+ ctx->charset_name = charsets[charset].name;
ctx->length = charsets[charset].length;
ctx->from_utf8 = charsets[source_charset].utf8;
ctx->to_utf8 = charsets[charset].utf8;
@@ -1338,7 +1408,7 @@ ngx_http_set_charset_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
if (cmd->offset == offsetof(ngx_http_charset_loc_conf_t, charset)
&& ngx_strcmp(value[1].data, "off") == 0)
{
- *cp = NGX_HTTP_NO_CHARSET;
+ *cp = NGX_HTTP_CHARSET_OFF;
return NGX_CONF_OK;
}
@@ -1418,27 +1488,27 @@ ngx_http_charset_create_main_conf(ngx_conf_t *cf)
mcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_charset_main_conf_t));
if (mcf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
if (ngx_array_init(&mcf->charsets, cf->pool, 2, sizeof(ngx_http_charset_t))
!= NGX_OK)
{
- return NGX_CONF_ERROR;
+ return NULL;
}
if (ngx_array_init(&mcf->tables, cf->pool, 1,
sizeof(ngx_http_charset_tables_t))
!= NGX_OK)
{
- return NGX_CONF_ERROR;
+ return NULL;
}
if (ngx_array_init(&mcf->recodes, cf->pool, 2,
sizeof(ngx_http_charset_recode_t))
!= NGX_OK)
{
- return NGX_CONF_ERROR;
+ return NULL;
}
return mcf;
@@ -1452,7 +1522,7 @@ ngx_http_charset_create_loc_conf(ngx_conf_t *cf)
lcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_charset_loc_conf_t));
if (lcf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
/*
@@ -1489,14 +1559,12 @@ ngx_http_charset_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
}
ngx_conf_merge_value(conf->override_charset, prev->override_charset, 0);
- ngx_conf_merge_value(conf->charset, prev->charset, NGX_HTTP_NO_CHARSET);
-
- if (conf->source_charset == NGX_CONF_UNSET) {
- conf->source_charset = prev->source_charset;
- }
+ ngx_conf_merge_value(conf->charset, prev->charset, NGX_HTTP_CHARSET_OFF);
+ ngx_conf_merge_value(conf->source_charset, prev->source_charset,
+ NGX_HTTP_CHARSET_OFF);
- if (conf->charset == NGX_HTTP_NO_CHARSET
- || conf->source_charset == NGX_CONF_UNSET
+ if (conf->charset == NGX_HTTP_CHARSET_OFF
+ || conf->source_charset == NGX_HTTP_CHARSET_OFF
|| conf->charset == conf->source_charset)
{
return NGX_CONF_OK;
diff --git a/src/http/modules/ngx_http_dav_module.c b/src/http/modules/ngx_http_dav_module.c
index 84a7672a4..2948eec06 100644
--- a/src/http/modules/ngx_http_dav_module.c
+++ b/src/http/modules/ngx_http_dav_module.c
@@ -53,8 +53,6 @@ static ngx_int_t ngx_http_dav_copy_dir_time(ngx_tree_ctx_t *ctx,
ngx_str_t *path);
static ngx_int_t ngx_http_dav_copy_tree_file(ngx_tree_ctx_t *ctx,
ngx_str_t *path);
-static ngx_int_t ngx_http_dav_copy_file(ngx_tree_ctx_t *ctx, u_char *from,
- u_char *to);
static ngx_int_t ngx_http_dav_depth(ngx_http_request_t *r, ngx_int_t dflt);
static ngx_int_t ngx_http_dav_error(ngx_log_t *log, ngx_err_t err,
@@ -216,6 +214,8 @@ ngx_http_dav_put_handler(ngx_http_request_t *r)
ngx_http_map_uri_to_path(r, &path, &root, 0);
+ path.len--;
+
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http put filename: \"%s\"", path.data);
@@ -249,7 +249,6 @@ ngx_http_dav_put_handler(ngx_http_request_t *r)
ext.time = -1;
ext.create_path = dlcf->create_full_put_path;
ext.delete_file = 1;
- ext.log_rename_error = 1;
ext.log = r->connection->log;
if (r->headers_in.date) {
@@ -491,6 +490,7 @@ ngx_http_dav_mkcol_handler(ngx_http_request_t *r, ngx_http_dav_loc_conf_t *dlcf)
p = ngx_http_map_uri_to_path(r, &path, &root, 0);
*(p - 1) = '\0';
+ r->uri.len--;
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http mkcol path: \"%s\"", path.data);
@@ -517,9 +517,10 @@ ngx_http_dav_copy_move_handler(ngx_http_request_t *r)
size_t len, root;
ngx_err_t err;
ngx_int_t rc, depth;
- ngx_uint_t overwrite, slash, dir;
- ngx_str_t path, uri;
+ ngx_uint_t overwrite, slash, dir, flags;
+ ngx_str_t path, uri, duri, args;
ngx_tree_ctx_t tree;
+ ngx_copy_file_t cf;
ngx_file_info_t fi;
ngx_table_elt_t *dest, *over;
ngx_ext_rename_file_t ext;
@@ -594,6 +595,14 @@ invalid_destination:
destination_done:
+ duri.len = last - p;
+ duri.data = p;
+ flags = 0;
+
+ if (ngx_http_parse_unsafe_uri(r, &duri, &args, &flags) != NGX_OK) {
+ goto invalid_destination;
+ }
+
if ((r->uri.data[r->uri.len - 1] == '/' && *(last - 1) != '/')
|| (r->uri.data[r->uri.len - 1] != '/' && *(last - 1) == '/'))
{
@@ -656,9 +665,7 @@ overwrite_done:
"http copy from: \"%s\"", path.data);
uri = r->uri;
-
- r->uri.len = last - p;
- r->uri.data = p;
+ r->uri = duri;
ngx_http_map_uri_to_path(r, &copy.path, &root, 0);
@@ -791,43 +798,24 @@ overwrite_done:
ext.time = -1;
ext.create_path = 1;
ext.delete_file = 0;
- ext.log_rename_error = 0;
ext.log = r->connection->log;
if (ngx_ext_rename_file(&path, &copy.path, &ext) == NGX_OK) {
return NGX_HTTP_NO_CONTENT;
}
- if (ext.rename_error != NGX_EXDEV) {
-
- if (ext.rename_error) {
- ngx_log_error(NGX_LOG_CRIT, r->connection->log,
- ext.rename_error,
- ngx_rename_file_n " \"%s\" to \"%s\" failed",
- path.data, copy.path.data);
- }
-
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
dlcf = ngx_http_get_module_loc_conf(r, ngx_http_dav_module);
- tree.size = ngx_file_size(&fi);
- tree.mtime = ngx_file_mtime(&fi);
- tree.access = dlcf->access;
- tree.log = r->connection->log;
-
- if (ngx_http_dav_copy_file(&tree, path.data, copy.path.data) == NGX_OK)
- {
- if (r->method == NGX_HTTP_MOVE) {
- rc = ngx_http_dav_delete_path(r, &path, 0);
-
- if (rc != NGX_OK) {
- return rc;
- }
- }
+ cf.size = ngx_file_size(&fi);
+ cf.buf_size = 0;
+ cf.access = dlcf->access;
+ cf.time = ngx_file_mtime(&fi);
+ cf.log = r->connection->log;
+ if (ngx_copy_file(path.data, copy.path.data, &cf) == NGX_OK) {
return NGX_HTTP_NO_CONTENT;
}
}
@@ -941,6 +929,7 @@ ngx_http_dav_copy_tree_file(ngx_tree_ctx_t *ctx, ngx_str_t *path)
{
u_char *p, *file;
size_t len;
+ ngx_copy_file_t cf;
ngx_http_dav_copy_ctx_t *copy;
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
@@ -961,7 +950,13 @@ ngx_http_dav_copy_tree_file(ngx_tree_ctx_t *ctx, ngx_str_t *path)
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->log, 0,
"http copy file to: \"%s\"", file);
- (void) ngx_http_dav_copy_file(ctx, path->data, file);
+ cf.size = ctx->size;
+ cf.buf_size = 0;
+ cf.access = ctx->access;
+ cf.time = ctx->mtime;
+ cf.log = ctx->log;
+
+ (void) ngx_copy_file(path->data, file, &cf);
ngx_free(file);
@@ -970,75 +965,6 @@ ngx_http_dav_copy_tree_file(ngx_tree_ctx_t *ctx, ngx_str_t *path)
static ngx_int_t
-ngx_http_dav_copy_file(ngx_tree_ctx_t *ctx, u_char *from, u_char *to)
-{
- off_t size;
- ssize_t n;
- ngx_fd_t fd, cfd;
- ngx_int_t rc;
- u_char buf[NGX_HTTP_DAV_COPY_BLOCK];
-
- fd = ngx_open_file(from, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0);
-
- if (fd == NGX_INVALID_FILE) {
- (void) ngx_http_dav_error(ctx->log, ngx_errno, 0, ngx_open_file_n,
- from);
- return NGX_ERROR;
- }
-
- cfd = ngx_open_file(to, NGX_FILE_WRONLY, NGX_FILE_CREATE_OR_OPEN,
- ctx->access);
-
- rc = NGX_ERROR;
-
- if (cfd == NGX_INVALID_FILE) {
- (void) ngx_http_dav_error(ctx->log, ngx_errno, 0, ngx_open_file_n, to);
- goto failed;
- }
-
- for (size = ctx->size; size > 0; size -= n) {
-
- n = ngx_read_fd(fd, buf, NGX_HTTP_DAV_COPY_BLOCK);
-
- if (n == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, ctx->log, ngx_errno,
- ngx_read_fd_n " \"%s\" failed", from);
- goto failed;
- }
-
- if (ngx_write_fd(cfd, buf, n) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, ctx->log, ngx_errno,
- ngx_write_fd_n " \"%s\" failed", to);
- goto failed;
- }
- }
-
- if (ngx_set_file_time(to, cfd, ctx->mtime) != NGX_OK) {
- ngx_log_error(NGX_LOG_ALERT, ctx->log, ngx_errno,
- ngx_set_file_time_n " \"%s\" failed", to);
- goto failed;
- }
-
- if (ngx_close_file(cfd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, ctx->log, ngx_errno,
- ngx_close_file_n " \"%s\" failed", to);
- goto failed;
- }
-
- rc = NGX_OK;
-
-failed:
-
- if (ngx_close_file(fd) == NGX_FILE_ERROR) {
- ngx_log_error(NGX_LOG_ALERT, ctx->log, ngx_errno,
- ngx_close_file_n " \"%s\" failed", from);
- }
-
- return rc;
-}
-
-
-static ngx_int_t
ngx_http_dav_depth(ngx_http_request_t *r, ngx_int_t dflt)
{
ngx_table_elt_t *depth;
@@ -1154,7 +1080,7 @@ ngx_http_dav_create_loc_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_dav_loc_conf_t));
if (conf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
/*
diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c
index 736a68600..3ce608db1 100644
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -543,19 +543,16 @@ ngx_http_fastcgi_handler(ngx_http_request_t *r)
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- f = ngx_pcalloc(r->pool, sizeof(ngx_http_fastcgi_ctx_t));
- if (f == NULL) {
- return NGX_ERROR;
+ if (ngx_http_upstream_create(r) != NGX_OK) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- ngx_http_set_ctx(r, f, ngx_http_fastcgi_module);
-
- u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t));
- if (u == NULL) {
+ f = ngx_pcalloc(r->pool, sizeof(ngx_http_fastcgi_ctx_t));
+ if (f == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- r->upstream = u;
+ ngx_http_set_ctx(r, f, ngx_http_fastcgi_module);
flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
@@ -565,15 +562,11 @@ ngx_http_fastcgi_handler(ngx_http_request_t *r)
}
}
+ u = r->upstream;
+
u->schema.len = sizeof("fastcgi://") - 1;
u->schema.data = (u_char *) "fastcgi://";
- u->peer.log = r->connection->log;
- u->peer.log_error = NGX_ERROR_ERR;
-#if (NGX_THREADS)
- u->peer.lock = &r->connection->lock;
-#endif
-
u->output.tag = (ngx_buf_tag_t) &ngx_http_fastcgi_module;
u->conf = &flcf->upstream;
@@ -1836,7 +1829,7 @@ ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_fastcgi_loc_conf_t));
if (conf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
/*
diff --git a/src/http/modules/ngx_http_geo_module.c b/src/http/modules/ngx_http_geo_module.c
index a38985632..0ec8d093b 100644
--- a/src/http/modules/ngx_http_geo_module.c
+++ b/src/http/modules/ngx_http_geo_module.c
@@ -35,6 +35,7 @@ typedef struct {
ngx_radix_tree_t *tree;
ngx_rbtree_t rbtree;
ngx_rbtree_node_t sentinel;
+ ngx_array_t *proxies;
ngx_pool_t *pool;
ngx_pool_t *temp_pool;
} ngx_http_geo_conf_ctx_t;
@@ -46,12 +47,16 @@ typedef struct {
ngx_http_geo_high_ranges_t *high;
} u;
+ ngx_array_t *proxies;
+
ngx_int_t index;
} ngx_http_geo_ctx_t;
static in_addr_t ngx_http_geo_addr(ngx_http_request_t *r,
ngx_http_geo_ctx_t *ctx);
+static in_addr_t ngx_http_geo_real_addr(ngx_http_request_t *r,
+ ngx_http_geo_ctx_t *ctx);
static char *ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static char *ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf);
static char *ngx_http_geo_range(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
@@ -64,6 +69,10 @@ static char *ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
ngx_str_t *value);
static ngx_http_variable_value_t *ngx_http_geo_value(ngx_conf_t *cf,
ngx_http_geo_conf_ctx_t *ctx, ngx_str_t *value);
+static char *ngx_http_geo_add_proxy(ngx_conf_t *cf,
+ ngx_http_geo_conf_ctx_t *ctx, ngx_cidr_t *cidr);
+static ngx_int_t ngx_http_geo_cidr_value(ngx_conf_t *cf, ngx_str_t *net,
+ ngx_cidr_t *cidr);
static ngx_command_t ngx_http_geo_commands[] = {
@@ -168,6 +177,50 @@ ngx_http_geo_range_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
static in_addr_t
ngx_http_geo_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx)
{
+ u_char *p, *ip;
+ size_t len;
+ in_addr_t addr;
+ ngx_uint_t i, n;
+ ngx_in_cidr_t *proxies;
+ ngx_table_elt_t *xfwd;
+
+ addr = ngx_http_geo_real_addr(r, ctx);
+
+ xfwd = r->headers_in.x_forwarded_for;
+
+ if (xfwd == NULL || ctx->proxies == NULL) {
+ return addr;
+ }
+
+ proxies = ctx->proxies->elts;
+ n = ctx->proxies->nelts;
+
+ for (i = 0; i < n; i++) {
+ if ((addr & proxies[i].mask) == proxies[i].addr) {
+
+ len = xfwd->value.len;
+ ip = xfwd->value.data;
+
+ for (p = ip + len - 1; p > ip; p--) {
+ if (*p == ' ' || *p == ',') {
+ p++;
+ len -= p - ip;
+ ip = p;
+ break;
+ }
+ }
+
+ return ntohl(ngx_inet_addr(ip, len));
+ }
+ }
+
+ return addr;
+}
+
+
+static in_addr_t
+ngx_http_geo_real_addr(ngx_http_request_t *r, ngx_http_geo_ctx_t *ctx)
+{
struct sockaddr_in *sin;
ngx_http_variable_value_t *v;
@@ -259,6 +312,7 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ctx.high = NULL;
ctx.tree = NULL;
+ ctx.proxies = NULL;
ctx.pool = cf->pool;
save = *cf;
@@ -271,6 +325,8 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
*cf = save;
+ geo->proxies = ctx.proxies;
+
if (ctx.high) {
for (i = 0; i < 0x10000; i++) {
@@ -341,6 +397,7 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
{
char *rv;
ngx_str_t *value, file;
+ ngx_cidr_t cidr;
ngx_http_geo_conf_ctx_t *ctx;
ctx = cf->ctx;
@@ -394,6 +451,16 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
rv = ngx_conf_parse(cf, &file);
goto done;
+
+ } else if (ngx_strcmp(value[0].data, "proxy") == 0) {
+
+ if (ngx_http_geo_cidr_value(cf, &value[1], &cidr) != NGX_OK) {
+ goto failed;
+ }
+
+ rv = ngx_http_geo_add_proxy(cf, ctx, &cidr);
+
+ goto done;
}
if (ctx->high) {
@@ -803,33 +870,8 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
del = 0;
}
- if (ngx_strcmp(net->data, "255.255.255.255") == 0) {
- cidr.u.in.addr = 0xffffffff;
- cidr.u.in.mask = 0xffffffff;
-
- } else {
- rc = ngx_ptocidr(net, &cidr);
-
- if (rc == NGX_ERROR) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid network \"%V\"", net);
- return NGX_CONF_ERROR;
- }
-
- if (cidr.family != AF_INET) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"geo\" supports IPv4 only");
- return NGX_CONF_ERROR;
- }
-
- if (rc == NGX_DONE) {
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "low address bits of %V are meaningless",
- net);
- }
-
- cidr.u.in.addr = ntohl(cidr.u.in.addr);
- cidr.u.in.mask = ntohl(cidr.u.in.mask);
+ if (ngx_http_geo_cidr_value(cf, net, &cidr) != NGX_OK) {
+ return NGX_CONF_ERROR;
}
if (del) {
@@ -864,7 +906,7 @@ ngx_http_geo_cidr(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
/* rc == NGX_BUSY */
- old = (ngx_http_variable_value_t *)
+ old = (ngx_http_variable_value_t *)
ngx_radix32tree_find(ctx->tree, cidr.u.in.addr & cidr.u.in.mask);
ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
@@ -927,3 +969,64 @@ ngx_http_geo_value(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
return val;
}
+
+
+static char *
+ngx_http_geo_add_proxy(ngx_conf_t *cf, ngx_http_geo_conf_ctx_t *ctx,
+ ngx_cidr_t *cidr)
+{
+ ngx_in_cidr_t *c;
+
+ if (ctx->proxies == NULL) {
+ ctx->proxies = ngx_array_create(ctx->pool, 4, sizeof(ngx_in_cidr_t));
+ if (ctx->proxies == NULL) {
+ return NGX_CONF_ERROR;
+ }
+ }
+
+ c = ngx_array_push(ctx->proxies);
+ if (c == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ c->addr = cidr->u.in.addr;
+ c->mask = cidr->u.in.mask;
+
+ return NGX_CONF_OK;
+}
+
+
+static ngx_int_t
+ngx_http_geo_cidr_value(ngx_conf_t *cf, ngx_str_t *net, ngx_cidr_t *cidr)
+{
+ ngx_int_t rc;
+
+ if (ngx_strcmp(net->data, "255.255.255.255") == 0) {
+ cidr->u.in.addr = 0xffffffff;
+ cidr->u.in.mask = 0xffffffff;
+
+ return NGX_OK;
+ }
+
+ rc = ngx_ptocidr(net, cidr);
+
+ if (rc == NGX_ERROR) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid network \"%V\"", net);
+ return NGX_ERROR;
+ }
+
+ if (cidr->family != AF_INET) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"geo\" supports IPv4 only");
+ return NGX_ERROR;
+ }
+
+ if (rc == NGX_DONE) {
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
+ "low address bits of %V are meaningless", net);
+ }
+
+ cidr->u.in.addr = ntohl(cidr->u.in.addr);
+ cidr->u.in.mask = ntohl(cidr->u.in.mask);
+
+ return NGX_OK;
+}
diff --git a/src/http/modules/ngx_http_geoip_module.c b/src/http/modules/ngx_http_geoip_module.c
new file mode 100644
index 000000000..81b872efb
--- /dev/null
+++ b/src/http/modules/ngx_http_geoip_module.c
@@ -0,0 +1,376 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_http.h>
+
+#include <GeoIP.h>
+#include <GeoIPCity.h>
+
+
+typedef struct {
+ GeoIP *country;
+ GeoIP *city;
+} ngx_http_geoip_conf_t;
+
+
+typedef struct {
+ ngx_str_t *name;
+ uintptr_t data;
+} ngx_http_geoip_var_t;
+
+
+typedef const char *(*ngx_http_geoip_variable_handler_pt)(GeoIP *, u_long addr);
+
+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_add_variables(ngx_conf_t *cf);
+static void *ngx_http_geoip_create_conf(ngx_conf_t *cf);
+static char *ngx_http_geoip_country(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
+static char *ngx_http_geoip_city(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
+static void ngx_http_geoip_cleanup(void *data);
+
+
+static ngx_command_t ngx_http_geoip_commands[] = {
+
+ { ngx_string("geoip_country"),
+ NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
+ ngx_http_geoip_country,
+ NGX_HTTP_MAIN_CONF_OFFSET,
+ 0,
+ NULL },
+
+ { ngx_string("geoip_city"),
+ NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
+ ngx_http_geoip_city,
+ NGX_HTTP_MAIN_CONF_OFFSET,
+ 0,
+ NULL },
+
+ ngx_null_command
+};
+
+
+static ngx_http_module_t ngx_http_geoip_module_ctx = {
+ ngx_http_geoip_add_variables, /* preconfiguration */
+ NULL, /* postconfiguration */
+
+ ngx_http_geoip_create_conf, /* create main configuration */
+ NULL, /* init main configuration */
+
+ NULL, /* create server configuration */
+ NULL, /* merge server configuration */
+
+ NULL, /* create location configuration */
+ NULL /* merge location configuration */
+};
+
+
+ngx_module_t ngx_http_geoip_module = {
+ NGX_MODULE_V1,
+ &ngx_http_geoip_module_ctx, /* module context */
+ ngx_http_geoip_commands, /* module directives */
+ NGX_HTTP_MODULE, /* module type */
+ NULL, /* init master */
+ NULL, /* init module */
+ NULL, /* init process */
+ NULL, /* init thread */
+ NULL, /* exit thread */
+ NULL, /* exit process */
+ NULL, /* exit master */
+ NGX_MODULE_V1_PADDING
+};
+
+
+static ngx_http_variable_t ngx_http_geoip_vars[] = {
+
+ { 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,
+ (uintptr_t) GeoIP_country_code3_by_ipnum, 0, 0 },
+
+ { 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,
+ 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,
+ offsetof(GeoIPRecord, country_name), 0, 0 },
+
+ { ngx_string("geoip_region"), NULL,
+ ngx_http_geoip_city_variable,
+ offsetof(GeoIPRecord, region), 0, 0 },
+
+ { ngx_string("geoip_city"), NULL,
+ ngx_http_geoip_city_variable,
+ offsetof(GeoIPRecord, city), 0, 0 },
+
+ { ngx_string("geoip_postal_code"), NULL,
+ ngx_http_geoip_city_variable,
+ offsetof(GeoIPRecord, postal_code), 0, 0 },
+
+ { ngx_null_string, NULL, NULL, 0, 0, 0 }
+};
+
+
+static ngx_int_t
+ngx_http_geoip_country_variable(ngx_http_request_t *r,
+ ngx_http_variable_value_t *v, uintptr_t data)
+{
+ ngx_http_geoip_variable_handler_pt handler =
+ (ngx_http_geoip_variable_handler_pt) data;
+
+ u_long addr;
+ const char *val;
+ struct sockaddr_in *sin;
+ ngx_http_geoip_conf_t *gcf;
+
+ gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module);
+
+ if (gcf->country == 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);
+
+ val = handler(gcf->country, addr);
+
+ if (val == NULL) {
+ goto not_found;
+ }
+
+ v->len = ngx_strlen(val);
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+ v->data = (u_char *) val;
+
+ return NGX_OK;
+
+not_found:
+
+ v->not_found = 1;
+
+ return NGX_OK;
+}
+
+
+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);
+
+ if (gr == NULL) {
+ goto not_found;
+ }
+
+ val = *(char **) ((char *) gr + data);
+
+ if (val == NULL) {
+ goto no_value;
+ }
+
+ len = ngx_strlen(val);
+ v->data = ngx_pnalloc(r->pool, len);
+
+ if (v->data == NULL) {
+ GeoIPRecord_delete(gr);
+ return NGX_ERROR;
+ }
+
+ ngx_memcpy(v->data, val, len);
+
+ v->len = len;
+ v->valid = 1;
+ v->no_cacheable = 0;
+ v->not_found = 0;
+
+ GeoIPRecord_delete(gr);
+
+ return NGX_OK;
+
+no_value:
+
+ GeoIPRecord_delete(gr);
+
+not_found:
+
+ v->not_found = 1;
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_geoip_add_variables(ngx_conf_t *cf)
+{
+ ngx_http_variable_t *var, *v;
+
+ for (v = ngx_http_geoip_vars; v->name.len; v++) {
+ var = ngx_http_add_variable(cf, &v->name, v->flags);
+ if (var == NULL) {
+ return NGX_ERROR;
+ }
+
+ var->get_handler = v->get_handler;
+ var->data = v->data;
+ }
+
+ return NGX_OK;
+}
+
+
+static void *
+ngx_http_geoip_create_conf(ngx_conf_t *cf)
+{
+ ngx_pool_cleanup_t *cln;
+ ngx_http_geoip_conf_t *conf;
+
+ conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_geoip_conf_t));
+ if (conf == NULL) {
+ return NULL;
+ }
+
+ cln = ngx_pool_cleanup_add(cf->pool, 0);
+ if (cln == NULL) {
+ return NULL;
+ }
+
+ cln->handler = ngx_http_geoip_cleanup;
+ cln->data = conf;
+
+ return conf;
+}
+
+
+static char *
+ngx_http_geoip_country(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_http_geoip_conf_t *gcf = conf;
+
+ ngx_str_t *value;
+
+ if (gcf->country) {
+ return "is duplicate";
+ }
+
+ value = cf->args->elts;
+
+ gcf->country = GeoIP_open((char *) value[1].data, GEOIP_MEMORY_CACHE);
+
+ if (gcf->country == NULL) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "GeoIO_open(\"%V\") failed", &value[1]);
+
+ return NGX_CONF_ERROR;
+ }
+
+ switch (gcf->country->databaseType) {
+
+ case GEOIP_COUNTRY_EDITION:
+ case GEOIP_PROXY_EDITION:
+ case GEOIP_NETSPEED_EDITION:
+
+ return NGX_CONF_OK;
+
+ default:
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid GeoIP database \"%V\" type:%d",
+ &value[1], gcf->country->databaseType);
+ return NGX_CONF_ERROR;
+ }
+}
+
+
+static char *
+ngx_http_geoip_city(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_http_geoip_conf_t *gcf = conf;
+
+ ngx_str_t *value;
+
+ if (gcf->city) {
+ return "is duplicate";
+ }
+
+ value = cf->args->elts;
+
+ gcf->city = GeoIP_open((char *) value[1].data, GEOIP_MEMORY_CACHE);
+
+ if (gcf->city == NULL) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "GeoIO_open(\"%V\") failed", &value[1]);
+
+ return NGX_CONF_ERROR;
+ }
+
+ switch (gcf->city->databaseType) {
+
+ case GEOIP_CITY_EDITION_REV0:
+ case GEOIP_CITY_EDITION_REV1:
+
+ return NGX_CONF_OK;
+
+ default:
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid GeoIP City database \"%V\" type:%d",
+ &value[1], gcf->city->databaseType);
+ return NGX_CONF_ERROR;
+ }
+}
+
+
+static void
+ngx_http_geoip_cleanup(void *data)
+{
+ ngx_http_geoip_conf_t *gcf = data;
+
+ if (gcf->country) {
+ GeoIP_delete(gcf->country);
+ }
+
+ if (gcf->city) {
+ GeoIP_delete(gcf->city);
+ }
+}
diff --git a/src/http/modules/ngx_http_gzip_filter_module.c b/src/http/modules/ngx_http_gzip_filter_module.c
index 7c7ca0a6c..62b430b71 100644
--- a/src/http/modules/ngx_http_gzip_filter_module.c
+++ b/src/http/modules/ngx_http_gzip_filter_module.c
@@ -1069,7 +1069,7 @@ ngx_http_gzip_create_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_gzip_conf_t));
if (conf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
/*
diff --git a/src/http/modules/ngx_http_gzip_static_module.c b/src/http/modules/ngx_http_gzip_static_module.c
index 22e806ac3..8080d9cb0 100644
--- a/src/http/modules/ngx_http_gzip_static_module.c
+++ b/src/http/modules/ngx_http_gzip_static_module.c
@@ -95,7 +95,13 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r)
gzcf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_static_module);
- if (!gzcf->enable || ngx_http_gzip_ok(r) != NGX_OK) {
+ if (!gzcf->enable) {
+ return NGX_DECLINED;
+ }
+
+ clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
+
+ if (clcf->gzip_vary && ngx_http_gzip_ok(r) != NGX_OK) {
return NGX_DECLINED;
}
@@ -116,8 +122,6 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r)
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
"http filename: \"%s\"", path.data);
- clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-
ngx_memzero(&of, sizeof(ngx_open_file_info_t));
of.directio = clcf->directio;
@@ -138,6 +142,7 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r)
case NGX_ENOTDIR:
case NGX_ENAMETOOLONG:
+ r->gzip = 0;
return NGX_DECLINED;
case NGX_EACCES:
@@ -251,7 +256,7 @@ ngx_http_gzip_static_create_conf(ngx_conf_t *cf)
conf = ngx_palloc(cf->pool, sizeof(ngx_http_gzip_static_conf_t));
if (conf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
conf->enable = NGX_CONF_UNSET;
diff --git a/src/http/modules/ngx_http_headers_filter_module.c b/src/http/modules/ngx_http_headers_filter_module.c
index 13cef0bea..3b5ebd68f 100644
--- a/src/http/modules/ngx_http_headers_filter_module.c
+++ b/src/http/modules/ngx_http_headers_filter_module.c
@@ -421,7 +421,7 @@ ngx_http_headers_create_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_headers_conf_t));
if (conf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
/*
diff --git a/src/http/modules/ngx_http_image_filter_module.c b/src/http/modules/ngx_http_image_filter_module.c
index c1c335a04..9a4dafe05 100644
--- a/src/http/modules/ngx_http_image_filter_module.c
+++ b/src/http/modules/ngx_http_image_filter_module.c
@@ -40,6 +40,11 @@ typedef struct {
ngx_uint_t height;
ngx_int_t jpeg_quality;
+ ngx_flag_t transparency;
+
+ ngx_http_complex_value_t *wcv;
+ ngx_http_complex_value_t *hcv;
+
size_t buffer_size;
} ngx_http_image_filter_conf_t;
@@ -53,6 +58,9 @@ typedef struct {
ngx_uint_t width;
ngx_uint_t height;
+ ngx_uint_t max_width;
+ ngx_uint_t max_height;
+
ngx_uint_t phase;
ngx_uint_t type;
} ngx_http_image_filter_ctx_t;
@@ -80,6 +88,9 @@ static gdImagePtr ngx_http_image_new(ngx_http_request_t *r, int w, int h,
static u_char *ngx_http_image_out(ngx_http_request_t *r, ngx_uint_t type,
gdImagePtr img, int *size);
static void ngx_http_image_cleanup(void *data);
+static ngx_uint_t ngx_http_image_filter_get_value(ngx_http_request_t *r,
+ ngx_http_complex_value_t *cv, ngx_uint_t v);
+static ngx_uint_t ngx_http_image_filter_value(ngx_str_t *value);
static void *ngx_http_image_filter_create_conf(ngx_conf_t *cf);
@@ -106,6 +117,13 @@ static ngx_command_t ngx_http_image_filter_commands[] = {
offsetof(ngx_http_image_filter_conf_t, jpeg_quality),
NULL },
+ { ngx_string("image_filter_transparency"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+ ngx_conf_set_flag_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_image_filter_conf_t, transparency),
+ NULL },
+
{ ngx_string("image_filter_buffer"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_size_slot,
@@ -454,7 +472,6 @@ ngx_http_image_read(ngx_http_request_t *r, ngx_chain_t *in)
static ngx_buf_t *
ngx_http_image_process(ngx_http_request_t *r)
{
- ngx_buf_t *b;
ngx_int_t rc;
ngx_http_image_filter_ctx_t *ctx;
ngx_http_image_filter_conf_t *conf;
@@ -468,20 +485,28 @@ ngx_http_image_process(ngx_http_request_t *r)
conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module);
if (conf->filter == NGX_HTTP_IMAGE_SIZE) {
+ return ngx_http_image_json(r, rc == NGX_OK ? ctx : NULL);
+ }
+
+ ctx->max_width = ngx_http_image_filter_get_value(r, conf->wcv, conf->width);
+ if (ctx->max_width == 0) {
+ return NULL;
+ }
- b = ngx_http_image_json(r, rc == NGX_OK ? ctx : NULL);
+ ctx->max_height = ngx_http_image_filter_get_value(r, conf->hcv,
+ conf->height);
+ if (ctx->max_height == 0) {
+ return NULL;
+ }
- } else if (rc == NGX_OK
- && ctx->width <= conf->width
- && ctx->height <= conf->height)
+ if (rc == NGX_OK
+ && ctx->width <= ctx->max_width
+ && ctx->height <= ctx->max_height)
{
- b = ngx_http_image_asis(r, ctx);
-
- } else {
- b = ngx_http_image_resize(r, ctx);
+ return ngx_http_image_asis(r, ctx);
}
- return b;
+ return ngx_http_image_resize(r, ctx);
}
@@ -662,8 +687,9 @@ ngx_http_image_size(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
static ngx_buf_t *
ngx_http_image_resize(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
{
- int sx, sy, dx, dy, ox, oy,
- colors, transparent, size;
+ int sx, sy, dx, dy, ox, oy, size,
+ colors, palette, transparent,
+ red, green, blue;
u_char *out;
ngx_buf_t *b;
ngx_uint_t resize;
@@ -682,29 +708,53 @@ 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 <= conf->width && (ngx_uint_t) sy <= conf->height) {
+ if ((ngx_uint_t) sx <= ctx->max_width
+ && (ngx_uint_t) sy <= ctx->max_height)
+ {
gdImageDestroy(src);
return ngx_http_image_asis(r, ctx);
}
colors = gdImageColorsTotal(src);
- transparent = gdImageGetTransparent(src);
+
+ if (colors && conf->transparency) {
+ transparent = gdImageGetTransparent(src);
+
+ if (transparent != -1) {
+ palette = colors;
+ red = gdImageRed(src, transparent);
+ green = gdImageGreen(src, transparent);
+ blue = gdImageBlue(src, transparent);
+
+ goto transparent;
+ }
+ }
+
+ palette = 0;
+ transparent = -1;
+ red = 0;
+ green = 0;
+ blue = 0;
+
+transparent:
+
+ gdImageColorTransparent(src, -1);
dx = sx;
dy = sy;
if (conf->filter == NGX_HTTP_IMAGE_RESIZE) {
- if ((ngx_uint_t) dx > conf->width) {
- dy = dy * conf->width / dx;
+ if ((ngx_uint_t) dx > ctx->max_width) {
+ dy = dy * ctx->max_width / dx;
dy = dy ? dy : 1;
- dx = conf->width;
+ dx = ctx->max_width;
}
- if ((ngx_uint_t) dy > conf->height) {
- dx = dx * conf->height / dy;
+ if ((ngx_uint_t) dy > ctx->max_height) {
+ dx = dx * ctx->max_height / dy;
dx = dx ? dx : 1;
- dy = conf->height;
+ dy = ctx->max_height;
}
resize = 1;
@@ -713,34 +763,44 @@ ngx_http_image_resize(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
resize = 0;
- if ((ngx_uint_t) (dx * 100 / dy) < conf->width * 100 / conf->height) {
-
- if ((ngx_uint_t) dx > conf->width) {
- dy = dy * conf->width / dx;
+ if ((ngx_uint_t) (dx * 100 / dy)
+ < ctx->max_width * 100 / ctx->max_height)
+ {
+ if ((ngx_uint_t) dx > ctx->max_width) {
+ dy = dy * ctx->max_width / dx;
dy = dy ? dy : 1;
- dx = conf->width;
+ dx = ctx->max_width;
resize = 1;
}
} else {
- if ((ngx_uint_t) dy > conf->height) {
- dx = dx * conf->height / dy;
+ if ((ngx_uint_t) dy > ctx->max_height) {
+ dx = dx * ctx->max_height / dy;
dx = dx ? dx : 1;
- dy = conf->height;
+ dy = ctx->max_height;
resize = 1;
}
}
}
if (resize) {
- dst = ngx_http_image_new(r, dx, dy, colors);
+ dst = ngx_http_image_new(r, dx, dy, palette);
if (dst == NULL) {
gdImageDestroy(src);
return NULL;
}
+ if (colors == 0) {
+ gdImageSaveAlpha(dst, 1);
+ gdImageAlphaBlending(dst, 0);
+ }
+
gdImageCopyResampled(dst, src, 0, 0, 0, 0, dx, dy, sx, sy);
+ if (colors) {
+ gdImageTrueColorToPalette(dst, 1, 256);
+ }
+
gdImageDestroy(src);
} else {
@@ -751,15 +811,15 @@ ngx_http_image_resize(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
src = dst;
- if ((ngx_uint_t) dx > conf->width) {
- ox = dx - conf->width;
+ if ((ngx_uint_t) dx > ctx->max_width) {
+ ox = dx - ctx->max_width;
} else {
ox = 0;
}
- if ((ngx_uint_t) dy > conf->height) {
- oy = dy - conf->height;
+ if ((ngx_uint_t) dy > ctx->max_height) {
+ oy = dy - ctx->max_height;
} else {
oy = 0;
@@ -781,13 +841,24 @@ ngx_http_image_resize(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
"image crop: %d x %d @ %d x %d",
dx, dy, ox, oy);
+ if (colors == 0) {
+ gdImageSaveAlpha(dst, 1);
+ gdImageAlphaBlending(dst, 0);
+ }
+
gdImageCopy(dst, src, 0, 0, ox, oy, dx - ox, dy - oy);
+ if (colors) {
+ gdImageTrueColorToPalette(dst, 1, 256);
+ }
+
gdImageDestroy(src);
}
}
- gdImageColorTransparent(dst, transparent);
+ if (transparent != -1 && colors) {
+ gdImageColorTransparent(dst, gdImageColorExact(dst, red, green, blue));
+ }
out = ngx_http_image_out(r, ctx->type, dst, &size);
@@ -941,6 +1012,43 @@ ngx_http_image_cleanup(void *data)
}
+static ngx_uint_t
+ngx_http_image_filter_get_value(ngx_http_request_t *r,
+ ngx_http_complex_value_t *cv, ngx_uint_t v)
+{
+ ngx_str_t val;
+
+ if (cv == NULL) {
+ return v;
+ }
+
+ if (ngx_http_complex_value(r, cv, &val) != NGX_OK) {
+ return 0;
+ }
+
+ return ngx_http_image_filter_value(&val);
+}
+
+
+static ngx_uint_t
+ngx_http_image_filter_value(ngx_str_t *value)
+{
+ ngx_int_t n;
+
+ if (value->len == 1 && value->data[0] == '-') {
+ return (ngx_uint_t) -1;
+ }
+
+ n = ngx_atoi(value->data, value->len);
+
+ if (n > 0) {
+ return (ngx_uint_t) n;
+ }
+
+ return 0;
+}
+
+
static void *
ngx_http_image_filter_create_conf(ngx_conf_t *cf)
{
@@ -948,11 +1056,12 @@ ngx_http_image_filter_create_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_image_filter_conf_t));
if (conf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
conf->filter = NGX_CONF_UNSET_UINT;
conf->jpeg_quality = NGX_CONF_UNSET;
+ conf->transparency = NGX_CONF_UNSET;
conf->buffer_size = NGX_CONF_UNSET_SIZE;
return conf;
@@ -974,12 +1083,16 @@ ngx_http_image_filter_merge_conf(ngx_conf_t *cf, void *parent, void *child)
conf->filter = prev->filter;
conf->width = prev->width;
conf->height = prev->height;
+ conf->wcv = prev->wcv;
+ conf->hcv = prev->hcv;
}
}
/* 75 is libjpeg default quality */
ngx_conf_merge_value(conf->jpeg_quality, prev->jpeg_quality, 75);
+ ngx_conf_merge_value(conf->transparency, prev->transparency, 1);
+
ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size,
1 * 1024 * 1024);
@@ -992,9 +1105,11 @@ ngx_http_image_filter(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_image_filter_conf_t *imcf = conf;
- ngx_str_t *value;
- ngx_int_t n;
- ngx_uint_t i;
+ ngx_str_t *value;
+ ngx_int_t n;
+ ngx_uint_t i;
+ ngx_http_complex_value_t cv;
+ ngx_http_compile_complex_value_t ccv;
value = cf->args->elts;
@@ -1027,32 +1142,60 @@ ngx_http_image_filter(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
goto failed;
}
- i++;
+ ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
- if (value[i].len == 1 && value[i].data[0] == '-') {
- imcf->width = (ngx_uint_t) -1;
+ ccv.cf = cf;
+ ccv.value = &value[++i];
+ ccv.complex_value = &cv;
- } else {
- n = ngx_atoi(value[i].data, value[i].len);
- if (n == NGX_ERROR) {
+ if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ if (cv.lengths == NULL) {
+ n = ngx_http_image_filter_value(&value[i]);
+
+ if (n == 0) {
goto failed;
}
imcf->width = (ngx_uint_t) n;
+
+ } else {
+ imcf->wcv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
+ if (imcf->wcv == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ *imcf->wcv = cv;
}
- i++;
+ ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
- if (value[i].len == 1 && value[i].data[0] == '-') {
- imcf->height = (ngx_uint_t) -1;
+ ccv.cf = cf;
+ ccv.value = &value[++i];
+ ccv.complex_value = &cv;
- } else {
- n = ngx_atoi(value[i].data, value[i].len);
- if (n == NGX_ERROR) {
+ if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ if (cv.lengths == NULL) {
+ n = ngx_http_image_filter_value(&value[i]);
+
+ if (n == 0) {
goto failed;
}
imcf->height = (ngx_uint_t) n;
+
+ } else {
+ imcf->hcv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
+ if (imcf->hcv == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ *imcf->hcv = cv;
}
return NGX_CONF_OK;
diff --git a/src/http/modules/ngx_http_index_module.c b/src/http/modules/ngx_http_index_module.c
index f88e599a7..d94fc118c 100644
--- a/src/http/modules/ngx_http_index_module.c
+++ b/src/http/modules/ngx_http_index_module.c
@@ -366,7 +366,7 @@ ngx_http_index_create_loc_conf(ngx_conf_t *cf)
conf = ngx_palloc(cf->pool, sizeof(ngx_http_index_loc_conf_t));
if (conf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
conf->indices = NULL;
diff --git a/src/http/modules/ngx_http_limit_req_module.c b/src/http/modules/ngx_http_limit_req_module.c
index 3d20b295d..f9b64f1f8 100644
--- a/src/http/modules/ngx_http_limit_req_module.c
+++ b/src/http/modules/ngx_http_limit_req_module.c
@@ -42,7 +42,10 @@ typedef struct {
ngx_shm_zone_t *shm_zone;
/* integer value, 1 corresponds to 0.001 r/s */
ngx_uint_t burst;
- ngx_uint_t nodelay;/* unsigned nodelay:1 */
+ ngx_uint_t limit_log_level;
+ ngx_uint_t delay_log_level;
+
+ ngx_uint_t nodelay; /* unsigned nodelay:1 */
} ngx_http_limit_req_conf_t;
@@ -62,6 +65,15 @@ static char *ngx_http_limit_req(ngx_conf_t *cf, ngx_command_t *cmd,
static ngx_int_t ngx_http_limit_req_init(ngx_conf_t *cf);
+static ngx_conf_enum_t ngx_http_limit_req_log_levels[] = {
+ { ngx_string("info"), NGX_LOG_INFO },
+ { ngx_string("notice"), NGX_LOG_NOTICE },
+ { ngx_string("warn"), NGX_LOG_WARN },
+ { ngx_string("error"), NGX_LOG_ERR },
+ { ngx_null_string, 0 }
+};
+
+
static ngx_command_t ngx_http_limit_req_commands[] = {
{ ngx_string("limit_req_zone"),
@@ -78,6 +90,13 @@ static ngx_command_t ngx_http_limit_req_commands[] = {
0,
NULL },
+ { ngx_string("limit_req_log_level"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_enum_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_limit_req_conf_t, limit_log_level),
+ &ngx_http_limit_req_log_levels },
+
ngx_null_command
};
@@ -181,12 +200,12 @@ ngx_http_limit_req_handler(ngx_http_request_t *r)
}
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "limit_req: %i %ui.%03ui", rc, excess / 1000, excess % 1000);
+ "limit_req: %i %ui.%03ui", rc, excess / 1000, excess % 1000);
if (rc == NGX_BUSY) {
ngx_shmtx_unlock(&ctx->shpool->mutex);
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ ngx_log_error(lrcf->limit_log_level, r->connection->log, 0,
"limiting requests, excess: %ui.%03ui by zone \"%V\"",
excess / 1000, excess % 1000, &lrcf->shm_zone->shm.name);
@@ -200,7 +219,7 @@ ngx_http_limit_req_handler(ngx_http_request_t *r)
return NGX_DECLINED;
}
- ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
+ ngx_log_error(lrcf->delay_log_level, r->connection->log, 0,
"delaying request, excess: %ui.%03ui, by zone \"%V\"",
excess / 1000, excess % 1000, &lrcf->shm_zone->shm.name);
@@ -263,8 +282,23 @@ done:
static void
ngx_http_limit_req_delay(ngx_http_request_t *r)
{
+ ngx_event_t *wev;
+
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "limit_req delay");
+ "limit_req delay");
+
+ wev = r->connection->write;
+
+ if (!wev->timedout) {
+
+ if (ngx_handle_write_event(wev, 0) != NGX_OK) {
+ ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+ }
+
+ return;
+ }
+
+ wev->timedout = 0;
if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) {
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
@@ -368,15 +402,16 @@ ngx_http_limit_req_lookup(ngx_http_limit_req_conf_t *lrcf, ngx_uint_t hash,
excess = 0;
}
+ if ((ngx_uint_t) excess > lrcf->burst) {
+ *lrp = lr;
+ return NGX_BUSY;
+ }
+
lr->excess = excess;
lr->last = now;
*lrp = lr;
- if ((ngx_uint_t) excess > lrcf->burst) {
- return NGX_BUSY;
- }
-
if (excess) {
return NGX_AGAIN;
}
@@ -522,7 +557,7 @@ ngx_http_limit_req_create_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_limit_req_conf_t));
if (conf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
/*
@@ -533,6 +568,8 @@ ngx_http_limit_req_create_conf(ngx_conf_t *cf)
* conf->nodelay = 0;
*/
+ conf->limit_log_level = NGX_CONF_UNSET_UINT;
+
return conf;
}
@@ -547,6 +584,12 @@ ngx_http_limit_req_merge_conf(ngx_conf_t *cf, void *parent, void *child)
*conf = *prev;
}
+ ngx_conf_merge_uint_value(conf->limit_log_level, prev->limit_log_level,
+ NGX_LOG_ERR);
+
+ conf->delay_log_level = (conf->limit_log_level == NGX_LOG_INFO) ?
+ NGX_LOG_INFO : conf->limit_log_level + 1;
+
return NGX_CONF_OK;
}
diff --git a/src/http/modules/ngx_http_limit_zone_module.c b/src/http/modules/ngx_http_limit_zone_module.c
index e11e0815b..31df316e4 100644
--- a/src/http/modules/ngx_http_limit_zone_module.c
+++ b/src/http/modules/ngx_http_limit_zone_module.c
@@ -33,6 +33,7 @@ typedef struct {
typedef struct {
ngx_shm_zone_t *shm_zone;
ngx_uint_t conn;
+ ngx_uint_t log_level;
} ngx_http_limit_zone_conf_t;
@@ -48,6 +49,15 @@ static char *ngx_http_limit_conn(ngx_conf_t *cf, ngx_command_t *cmd,
static ngx_int_t ngx_http_limit_zone_init(ngx_conf_t *cf);
+static ngx_conf_enum_t ngx_http_limit_conn_log_levels[] = {
+ { ngx_string("info"), NGX_LOG_INFO },
+ { ngx_string("notice"), NGX_LOG_NOTICE },
+ { ngx_string("warn"), NGX_LOG_WARN },
+ { ngx_string("error"), NGX_LOG_ERR },
+ { ngx_null_string, 0 }
+};
+
+
static ngx_command_t ngx_http_limit_zone_commands[] = {
{ ngx_string("limit_zone"),
@@ -64,6 +74,13 @@ static ngx_command_t ngx_http_limit_zone_commands[] = {
0,
NULL },
+ { ngx_string("limit_conn_log_level"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_enum_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_limit_zone_conf_t, log_level),
+ &ngx_http_limit_conn_log_levels },
+
ngx_null_command
};
@@ -189,7 +206,7 @@ ngx_http_limit_zone_handler(ngx_http_request_t *r)
ngx_shmtx_unlock(&shpool->mutex);
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ ngx_log_error(lzcf->log_level, r->connection->log, 0,
"limiting connections by zone \"%V\"",
&lzcf->shm_zone->shm.name);
@@ -381,7 +398,7 @@ ngx_http_limit_zone_create_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_limit_zone_conf_t));
if (conf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
/*
@@ -391,6 +408,8 @@ ngx_http_limit_zone_create_conf(ngx_conf_t *cf)
* conf->conn = 0;
*/
+ conf->log_level = NGX_CONF_UNSET_UINT;
+
return conf;
}
@@ -405,6 +424,8 @@ ngx_http_limit_zone_merge_conf(ngx_conf_t *cf, void *parent, void *child)
*conf = *prev;
}
+ ngx_conf_merge_uint_value(conf->log_level, prev->log_level, NGX_LOG_ERR);
+
return NGX_CONF_OK;
}
diff --git a/src/http/modules/ngx_http_log_module.c b/src/http/modules/ngx_http_log_module.c
index efe720bf5..1ff105821 100644
--- a/src/http/modules/ngx_http_log_module.c
+++ b/src/http/modules/ngx_http_log_module.c
@@ -676,7 +676,7 @@ ngx_http_log_escape(u_char *dst, u_char *src, size_t size)
/* find the number of the characters to be escaped */
- n = 0;
+ n = 0;
for (i = 0; i < size; i++) {
if (escape[*src >> 5] & (1 << (*src & 0x1f))) {
@@ -714,18 +714,18 @@ ngx_http_log_create_main_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_log_main_conf_t));
if (conf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
if (ngx_array_init(&conf->formats, cf->pool, 4, sizeof(ngx_http_log_fmt_t))
!= NGX_OK)
{
- return NGX_CONF_ERROR;
+ return NULL;
}
fmt = ngx_array_push(&conf->formats);
if (fmt == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
fmt->name.len = sizeof("combined") - 1;
@@ -735,7 +735,7 @@ ngx_http_log_create_main_conf(ngx_conf_t *cf)
fmt->ops = ngx_array_create(cf->pool, 16, sizeof(ngx_http_log_op_t));
if (fmt->ops == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
return conf;
@@ -749,7 +749,7 @@ ngx_http_log_create_loc_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_log_loc_conf_t));
if (conf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
conf->open_file_cache = NGX_CONF_UNSET_PTR;
diff --git a/src/http/modules/ngx_http_map_module.c b/src/http/modules/ngx_http_map_module.c
index d0eb02c64..1f7786c3c 100644
--- a/src/http/modules/ngx_http_map_module.c
+++ b/src/http/modules/ngx_http_map_module.c
@@ -160,7 +160,7 @@ ngx_http_map_create_conf(ngx_conf_t *cf)
mcf = ngx_palloc(cf->pool, sizeof(ngx_http_map_conf_t));
if (mcf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
mcf->hash_max_size = NGX_CONF_UNSET_UINT;
diff --git a/src/http/modules/ngx_http_memcached_module.c b/src/http/modules/ngx_http_memcached_module.c
index f68be1e44..dc7c76719 100644
--- a/src/http/modules/ngx_http_memcached_module.c
+++ b/src/http/modules/ngx_http_memcached_module.c
@@ -176,24 +176,19 @@ ngx_http_memcached_handler(ngx_http_request_t *r)
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- mlcf = ngx_http_get_module_loc_conf(r, ngx_http_memcached_module);
-
- u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t));
- if (u == NULL) {
+ if (ngx_http_upstream_create(r) != NGX_OK) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
+ u = r->upstream;
+
u->schema.len = sizeof("memcached://") - 1;
u->schema.data = (u_char *) "memcached://";
- u->peer.log = r->connection->log;
- u->peer.log_error = NGX_ERROR_ERR;
-#if (NGX_THREADS)
- u->peer.lock = &r->connection->lock;
-#endif
-
u->output.tag = (ngx_buf_tag_t) &ngx_http_memcached_module;
+ mlcf = ngx_http_get_module_loc_conf(r, ngx_http_memcached_module);
+
u->conf = &mlcf->upstream;
u->create_request = ngx_http_memcached_create_request;
@@ -202,8 +197,6 @@ ngx_http_memcached_handler(ngx_http_request_t *r)
u->abort_request = ngx_http_memcached_abort_request;
u->finalize_request = ngx_http_memcached_finalize_request;
- r->upstream = u;
-
ctx = ngx_palloc(r->pool, sizeof(ngx_http_memcached_ctx_t));
if (ctx == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
@@ -513,7 +506,7 @@ ngx_http_memcached_create_loc_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_memcached_loc_conf_t));
if (conf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
/*
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index 96bd89b6d..f4ed8a7a1 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -590,13 +590,10 @@ ngx_http_proxy_handler(ngx_http_request_t *r)
ngx_http_proxy_ctx_t *ctx;
ngx_http_proxy_loc_conf_t *plcf;
- u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t));
- if (u == NULL) {
+ if (ngx_http_upstream_create(r) != NGX_OK) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}
- r->upstream = u;
-
ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_proxy_ctx_t));
if (ctx == NULL) {
return NGX_ERROR;
@@ -606,6 +603,8 @@ ngx_http_proxy_handler(ngx_http_request_t *r)
plcf = ngx_http_get_module_loc_conf(r, ngx_http_proxy_module);
+ u = r->upstream;
+
if (plcf->proxy_lengths == 0) {
ctx->vars = plcf->vars;
u->schema = plcf->vars.schema;
@@ -619,12 +618,6 @@ ngx_http_proxy_handler(ngx_http_request_t *r)
}
}
- u->peer.log = r->connection->log;
- u->peer.log_error = NGX_ERROR_ERR;
-#if (NGX_THREADS)
- u->peer.lock = &r->connection->lock;
-#endif
-
u->output.tag = (ngx_buf_tag_t) &ngx_http_proxy_module;
u->conf = &plcf->upstream;
@@ -1884,7 +1877,7 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_proxy_loc_conf_t));
if (conf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
/*
diff --git a/src/http/modules/ngx_http_random_index_module.c b/src/http/modules/ngx_http_random_index_module.c
index 7ddb819af..bb5544ae6 100644
--- a/src/http/modules/ngx_http_random_index_module.c
+++ b/src/http/modules/ngx_http_random_index_module.c
@@ -280,7 +280,7 @@ ngx_http_random_index_create_loc_conf(ngx_conf_t *cf)
conf = ngx_palloc(cf->pool, sizeof(ngx_http_random_index_loc_conf_t));
if (conf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
conf->enable = NGX_CONF_UNSET;
diff --git a/src/http/modules/ngx_http_realip_module.c b/src/http/modules/ngx_http_realip_module.c
index b069a1eba..3b2cce679 100644
--- a/src/http/modules/ngx_http_realip_module.c
+++ b/src/http/modules/ngx_http_realip_module.c
@@ -360,7 +360,7 @@ ngx_http_realip_create_loc_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_realip_loc_conf_t));
if (conf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
/*
diff --git a/src/http/modules/ngx_http_referer_module.c b/src/http/modules/ngx_http_referer_module.c
index 05828997b..658f4a19c 100644
--- a/src/http/modules/ngx_http_referer_module.c
+++ b/src/http/modules/ngx_http_referer_module.c
@@ -221,7 +221,7 @@ ngx_http_referer_create_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_referer_conf_t));
if (conf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
#if (NGX_PCRE)
diff --git a/src/http/modules/ngx_http_rewrite_module.c b/src/http/modules/ngx_http_rewrite_module.c
index a84844356..1f98cf829 100644
--- a/src/http/modules/ngx_http_rewrite_module.c
+++ b/src/http/modules/ngx_http_rewrite_module.c
@@ -220,7 +220,7 @@ ngx_http_rewrite_create_loc_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_rewrite_loc_conf_t));
if (conf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
conf->stack_size = NGX_CONF_UNSET_UINT;
@@ -446,7 +446,7 @@ ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}
- *code = (uintptr_t) NULL;
+ *code = NULL;
}
regex->next = (u_char *) lcf->codes->elts + lcf->codes->nelts
@@ -568,7 +568,7 @@ ngx_http_rewrite_if(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
if_code = ngx_array_push_n(lcf->codes, sizeof(ngx_http_script_if_code_t));
if (if_code == NULL) {
- return NULL;
+ return NGX_CONF_ERROR;
}
if_code->code = ngx_http_script_if_code;
diff --git a/src/http/modules/ngx_http_secure_link_module.c b/src/http/modules/ngx_http_secure_link_module.c
index 049a45c3e..2f9351d91 100644
--- a/src/http/modules/ngx_http_secure_link_module.c
+++ b/src/http/modules/ngx_http_secure_link_module.c
@@ -152,7 +152,7 @@ ngx_http_secure_link_create_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_secure_link_conf_t));
if (conf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
/*
diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c
index d27d854a8..d03e58407 100644
--- a/src/http/modules/ngx_http_ssi_filter_module.c
+++ b/src/http/modules/ngx_http_ssi_filter_module.c
@@ -360,6 +360,7 @@ ngx_http_ssi_header_filter(ngx_http_request_t *r)
if (r == r->main) {
ngx_http_clear_content_length(r);
ngx_http_clear_last_modified(r);
+ ngx_http_clear_accept_ranges(r);
}
return ngx_http_next_header_filter(r);
@@ -1907,7 +1908,7 @@ ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
args.len = 0;
args.data = NULL;
- flags = 0;
+ flags = NGX_HTTP_LOG_UNSAFE;
if (ngx_http_parse_unsafe_uri(r, uri, &args, &flags) != NGX_OK) {
return NGX_HTTP_SSI_ERROR;
@@ -2689,14 +2690,14 @@ ngx_http_ssi_create_main_conf(ngx_conf_t *cf)
smcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_ssi_main_conf_t));
if (smcf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
smcf->commands.pool = cf->pool;
smcf->commands.temp_pool = cf->temp_pool;
if (ngx_hash_keys_array_init(&smcf->commands, NGX_HASH_SMALL) != NGX_OK) {
- return NGX_CONF_ERROR;
+ return NULL;
}
return smcf;
@@ -2736,7 +2737,7 @@ ngx_http_ssi_create_loc_conf(ngx_conf_t *cf)
slcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_ssi_loc_conf_t));
if (slcf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
/*
diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c
index 3bf52a2c7..e428c36de 100644
--- a/src/http/modules/ngx_http_ssl_module.c
+++ b/src/http/modules/ngx_http_ssl_module.c
@@ -31,15 +31,6 @@ static char *ngx_http_ssl_enable(ngx_conf_t *cf, ngx_command_t *cmd,
static char *ngx_http_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
-#if !defined (SSL_OP_CIPHER_SERVER_PREFERENCE)
-
-static char *ngx_http_ssl_nosupported(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-
-static char ngx_http_ssl_openssl097[] = "OpenSSL 0.9.7 and higher";
-
-#endif
-
static ngx_conf_bitmask_t ngx_http_ssl_protocols[] = {
{ ngx_string("SSLv2"), NGX_SSL_SSLv2 },
@@ -52,7 +43,7 @@ static ngx_conf_bitmask_t ngx_http_ssl_protocols[] = {
static ngx_conf_enum_t ngx_http_ssl_verify[] = {
{ ngx_string("off"), 0 },
{ ngx_string("on"), 1 },
- { ngx_string("ask"), 2 },
+ { ngx_string("optional"), 2 },
{ ngx_null_string, 0 }
};
@@ -124,14 +115,10 @@ static ngx_command_t ngx_http_ssl_commands[] = {
{ ngx_string("ssl_prefer_server_ciphers"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
-#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
ngx_conf_set_flag_slot,
NGX_HTTP_SRV_CONF_OFFSET,
offsetof(ngx_http_ssl_srv_conf_t, prefer_server_ciphers),
NULL },
-#else
- ngx_http_ssl_nosupported, 0, 0, ngx_http_ssl_openssl097 },
-#endif
{ ngx_string("ssl_session_cache"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE12,
@@ -147,6 +134,13 @@ static ngx_command_t ngx_http_ssl_commands[] = {
offsetof(ngx_http_ssl_srv_conf_t, session_timeout),
NULL },
+ { ngx_string("ssl_crl"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_str_slot,
+ NGX_HTTP_SRV_CONF_OFFSET,
+ offsetof(ngx_http_ssl_srv_conf_t, crl),
+ NULL },
+
ngx_null_command
};
@@ -206,6 +200,9 @@ static ngx_http_variable_t ngx_http_ssl_vars[] = {
{ ngx_string("ssl_client_serial"), NULL, ngx_http_ssl_variable,
(uintptr_t) ngx_ssl_get_serial_number, NGX_HTTP_VAR_CHANGEABLE, 0 },
+ { ngx_string("ssl_client_verify"), NULL, ngx_http_ssl_variable,
+ (uintptr_t) ngx_ssl_get_client_verify, NGX_HTTP_VAR_CHANGEABLE, 0 },
+
{ ngx_null_string, NULL, NULL, 0, 0, 0 }
};
@@ -302,7 +299,7 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
sscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_ssl_srv_conf_t));
if (sscf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
/*
@@ -313,6 +310,7 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t *cf)
* sscf->certificate_key = { 0, NULL };
* sscf->dhparam = { 0, NULL };
* sscf->client_certificate = { 0, NULL };
+ * sscf->crl = { 0, NULL };
* sscf->ciphers.len = 0;
* sscf->ciphers.data = NULL;
* sscf->shm_zone = NULL;
@@ -359,6 +357,7 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_str_value(conf->client_certificate, prev->client_certificate,
"");
+ ngx_conf_merge_str_value(conf->crl, prev->crl, "");
ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS);
@@ -407,9 +406,10 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_http_ssl_servername)
== 0)
{
- ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0,
- "SSL_CTX_set_tlsext_servername_callback() failed");
- return NGX_CONF_ERROR;
+ ngx_log_error(NGX_LOG_WARN, cf->log, 0,
+ "nginx was built with SNI support, however, now it is linked "
+ "dynamically to an OpenSSL library which has no tlsext support, "
+ "therefore SNI is not available");
}
#endif
@@ -453,16 +453,16 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
{
return NGX_CONF_ERROR;
}
- }
-#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
+ if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+ }
if (conf->prefer_server_ciphers) {
SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
}
-#endif
-
/* a temporary 512-bit RSA key is required for export versions of MSIE */
if (ngx_ssl_generate_rsa512_key(&conf->ssl) != NGX_OK) {
return NGX_CONF_ERROR;
@@ -620,18 +620,3 @@ invalid:
return NGX_CONF_ERROR;
}
-
-
-#if !defined (SSL_OP_CIPHER_SERVER_PREFERENCE)
-
-static char *
-ngx_http_ssl_nosupported(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"%V\" directive is available only in %s,",
- &cmd->name, cmd->post);
-
- return NGX_CONF_ERROR;
-}
-
-#endif
diff --git a/src/http/modules/ngx_http_ssl_module.h b/src/http/modules/ngx_http_ssl_module.h
index da7f04736..29eedc8ae 100644
--- a/src/http/modules/ngx_http_ssl_module.h
+++ b/src/http/modules/ngx_http_ssl_module.h
@@ -33,6 +33,7 @@ typedef struct {
ngx_str_t certificate_key;
ngx_str_t dhparam;
ngx_str_t client_certificate;
+ ngx_str_t crl;
ngx_str_t ciphers;
diff --git a/src/http/modules/ngx_http_sub_filter_module.c b/src/http/modules/ngx_http_sub_filter_module.c
index 34f32946d..9f078819d 100644
--- a/src/http/modules/ngx_http_sub_filter_module.c
+++ b/src/http/modules/ngx_http_sub_filter_module.c
@@ -638,7 +638,7 @@ ngx_http_sub_create_conf(ngx_conf_t *cf)
slcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_sub_loc_conf_t));
if (slcf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
/*
diff --git a/src/http/modules/ngx_http_userid_filter_module.c b/src/http/modules/ngx_http_userid_filter_module.c
index 3462f649c..9997274a6 100644
--- a/src/http/modules/ngx_http_userid_filter_module.c
+++ b/src/http/modules/ngx_http_userid_filter_module.c
@@ -570,7 +570,7 @@ ngx_http_userid_create_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_userid_conf_t));
if (conf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
/*
diff --git a/src/http/modules/ngx_http_xslt_filter_module.c b/src/http/modules/ngx_http_xslt_filter_module.c
index afa605a23..c14d1c4a1 100644
--- a/src/http/modules/ngx_http_xslt_filter_module.c
+++ b/src/http/modules/ngx_http_xslt_filter_module.c
@@ -404,7 +404,7 @@ ngx_http_xslt_add_chunk(ngx_http_request_t *r, ngx_http_xslt_filter_ctx_t *ctx,
sax->endElementNs = ngx_http_xslt_sax_end_element;
sax->characters = ngx_http_xslt_sax_characters;
- sax->ignorableWhitespace = ngx_http_xslt_sax_characters;
+ sax->ignorableWhitespace = ngx_http_xslt_sax_characters;
sax->cdataBlock = ngx_http_xslt_sax_cdata_block;
sax->getEntity = ngx_http_xslt_sax_get_entity;
sax->resolveEntity = ngx_http_xslt_sax_resolve_entity;
@@ -1172,7 +1172,7 @@ ngx_http_xslt_filter_create_main_conf(ngx_conf_t *cf)
conf = ngx_palloc(cf->pool, sizeof(ngx_http_xslt_filter_main_conf_t));
if (conf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
if (ngx_array_init(&conf->dtd_files, cf->pool, 1,
@@ -1200,7 +1200,7 @@ ngx_http_xslt_filter_create_conf(ngx_conf_t *cf)
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_xslt_filter_loc_conf_t));
if (conf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
/*
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index 144d4927c..710bcf675 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.62';
+our $VERSION = '0.7.63';
require XSLoader;
XSLoader::load('nginx', $VERSION);
diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c
index e22428a78..bdeb31c53 100644
--- a/src/http/modules/perl/ngx_http_perl_module.c
+++ b/src/http/modules/perl/ngx_http_perl_module.c
@@ -13,8 +13,8 @@
typedef struct {
PerlInterpreter *perl;
HV *nginx;
- ngx_str_t modules;
- ngx_array_t requires;
+ ngx_array_t *modules;
+ ngx_array_t *requires;
} ngx_http_perl_main_conf_t;
@@ -57,8 +57,6 @@ static char *ngx_http_perl_init_main_conf(ngx_conf_t *cf, void *conf);
static void *ngx_http_perl_create_loc_conf(ngx_conf_t *cf);
static char *ngx_http_perl_merge_loc_conf(ngx_conf_t *cf, void *parent,
void *child);
-static char *ngx_http_perl_require(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
static char *ngx_http_perl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static char *ngx_http_perl_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
@@ -74,16 +72,16 @@ static ngx_command_t ngx_http_perl_commands[] = {
{ ngx_string("perl_modules"),
NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_str_slot,
+ ngx_conf_set_str_array_slot,
NGX_HTTP_MAIN_CONF_OFFSET,
offsetof(ngx_http_perl_main_conf_t, modules),
NULL },
{ ngx_string("perl_require"),
NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
- ngx_http_perl_require,
+ ngx_conf_set_str_array_slot,
NGX_HTTP_MAIN_CONF_OFFSET,
- 0,
+ offsetof(ngx_http_perl_main_conf_t, requires),
NULL },
{ ngx_string("perl"),
@@ -458,8 +456,10 @@ ngx_http_perl_ssi(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ssi_ctx,
static char *
ngx_http_perl_init_interpreter(ngx_conf_t *cf, ngx_http_perl_main_conf_t *pmcf)
{
+ ngx_str_t *m;
+ ngx_uint_t i;
#if (NGX_HAVE_PERL_MULTIPLICITY)
- ngx_pool_cleanup_t *cln;
+ ngx_pool_cleanup_t *cln;
cln = ngx_pool_cleanup_add(cf->pool, 0);
if (cln == NULL) {
@@ -471,14 +471,29 @@ ngx_http_perl_init_interpreter(ngx_conf_t *cf, ngx_http_perl_main_conf_t *pmcf)
#endif
#ifdef NGX_PERL_MODULES
- if (pmcf->modules.data == NULL) {
- pmcf->modules.data = NGX_PERL_MODULES;
+ if (pmcf->modules == NGX_CONF_UNSET_PTR) {
+
+ pmcf->modules = ngx_array_create(cf->pool, 1, sizeof(ngx_str_t));
+ if (pmcf->modules == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ m = ngx_array_push(pmcf->modules);
+ if (m == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ m->len = sizeof(NGX_PERL_MODULES) - 1;
+ m->data = NGX_PERL_MODULES;
}
#endif
- if (pmcf->modules.data) {
- if (ngx_conf_full_name(cf->cycle, &pmcf->modules, 0) != NGX_OK) {
- return NGX_CONF_ERROR;
+ if (pmcf->modules != NGX_CONF_UNSET_PTR) {
+ m = pmcf->modules->elts;
+ for (i = 0; i < pmcf->modules->nelts; i++) {
+ if (ngx_conf_full_name(cf->cycle, &m[i], 0) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
}
}
@@ -490,7 +505,7 @@ ngx_http_perl_init_interpreter(ngx_conf_t *cf, ngx_http_perl_main_conf_t *pmcf)
return NGX_CONF_ERROR;
}
- if (ngx_http_perl_run_requires(aTHX_ &pmcf->requires, cf->log)
+ if (ngx_http_perl_run_requires(aTHX_ pmcf->requires, cf->log)
!= NGX_OK)
{
return NGX_CONF_ERROR;
@@ -538,7 +553,9 @@ ngx_http_perl_create_interpreter(ngx_conf_t *cf,
int n;
STRLEN len;
SV *sv;
- char *ver, *embedding[6];
+ char *ver, **embedding;
+ ngx_str_t *m;
+ ngx_uint_t i;
PerlInterpreter *perl;
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cf->log, 0, "create perl interpreter");
@@ -564,15 +581,21 @@ ngx_http_perl_create_interpreter(ngx_conf_t *cf,
PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
#endif
- embedding[0] = "";
+ n = (pmcf->modules != NGX_CONF_UNSET_PTR) ? pmcf->modules->nelts * 2 : 0;
- if (pmcf->modules.data) {
- embedding[1] = "-I";
- embedding[2] = (char *) pmcf->modules.data;
- n = 3;
+ embedding = ngx_palloc(cf->pool, (4 + n) * sizeof(char *));
+ if (embedding == NULL) {
+ goto fail;
+ }
- } else {
- n = 1;
+ embedding[0] = "";
+
+ if (n++) {
+ m = pmcf->modules->elts;
+ for (i = 0; i < pmcf->modules->nelts; i++) {
+ embedding[2 * i + 1] = "-I";
+ embedding[2 * i + 2] = (char *) m[i].data;
+ }
}
embedding[n++] = "-Mnginx";
@@ -596,7 +619,7 @@ ngx_http_perl_create_interpreter(ngx_conf_t *cf,
goto fail;
}
- if (ngx_http_perl_run_requires(aTHX_ &pmcf->requires, cf->log) != NGX_OK) {
+ if (ngx_http_perl_run_requires(aTHX_ pmcf->requires, cf->log) != NGX_OK) {
goto fail;
}
@@ -617,26 +640,28 @@ fail:
static ngx_int_t
ngx_http_perl_run_requires(pTHX_ ngx_array_t *requires, ngx_log_t *log)
{
- char **script;
+ u_char *err;
STRLEN len;
- ngx_str_t err;
+ ngx_str_t *script;
ngx_uint_t i;
+ if (requires == NGX_CONF_UNSET_PTR) {
+ return NGX_OK;
+ }
+
script = requires->elts;
for (i = 0; i < requires->nelts; i++) {
- require_pv(script[i]);
+ require_pv((char *) script[i].data);
if (SvTRUE(ERRSV)) {
- err.data = (u_char *) SvPV(ERRSV, len);
- for (len--; err.data[len] == LF || err.data[len] == CR; len--) {
- /* void */
- }
- err.len = len + 1;
+ err = (u_char *) SvPV(ERRSV, len);
+ while (--len && (err[len] == CR || err[len] == LF)) { /* void */ }
ngx_log_error(NGX_LOG_EMERG, log, 0,
- "require_pv(\"%s\") failed: \"%V\"", script[i], &err);
+ "require_pv(\"%s\") failed: \"%*s\"",
+ script[i].data, len + 1, err);
return NGX_ERROR;
}
@@ -653,8 +678,8 @@ ngx_http_perl_call_handler(pTHX_ ngx_http_request_t *r, HV *nginx, SV *sub,
SV *sv;
int n, status;
char *line;
+ u_char *err;
STRLEN len, n_a;
- ngx_str_t err;
ngx_uint_t i;
ngx_connection_t *c;
@@ -724,14 +749,11 @@ ngx_http_perl_call_handler(pTHX_ ngx_http_request_t *r, HV *nginx, SV *sub,
if (SvTRUE(ERRSV)) {
- err.data = (u_char *) SvPV(ERRSV, len);
- for (len--; err.data[len] == LF || err.data[len] == CR; len--) {
- /* void */
- }
- err.len = len + 1;
+ err = (u_char *) SvPV(ERRSV, len);
+ while (--len && (err[len] == CR || err[len] == LF)) { /* void */ }
ngx_log_error(NGX_LOG_ERR, c->log, 0,
- "call_sv(\"%V\") failed: \"%V\"", handler, &err);
+ "call_sv(\"%V\") failed: \"%*s\"", handler, len + 1, err);
if (rv) {
return NGX_ERROR;
@@ -765,7 +787,10 @@ ngx_http_perl_eval_anon_sub(pTHX_ ngx_str_t *handler, SV **sv)
}
}
- if (ngx_strncmp(p, "sub ", 4) == 0 || ngx_strncmp(p, "use ", 4) == 0) {
+ if (ngx_strncmp(p, "sub ", 4) == 0
+ || ngx_strncmp(p, "sub{", 4) == 0
+ || ngx_strncmp(p, "use ", 4) == 0)
+ {
*sv = eval_pv((char *) p, FALSE);
/* eval_pv() does not set ERRSV on failure */
@@ -784,15 +809,12 @@ ngx_http_perl_create_main_conf(ngx_conf_t *cf)
pmcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_perl_main_conf_t));
if (pmcf == NULL) {
- return NGX_CONF_ERROR;
- }
-
- if (ngx_array_init(&pmcf->requires, cf->pool, 1, sizeof(u_char *))
- != NGX_OK)
- {
return NULL;
}
+ pmcf->modules = NGX_CONF_UNSET_PTR;
+ pmcf->requires = NGX_CONF_UNSET_PTR;
+
return pmcf;
}
@@ -869,7 +891,7 @@ ngx_http_perl_create_loc_conf(ngx_conf_t *cf)
plcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_perl_loc_conf_t));
if (plcf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
/*
@@ -898,28 +920,6 @@ ngx_http_perl_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
static char *
-ngx_http_perl_require(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_perl_main_conf_t *pmcf = conf;
-
- u_char **p;
- ngx_str_t *value;
-
- value = cf->args->elts;
-
- p = ngx_array_push(&pmcf->requires);
-
- if (p == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *p = value[1].data;
-
- return NGX_CONF_OK;
-}
-
-
-static char *
ngx_http_perl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_perl_loc_conf_t *plcf = conf;
diff --git a/src/http/ngx_http_cache.h b/src/http/ngx_http_cache.h
index 1ee80751d..6ac6fd876 100644
--- a/src/http/ngx_http_cache.h
+++ b/src/http/ngx_http_cache.h
@@ -97,6 +97,7 @@ typedef struct {
ngx_rbtree_node_t sentinel;
ngx_queue_t queue;
ngx_atomic_t cold;
+ ngx_atomic_t loading;
off_t size;
} ngx_http_file_cache_sh_t;
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 2e3b91393..799dfc856 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -433,6 +433,14 @@ static ngx_command_t ngx_http_core_commands[] = {
offsetof(ngx_http_core_loc_conf_t, limit_rate),
NULL },
+ { ngx_string("limit_rate_after"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
+ |NGX_CONF_TAKE1,
+ ngx_conf_set_size_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_core_loc_conf_t, limit_rate_after),
+ NULL },
+
{ ngx_string("keepalive_timeout"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
ngx_http_core_keepalive,
@@ -877,6 +885,7 @@ ngx_http_core_find_config_phase(ngx_http_request_t *r,
"client intended to send too large body: %O bytes",
r->headers_in.content_length_n);
+ (void) ngx_http_discard_request_body(r);
ngx_http_finalize_request(r, NGX_HTTP_REQUEST_ENTITY_TOO_LARGE);
return NGX_OK;
}
@@ -2691,14 +2700,14 @@ ngx_http_core_create_main_conf(ngx_conf_t *cf)
cmcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_main_conf_t));
if (cmcf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
if (ngx_array_init(&cmcf->servers, cf->pool, 4,
sizeof(ngx_http_core_srv_conf_t *))
!= NGX_OK)
{
- return NGX_CONF_ERROR;
+ return NULL;
}
cmcf->server_names_hash_max_size = NGX_CONF_UNSET_UINT;
@@ -2750,7 +2759,7 @@ ngx_http_core_create_srv_conf(ngx_conf_t *cf)
cscf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_srv_conf_t));
if (cscf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
/*
@@ -2763,14 +2772,14 @@ ngx_http_core_create_srv_conf(ngx_conf_t *cf)
sizeof(ngx_http_listen_t))
!= NGX_OK)
{
- return NGX_CONF_ERROR;
+ return NULL;
}
if (ngx_array_init(&cscf->server_names, cf->temp_pool, 4,
sizeof(ngx_http_server_name_t))
!= NGX_OK)
{
- return NGX_CONF_ERROR;
+ return NULL;
}
cscf->connection_pool_size = NGX_CONF_UNSET_SIZE;
@@ -2881,7 +2890,7 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf)
lcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_loc_conf_t));
if (lcf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
/*
@@ -2920,6 +2929,7 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf)
lcf->send_lowat = NGX_CONF_UNSET_SIZE;
lcf->postpone_output = NGX_CONF_UNSET_SIZE;
lcf->limit_rate = NGX_CONF_UNSET_SIZE;
+ lcf->limit_rate_after = NGX_CONF_UNSET_SIZE;
lcf->keepalive_timeout = NGX_CONF_UNSET_MSEC;
lcf->keepalive_header = NGX_CONF_UNSET;
lcf->keepalive_requests = NGX_CONF_UNSET_UINT;
@@ -3119,6 +3129,8 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_size_value(conf->postpone_output, prev->postpone_output,
1460);
ngx_conf_merge_size_value(conf->limit_rate, prev->limit_rate, 0);
+ ngx_conf_merge_size_value(conf->limit_rate_after, prev->limit_rate_after,
+ 0);
ngx_conf_merge_msec_value(conf->keepalive_timeout,
prev->keepalive_timeout, 75000);
ngx_conf_merge_sec_value(conf->keepalive_header,
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index e5b68f330..71d5b953c 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -324,6 +324,7 @@ struct ngx_http_core_loc_conf_s {
size_t send_lowat; /* send_lowat */
size_t postpone_output; /* postpone_output */
size_t limit_rate; /* limit_rate */
+ size_t limit_rate_after; /* limit_rate_after */
size_t sendfile_max_chunk; /* sendfile_max_chunk */
ngx_msec_t client_body_timeout; /* client_body_timeout */
diff --git a/src/http/ngx_http_file_cache.c b/src/http/ngx_http_file_cache.c
index 8e908a1dc..a60483d59 100644
--- a/src/http/ngx_http_file_cache.c
+++ b/src/http/ngx_http_file_cache.c
@@ -53,6 +53,7 @@ ngx_http_file_cache_init(ngx_shm_zone_t *shm_zone, void *data)
ngx_http_file_cache_t *ocache = data;
size_t len;
+ ngx_uint_t n;
ngx_http_file_cache_t *cache;
cache = shm_zone->data;
@@ -68,6 +69,15 @@ ngx_http_file_cache_init(ngx_shm_zone_t *shm_zone, void *data)
return NGX_ERROR;
}
+ for (n = 0; n < 3; n++) {
+ if (cache->path->level[n] != ocache->path->level[n]) {
+ ngx_log_error(NGX_LOG_EMERG, shm_zone->shm.log, 0,
+ "cache \"%V\" had previously different levels",
+ &shm_zone->shm.name);
+ return NGX_ERROR;
+ }
+ }
+
cache->sh = ocache->sh;
cache->shpool = ocache->shpool;
@@ -75,6 +85,10 @@ ngx_http_file_cache_init(ngx_shm_zone_t *shm_zone, void *data)
cache->max_size /= cache->bsize;
+ if (!cache->sh->cold || cache->sh->loading) {
+ cache->path->loader = NULL;
+ }
+
return NGX_OK;
}
@@ -100,6 +114,7 @@ ngx_http_file_cache_init(ngx_shm_zone_t *shm_zone, void *data)
ngx_queue_init(&cache->sh->queue);
cache->sh->cold = 1;
+ cache->sh->loading = 0;
cache->sh->size = 0;
cache->bsize = ngx_fs_bsize(cache->path->name.data);
@@ -603,7 +618,7 @@ ngx_http_file_cache_set_header(ngx_http_request_t *r, u_char *buf)
void
ngx_http_file_cache_update(ngx_http_request_t *r, ngx_temp_file_t *tf)
{
- off_t size;
+ off_t size, length;
ngx_int_t rc;
ngx_file_uniq_t uniq;
ngx_file_info_t fi;
@@ -625,6 +640,7 @@ ngx_http_file_cache_update(ngx_http_request_t *r, ngx_temp_file_t *tf)
cache = c->file_cache;
uniq = 0;
+ length = 0;
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http file cache rename: \"%s\" to \"%s\"",
@@ -635,7 +651,6 @@ ngx_http_file_cache_update(ngx_http_request_t *r, ngx_temp_file_t *tf)
ext.time = -1;
ext.create_path = 1;
ext.delete_file = 1;
- ext.log_rename_error = 1;
ext.log = r->connection->log;
rc = ngx_ext_rename_file(&tf->file.name, &c->file.name, &ext);
@@ -650,10 +665,11 @@ ngx_http_file_cache_update(ngx_http_request_t *r, ngx_temp_file_t *tf)
} else {
uniq = ngx_file_uniq(&fi);
+ length = ngx_file_size(&fi);
}
}
- size = (c->length + cache->bsize - 1) / cache->bsize;
+ size = (length + cache->bsize - 1) / cache->bsize;
ngx_shmtx_lock(&cache->shpool->mutex);
@@ -663,7 +679,7 @@ ngx_http_file_cache_update(ngx_http_request_t *r, ngx_temp_file_t *tf)
size = size - (c->node->length + cache->bsize - 1) / cache->bsize;
- c->node->length = c->length;
+ c->node->length = length;
cache->sh->size += size;
@@ -1026,39 +1042,8 @@ ngx_http_file_cache_manager(void *data)
{
ngx_http_file_cache_t *cache = data;
- off_t size;
- time_t next;
- ngx_tree_ctx_t tree;
-
- if (cache->sh->cold) {
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
- "http file cache manager update");
-
- tree.init_handler = NULL;
- tree.file_handler = ngx_http_file_cache_manage_file;
- tree.pre_tree_handler = ngx_http_file_cache_noop;
- tree.post_tree_handler = ngx_http_file_cache_noop;
- tree.spec_handler = ngx_http_file_cache_delete_file;
- tree.data = cache;
- tree.alloc = 0;
- tree.log = ngx_cycle->log;
-
- cache->last = ngx_current_msec;
- cache->files = 0;
-
- if (ngx_walk_tree(&tree, &cache->path->name) == NGX_ABORT) {
- return 10;
- }
-
- cache->sh->cold = 0;
-
- ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0,
- "http file cache: %V %.3fM, bsize: %uz",
- &cache->path->name,
- ((double) cache->sh->size * cache->bsize) / (1024 * 1024),
- cache->bsize);
- }
+ off_t size;
+ time_t next;
next = ngx_http_file_cache_expire(cache);
@@ -1088,6 +1073,52 @@ ngx_http_file_cache_manager(void *data)
}
+static void
+ngx_http_file_cache_loader(void *data)
+{
+ ngx_http_file_cache_t *cache = data;
+
+ ngx_tree_ctx_t tree;
+
+ if (!cache->sh->cold || cache->sh->loading) {
+ return;
+ }
+
+ if (!ngx_atomic_cmp_set(&cache->sh->loading, 0, ngx_pid)) {
+ return;
+ }
+
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
+ "http file cache loader");
+
+ tree.init_handler = NULL;
+ tree.file_handler = ngx_http_file_cache_manage_file;
+ tree.pre_tree_handler = ngx_http_file_cache_noop;
+ tree.post_tree_handler = ngx_http_file_cache_noop;
+ tree.spec_handler = ngx_http_file_cache_delete_file;
+ tree.data = cache;
+ tree.alloc = 0;
+ tree.log = ngx_cycle->log;
+
+ cache->last = ngx_current_msec;
+ cache->files = 0;
+
+ if (ngx_walk_tree(&tree, &cache->path->name) == NGX_ABORT) {
+ cache->sh->loading = 0;
+ return;
+ }
+
+ cache->sh->cold = 0;
+ cache->sh->loading = 0;
+
+ ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0,
+ "http file cache: %V %.3fM, bsize: %uz",
+ &cache->path->name,
+ ((double) cache->sh->size * cache->bsize) / (1024 * 1024),
+ cache->bsize);
+}
+
+
static ngx_int_t
ngx_http_file_cache_manager_sleep(ngx_http_file_cache_t *cache)
{
@@ -1468,6 +1499,7 @@ ngx_http_file_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
cache->path->manager = ngx_http_file_cache_manager;
+ cache->path->loader = ngx_http_file_cache_loader;
cache->path->data = cache;
if (ngx_add_path(cf, &cache->path) != NGX_OK) {
diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c
index 160f96dbe..b638f86fc 100644
--- a/src/http/ngx_http_parse.c
+++ b/src/http/ngx_http_parse.c
@@ -143,7 +143,7 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
break;
}
- if (ch < 'A' || ch > 'Z') {
+ if ((ch < 'A' || ch > 'Z') && ch != '_') {
return NGX_HTTP_PARSE_INVALID_METHOD;
}
@@ -257,7 +257,7 @@ ngx_http_parse_request_line(ngx_http_request_t *r, ngx_buf_t *b)
break;
}
- if (ch < 'A' || ch > 'Z') {
+ if ((ch < 'A' || ch > 'Z') && ch != '_') {
return NGX_HTTP_PARSE_INVALID_METHOD;
}
@@ -1322,8 +1322,10 @@ ngx_http_parse_unsafe_uri(ngx_http_request_t *r, ngx_str_t *uri,
unsafe:
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "unsafe URI \"%V\" was detected", uri);
+ if (*flags & NGX_HTTP_LOG_UNSAFE) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "unsafe URI \"%V\" was detected", uri);
+ }
return NGX_ERROR;
}
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index 4930b502f..13b069226 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -129,7 +129,7 @@ ngx_http_header_t ngx_http_headers_in[] = {
{ ngx_string("Keep-Alive"), offsetof(ngx_http_headers_in_t, keep_alive),
ngx_http_process_header_line },
-#if (NGX_HTTP_PROXY || NGX_HTTP_REALIP)
+#if (NGX_HTTP_PROXY || NGX_HTTP_REALIP || NGX_HTTP_GEO)
{ ngx_string("X-Forwarded-For"),
offsetof(ngx_http_headers_in_t, x_forwarded_for),
ngx_http_process_header_line },
@@ -384,6 +384,7 @@ ngx_http_init_request(ngx_event_t *rev)
r->loc_conf = cscf->ctx->loc_conf;
rev->handler = ngx_http_process_request_line;
+ r->read_event_handler = ngx_http_block_reading;
#if (NGX_HTTP_SSL)
@@ -451,13 +452,15 @@ ngx_http_init_request(ngx_event_t *rev)
sizeof(ngx_table_elt_t))
!= NGX_OK)
{
- ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+ ngx_destroy_pool(r->pool);
+ ngx_http_close_connection(c);
return;
}
r->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module);
if (r->ctx == NULL) {
- ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+ ngx_destroy_pool(r->pool);
+ ngx_http_close_connection(c);
return;
}
@@ -466,7 +469,8 @@ ngx_http_init_request(ngx_event_t *rev)
r->variables = ngx_pcalloc(r->pool, cmcf->variables.nelts
* sizeof(ngx_http_variable_value_t));
if (r->variables == NULL) {
- ngx_http_close_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+ ngx_destroy_pool(r->pool);
+ ngx_http_close_connection(c);
return;
}
@@ -1374,8 +1378,13 @@ ngx_http_process_user_agent(ngx_http_request_t *r, ngx_table_elt_t *h,
r->headers_in.msie4 = 1;
/* fall through */
case '5':
- case '6':
r->headers_in.msie6 = 1;
+ break;
+ case '6':
+ if (ngx_strstrn(msie + 8, "SV1", 3 - 1) == NULL) {
+ r->headers_in.msie6 = 1;
+ }
+ break;
}
}
@@ -1517,7 +1526,7 @@ ngx_http_process_request(ngx_http_request_t *r)
sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module);
- if (sscf->verify == 1) {
+ if (sscf->verify) {
rc = SSL_get_verify_result(c->ssl->connection);
if (rc != X509_V_OK) {
@@ -1532,20 +1541,22 @@ ngx_http_process_request(ngx_http_request_t *r)
return;
}
- cert = SSL_get_peer_certificate(c->ssl->connection);
+ if (sscf->verify == 1) {
+ cert = SSL_get_peer_certificate(c->ssl->connection);
- if (cert == NULL) {
- ngx_log_error(NGX_LOG_INFO, c->log, 0,
- "client sent no required SSL certificate");
+ if (cert == NULL) {
+ ngx_log_error(NGX_LOG_INFO, c->log, 0,
+ "client sent no required SSL certificate");
- ngx_ssl_remove_cached_session(sscf->ssl.ctx,
+ ngx_ssl_remove_cached_session(sscf->ssl.ctx,
(SSL_get0_session(c->ssl->connection)));
- ngx_http_finalize_request(r, NGX_HTTPS_NO_CERT);
- return;
- }
+ ngx_http_finalize_request(r, NGX_HTTPS_NO_CERT);
+ return;
+ }
- X509_free(cert);
+ X509_free(cert);
+ }
}
}
@@ -2703,7 +2714,14 @@ ngx_http_send_special(ngx_http_request_t *r, ngx_uint_t flags)
}
if (flags & NGX_HTTP_LAST) {
- b->last_buf = 1;
+
+ if (r == r->main && !r->post_action) {
+ b->last_buf = 1;
+
+ } else {
+ b->sync = 1;
+ b->last_in_chain = 1;
+ }
}
if (flags & NGX_HTTP_FLUSH) {
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
index 97ffbbf21..78dabddbd 100644
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -60,6 +60,7 @@
#define NGX_HTTP_ZERO_IN_URI 1
#define NGX_HTTP_SUBREQUEST_IN_MEMORY 2
#define NGX_HTTP_SUBREQUEST_WAITED 4
+#define NGX_HTTP_LOG_UNSAFE 8
#define NGX_HTTP_OK 200
@@ -184,7 +185,7 @@ typedef struct {
ngx_table_elt_t *keep_alive;
-#if (NGX_HTTP_PROXY || NGX_HTTP_REALIP)
+#if (NGX_HTTP_PROXY || NGX_HTTP_REALIP || NGX_HTTP_GEO)
ngx_table_elt_t *x_forwarded_for;
#endif
@@ -488,7 +489,6 @@ struct ngx_http_request_s {
unsigned root_tested:1;
unsigned done:1;
unsigned logged:1;
- unsigned utf8:1;
unsigned buffered:4;
diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c
index f67c6628d..ad9d88b40 100644
--- a/src/http/ngx_http_script.c
+++ b/src/http/ngx_http_script.c
@@ -561,7 +561,7 @@ ngx_http_script_add_code(ngx_array_t *codes, size_t size, void *code)
new = ngx_array_push_n(codes, size);
if (new == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
if (code) {
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index 8c7f9a473..ed86a382c 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -230,19 +230,19 @@ ngx_http_upstream_header_t ngx_http_upstream_headers_in[] = {
{ ngx_string("X-Accel-Redirect"),
ngx_http_upstream_process_header_line,
offsetof(ngx_http_upstream_headers_in_t, x_accel_redirect),
- ngx_http_upstream_ignore_header_line, 0, 0 },
+ ngx_http_upstream_copy_header_line, 0, 0 },
{ ngx_string("X-Accel-Limit-Rate"),
ngx_http_upstream_process_limit_rate, 0,
- ngx_http_upstream_ignore_header_line, 0, 0 },
+ ngx_http_upstream_copy_header_line, 0, 0 },
{ ngx_string("X-Accel-Buffering"),
ngx_http_upstream_process_buffering, 0,
- ngx_http_upstream_ignore_header_line, 0, 0 },
+ ngx_http_upstream_copy_header_line, 0, 0 },
{ ngx_string("X-Accel-Charset"),
ngx_http_upstream_process_charset, 0,
- ngx_http_upstream_ignore_header_line, 0, 0 },
+ ngx_http_upstream_copy_header_line, 0, 0 },
#if (NGX_HTTP_GZIP)
{ ngx_string("Content-Encoding"),
@@ -354,6 +354,35 @@ ngx_conf_bitmask_t ngx_http_upstream_cache_method_mask[] = {
};
+ngx_int_t
+ngx_http_upstream_create(ngx_http_request_t *r)
+{
+ ngx_http_upstream_t *u;
+
+ u = r->upstream;
+
+ if (u && u->cleanup) {
+ ngx_http_upstream_cleanup(r);
+ *u->cleanup = NULL;
+ }
+
+ u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t));
+ if (u == NULL) {
+ return NGX_ERROR;
+ }
+
+ r->upstream = u;
+
+ u->peer.log = r->connection->log;
+ u->peer.log_error = NGX_ERROR_ERR;
+#if (NGX_THREADS)
+ u->peer.lock = &r->connection->lock;
+#endif
+
+ return NGX_OK;
+}
+
+
void
ngx_http_upstream_init(ngx_http_request_t *r)
{
@@ -1733,7 +1762,7 @@ ngx_http_upstream_process_headers(ngx_http_request_t *r, ngx_http_upstream_t *u)
uri = &u->headers_in.x_accel_redirect->value;
args.len = 0;
args.data = NULL;
- flags = 0;
+ flags = NGX_HTTP_LOG_UNSAFE;
if (ngx_http_parse_unsafe_uri(r, uri, &args, &flags) != NGX_OK) {
ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
@@ -2034,11 +2063,6 @@ ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u)
r->cache->date = now;
r->cache->body_start = (u_short) (u->buffer.pos - u->buffer.start);
- if (r->headers_out.content_length_n != -1) {
- r->cache->length = r->cache->body_start
- + r->headers_out.content_length_n;
- }
-
ngx_http_file_cache_set_header(r, u->buffer.start);
} else {
@@ -2616,7 +2640,6 @@ ngx_http_upstream_store(ngx_http_request_t *r, ngx_http_upstream_t *u)
ext.time = -1;
ext.create_path = 1;
ext.delete_file = 1;
- ext.log_rename_error = 1;
ext.log = r->connection->log;
if (u->headers_in.last_modified) {
@@ -2643,6 +2666,8 @@ ngx_http_upstream_store(ngx_http_request_t *r, ngx_http_upstream_t *u)
}
}
+ path.len--;
+
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"upstream stores \"%s\" to \"%s\"",
tf->file.name.data, path.data);
@@ -2864,7 +2889,7 @@ ngx_http_upstream_finalize_request(ngx_http_request_t *r,
#if (NGX_HTTP_CACHE)
- if (u->cacheable) {
+ if (u->cacheable && r->cache) {
time_t valid;
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@@ -2898,7 +2923,7 @@ ngx_http_upstream_finalize_request(ngx_http_request_t *r,
r->connection->log->action = "sending to client";
- if (rc == 0 && r == r->main && !r->post_action) {
+ if (rc == 0) {
rc = ngx_http_send_special(r, NGX_HTTP_LAST);
}
@@ -3311,10 +3336,11 @@ ngx_http_upstream_copy_last_modified(ngx_http_request_t *r, ngx_table_elt_t *h,
*ho = *h;
+ r->headers_out.last_modified = ho;
+
#if (NGX_HTTP_CACHE)
if (r->upstream->cacheable) {
- r->headers_out.last_modified = ho;
r->headers_out.last_modified_time = ngx_http_parse_time(h->value.data,
h->value.len);
}
@@ -3438,6 +3464,8 @@ ngx_http_upstream_copy_allow_ranges(ngx_http_request_t *r,
*ho = *h;
+ r->headers_out.accept_ranges = ho;
+
return NGX_OK;
}
@@ -4274,7 +4302,7 @@ ngx_http_upstream_create_main_conf(ngx_conf_t *cf)
sizeof(ngx_http_upstream_srv_conf_t *))
!= NGX_OK)
{
- return NGX_CONF_ERROR;
+ return NULL;
}
return umcf;
diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h
index fc777670e..ac2682d6f 100644
--- a/src/http/ngx_http_upstream.h
+++ b/src/http/ngx_http_upstream.h
@@ -317,6 +317,7 @@ typedef struct {
ngx_int_t ngx_http_upstream_header_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
+ngx_int_t ngx_http_upstream_create(ngx_http_request_t *r);
void ngx_http_upstream_init(ngx_http_request_t *r);
ngx_http_upstream_srv_conf_t *ngx_http_upstream_add(ngx_conf_t *cf,
ngx_url_t *u, ngx_uint_t flags);
diff --git a/src/http/ngx_http_write_filter_module.c b/src/http/ngx_http_write_filter_module.c
index 4381a4a57..46351349c 100644
--- a/src/http/ngx_http_write_filter_module.c
+++ b/src/http/ngx_http_write_filter_module.c
@@ -46,7 +46,7 @@ ngx_module_t ngx_http_write_filter_module = {
ngx_int_t
ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
{
- off_t size, sent, limit;
+ off_t size, sent, nsent, limit;
ngx_uint_t last, flush;
ngx_msec_t delay;
ngx_chain_t *cl, *ln, **ll, *chain;
@@ -210,7 +210,8 @@ ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
}
if (r->limit_rate) {
- limit = r->limit_rate * (ngx_time() - r->start_sec + 1) - c->sent;
+ limit = r->limit_rate * (ngx_time() - r->start_sec + 1)
+ - (c->sent - clcf->limit_rate_after);
if (limit <= 0) {
c->write->delayed = 1;
@@ -245,7 +246,23 @@ ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
}
if (r->limit_rate) {
- delay = (ngx_msec_t) ((c->sent - sent) * 1000 / r->limit_rate + 1);
+
+ nsent = c->sent;
+
+ if (clcf->limit_rate_after) {
+
+ sent -= clcf->limit_rate_after;
+ if (sent < 0) {
+ sent = 0;
+ }
+
+ nsent -= clcf->limit_rate_after;
+ if (nsent < 0) {
+ nsent = 0;
+ }
+ }
+
+ delay = (ngx_msec_t) ((nsent - sent) * 1000 / r->limit_rate + 1);
if (delay > 0) {
c->write->delayed = 1;
diff --git a/src/mail/ngx_mail_auth_http_module.c b/src/mail/ngx_mail_auth_http_module.c
index f7ad3085b..acd06656f 100644
--- a/src/mail/ngx_mail_auth_http_module.c
+++ b/src/mail/ngx_mail_auth_http_module.c
@@ -1302,7 +1302,7 @@ ngx_mail_auth_http_create_conf(ngx_conf_t *cf)
ahcf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_auth_http_conf_t));
if (ahcf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
ahcf->timeout = NGX_CONF_UNSET_MSEC;
diff --git a/src/mail/ngx_mail_core_module.c b/src/mail/ngx_mail_core_module.c
index d0addb059..bd2c916d5 100644
--- a/src/mail/ngx_mail_core_module.c
+++ b/src/mail/ngx_mail_core_module.c
@@ -120,20 +120,20 @@ ngx_mail_core_create_main_conf(ngx_conf_t *cf)
cmcf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_core_main_conf_t));
if (cmcf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
if (ngx_array_init(&cmcf->servers, cf->pool, 4,
sizeof(ngx_mail_core_srv_conf_t *))
!= NGX_OK)
{
- return NGX_CONF_ERROR;
+ return NULL;
}
if (ngx_array_init(&cmcf->listen, cf->pool, 4, sizeof(ngx_mail_listen_t))
!= NGX_OK)
{
- return NGX_CONF_ERROR;
+ return NULL;
}
return cmcf;
diff --git a/src/mail/ngx_mail_proxy_module.c b/src/mail/ngx_mail_proxy_module.c
index 193df8ada..b408ed7d3 100644
--- a/src/mail/ngx_mail_proxy_module.c
+++ b/src/mail/ngx_mail_proxy_module.c
@@ -1061,7 +1061,7 @@ ngx_mail_proxy_create_conf(ngx_conf_t *cf)
pcf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_proxy_conf_t));
if (pcf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
pcf->enable = NGX_CONF_UNSET;
diff --git a/src/mail/ngx_mail_ssl_module.c b/src/mail/ngx_mail_ssl_module.c
index 4e2bda5f2..025df54d7 100644
--- a/src/mail/ngx_mail_ssl_module.c
+++ b/src/mail/ngx_mail_ssl_module.c
@@ -22,15 +22,6 @@ static char *ngx_mail_ssl_starttls(ngx_conf_t *cf, ngx_command_t *cmd,
static char *ngx_mail_ssl_session_cache(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
-#if !defined (SSL_OP_CIPHER_SERVER_PREFERENCE)
-
-static char *ngx_mail_ssl_nosupported(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-
-static char ngx_mail_ssl_openssl097[] = "OpenSSL 0.9.7 and higher";
-
-#endif
-
static ngx_conf_enum_t ngx_http_starttls_state[] = {
{ ngx_string("off"), NGX_MAIL_STARTTLS_OFF },
@@ -102,14 +93,10 @@ static ngx_command_t ngx_mail_ssl_commands[] = {
{ ngx_string("ssl_prefer_server_ciphers"),
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG,
-#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
ngx_conf_set_flag_slot,
NGX_MAIL_SRV_CONF_OFFSET,
offsetof(ngx_mail_ssl_conf_t, prefer_server_ciphers),
NULL },
-#else
- ngx_mail_ssl_nosupported, 0, 0, ngx_mail_ssl_openssl097 },
-#endif
{ ngx_string("ssl_session_cache"),
NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE12,
@@ -166,7 +153,7 @@ ngx_mail_ssl_create_conf(ngx_conf_t *cf)
scf = ngx_pcalloc(cf->pool, sizeof(ngx_mail_ssl_conf_t));
if (scf == NULL) {
- return NGX_CONF_ERROR;
+ return NULL;
}
/*
@@ -297,14 +284,10 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child)
}
}
-#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
-
if (conf->prefer_server_ciphers) {
SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
}
-#endif
-
if (ngx_ssl_generate_rsa512_key(&conf->ssl) != NGX_OK) {
return NGX_CONF_ERROR;
}
@@ -492,18 +475,3 @@ invalid:
return NGX_CONF_ERROR;
}
-
-
-#if !defined (SSL_OP_CIPHER_SERVER_PREFERENCE)
-
-static char *
-ngx_mail_ssl_nosupported(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"%V\" directive is available only in %s,",
- &cmd->name, cmd->post);
-
- return NGX_CONF_ERROR;
-}
-
-#endif
diff --git a/src/os/unix/ngx_errno.h b/src/os/unix/ngx_errno.h
index 3dbfa227e..379f36777 100644
--- a/src/os/unix/ngx_errno.h
+++ b/src/os/unix/ngx_errno.h
@@ -16,6 +16,7 @@ typedef int ngx_err_t;
#define NGX_EPERM EPERM
#define NGX_ENOENT ENOENT
+#define NGX_ENOPATH ENOENT
#define NGX_ESRCH ESRCH
#define NGX_EINTR EINTR
#define NGX_ECHILD ECHILD
diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h
index cf5c3ed91..5395acd03 100644
--- a/src/os/unix/ngx_files.h
+++ b/src/os/unix/ngx_files.h
@@ -18,13 +18,13 @@ typedef ino_t ngx_file_uniq_t;
typedef struct {
- DIR *dir;
- struct dirent *de;
- struct stat info;
+ DIR *dir;
+ struct dirent *de;
+ struct stat info;
- unsigned type:8;
- unsigned valid_info:1;
- unsigned valid_type:1;
+ unsigned type:8;
+ unsigned valid_info:1;
+ unsigned valid_type:1;
} ngx_dir_t;
diff --git a/src/os/unix/ngx_process.c b/src/os/unix/ngx_process.c
index c480d6899..21a92f178 100644
--- a/src/os/unix/ngx_process.c
+++ b/src/os/unix/ngx_process.c
@@ -214,21 +214,33 @@ ngx_spawn_process(ngx_cycle_t *cycle, ngx_spawn_proc_pt proc, void *data,
switch (respawn) {
+ case NGX_PROCESS_NORESPAWN:
+ ngx_processes[s].respawn = 0;
+ ngx_processes[s].just_spawn = 0;
+ ngx_processes[s].detached = 0;
+ break;
+
+ case NGX_PROCESS_JUST_SPAWN:
+ ngx_processes[s].respawn = 0;
+ ngx_processes[s].just_spawn = 1;
+ ngx_processes[s].detached = 0;
+ break;
+
case NGX_PROCESS_RESPAWN:
ngx_processes[s].respawn = 1;
- ngx_processes[s].just_respawn = 0;
+ ngx_processes[s].just_spawn = 0;
ngx_processes[s].detached = 0;
break;
case NGX_PROCESS_JUST_RESPAWN:
ngx_processes[s].respawn = 1;
- ngx_processes[s].just_respawn = 1;
+ ngx_processes[s].just_spawn = 1;
ngx_processes[s].detached = 0;
break;
case NGX_PROCESS_DETACHED:
ngx_processes[s].respawn = 0;
- ngx_processes[s].just_respawn = 0;
+ ngx_processes[s].just_spawn = 0;
ngx_processes[s].detached = 1;
break;
}
diff --git a/src/os/unix/ngx_process.h b/src/os/unix/ngx_process.h
index a34ca6142..aba0b5169 100644
--- a/src/os/unix/ngx_process.h
+++ b/src/os/unix/ngx_process.h
@@ -27,7 +27,7 @@ typedef struct {
char *name;
unsigned respawn:1;
- unsigned just_respawn:1;
+ unsigned just_spawn:1;
unsigned detached:1;
unsigned exiting:1;
unsigned exited:1;
@@ -45,9 +45,10 @@ typedef struct {
#define NGX_MAX_PROCESSES 1024
#define NGX_PROCESS_NORESPAWN -1
-#define NGX_PROCESS_RESPAWN -2
-#define NGX_PROCESS_JUST_RESPAWN -3
-#define NGX_PROCESS_DETACHED -4
+#define NGX_PROCESS_JUST_SPAWN -2
+#define NGX_PROCESS_RESPAWN -3
+#define NGX_PROCESS_JUST_RESPAWN -4
+#define NGX_PROCESS_DETACHED -5
#define ngx_getpid getpid
diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c
index 1ee278fe8..69db458f5 100644
--- a/src/os/unix/ngx_process_cycle.c
+++ b/src/os/unix/ngx_process_cycle.c
@@ -12,7 +12,9 @@
static void ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n,
ngx_int_t type);
-static void ngx_start_cache_manager_process(ngx_cycle_t *cycle, ngx_int_t type);
+static void ngx_start_cache_manager_processes(ngx_cycle_t *cycle,
+ ngx_uint_t respawn);
+static void ngx_pass_open_channel(ngx_cycle_t *cycle, ngx_channel_t *ch);
static void ngx_signal_worker_processes(ngx_cycle_t *cycle, int signo);
static ngx_uint_t ngx_reap_children(ngx_cycle_t *cycle);
static void ngx_master_process_exit(ngx_cycle_t *cycle);
@@ -26,6 +28,7 @@ static ngx_thread_value_t ngx_worker_thread_cycle(void *data);
#endif
static void ngx_cache_manager_process_cycle(ngx_cycle_t *cycle, void *data);
static void ngx_cache_manager_process_handler(ngx_event_t *ev);
+static void ngx_cache_loader_process_handler(ngx_event_t *ev);
ngx_uint_t ngx_process;
@@ -62,6 +65,15 @@ u_long cpu_affinity;
static u_char master_process[] = "master process";
+static ngx_cache_manager_ctx_t ngx_cache_manager_ctx = {
+ ngx_cache_manager_process_handler, "cache manager process", 0
+};
+
+static ngx_cache_manager_ctx_t ngx_cache_loader_ctx = {
+ ngx_cache_loader_process_handler, "cache loader process", 60000
+};
+
+
static ngx_cycle_t ngx_exit_cycle;
static ngx_log_t ngx_exit_log;
static ngx_open_file_t ngx_exit_log_file;
@@ -123,7 +135,7 @@ ngx_master_process_cycle(ngx_cycle_t *cycle)
ngx_start_worker_processes(cycle, ccf->worker_processes,
NGX_PROCESS_RESPAWN);
- ngx_start_cache_manager_process(cycle, NGX_PROCESS_RESPAWN);
+ ngx_start_cache_manager_processes(cycle, 0);
ngx_new_binary = 0;
delay = 0;
@@ -207,7 +219,7 @@ ngx_master_process_cycle(ngx_cycle_t *cycle)
if (ngx_new_binary) {
ngx_start_worker_processes(cycle, ccf->worker_processes,
NGX_PROCESS_RESPAWN);
- ngx_start_cache_manager_process(cycle, NGX_PROCESS_RESPAWN);
+ ngx_start_cache_manager_processes(cycle, 0);
ngx_noaccepting = 0;
continue;
@@ -226,7 +238,7 @@ ngx_master_process_cycle(ngx_cycle_t *cycle)
ngx_core_module);
ngx_start_worker_processes(cycle, ccf->worker_processes,
NGX_PROCESS_JUST_RESPAWN);
- ngx_start_cache_manager_process(cycle, NGX_PROCESS_JUST_RESPAWN);
+ ngx_start_cache_manager_processes(cycle, 1);
live = 1;
ngx_signal_worker_processes(cycle,
ngx_signal_value(NGX_SHUTDOWN_SIGNAL));
@@ -236,7 +248,7 @@ ngx_master_process_cycle(ngx_cycle_t *cycle)
ngx_restart = 0;
ngx_start_worker_processes(cycle, ccf->worker_processes,
NGX_PROCESS_RESPAWN);
- ngx_start_cache_manager_process(cycle, NGX_PROCESS_RESPAWN);
+ ngx_start_cache_manager_processes(cycle, 0);
live = 1;
}
@@ -269,8 +281,6 @@ ngx_single_process_cycle(ngx_cycle_t *cycle)
{
ngx_uint_t i;
- ngx_init_temp_number();
-
for (i = 0; ngx_modules[i]; i++) {
if (ngx_modules[i]->init_process) {
if (ngx_modules[i]->init_process(cycle) == NGX_ERROR) {
@@ -321,7 +331,7 @@ ngx_single_process_cycle(ngx_cycle_t *cycle)
static void
ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type)
{
- ngx_int_t i, s;
+ ngx_int_t i;
ngx_channel_t ch;
ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start worker processes");
@@ -339,58 +349,70 @@ ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t n, ngx_int_t type)
ch.slot = ngx_process_slot;
ch.fd = ngx_processes[ngx_process_slot].channel[0];
- for (s = 0; s < ngx_last_process; s++) {
-
- if (s == ngx_process_slot
- || ngx_processes[s].pid == -1
- || ngx_processes[s].channel[0] == -1)
- {
- continue;
- }
-
- ngx_log_debug6(NGX_LOG_DEBUG_CORE, cycle->log, 0,
- "pass channel s:%d pid:%P fd:%d to s:%i pid:%P fd:%d",
- ch.slot, ch.pid, ch.fd,
- s, ngx_processes[s].pid,
- ngx_processes[s].channel[0]);
-
- /* TODO: NGX_AGAIN */
-
- ngx_write_channel(ngx_processes[s].channel[0],
- &ch, sizeof(ngx_channel_t), cycle->log);
- }
+ ngx_pass_open_channel(cycle, &ch);
}
}
static void
-ngx_start_cache_manager_process(ngx_cycle_t *cycle, ngx_int_t type)
+ngx_start_cache_manager_processes(ngx_cycle_t *cycle, ngx_uint_t respawn)
{
- ngx_int_t i;
- ngx_uint_t n;
+ ngx_uint_t i, manager, loader;
ngx_path_t **path;
ngx_channel_t ch;
+ manager = 0;
+ loader = 0;
+
path = ngx_cycle->pathes.elts;
- for (n = 0; n < ngx_cycle->pathes.nelts; n++) {
- if (path[n]->manager) {
- goto start;
+ for (i = 0; i < ngx_cycle->pathes.nelts; i++) {
+
+ if (path[i]->manager) {
+ manager = 1;
+ }
+
+ if (path[i]->loader) {
+ loader = 1;
}
}
- return;
+ if (manager == 0) {
+ return;
+ }
-start:
+ ngx_spawn_process(cycle, ngx_cache_manager_process_cycle,
+ &ngx_cache_manager_ctx, "cache manager process",
+ respawn ? NGX_PROCESS_JUST_RESPAWN : NGX_PROCESS_RESPAWN);
ch.command = NGX_CMD_OPEN_CHANNEL;
+ ch.pid = ngx_processes[ngx_process_slot].pid;
+ ch.slot = ngx_process_slot;
+ ch.fd = ngx_processes[ngx_process_slot].channel[0];
+
+ ngx_pass_open_channel(cycle, &ch);
- ngx_spawn_process(cycle, ngx_cache_manager_process_cycle, NULL,
- "cache manager process", type);
+ if (loader == 0) {
+ return;
+ }
+ ngx_spawn_process(cycle, ngx_cache_manager_process_cycle,
+ &ngx_cache_loader_ctx, "cache loader process",
+ respawn ? NGX_PROCESS_JUST_SPAWN : NGX_PROCESS_NORESPAWN);
+
+ ch.command = NGX_CMD_OPEN_CHANNEL;
ch.pid = ngx_processes[ngx_process_slot].pid;
ch.slot = ngx_process_slot;
ch.fd = ngx_processes[ngx_process_slot].channel[0];
+ ngx_pass_open_channel(cycle, &ch);
+}
+
+
+static void
+ngx_pass_open_channel(ngx_cycle_t *cycle, ngx_channel_t *ch)
+{
+ ngx_int_t i;
+
for (i = 0; i < ngx_last_process; i++) {
if (i == ngx_process_slot
@@ -402,14 +424,14 @@ start:
ngx_log_debug6(NGX_LOG_DEBUG_CORE, cycle->log, 0,
"pass channel s:%d pid:%P fd:%d to s:%i pid:%P fd:%d",
- ch.slot, ch.pid, ch.fd,
+ ch->slot, ch->pid, ch->fd,
i, ngx_processes[i].pid,
ngx_processes[i].channel[0]);
/* TODO: NGX_AGAIN */
ngx_write_channel(ngx_processes[i].channel[0],
- &ch, sizeof(ngx_channel_t), cycle->log);
+ ch, sizeof(ngx_channel_t), cycle->log);
}
}
@@ -460,14 +482,14 @@ ngx_signal_worker_processes(ngx_cycle_t *cycle, int signo)
ngx_processes[i].exited,
ngx_processes[i].detached,
ngx_processes[i].respawn,
- ngx_processes[i].just_respawn);
+ ngx_processes[i].just_spawn);
if (ngx_processes[i].detached || ngx_processes[i].pid == -1) {
continue;
}
- if (ngx_processes[i].just_respawn) {
- ngx_processes[i].just_respawn = 0;
+ if (ngx_processes[i].just_spawn) {
+ ngx_processes[i].just_spawn = 0;
continue;
}
@@ -536,7 +558,7 @@ ngx_reap_children(ngx_cycle_t *cycle)
ngx_processes[i].exited,
ngx_processes[i].detached,
ngx_processes[i].respawn,
- ngx_processes[i].just_respawn);
+ ngx_processes[i].just_spawn);
if (ngx_processes[i].pid == -1) {
continue;
@@ -593,26 +615,7 @@ ngx_reap_children(ngx_cycle_t *cycle)
ch.slot = ngx_process_slot;
ch.fd = ngx_processes[ngx_process_slot].channel[0];
- for (n = 0; n < ngx_last_process; n++) {
-
- if (n == ngx_process_slot
- || ngx_processes[n].pid == -1
- || ngx_processes[n].channel[0] == -1)
- {
- continue;
- }
-
- ngx_log_debug6(NGX_LOG_DEBUG_CORE, cycle->log, 0,
- "pass channel s:%d pid:%P fd:%d to s:%i pid:%P fd:%d",
- ch.slot, ch.pid, ch.fd,
- n, ngx_processes[n].pid,
- ngx_processes[n].channel[0]);
-
- /* TODO: NGX_AGAIN */
-
- ngx_write_channel(ngx_processes[n].channel[0],
- &ch, sizeof(ngx_channel_t), cycle->log);
- }
+ ngx_pass_open_channel(cycle, &ch);
live = 1;
@@ -928,8 +931,6 @@ ngx_worker_process_init(ngx_cycle_t *cycle, ngx_uint_t priority)
"sigprocmask() failed");
}
- ngx_init_temp_number();
-
/*
* disable deleting previous events for the listening sockets because
* in the worker processes there are no events at all at this point
@@ -1268,6 +1269,8 @@ ngx_worker_thread_cycle(void *data)
static void
ngx_cache_manager_process_cycle(ngx_cycle_t *cycle, void *data)
{
+ ngx_cache_manager_ctx_t *ctx = data;
+
void *ident[4];
ngx_event_t ev;
@@ -1278,16 +1281,16 @@ ngx_cache_manager_process_cycle(ngx_cycle_t *cycle, void *data)
ngx_close_listening_sockets(cycle);
ngx_memzero(&ev, sizeof(ngx_event_t));
- ev.handler = ngx_cache_manager_process_handler;
+ ev.handler = ctx->handler;
ev.data = ident;
ev.log = cycle->log;
ident[3] = (void *) -1;
ngx_use_accept_mutex = 0;
- ngx_setproctitle("cache manager process");
+ ngx_setproctitle(ctx->name);
- ngx_add_timer(&ev, 0);
+ ngx_add_timer(&ev, ctx->delay);
for ( ;; ) {
@@ -1334,3 +1337,29 @@ ngx_cache_manager_process_handler(ngx_event_t *ev)
ngx_add_timer(ev, next * 1000);
}
+
+
+static void
+ngx_cache_loader_process_handler(ngx_event_t *ev)
+{
+ ngx_uint_t i;
+ ngx_path_t **path;
+ ngx_cycle_t *cycle;
+
+ cycle = (ngx_cycle_t *) ngx_cycle;
+
+ path = cycle->pathes.elts;
+ for (i = 0; i < cycle->pathes.nelts; i++) {
+
+ if (ngx_terminate || ngx_quit) {
+ break;
+ }
+
+ if (path[i]->loader) {
+ path[i]->loader(path[i]->data);
+ ngx_time_update(0, 0);
+ }
+ }
+
+ exit(0);
+}
diff --git a/src/os/unix/ngx_process_cycle.h b/src/os/unix/ngx_process_cycle.h
index 9bf04749f..f46ad463f 100644
--- a/src/os/unix/ngx_process_cycle.h
+++ b/src/os/unix/ngx_process_cycle.h
@@ -25,6 +25,13 @@
#define NGX_PROCESS_SIGNALLER 3
+typedef struct {
+ ngx_event_handler_pt handler;
+ char *name;
+ ngx_msec_t delay;
+} ngx_cache_manager_ctx_t;
+
+
void ngx_master_process_cycle(ngx_cycle_t *cycle);
void ngx_single_process_cycle(ngx_cycle_t *cycle);