summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2011-11-14 15:42:44 +0000
committerJonathan Kolb <jon@b0g.us>2011-11-14 15:42:44 +0000
commitfe0ffd542b079021418c77ba3281df919ed1bf71 (patch)
tree7e8222ce923ee4353714a2018c27b1fc72bb42cb
parent156a15693d0135dc47addb295c1519cf9d29abf9 (diff)
downloadnginx-fe0ffd542b079021418c77ba3281df919ed1bf71.tar.gz
Changes with nginx 1.1.8 14 Nov 2011v1.1.8
*) Change: the ngx_http_limit_zone_module was renamed to the ngx_http_limit_conn_module. *) Change: the "limit_zone" directive was superseded by the "limit_conn_zone" directive with a new syntax. *) Feature: support for multiple "limit_conn" limits on the same level. *) Feature: the "image_filter_sharpen" directive. *) Bugfix: a segmentation fault might occur in a worker process if resolver got a big DNS response. Thanks to Ben Hawkes. *) Bugfix: in cache key calculation if internal MD5 implementation was used; the bug had appeared in 1.0.4. *) Bugfix: the "If-Modified-Since", "If-Range", etc. client request header lines might be passed to backend while caching; or not passed without caching if caching was enabled in another part of the configuration. *) Bugfix: the module ngx_http_mp4_module sent incorrect "Content-Length" response header line if the "start" argument was used. Thanks to Piotr Sikora.
-rw-r--r--CHANGES38
-rw-r--r--CHANGES.ru30
-rw-r--r--auto/modules6
-rw-r--r--auto/options14
-rw-r--r--auto/sources4
-rw-r--r--auto/summary2
-rw-r--r--conf/mime.types2
-rw-r--r--src/core/nginx.c38
-rw-r--r--src/core/nginx.h4
-rw-r--r--src/core/ngx_log.h16
-rw-r--r--src/core/ngx_md5.c3
-rw-r--r--src/core/ngx_resolver.c14
-rw-r--r--src/http/modules/ngx_http_fastcgi_module.c156
-rw-r--r--src/http/modules/ngx_http_image_filter_module.c72
-rw-r--r--src/http/modules/ngx_http_limit_conn_module.c751
-rw-r--r--src/http/modules/ngx_http_limit_zone_module.c556
-rw-r--r--src/http/modules/ngx_http_mp4_module.c3
-rw-r--r--src/http/modules/ngx_http_proxy_module.c62
-rw-r--r--src/http/modules/ngx_http_scgi_module.c152
-rw-r--r--src/http/modules/ngx_http_ssi_filter_module.c4
-rw-r--r--src/http/modules/ngx_http_ssl_module.c2
-rw-r--r--src/http/modules/ngx_http_uwsgi_module.c150
-rw-r--r--src/http/modules/perl/nginx.pm2
-rw-r--r--src/http/ngx_http_core_module.c16
-rw-r--r--src/http/ngx_http_request.h2
-rw-r--r--src/mail/ngx_mail_proxy_module.c2
-rw-r--r--src/os/unix/ngx_files.h1
27 files changed, 1296 insertions, 806 deletions
diff --git a/CHANGES b/CHANGES
index 1b10e40bd..8eb55250d 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,15 +1,45 @@
+Changes with nginx 1.1.8 14 Nov 2011
+
+ *) Change: the ngx_http_limit_zone_module was renamed to the
+ ngx_http_limit_conn_module.
+
+ *) Change: the "limit_zone" directive was superseded by the
+ "limit_conn_zone" directive with a new syntax.
+
+ *) Feature: support for multiple "limit_conn" limits on the same level.
+
+ *) Feature: the "image_filter_sharpen" directive.
+
+ *) Bugfix: a segmentation fault might occur in a worker process if
+ resolver got a big DNS response.
+ Thanks to Ben Hawkes.
+
+ *) Bugfix: in cache key calculation if internal MD5 implementation was
+ used; the bug had appeared in 1.0.4.
+
+ *) Bugfix: the "If-Modified-Since", "If-Range", etc. client request
+ header lines might be passed to backend while caching; or not passed
+ without caching if caching was enabled in another part of the
+ configuration.
+
+ *) Bugfix: the module ngx_http_mp4_module sent incorrect
+ "Content-Length" response header line if the "start" argument was
+ used.
+ Thanks to Piotr Sikora.
+
+
Changes with nginx 1.1.7 31 Oct 2011
- *) Feature: support of several resolvers in the "resolver" directive.
+ *) Feature: support of several DNS servers in the "resolver" directive.
Thanks to Kirill A. Korinskiy.
- *) Bugfix: a segmentation fault occurred on start or while
+ *) Bugfix: a segmentation fault occurred on start or during
reconfiguration if the "ssl" directive was used at http level and
there was no "ssl_certificate" defined.
- *) Bugfix: reduced memory consumption while proxying of big files if
- they were buffered to disk.
+ *) Bugfix: reduced memory consumption while proxying big files if they
+ were buffered to disk.
*) Bugfix: a segmentation fault might occur in a worker process if
"proxy_http_version 1.1" directive was used.
diff --git a/CHANGES.ru b/CHANGES.ru
index b644af99f..350b64b69 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,34 @@
+Изменения в nginx 1.1.8 14.11.2011
+
+ *) Изменение: модуль ngx_http_limit_zone_module переименован в
+ ngx_http_limit_conn_module.
+
+ *) Изменение: директива limit_zone заменена директивой limit_conn_zone с
+ новым синтаксисом.
+
+ *) Добавление: поддержка ограничения по нескольким limit_conn на одном
+ уровне.
+
+ *) Добавление: директива image_filter_sharpen.
+
+ *) Исправление: в рабочем процессе мог произойти segmentation fault,
+ если resolver получил большой DNS-ответ.
+ Спасибо Ben Hawkes.
+
+ *) Исправление: в вычислении ключа для кэширования, если использовалась
+ внутренняя реализация MD5; ошибка появилась в 1.0.4.
+
+ *) Исправление: строки "If-Modified-Since", "If-Range" и им подобные в
+ заголовке запроса клиента могли передаваться бэкенду при кэшировании;
+ или не передаваться при выключенном кэшировании, если кэширование
+ было включено в другой части конфигурации.
+
+ *) Исправление: модуль ngx_http_mp4_module выдавал неверную строку
+ "Content-Length" в заголовке ответа, использовался аргумент start.
+ Спасибо Piotr Sikora.
+
+
Изменения в nginx 1.1.7 31.10.2011
*) Добавление: поддержка нескольких DNS серверов в директиве "resolver".
diff --git a/auto/modules b/auto/modules
index 57f0f89e7..a8607eefc 100644
--- a/auto/modules
+++ b/auto/modules
@@ -210,9 +210,9 @@ if [ $HTTP_ACCESS = YES ]; then
HTTP_SRCS="$HTTP_SRCS $HTTP_ACCESS_SRCS"
fi
-if [ $HTTP_LIMIT_ZONE = YES ]; then
- HTTP_MODULES="$HTTP_MODULES $HTTP_LIMIT_ZONE_MODULE"
- HTTP_SRCS="$HTTP_SRCS $HTTP_LIMIT_ZONE_SRCS"
+if [ $HTTP_LIMIT_CONN = YES ]; then
+ HTTP_MODULES="$HTTP_MODULES $HTTP_LIMIT_CONN_MODULE"
+ HTTP_SRCS="$HTTP_SRCS $HTTP_LIMIT_CONN_SRCS"
fi
if [ $HTTP_LIMIT_REQ = YES ]; then
diff --git a/auto/options b/auto/options
index a79f311d3..e8de4ff45 100644
--- a/auto/options
+++ b/auto/options
@@ -85,7 +85,7 @@ HTTP_UWSGI=YES
HTTP_SCGI=YES
HTTP_PERL=NO
HTTP_MEMCACHED=YES
-HTTP_LIMIT_ZONE=YES
+HTTP_LIMIT_CONN=YES
HTTP_LIMIT_REQ=YES
HTTP_EMPTY_GIF=YES
HTTP_BROWSER=YES
@@ -143,6 +143,8 @@ NGX_LIBATOMIC=NO
NGX_CPU_CACHE_LINE=
+NGX_POST_CONF_MSG=
+
opt=
for option
@@ -227,7 +229,13 @@ do
--without-http_uwsgi_module) HTTP_UWSGI=NO ;;
--without-http_scgi_module) HTTP_SCGI=NO ;;
--without-http_memcached_module) HTTP_MEMCACHED=NO ;;
- --without-http_limit_zone_module) HTTP_LIMIT_ZONE=NO ;;
+ --without-http_limit_zone_module)
+ HTTP_LIMIT_CONN=NO
+ NGX_POST_CONF_MSG="$NGX_POST_CONF_MSG
+$0: warning: the \"--without-http_limit_zone_module\" option is deprecated, \
+use the \"--without-http_limit_conn_module\" option instead"
+ ;;
+ --without-http_limit_conn_module) HTTP_LIMIT_CONN=NO ;;
--without-http_limit_req_module) HTTP_LIMIT_REQ=NO ;;
--without-http_empty_gif_module) HTTP_EMPTY_GIF=NO ;;
--without-http_browser_module) HTTP_BROWSER=NO ;;
@@ -364,7 +372,7 @@ cat << END
--without-http_uwsgi_module disable ngx_http_uwsgi_module
--without-http_scgi_module disable ngx_http_scgi_module
--without-http_memcached_module disable ngx_http_memcached_module
- --without-http_limit_zone_module disable ngx_http_limit_zone_module
+ --without-http_limit_conn_module disable ngx_http_limit_conn_module
--without-http_limit_req_module disable ngx_http_limit_req_module
--without-http_empty_gif_module disable ngx_http_empty_gif_module
--without-http_browser_module disable ngx_http_browser_module
diff --git a/auto/sources b/auto/sources
index 6c973f66b..24fa3b89f 100644
--- a/auto/sources
+++ b/auto/sources
@@ -435,8 +435,8 @@ HTTP_MEMCACHED_MODULE=ngx_http_memcached_module
HTTP_MEMCACHED_SRCS=src/http/modules/ngx_http_memcached_module.c
-HTTP_LIMIT_ZONE_MODULE=ngx_http_limit_zone_module
-HTTP_LIMIT_ZONE_SRCS=src/http/modules/ngx_http_limit_zone_module.c
+HTTP_LIMIT_CONN_MODULE=ngx_http_limit_conn_module
+HTTP_LIMIT_CONN_SRCS=src/http/modules/ngx_http_limit_conn_module.c
HTTP_LIMIT_REQ_MODULE=ngx_http_limit_req_module
diff --git a/auto/summary b/auto/summary
index 010a5be49..c65946c31 100644
--- a/auto/summary
+++ b/auto/summary
@@ -111,3 +111,5 @@ fi
if [ $HTTP_SCGI = YES ]; then
echo " nginx http scgi temporary files: \"$NGX_HTTP_SCGI_TEMP_PATH\""
fi
+
+echo "$NGX_POST_CONF_MSG"
diff --git a/conf/mime.types b/conf/mime.types
index 24e866e8f..0c4a00d59 100644
--- a/conf/mime.types
+++ b/conf/mime.types
@@ -22,6 +22,7 @@ types {
image/x-jng jng;
image/x-ms-bmp bmp;
image/svg+xml svg;
+ image/webp webp;
application/java-archive jar war ear;
application/mac-binhex40 hqx;
@@ -69,6 +70,7 @@ types {
video/mp4 mp4;
video/mpeg mpeg mpg;
video/quicktime mov;
+ video/webm webm;
video/x-flv flv;
video/x-m4v m4v;
video/x-mng mng;
diff --git a/src/core/nginx.c b/src/core/nginx.c
index da32c1a50..9e00a2d86 100644
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -214,47 +214,49 @@ main(int argc, char *const *argv)
}
if (ngx_show_version) {
- ngx_log_stderr(0, "nginx version: " NGINX_VER);
+ ngx_write_stderr("nginx version: " NGINX_VER NGX_LINEFEED);
if (ngx_show_help) {
- ngx_log_stderr(0,
+ ngx_write_stderr(
"Usage: nginx [-?hvVtq] [-s signal] [-c filename] "
- "[-p prefix] [-g directives]" CRLF CRLF
- "Options:" CRLF
- " -?,-h : this help" CRLF
- " -v : show version and exit" CRLF
+ "[-p prefix] [-g directives]" NGX_LINEFEED
+ NGX_LINEFEED
+ "Options:" NGX_LINEFEED
+ " -?,-h : this help" NGX_LINEFEED
+ " -v : show version and exit" NGX_LINEFEED
" -V : show version and configure options then exit"
- CRLF
- " -t : test configuration and exit" CRLF
+ NGX_LINEFEED
+ " -t : test configuration and exit" NGX_LINEFEED
" -q : suppress non-error messages "
- "during configuration testing" CRLF
+ "during configuration testing" NGX_LINEFEED
" -s signal : send signal to a master process: "
- "stop, quit, reopen, reload" CRLF
+ "stop, quit, reopen, reload" NGX_LINEFEED
#ifdef NGX_PREFIX
" -p prefix : set prefix path (default: "
- NGX_PREFIX ")" CRLF
+ NGX_PREFIX ")" NGX_LINEFEED
#else
- " -p prefix : set prefix path (default: NONE)" CRLF
+ " -p prefix : set prefix path (default: NONE)" NGX_LINEFEED
#endif
" -c filename : set configuration file (default: "
- NGX_CONF_PATH ")" CRLF
+ NGX_CONF_PATH ")" NGX_LINEFEED
" -g directives : set global directives out of configuration "
- "file" CRLF
+ "file" NGX_LINEFEED NGX_LINEFEED
);
}
if (ngx_show_configure) {
+ ngx_write_stderr(
#ifdef NGX_COMPILER
- ngx_log_stderr(0, "built by " NGX_COMPILER);
+ "built by " NGX_COMPILER NGX_LINEFEED
#endif
#if (NGX_SSL)
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
- ngx_log_stderr(0, "TLS SNI support enabled");
+ "TLS SNI support enabled" NGX_LINEFEED
#else
- ngx_log_stderr(0, "TLS SNI support disabled");
+ "TLS SNI support disabled" NGX_LINEFEED
#endif
#endif
- ngx_log_stderr(0, "configure arguments:" NGX_CONFIGURE);
+ "configure arguments:" NGX_CONFIGURE NGX_LINEFEED);
}
if (!ngx_test_config) {
diff --git a/src/core/nginx.h b/src/core/nginx.h
index 631b83f76..4b8badc02 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,8 +8,8 @@
#define _NGINX_H_INCLUDED_
-#define nginx_version 1001007
-#define NGINX_VERSION "1.1.7"
+#define nginx_version 1001008
+#define NGINX_VERSION "1.1.8"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
diff --git a/src/core/ngx_log.h b/src/core/ngx_log.h
index 1054836f1..a55ef449c 100644
--- a/src/core/ngx_log.h
+++ b/src/core/ngx_log.h
@@ -203,6 +203,22 @@ void ngx_cdecl ngx_log_stderr(ngx_err_t err, const char *fmt, ...);
u_char *ngx_log_errno(u_char *buf, u_char *last, ngx_err_t err);
+/*
+ * ngx_write_stderr() cannot be implemented as macro, since
+ * MSVC does not allow to use #ifdef inside macro parameters.
+ *
+ * ngx_write_fd() is used instead of ngx_write_console(), since
+ * CharToOemBuff() inside ngx_write_console() cannot be used with
+ * read only buffer as destination and CharToOemBuff() is not needed
+ * for ngx_write_stderr() anyway.
+ */
+static ngx_inline void
+ngx_write_stderr(char *text)
+{
+ (void) ngx_write_fd(ngx_stderr, text, strlen(text));
+}
+
+
extern ngx_module_t ngx_errlog_module;
extern ngx_uint_t ngx_use_stderr;
diff --git a/src/core/ngx_md5.c b/src/core/ngx_md5.c
index 09a93991e..440c75bca 100644
--- a/src/core/ngx_md5.c
+++ b/src/core/ngx_md5.c
@@ -47,7 +47,8 @@ ngx_md5_update(ngx_md5_t *ctx, const void *data, size_t size)
return;
}
- data = ngx_cpymem(&ctx->buffer[used], data, free);
+ ngx_memcpy(&ctx->buffer[used], data, free);
+ data = (u_char *) data + free;
size -= free;
(void) ngx_md5_body(ctx, ctx->buffer, 64);
}
diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c
index 268faa456..35818a7ae 100644
--- a/src/core/ngx_resolver.c
+++ b/src/core/ngx_resolver.c
@@ -1952,7 +1952,13 @@ done:
n = *src++;
for ( ;; ) {
- if (n != 0xc0) {
+ if (n & 0xc0) {
+ n = ((n & 0x3f) << 8) + *src;
+ src = &buf[n];
+
+ n = *src++;
+
+ } else {
ngx_memcpy(dst, src, n);
dst += n;
src += n;
@@ -1962,12 +1968,6 @@ done:
if (n != 0) {
*dst++ = '.';
}
-
- } else {
- n = ((n & 0x3f) << 8) + *src;
- src = &buf[n];
-
- n = *src++;
}
if (n == 0) {
diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c
index 6f639acc2..2dc56c76b 100644
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -147,6 +147,9 @@ static ngx_int_t ngx_http_fastcgi_add_variables(ngx_conf_t *cf);
static void *ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf);
static char *ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf,
void *parent, void *child);
+static ngx_int_t ngx_http_fastcgi_merge_params(ngx_conf_t *cf,
+ ngx_http_fastcgi_loc_conf_t *conf, ngx_http_fastcgi_loc_conf_t *prev);
+
static ngx_int_t ngx_http_fastcgi_script_name_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t data);
static ngx_int_t ngx_http_fastcgi_path_info_variable(ngx_http_request_t *r,
@@ -436,7 +439,7 @@ static ngx_command_t ngx_http_fastcgi_commands[] = {
&ngx_http_upstream_ignore_headers_masks },
{ ngx_string("fastcgi_catch_stderr"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_str_array_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_fastcgi_loc_conf_t, catch_stderr),
@@ -2085,17 +2088,9 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_http_fastcgi_loc_conf_t *prev = parent;
ngx_http_fastcgi_loc_conf_t *conf = child;
- u_char *p;
size_t size;
- uintptr_t *code;
- ngx_uint_t i;
- ngx_array_t headers_names;
- ngx_keyval_t *src;
- ngx_hash_key_t *hk;
ngx_hash_init_t hash;
ngx_http_core_loc_conf_t *clcf;
- ngx_http_script_compile_t sc;
- ngx_http_script_copy_code_t *copy;
if (conf->upstream.store != 0) {
ngx_conf_merge_value(conf->upstream.store,
@@ -2355,95 +2350,146 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
}
#endif
- if (conf->params_source == NULL) {
- conf->flushes = prev->flushes;
- conf->params_len = prev->params_len;
- conf->params = prev->params;
- conf->params_source = prev->params_source;
- conf->headers_hash = prev->headers_hash;
+ if (ngx_http_fastcgi_merge_params(cf, conf, prev) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
-#if (NGX_HTTP_CACHE)
+ return NGX_CONF_OK;
+}
- if (conf->params_source == NULL) {
- if ((conf->upstream.cache == NULL)
- == (prev->upstream.cache == NULL))
- {
- return NGX_CONF_OK;
- }
+static ngx_int_t
+ngx_http_fastcgi_merge_params(ngx_conf_t *cf,
+ ngx_http_fastcgi_loc_conf_t *conf, ngx_http_fastcgi_loc_conf_t *prev)
+{
+ u_char *p;
+ size_t size;
+ uintptr_t *code;
+ ngx_uint_t i, nsrc;
+ ngx_array_t headers_names;
+#if (NGX_HTTP_CACHE)
+ ngx_array_t params_merged;
+#endif
+ ngx_keyval_t *src;
+ ngx_hash_key_t *hk;
+ ngx_hash_init_t hash;
+ ngx_http_script_compile_t sc;
+ ngx_http_script_copy_code_t *copy;
- /* 6 is a number of ngx_http_fastcgi_cache_headers entries */
- conf->params_source = ngx_array_create(cf->pool, 6,
- sizeof(ngx_keyval_t));
- if (conf->params_source == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-#else
+ if (conf->params_source == NULL) {
+ conf->params_source = prev->params_source;
- if (conf->params_source == NULL) {
- return NGX_CONF_OK;
+ if (prev->headers_hash.buckets
+#if (NGX_HTTP_CACHE)
+ && ((conf->upstream.cache == NULL) == (prev->upstream.cache == NULL))
+#endif
+ )
+ {
+ conf->flushes = prev->flushes;
+ conf->params_len = prev->params_len;
+ conf->params = prev->params;
+ conf->headers_hash = prev->headers_hash;
+ conf->header_params = prev->header_params;
+
+ return NGX_OK;
}
+ }
+ if (conf->params_source == NULL
+#if (NGX_HTTP_CACHE)
+ && (conf->upstream.cache == NULL)
#endif
+ )
+ {
+ conf->headers_hash.buckets = (void *) 1;
+ return NGX_OK;
}
conf->params_len = ngx_array_create(cf->pool, 64, 1);
if (conf->params_len == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
conf->params = ngx_array_create(cf->pool, 512, 1);
if (conf->params == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
if (ngx_array_init(&headers_names, cf->temp_pool, 4, sizeof(ngx_hash_key_t))
!= NGX_OK)
{
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
- src = conf->params_source->elts;
+ if (conf->params_source) {
+ src = conf->params_source->elts;
+ nsrc = conf->params_source->nelts;
+
+ } else {
+ src = NULL;
+ nsrc = 0;
+ }
#if (NGX_HTTP_CACHE)
if (conf->upstream.cache) {
ngx_keyval_t *h, *s;
- for (h = ngx_http_fastcgi_cache_headers; h->key.len; h++) {
+ if (ngx_array_init(&params_merged, cf->temp_pool, 4, sizeof(ngx_keyval_t))
+ != NGX_OK)
+ {
+ return NGX_ERROR;
+ }
+
+ for (i = 0; i < nsrc; i++) {
+
+ s = ngx_array_push(&params_merged);
+ if (s == NULL) {
+ return NGX_ERROR;
+ }
+
+ *s = src[i];
+ }
+
+ h = ngx_http_fastcgi_cache_headers;
+
+ while (h->key.len) {
+
+ src = params_merged.elts;
+ nsrc = params_merged.nelts;
- for (i = 0; i < conf->params_source->nelts; i++) {
+ for (i = 0; i < nsrc; i++) {
if (ngx_strcasecmp(h->key.data, src[i].key.data) == 0) {
goto next;
}
}
- s = ngx_array_push(conf->params_source);
+ s = ngx_array_push(&params_merged);
if (s == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
*s = *h;
- src = conf->params_source->elts;
-
next:
h++;
}
+
+ src = params_merged.elts;
+ nsrc = params_merged.nelts;
}
#endif
- for (i = 0; i < conf->params_source->nelts; i++) {
+ for (i = 0; i < nsrc; i++) {
if (src[i].key.len > sizeof("HTTP_") - 1
&& ngx_strncmp(src[i].key.data, "HTTP_", sizeof("HTTP_") - 1) == 0)
{
hk = ngx_array_push(&headers_names);
if (hk == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
hk->key.len = src[i].key.len - 5;
@@ -2459,7 +2505,7 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
copy = ngx_array_push_n(conf->params_len,
sizeof(ngx_http_script_copy_code_t));
if (copy == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code;
@@ -2468,11 +2514,11 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
size = (sizeof(ngx_http_script_copy_code_t)
+ src[i].key.len + sizeof(uintptr_t) - 1)
- & ~(sizeof(uintptr_t) - 1);
+ & ~(sizeof(uintptr_t) - 1);
copy = ngx_array_push_n(conf->params, size);
if (copy == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
copy->code = ngx_http_script_copy_code;
@@ -2491,12 +2537,12 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
sc.values = &conf->params;
if (ngx_http_script_compile(&sc) != NGX_OK) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t));
if (code == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
*code = (uintptr_t) NULL;
@@ -2504,7 +2550,7 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
code = ngx_array_push_n(conf->params, sizeof(uintptr_t));
if (code == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
*code = (uintptr_t) NULL;
@@ -2512,12 +2558,11 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t));
if (code == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
*code = (uintptr_t) NULL;
-
conf->header_params = headers_names.nelts;
hash.hash = &conf->headers_hash;
@@ -2528,12 +2573,7 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
hash.pool = cf->pool;
hash.temp_pool = NULL;
- if (ngx_hash_init(&hash, headers_names.elts, headers_names.nelts) != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
+ return ngx_hash_init(&hash, headers_names.elts, headers_names.nelts);
}
diff --git a/src/http/modules/ngx_http_image_filter_module.c b/src/http/modules/ngx_http_image_filter_module.c
index dd3803fe3..31f26ec50 100644
--- a/src/http/modules/ngx_http_image_filter_module.c
+++ b/src/http/modules/ngx_http_image_filter_module.c
@@ -41,6 +41,7 @@ typedef struct {
ngx_uint_t height;
ngx_uint_t angle;
ngx_uint_t jpeg_quality;
+ ngx_uint_t sharpen;
ngx_flag_t transparency;
@@ -48,6 +49,7 @@ typedef struct {
ngx_http_complex_value_t *hcv;
ngx_http_complex_value_t *acv;
ngx_http_complex_value_t *jqcv;
+ ngx_http_complex_value_t *shcv;
size_t buffer_size;
} ngx_http_image_filter_conf_t;
@@ -105,6 +107,8 @@ static char *ngx_http_image_filter(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char *ngx_http_image_filter_jpeg_quality(ngx_conf_t *cf,
ngx_command_t *cmd, void *conf);
+static char *ngx_http_image_filter_sharpen(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
static ngx_int_t ngx_http_image_filter_init(ngx_conf_t *cf);
@@ -124,6 +128,13 @@ static ngx_command_t ngx_http_image_filter_commands[] = {
0,
NULL },
+ { ngx_string("image_filter_sharpen"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_http_image_filter_sharpen,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ 0,
+ 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,
@@ -724,7 +735,7 @@ 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, ax, ay, size,
- colors, palette, transparent,
+ colors, palette, transparent, sharpen,
red, green, blue, t;
u_char *out;
ngx_buf_t *b;
@@ -948,6 +959,11 @@ transparent:
gdImageColorTransparent(dst, gdImageColorExact(dst, red, green, blue));
}
+ sharpen = ngx_http_image_filter_get_value(r, conf->shcv, conf->sharpen);
+ if (sharpen > 0) {
+ gdImageSharpen(dst, sharpen);
+ }
+
out = ngx_http_image_out(r, ctx->type, dst, &size);
ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@@ -1156,6 +1172,7 @@ ngx_http_image_filter_create_conf(ngx_conf_t *cf)
conf->filter = NGX_CONF_UNSET_UINT;
conf->jpeg_quality = NGX_CONF_UNSET_UINT;
+ conf->sharpen = NGX_CONF_UNSET_UINT;
conf->angle = NGX_CONF_UNSET_UINT;
conf->transparency = NGX_CONF_UNSET;
conf->buffer_size = NGX_CONF_UNSET_SIZE;
@@ -1191,6 +1208,12 @@ ngx_http_image_filter_merge_conf(ngx_conf_t *cf, void *parent, void *child)
conf->jqcv = prev->jqcv;
}
+ ngx_conf_merge_uint_value(conf->sharpen, prev->sharpen, 0);
+
+ if (conf->shcv == NULL) {
+ conf->shcv = prev->shcv;
+ }
+
ngx_conf_merge_uint_value(conf->angle, prev->angle, 0);
if (conf->acv == NULL) {
conf->acv = prev->acv;
@@ -1401,6 +1424,53 @@ ngx_http_image_filter_jpeg_quality(ngx_conf_t *cf, ngx_command_t *cmd,
}
+static char *
+ngx_http_image_filter_sharpen(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_http_complex_value_t cv;
+ ngx_http_compile_complex_value_t ccv;
+
+ value = cf->args->elts;
+
+ ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
+
+ ccv.cf = cf;
+ ccv.value = &value[1];
+ ccv.complex_value = &cv;
+
+ if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ if (cv.lengths == NULL) {
+ n = ngx_http_image_filter_value(&value[1]);
+
+ if (n < 0) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid parameter \"%V\"", &value[1]);
+ return NGX_CONF_ERROR;
+ }
+
+ imcf->sharpen = (ngx_uint_t) n;
+
+ } else {
+ imcf->shcv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
+ if (imcf->shcv == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ *imcf->shcv = cv;
+ }
+
+ return NGX_CONF_OK;
+}
+
+
static ngx_int_t
ngx_http_image_filter_init(ngx_conf_t *cf)
{
diff --git a/src/http/modules/ngx_http_limit_conn_module.c b/src/http/modules/ngx_http_limit_conn_module.c
new file mode 100644
index 000000000..a84d54d7e
--- /dev/null
+++ b/src/http/modules/ngx_http_limit_conn_module.c
@@ -0,0 +1,751 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_http.h>
+
+
+typedef struct {
+ u_char color;
+ u_char len;
+ u_short conn;
+ u_char data[1];
+} ngx_http_limit_conn_node_t;
+
+
+typedef struct {
+ ngx_shm_zone_t *shm_zone;
+ ngx_rbtree_node_t *node;
+} ngx_http_limit_conn_cleanup_t;
+
+
+typedef struct {
+ ngx_rbtree_t *rbtree;
+ ngx_int_t index;
+ ngx_str_t var;
+} ngx_http_limit_conn_ctx_t;
+
+
+typedef struct {
+ ngx_shm_zone_t *shm_zone;
+ ngx_uint_t conn;
+} ngx_http_limit_conn_limit_t;
+
+
+typedef struct {
+ ngx_array_t limits;
+ ngx_uint_t log_level;
+} ngx_http_limit_conn_conf_t;
+
+
+static ngx_rbtree_node_t *ngx_http_limit_conn_lookup(ngx_rbtree_t *rbtree,
+ ngx_http_variable_value_t *vv, uint32_t hash);
+static void ngx_http_limit_conn_cleanup(void *data);
+static ngx_inline void ngx_http_limit_conn_cleanup_all(ngx_pool_t *pool);
+
+static void *ngx_http_limit_conn_create_conf(ngx_conf_t *cf);
+static char *ngx_http_limit_conn_merge_conf(ngx_conf_t *cf, void *parent,
+ void *child);
+static char *ngx_http_limit_conn_zone(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
+static char *ngx_http_limit_zone(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
+static char *ngx_http_limit_conn(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
+static ngx_int_t ngx_http_limit_conn_init(ngx_conf_t *cf);
+
+
+static ngx_conf_deprecated_t ngx_conf_deprecated_limit_zone = {
+ ngx_conf_deprecated, "limit_zone", "limit_conn_zone"
+};
+
+
+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_conn_commands[] = {
+
+ { ngx_string("limit_conn_zone"),
+ NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE2,
+ ngx_http_limit_conn_zone,
+ 0,
+ 0,
+ NULL },
+
+ { ngx_string("limit_zone"),
+ NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE3,
+ ngx_http_limit_zone,
+ 0,
+ 0,
+ NULL },
+
+ { ngx_string("limit_conn"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
+ ngx_http_limit_conn,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ 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_conn_conf_t, log_level),
+ &ngx_http_limit_conn_log_levels },
+
+ ngx_null_command
+};
+
+
+static ngx_http_module_t ngx_http_limit_conn_module_ctx = {
+ NULL, /* preconfiguration */
+ ngx_http_limit_conn_init, /* postconfiguration */
+
+ NULL, /* create main configuration */
+ NULL, /* init main configuration */
+
+ NULL, /* create server configuration */
+ NULL, /* merge server configuration */
+
+ ngx_http_limit_conn_create_conf, /* create location configration */
+ ngx_http_limit_conn_merge_conf /* merge location configration */
+};
+
+
+ngx_module_t ngx_http_limit_conn_module = {
+ NGX_MODULE_V1,
+ &ngx_http_limit_conn_module_ctx, /* module context */
+ ngx_http_limit_conn_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_int_t
+ngx_http_limit_conn_handler(ngx_http_request_t *r)
+{
+ size_t len, n;
+ uint32_t hash;
+ ngx_uint_t i;
+ ngx_slab_pool_t *shpool;
+ ngx_rbtree_node_t *node;
+ ngx_pool_cleanup_t *cln;
+ ngx_http_variable_value_t *vv;
+ ngx_http_limit_conn_ctx_t *ctx;
+ ngx_http_limit_conn_node_t *lc;
+ ngx_http_limit_conn_conf_t *lccf;
+ ngx_http_limit_conn_limit_t *limits;
+ ngx_http_limit_conn_cleanup_t *lccln;
+
+ if (r->main->limit_conn_set) {
+ return NGX_DECLINED;
+ }
+
+ r->main->limit_conn_set = 1;
+
+ lccf = ngx_http_get_module_loc_conf(r, ngx_http_limit_conn_module);
+ limits = lccf->limits.elts;
+
+ for (i = 0; i < lccf->limits.nelts; i++) {
+ ctx = limits[i].shm_zone->data;
+
+ vv = ngx_http_get_indexed_variable(r, ctx->index);
+
+ if (vv == NULL || vv->not_found) {
+ continue;
+ }
+
+ len = vv->len;
+
+ if (len == 0) {
+ continue;
+ }
+
+ if (len > 255) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+ "the value of the \"%V\" variable "
+ "is more than 255 bytes: \"%v\"",
+ &ctx->var, vv);
+ continue;
+ }
+
+ hash = ngx_crc32_short(vv->data, len);
+
+ shpool = (ngx_slab_pool_t *) limits[i].shm_zone->shm.addr;
+
+ ngx_shmtx_lock(&shpool->mutex);
+
+ node = ngx_http_limit_conn_lookup(ctx->rbtree, vv, hash);
+
+ if (node == NULL) {
+
+ n = offsetof(ngx_rbtree_node_t, color)
+ + offsetof(ngx_http_limit_conn_node_t, data)
+ + len;
+
+ node = ngx_slab_alloc_locked(shpool, n);
+
+ if (node == NULL) {
+ ngx_shmtx_unlock(&shpool->mutex);
+ ngx_http_limit_conn_cleanup_all(r->pool);
+ return NGX_HTTP_SERVICE_UNAVAILABLE;
+ }
+
+ lc = (ngx_http_limit_conn_node_t *) &node->color;
+
+ node->key = hash;
+ lc->len = (u_char) len;
+ lc->conn = 1;
+ ngx_memcpy(lc->data, vv->data, len);
+
+ ngx_rbtree_insert(ctx->rbtree, node);
+
+ } else {
+
+ lc = (ngx_http_limit_conn_node_t *) &node->color;
+
+ if ((ngx_uint_t) lc->conn >= limits[i].conn) {
+
+ ngx_shmtx_unlock(&shpool->mutex);
+
+ ngx_log_error(lccf->log_level, r->connection->log, 0,
+ "limiting connections by zone \"%V\"",
+ &limits[i].shm_zone->shm.name);
+
+ ngx_http_limit_conn_cleanup_all(r->pool);
+ return NGX_HTTP_SERVICE_UNAVAILABLE;
+ }
+
+ lc->conn++;
+ }
+
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "limit zone: %08XD %d", node->key, lc->conn);
+
+ ngx_shmtx_unlock(&shpool->mutex);
+
+ cln = ngx_pool_cleanup_add(r->pool,
+ sizeof(ngx_http_limit_conn_cleanup_t));
+ if (cln == NULL) {
+ return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ }
+
+ cln->handler = ngx_http_limit_conn_cleanup;
+ lccln = cln->data;
+
+ lccln->shm_zone = limits[i].shm_zone;
+ lccln->node = node;
+ }
+
+ return NGX_DECLINED;
+}
+
+
+static void
+ngx_http_limit_conn_rbtree_insert_value(ngx_rbtree_node_t *temp,
+ ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
+{
+ ngx_rbtree_node_t **p;
+ ngx_http_limit_conn_node_t *lcn, *lcnt;
+
+ for ( ;; ) {
+
+ if (node->key < temp->key) {
+
+ p = &temp->left;
+
+ } else if (node->key > temp->key) {
+
+ p = &temp->right;
+
+ } else { /* node->key == temp->key */
+
+ lcn = (ngx_http_limit_conn_node_t *) &node->color;
+ lcnt = (ngx_http_limit_conn_node_t *) &temp->color;
+
+ p = (ngx_memn2cmp(lcn->data, lcnt->data, lcn->len, lcnt->len) < 0)
+ ? &temp->left : &temp->right;
+ }
+
+ if (*p == sentinel) {
+ break;
+ }
+
+ temp = *p;
+ }
+
+ *p = node;
+ node->parent = temp;
+ node->left = sentinel;
+ node->right = sentinel;
+ ngx_rbt_red(node);
+}
+
+
+static ngx_rbtree_node_t *
+ngx_http_limit_conn_lookup(ngx_rbtree_t *rbtree, ngx_http_variable_value_t *vv,
+ uint32_t hash)
+{
+ ngx_int_t rc;
+ ngx_rbtree_node_t *node, *sentinel;
+ ngx_http_limit_conn_node_t *lcn;
+
+ node = rbtree->root;
+ sentinel = rbtree->sentinel;
+
+ while (node != sentinel) {
+
+ if (hash < node->key) {
+ node = node->left;
+ continue;
+ }
+
+ if (hash > node->key) {
+ node = node->right;
+ continue;
+ }
+
+ /* hash == node->key */
+
+ do {
+ lcn = (ngx_http_limit_conn_node_t *) &node->color;
+
+ rc = ngx_memn2cmp(vv->data, lcn->data,
+ (size_t) vv->len, (size_t) lcn->len);
+ if (rc == 0) {
+ return node;
+ }
+
+ node = (rc < 0) ? node->left : node->right;
+
+ } while (node != sentinel && hash == node->key);
+
+ break;
+ }
+
+ return NULL;
+}
+
+
+static void
+ngx_http_limit_conn_cleanup(void *data)
+{
+ ngx_http_limit_conn_cleanup_t *lccln = data;
+
+ ngx_slab_pool_t *shpool;
+ ngx_rbtree_node_t *node;
+ ngx_http_limit_conn_ctx_t *ctx;
+ ngx_http_limit_conn_node_t *lc;
+
+ ctx = lccln->shm_zone->data;
+ shpool = (ngx_slab_pool_t *) lccln->shm_zone->shm.addr;
+ node = lccln->node;
+ lc = (ngx_http_limit_conn_node_t *) &node->color;
+
+ ngx_shmtx_lock(&shpool->mutex);
+
+ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, lccln->shm_zone->shm.log, 0,
+ "limit zone cleanup: %08XD %d", node->key, lc->conn);
+
+ lc->conn--;
+
+ if (lc->conn == 0) {
+ ngx_rbtree_delete(ctx->rbtree, node);
+ ngx_slab_free_locked(shpool, node);
+ }
+
+ ngx_shmtx_unlock(&shpool->mutex);
+}
+
+
+static ngx_inline void
+ngx_http_limit_conn_cleanup_all(ngx_pool_t *pool)
+{
+ ngx_pool_cleanup_t *cln;
+
+ cln = pool->cleanup;
+
+ while (cln && cln->handler == ngx_http_limit_conn_cleanup) {
+ ngx_http_limit_conn_cleanup(cln->data);
+ cln = cln->next;
+ }
+
+ pool->cleanup = cln;
+}
+
+
+static ngx_int_t
+ngx_http_limit_conn_init_zone(ngx_shm_zone_t *shm_zone, void *data)
+{
+ ngx_http_limit_conn_ctx_t *octx = data;
+
+ size_t len;
+ ngx_slab_pool_t *shpool;
+ ngx_rbtree_node_t *sentinel;
+ ngx_http_limit_conn_ctx_t *ctx;
+
+ ctx = shm_zone->data;
+
+ if (octx) {
+ if (ngx_strcmp(ctx->var.data, octx->var.data) != 0) {
+ ngx_log_error(NGX_LOG_EMERG, shm_zone->shm.log, 0,
+ "limit_conn_zone \"%V\" uses the \"%V\" variable "
+ "while previously it used the \"%V\" variable",
+ &shm_zone->shm.name, &ctx->var, &octx->var);
+ return NGX_ERROR;
+ }
+
+ ctx->rbtree = octx->rbtree;
+
+ return NGX_OK;
+ }
+
+ shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
+
+ if (shm_zone->shm.exists) {
+ ctx->rbtree = shpool->data;
+
+ return NGX_OK;
+ }
+
+ ctx->rbtree = ngx_slab_alloc(shpool, sizeof(ngx_rbtree_t));
+ if (ctx->rbtree == NULL) {
+ return NGX_ERROR;
+ }
+
+ shpool->data = ctx->rbtree;
+
+ sentinel = ngx_slab_alloc(shpool, sizeof(ngx_rbtree_node_t));
+ if (sentinel == NULL) {
+ return NGX_ERROR;
+ }
+
+ ngx_rbtree_init(ctx->rbtree, sentinel,
+ ngx_http_limit_conn_rbtree_insert_value);
+
+ len = sizeof(" in limit_conn_zone \"\"") + shm_zone->shm.name.len;
+
+ shpool->log_ctx = ngx_slab_alloc(shpool, len);
+ if (shpool->log_ctx == NULL) {
+ return NGX_ERROR;
+ }
+
+ ngx_sprintf(shpool->log_ctx, " in limit_conn_zone \"%V\"%Z",
+ &shm_zone->shm.name);
+
+ return NGX_OK;
+}
+
+
+static void *
+ngx_http_limit_conn_create_conf(ngx_conf_t *cf)
+{
+ ngx_http_limit_conn_conf_t *conf;
+
+ conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_limit_conn_conf_t));
+ if (conf == NULL) {
+ return NULL;
+ }
+
+ /*
+ * set by ngx_pcalloc():
+ *
+ * conf->limits.elts = NULL;
+ */
+
+ conf->log_level = NGX_CONF_UNSET_UINT;
+
+ return conf;
+}
+
+
+static char *
+ngx_http_limit_conn_merge_conf(ngx_conf_t *cf, void *parent, void *child)
+{
+ ngx_http_limit_conn_conf_t *prev = parent;
+ ngx_http_limit_conn_conf_t *conf = child;
+
+ if (conf->limits.elts == NULL) {
+ *conf = *prev;
+ }
+
+ ngx_conf_merge_uint_value(conf->log_level, prev->log_level, NGX_LOG_ERR);
+
+ return NGX_CONF_OK;
+}
+
+
+static char *
+ngx_http_limit_conn_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ u_char *p;
+ ssize_t size;
+ ngx_str_t *value, name, s;
+ ngx_uint_t i;
+ ngx_shm_zone_t *shm_zone;
+ ngx_http_limit_conn_ctx_t *ctx;
+
+ value = cf->args->elts;
+
+ ctx = NULL;
+ size = 0;
+ name.len = 0;
+
+ for (i = 1; i < cf->args->nelts; i++) {
+
+ if (ngx_strncmp(value[i].data, "zone=", 5) == 0) {
+
+ name.data = value[i].data + 5;
+
+ p = (u_char *) ngx_strchr(name.data, ':');
+
+ if (p == NULL) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid zone size \"%V\"", &value[i]);
+ return NGX_CONF_ERROR;
+ }
+
+ name.len = p - name.data;
+
+ s.data = p + 1;
+ s.len = value[i].data + value[i].len - s.data;
+
+ size = ngx_parse_size(&s);
+
+ if (size == NGX_ERROR) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid zone size \"%V\"", &value[i]);
+ return NGX_CONF_ERROR;
+ }
+
+ if (size < (ssize_t) (8 * ngx_pagesize)) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "zone \"%V\" is too small", &value[i]);
+ return NGX_CONF_ERROR;
+ }
+
+ continue;
+ }
+
+ if (value[i].data[0] == '$') {
+
+ value[i].len--;
+ value[i].data++;
+
+ ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_limit_conn_ctx_t));
+ if (ctx == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ ctx->index = ngx_http_get_variable_index(cf, &value[i]);
+ if (ctx->index == NGX_ERROR) {
+ return NGX_CONF_ERROR;
+ }
+
+ ctx->var = value[i];
+
+ continue;
+ }
+
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid parameter \"%V\"", &value[i]);
+ return NGX_CONF_ERROR;
+ }
+
+ if (name.len == 0) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "\"%V\" must have \"zone\" parameter",
+ &cmd->name);
+ return NGX_CONF_ERROR;
+ }
+
+ if (ctx == NULL) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "no variable is defined for %V \"%V\"",
+ &cmd->name, &name);
+ return NGX_CONF_ERROR;
+ }
+
+ shm_zone = ngx_shared_memory_add(cf, &name, size,
+ &ngx_http_limit_conn_module);
+ if (shm_zone == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ if (shm_zone->data) {
+ ctx = shm_zone->data;
+
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "%V \"%V\" is already bound to variable \"%V\"",
+ &cmd->name, &name, &ctx->var);
+ return NGX_CONF_ERROR;
+ }
+
+ shm_zone->init = ngx_http_limit_conn_init_zone;
+ shm_zone->data = ctx;
+
+ return NGX_CONF_OK;
+}
+
+
+static char *
+ngx_http_limit_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ssize_t n;
+ ngx_str_t *value;
+ ngx_shm_zone_t *shm_zone;
+ ngx_http_limit_conn_ctx_t *ctx;
+
+ ngx_conf_deprecated(cf, &ngx_conf_deprecated_limit_zone, NULL);
+
+ value = cf->args->elts;
+
+ if (value[2].data[0] != '$') {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid variable name \"%V\"", &value[2]);
+ return NGX_CONF_ERROR;
+ }
+
+ value[2].len--;
+ value[2].data++;
+
+ ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_limit_conn_ctx_t));
+ if (ctx == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ ctx->index = ngx_http_get_variable_index(cf, &value[2]);
+ if (ctx->index == NGX_ERROR) {
+ return NGX_CONF_ERROR;
+ }
+
+ ctx->var = value[2];
+
+ n = ngx_parse_size(&value[3]);
+
+ if (n == NGX_ERROR) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid size of limit_zone \"%V\"", &value[3]);
+ return NGX_CONF_ERROR;
+ }
+
+ if (n < (ngx_int_t) (8 * ngx_pagesize)) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "limit_zone \"%V\" is too small", &value[1]);
+ return NGX_CONF_ERROR;
+ }
+
+
+ shm_zone = ngx_shared_memory_add(cf, &value[1], n,
+ &ngx_http_limit_conn_module);
+ if (shm_zone == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ if (shm_zone->data) {
+ ctx = shm_zone->data;
+
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "limit_zone \"%V\" is already bound to variable \"%V\"",
+ &value[1], &ctx->var);
+ return NGX_CONF_ERROR;
+ }
+
+ shm_zone->init = ngx_http_limit_conn_init_zone;
+ shm_zone->data = ctx;
+
+ return NGX_CONF_OK;
+}
+
+
+static char *
+ngx_http_limit_conn(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_shm_zone_t *shm_zone;
+ ngx_http_limit_conn_conf_t *lccf = conf;
+ ngx_http_limit_conn_limit_t *limit, *limits;
+
+ ngx_str_t *value;
+ ngx_int_t n;
+ ngx_uint_t i;
+
+ value = cf->args->elts;
+
+ shm_zone = ngx_shared_memory_add(cf, &value[1], 0,
+ &ngx_http_limit_conn_module);
+ if (shm_zone == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ limits = lccf->limits.elts;
+
+ if (limits == NULL) {
+ if (ngx_array_init(&lccf->limits, cf->pool, 1,
+ sizeof(ngx_http_limit_conn_limit_t))
+ != NGX_OK)
+ {
+ return NGX_CONF_ERROR;
+ }
+ }
+
+ for (i = 0; i < lccf->limits.nelts; i++) {
+ if (shm_zone == limits[i].shm_zone) {
+ return "is duplicate";
+ }
+ }
+
+ n = ngx_atoi(value[2].data, value[2].len);
+ if (n <= 0) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid number of connections \"%V\"", &value[2]);
+ return NGX_CONF_ERROR;
+ }
+
+ if (n > 65535) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "connection limit must be less 65536");
+ return NGX_CONF_ERROR;
+ }
+
+ limit = ngx_array_push(&lccf->limits);
+ limit->conn = n;
+ limit->shm_zone = shm_zone;
+
+ return NGX_CONF_OK;
+}
+
+
+static ngx_int_t
+ngx_http_limit_conn_init(ngx_conf_t *cf)
+{
+ ngx_http_handler_pt *h;
+ ngx_http_core_main_conf_t *cmcf;
+
+ cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
+
+ h = ngx_array_push(&cmcf->phases[NGX_HTTP_PREACCESS_PHASE].handlers);
+ if (h == NULL) {
+ return NGX_ERROR;
+ }
+
+ *h = ngx_http_limit_conn_handler;
+
+ return NGX_OK;
+}
diff --git a/src/http/modules/ngx_http_limit_zone_module.c b/src/http/modules/ngx_http_limit_zone_module.c
deleted file mode 100644
index 31df316e4..000000000
--- a/src/http/modules/ngx_http_limit_zone_module.c
+++ /dev/null
@@ -1,556 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-
-typedef struct {
- u_char color;
- u_char len;
- u_short conn;
- u_char data[1];
-} ngx_http_limit_zone_node_t;
-
-
-typedef struct {
- ngx_shm_zone_t *shm_zone;
- ngx_rbtree_node_t *node;
-} ngx_http_limit_zone_cleanup_t;
-
-
-typedef struct {
- ngx_rbtree_t *rbtree;
- ngx_int_t index;
- ngx_str_t var;
-} ngx_http_limit_zone_ctx_t;
-
-
-typedef struct {
- ngx_shm_zone_t *shm_zone;
- ngx_uint_t conn;
- ngx_uint_t log_level;
-} ngx_http_limit_zone_conf_t;
-
-
-static void ngx_http_limit_zone_cleanup(void *data);
-
-static void *ngx_http_limit_zone_create_conf(ngx_conf_t *cf);
-static char *ngx_http_limit_zone_merge_conf(ngx_conf_t *cf, void *parent,
- void *child);
-static char *ngx_http_limit_zone(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_limit_conn(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-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"),
- NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE3,
- ngx_http_limit_zone,
- 0,
- 0,
- NULL },
-
- { ngx_string("limit_conn"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
- ngx_http_limit_conn,
- NGX_HTTP_LOC_CONF_OFFSET,
- 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
-};
-
-
-static ngx_http_module_t ngx_http_limit_zone_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_limit_zone_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_limit_zone_create_conf, /* create location configration */
- ngx_http_limit_zone_merge_conf /* merge location configration */
-};
-
-
-ngx_module_t ngx_http_limit_zone_module = {
- NGX_MODULE_V1,
- &ngx_http_limit_zone_module_ctx, /* module context */
- ngx_http_limit_zone_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_int_t
-ngx_http_limit_zone_handler(ngx_http_request_t *r)
-{
- size_t len, n;
- uint32_t hash;
- ngx_int_t rc;
- ngx_slab_pool_t *shpool;
- ngx_rbtree_node_t *node, *sentinel;
- ngx_pool_cleanup_t *cln;
- ngx_http_variable_value_t *vv;
- ngx_http_limit_zone_ctx_t *ctx;
- ngx_http_limit_zone_node_t *lz;
- ngx_http_limit_zone_conf_t *lzcf;
- ngx_http_limit_zone_cleanup_t *lzcln;
-
- if (r->main->limit_zone_set) {
- return NGX_DECLINED;
- }
-
- lzcf = ngx_http_get_module_loc_conf(r, ngx_http_limit_zone_module);
-
- if (lzcf->shm_zone == NULL) {
- return NGX_DECLINED;
- }
-
- ctx = lzcf->shm_zone->data;
-
- vv = ngx_http_get_indexed_variable(r, ctx->index);
-
- if (vv == NULL || vv->not_found) {
- return NGX_DECLINED;
- }
-
- len = vv->len;
-
- if (len == 0) {
- return NGX_DECLINED;
- }
-
- if (len > 255) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "the value of the \"%V\" variable "
- "is more than 255 bytes: \"%v\"",
- &ctx->var, vv);
- return NGX_DECLINED;
- }
-
- r->main->limit_zone_set = 1;
-
- hash = ngx_crc32_short(vv->data, len);
-
- cln = ngx_pool_cleanup_add(r->pool, sizeof(ngx_http_limit_zone_cleanup_t));
- if (cln == NULL) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
- }
-
- shpool = (ngx_slab_pool_t *) lzcf->shm_zone->shm.addr;
-
- ngx_shmtx_lock(&shpool->mutex);
-
- node = ctx->rbtree->root;
- sentinel = ctx->rbtree->sentinel;
-
- while (node != sentinel) {
-
- if (hash < node->key) {
- node = node->left;
- continue;
- }
-
- if (hash > node->key) {
- node = node->right;
- continue;
- }
-
- /* hash == node->key */
-
- do {
- lz = (ngx_http_limit_zone_node_t *) &node->color;
-
- rc = ngx_memn2cmp(vv->data, lz->data, len, (size_t) lz->len);
-
- if (rc == 0) {
- if ((ngx_uint_t) lz->conn < lzcf->conn) {
- lz->conn++;
- goto done;
- }
-
- ngx_shmtx_unlock(&shpool->mutex);
-
- ngx_log_error(lzcf->log_level, r->connection->log, 0,
- "limiting connections by zone \"%V\"",
- &lzcf->shm_zone->shm.name);
-
- return NGX_HTTP_SERVICE_UNAVAILABLE;
- }
-
- node = (rc < 0) ? node->left : node->right;
-
- } while (node != sentinel && hash == node->key);
-
- break;
- }
-
- n = offsetof(ngx_rbtree_node_t, color)
- + offsetof(ngx_http_limit_zone_node_t, data)
- + len;
-
- node = ngx_slab_alloc_locked(shpool, n);
- if (node == NULL) {
- ngx_shmtx_unlock(&shpool->mutex);
- return NGX_HTTP_SERVICE_UNAVAILABLE;
- }
-
- lz = (ngx_http_limit_zone_node_t *) &node->color;
-
- node->key = hash;
- lz->len = (u_char) len;
- lz->conn = 1;
- ngx_memcpy(lz->data, vv->data, len);
-
- ngx_rbtree_insert(ctx->rbtree, node);
-
-done:
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "limit zone: %08XD %d", node->key, lz->conn);
-
- ngx_shmtx_unlock(&shpool->mutex);
-
- cln->handler = ngx_http_limit_zone_cleanup;
- lzcln = cln->data;
-
- lzcln->shm_zone = lzcf->shm_zone;
- lzcln->node = node;
-
- return NGX_DECLINED;
-}
-
-
-static void
-ngx_http_limit_zone_rbtree_insert_value(ngx_rbtree_node_t *temp,
- ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)
-{
- ngx_rbtree_node_t **p;
- ngx_http_limit_zone_node_t *lzn, *lznt;
-
- for ( ;; ) {
-
- if (node->key < temp->key) {
-
- p = &temp->left;
-
- } else if (node->key > temp->key) {
-
- p = &temp->right;
-
- } else { /* node->key == temp->key */
-
- lzn = (ngx_http_limit_zone_node_t *) &node->color;
- lznt = (ngx_http_limit_zone_node_t *) &temp->color;
-
- p = (ngx_memn2cmp(lzn->data, lznt->data, lzn->len, lznt->len) < 0)
- ? &temp->left : &temp->right;
- }
-
- if (*p == sentinel) {
- break;
- }
-
- temp = *p;
- }
-
- *p = node;
- node->parent = temp;
- node->left = sentinel;
- node->right = sentinel;
- ngx_rbt_red(node);
-}
-
-
-static void
-ngx_http_limit_zone_cleanup(void *data)
-{
- ngx_http_limit_zone_cleanup_t *lzcln = data;
-
- ngx_slab_pool_t *shpool;
- ngx_rbtree_node_t *node;
- ngx_http_limit_zone_ctx_t *ctx;
- ngx_http_limit_zone_node_t *lz;
-
- ctx = lzcln->shm_zone->data;
- shpool = (ngx_slab_pool_t *) lzcln->shm_zone->shm.addr;
- node = lzcln->node;
- lz = (ngx_http_limit_zone_node_t *) &node->color;
-
- ngx_shmtx_lock(&shpool->mutex);
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, lzcln->shm_zone->shm.log, 0,
- "limit zone cleanup: %08XD %d", node->key, lz->conn);
-
- lz->conn--;
-
- if (lz->conn == 0) {
- ngx_rbtree_delete(ctx->rbtree, node);
- ngx_slab_free_locked(shpool, node);
- }
-
- ngx_shmtx_unlock(&shpool->mutex);
-}
-
-
-static ngx_int_t
-ngx_http_limit_zone_init_zone(ngx_shm_zone_t *shm_zone, void *data)
-{
- ngx_http_limit_zone_ctx_t *octx = data;
-
- size_t len;
- ngx_slab_pool_t *shpool;
- ngx_rbtree_node_t *sentinel;
- ngx_http_limit_zone_ctx_t *ctx;
-
- ctx = shm_zone->data;
-
- if (octx) {
- if (ngx_strcmp(ctx->var.data, octx->var.data) != 0) {
- ngx_log_error(NGX_LOG_EMERG, shm_zone->shm.log, 0,
- "limit_zone \"%V\" uses the \"%V\" variable "
- "while previously it used the \"%V\" variable",
- &shm_zone->shm.name, &ctx->var, &octx->var);
- return NGX_ERROR;
- }
-
- ctx->rbtree = octx->rbtree;
-
- return NGX_OK;
- }
-
- shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
-
- if (shm_zone->shm.exists) {
- ctx->rbtree = shpool->data;
-
- return NGX_OK;
- }
-
- ctx->rbtree = ngx_slab_alloc(shpool, sizeof(ngx_rbtree_t));
- if (ctx->rbtree == NULL) {
- return NGX_ERROR;
- }
-
- shpool->data = ctx->rbtree;
-
- sentinel = ngx_slab_alloc(shpool, sizeof(ngx_rbtree_node_t));
- if (sentinel == NULL) {
- return NGX_ERROR;
- }
-
- ngx_rbtree_init(ctx->rbtree, sentinel,
- ngx_http_limit_zone_rbtree_insert_value);
-
- len = sizeof(" in limit_zone \"\"") + shm_zone->shm.name.len;
-
- shpool->log_ctx = ngx_slab_alloc(shpool, len);
- if (shpool->log_ctx == NULL) {
- return NGX_ERROR;
- }
-
- ngx_sprintf(shpool->log_ctx, " in limit_zone \"%V\"%Z",
- &shm_zone->shm.name);
-
- return NGX_OK;
-}
-
-
-static void *
-ngx_http_limit_zone_create_conf(ngx_conf_t *cf)
-{
- ngx_http_limit_zone_conf_t *conf;
-
- conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_limit_zone_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * conf->shm_zone = NULL;
- * conf->conn = 0;
- */
-
- conf->log_level = NGX_CONF_UNSET_UINT;
-
- return conf;
-}
-
-
-static char *
-ngx_http_limit_zone_merge_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_limit_zone_conf_t *prev = parent;
- ngx_http_limit_zone_conf_t *conf = child;
-
- if (conf->shm_zone == NULL) {
- *conf = *prev;
- }
-
- ngx_conf_merge_uint_value(conf->log_level, prev->log_level, NGX_LOG_ERR);
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_limit_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ssize_t n;
- ngx_str_t *value;
- ngx_shm_zone_t *shm_zone;
- ngx_http_limit_zone_ctx_t *ctx;
-
- value = cf->args->elts;
-
- if (value[2].data[0] != '$') {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid variable name \"%V\"", &value[2]);
- return NGX_CONF_ERROR;
- }
-
- value[2].len--;
- value[2].data++;
-
- ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_limit_zone_ctx_t));
- if (ctx == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ctx->index = ngx_http_get_variable_index(cf, &value[2]);
- if (ctx->index == NGX_ERROR) {
- return NGX_CONF_ERROR;
- }
-
- ctx->var = value[2];
-
- n = ngx_parse_size(&value[3]);
-
- if (n == NGX_ERROR) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid size of limit_zone \"%V\"", &value[3]);
- return NGX_CONF_ERROR;
- }
-
- if (n < (ngx_int_t) (8 * ngx_pagesize)) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "limit_zone \"%V\" is too small", &value[1]);
- return NGX_CONF_ERROR;
- }
-
-
- shm_zone = ngx_shared_memory_add(cf, &value[1], n,
- &ngx_http_limit_zone_module);
- if (shm_zone == NULL) {
- return NGX_CONF_ERROR;
- }
-
- if (shm_zone->data) {
- ctx = shm_zone->data;
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "limit_zone \"%V\" is already bound to variable \"%V\"",
- &value[1], &ctx->var);
- return NGX_CONF_ERROR;
- }
-
- shm_zone->init = ngx_http_limit_zone_init_zone;
- shm_zone->data = ctx;
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_limit_conn(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_limit_zone_conf_t *lzcf = conf;
-
- ngx_int_t n;
- ngx_str_t *value;
-
- if (lzcf->shm_zone) {
- return "is duplicate";
- }
-
- value = cf->args->elts;
-
- lzcf->shm_zone = ngx_shared_memory_add(cf, &value[1], 0,
- &ngx_http_limit_zone_module);
- if (lzcf->shm_zone == NULL) {
- return NGX_CONF_ERROR;
- }
-
- n = ngx_atoi(value[2].data, value[2].len);
- if (n <= 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid number of connections \"%V\"", &value[2]);
- return NGX_CONF_ERROR;
- }
-
- if (n > 65535) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "connection limit must be less 65536");
- return NGX_CONF_ERROR;
- }
-
- lzcf->conn = n;
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_limit_zone_init(ngx_conf_t *cf)
-{
- ngx_http_handler_pt *h;
- ngx_http_core_main_conf_t *cmcf;
-
- cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
-
- h = ngx_array_push(&cmcf->phases[NGX_HTTP_PREACCESS_PHASE].handlers);
- if (h == NULL) {
- return NGX_ERROR;
- }
-
- *h = ngx_http_limit_zone_handler;
-
- return NGX_OK;
-}
diff --git a/src/http/modules/ngx_http_mp4_module.c b/src/http/modules/ngx_http_mp4_module.c
index a6752123a..a4a47ee8e 100644
--- a/src/http/modules/ngx_http_mp4_module.c
+++ b/src/http/modules/ngx_http_mp4_module.c
@@ -1066,7 +1066,6 @@ ngx_http_mp4_update_mdat_atom(ngx_http_mp4_file_t *mp4, off_t start_offset)
atom_data_size = mp4->mdat_data.buf->file_last - start_offset;
mp4->mdat_data.buf->file_pos = start_offset;
- mp4->content_length += atom_data_size;
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
"mdat new offset @%O:%O", start_offset, atom_data_size);
@@ -1083,6 +1082,8 @@ ngx_http_mp4_update_mdat_atom(ngx_http_mp4_file_t *mp4, off_t start_offset)
atom_header_size = sizeof(ngx_mp4_atom_header_t);
}
+ mp4->content_length += atom_header_size + atom_data_size;
+
ngx_mp4_set_32value(atom_header, atom_size);
ngx_mp4_set_atom_name(atom_header, 'm', 'd', 'a', 't');
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index 24fbc2f79..5476f396e 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -543,6 +543,7 @@ static ngx_keyval_t ngx_http_proxy_cache_headers[] = {
{ ngx_string("Connection"), ngx_string("close") },
{ ngx_string("Keep-Alive"), ngx_string("") },
{ ngx_string("Expect"), ngx_string("") },
+ { ngx_string("Upgrade"), ngx_string("") },
{ ngx_string("If-Modified-Since"), ngx_string("") },
{ ngx_string("If-Unmodified-Since"), ngx_string("") },
{ ngx_string("If-None-Match"), ngx_string("") },
@@ -2493,7 +2494,6 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
u_char *p;
size_t size;
- ngx_keyval_t *s;
ngx_hash_init_t hash;
ngx_http_core_loc_conf_t *clcf;
ngx_http_proxy_redirect_t *pr;
@@ -2841,22 +2841,6 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
if (ngx_http_script_compile(&sc) != NGX_OK) {
return NGX_CONF_ERROR;
}
-
- if (conf->headers_source == NULL) {
- conf->headers_source = ngx_array_create(cf->pool, 4,
- sizeof(ngx_keyval_t));
- if (conf->headers_source == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-
- s = ngx_array_push(conf->headers_source);
- if (s == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ngx_str_set(&s->key, "Content-Length");
- ngx_str_set(&s->value, "$proxy_internal_body_length");
}
if (ngx_http_proxy_merge_headers(cf, conf, prev) != NGX_OK) {
@@ -2875,7 +2859,7 @@ ngx_http_proxy_merge_headers(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *conf,
size_t size;
uintptr_t *code;
ngx_uint_t i;
- ngx_array_t headers_names;
+ ngx_array_t headers_names, headers_merged;
ngx_keyval_t *src, *s, *h;
ngx_hash_key_t *hk;
ngx_hash_init_t hash;
@@ -2891,6 +2875,8 @@ ngx_http_proxy_merge_headers(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *conf,
}
if (conf->headers_set_hash.buckets
+ && ((conf->body_source.data == NULL)
+ == (prev->body_source.data == NULL))
#if (NGX_HTTP_CACHE)
&& ((conf->upstream.cache == NULL) == (prev->upstream.cache == NULL))
#endif
@@ -2906,6 +2892,12 @@ ngx_http_proxy_merge_headers(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *conf,
return NGX_ERROR;
}
+ if (ngx_array_init(&headers_merged, cf->temp_pool, 4, sizeof(ngx_keyval_t))
+ != NGX_OK)
+ {
+ return NGX_ERROR;
+ }
+
if (conf->headers_source == NULL) {
conf->headers_source = ngx_array_create(cf->pool, 4,
sizeof(ngx_keyval_t));
@@ -2925,8 +2917,6 @@ ngx_http_proxy_merge_headers(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *conf,
}
- src = conf->headers_source->elts;
-
#if (NGX_HTTP_CACHE)
h = conf->upstream.cache ? ngx_http_proxy_cache_headers:
@@ -2937,31 +2927,51 @@ ngx_http_proxy_merge_headers(ngx_conf_t *cf, ngx_http_proxy_loc_conf_t *conf,
#endif
+ src = conf->headers_source->elts;
+ for (i = 0; i < conf->headers_source->nelts; i++) {
+
+ s = ngx_array_push(&headers_merged);
+ if (s == NULL) {
+ return NGX_ERROR;
+ }
+
+ *s = src[i];
+ }
+
while (h->key.len) {
- for (i = 0; i < conf->headers_source->nelts; i++) {
+ src = headers_merged.elts;
+ for (i = 0; i < headers_merged.nelts; i++) {
if (ngx_strcasecmp(h->key.data, src[i].key.data) == 0) {
goto next;
}
}
- s = ngx_array_push(conf->headers_source);
+ s = ngx_array_push(&headers_merged);
if (s == NULL) {
return NGX_ERROR;
}
*s = *h;
- src = conf->headers_source->elts;
-
next:
h++;
}
+ if (conf->body_source.data) {
+ s = ngx_array_push(&headers_merged);
+ if (s == NULL) {
+ return NGX_ERROR;
+ }
- src = conf->headers_source->elts;
- for (i = 0; i < conf->headers_source->nelts; i++) {
+ ngx_str_set(&s->key, "Content-Length");
+ ngx_str_set(&s->value, "$proxy_internal_body_length");
+ }
+
+
+ src = headers_merged.elts;
+ for (i = 0; i < headers_merged.nelts; i++) {
hk = ngx_array_push(&headers_names);
if (hk == NULL) {
diff --git a/src/http/modules/ngx_http_scgi_module.c b/src/http/modules/ngx_http_scgi_module.c
index 393edde24..1feac713b 100644
--- a/src/http/modules/ngx_http_scgi_module.c
+++ b/src/http/modules/ngx_http_scgi_module.c
@@ -43,6 +43,8 @@ static void ngx_http_scgi_finalize_request(ngx_http_request_t *r, ngx_int_t rc);
static void *ngx_http_scgi_create_loc_conf(ngx_conf_t *cf);
static char *ngx_http_scgi_merge_loc_conf(ngx_conf_t *cf, void *parent,
void *child);
+static ngx_int_t ngx_http_scgi_merge_params(ngx_conf_t *cf,
+ ngx_http_scgi_loc_conf_t *conf, ngx_http_scgi_loc_conf_t *prev);
static char *ngx_http_scgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static char *ngx_http_scgi_store(ngx_conf_t *cf, ngx_command_t *cmd,
@@ -1059,17 +1061,9 @@ ngx_http_scgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_http_scgi_loc_conf_t *prev = parent;
ngx_http_scgi_loc_conf_t *conf = child;
- u_char *p;
size_t size;
- uintptr_t *code;
- ngx_uint_t i;
- ngx_array_t headers_names;
- ngx_keyval_t *src;
- ngx_hash_key_t *hk;
ngx_hash_init_t hash;
ngx_http_core_loc_conf_t *clcf;
- ngx_http_script_compile_t sc;
- ngx_http_script_copy_code_t *copy;
if (conf->upstream.store != 0) {
ngx_conf_merge_value(conf->upstream.store, prev->upstream.store, 0);
@@ -1307,95 +1301,146 @@ ngx_http_scgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
}
}
- if (conf->params_source == NULL) {
- conf->flushes = prev->flushes;
- conf->params_len = prev->params_len;
- conf->params = prev->params;
- conf->params_source = prev->params_source;
- conf->headers_hash = prev->headers_hash;
+ if (ngx_http_scgi_merge_params(cf, conf, prev) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
-#if (NGX_HTTP_CACHE)
+ return NGX_CONF_OK;
+}
- if (conf->params_source == NULL) {
- if ((conf->upstream.cache == NULL)
- == (prev->upstream.cache == NULL))
- {
- return NGX_CONF_OK;
- }
+static ngx_int_t
+ngx_http_scgi_merge_params(ngx_conf_t *cf, ngx_http_scgi_loc_conf_t *conf,
+ ngx_http_scgi_loc_conf_t *prev)
+{
+ u_char *p;
+ size_t size;
+ uintptr_t *code;
+ ngx_uint_t i, nsrc;
+ ngx_array_t headers_names;
+#if (NGX_HTTP_CACHE)
+ ngx_array_t params_merged;
+#endif
+ ngx_keyval_t *src;
+ ngx_hash_key_t *hk;
+ ngx_hash_init_t hash;
+ ngx_http_script_compile_t sc;
+ ngx_http_script_copy_code_t *copy;
- /* 6 is a number of ngx_http_scgi_cache_headers entries */
- conf->params_source = ngx_array_create(cf->pool, 6,
- sizeof(ngx_keyval_t));
- if (conf->params_source == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-#else
+ if (conf->params_source == NULL) {
+ conf->params_source = prev->params_source;
+
+ if (prev->headers_hash.buckets
+#if (NGX_HTTP_CACHE)
+ && ((conf->upstream.cache == NULL) == (prev->upstream.cache == NULL))
+#endif
+ )
+ {
+ conf->flushes = prev->flushes;
+ conf->params_len = prev->params_len;
+ conf->params = prev->params;
+ conf->headers_hash = prev->headers_hash;
+ conf->header_params = prev->header_params;
- if (conf->params_source == NULL) {
- return NGX_CONF_OK;
+ return NGX_OK;
}
+ }
+ if (conf->params_source == NULL
+#if (NGX_HTTP_CACHE)
+ && (conf->upstream.cache == NULL)
#endif
+ )
+ {
+ conf->headers_hash.buckets = (void *) 1;
+ return NGX_OK;
}
conf->params_len = ngx_array_create(cf->pool, 64, 1);
if (conf->params_len == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
conf->params = ngx_array_create(cf->pool, 512, 1);
if (conf->params == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
if (ngx_array_init(&headers_names, cf->temp_pool, 4, sizeof(ngx_hash_key_t))
!= NGX_OK)
{
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
- src = conf->params_source->elts;
+ if (conf->params_source) {
+ src = conf->params_source->elts;
+ nsrc = conf->params_source->nelts;
+
+ } else {
+ src = NULL;
+ nsrc = 0;
+ }
#if (NGX_HTTP_CACHE)
if (conf->upstream.cache) {
ngx_keyval_t *h, *s;
- for (h = ngx_http_scgi_cache_headers; h->key.len; h++) {
+ if (ngx_array_init(&params_merged, cf->temp_pool, 4, sizeof(ngx_keyval_t))
+ != NGX_OK)
+ {
+ return NGX_ERROR;
+ }
+
+ for (i = 0; i < nsrc; i++) {
+
+ s = ngx_array_push(&params_merged);
+ if (s == NULL) {
+ return NGX_ERROR;
+ }
+
+ *s = src[i];
+ }
+
+ h = ngx_http_scgi_cache_headers;
- for (i = 0; i < conf->params_source->nelts; i++) {
+ while (h->key.len) {
+
+ src = params_merged.elts;
+ nsrc = params_merged.nelts;
+
+ for (i = 0; i < nsrc; i++) {
if (ngx_strcasecmp(h->key.data, src[i].key.data) == 0) {
goto next;
}
}
- s = ngx_array_push(conf->params_source);
+ s = ngx_array_push(&params_merged);
if (s == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
*s = *h;
- src = conf->params_source->elts;
-
next:
h++;
}
+
+ src = params_merged.elts;
+ nsrc = params_merged.nelts;
}
#endif
- for (i = 0; i < conf->params_source->nelts; i++) {
+ for (i = 0; i < nsrc; i++) {
if (src[i].key.len > sizeof("HTTP_") - 1
&& ngx_strncmp(src[i].key.data, "HTTP_", sizeof("HTTP_") - 1) == 0)
{
hk = ngx_array_push(&headers_names);
if (hk == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
hk->key.len = src[i].key.len - 5;
@@ -1411,7 +1456,7 @@ ngx_http_scgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
copy = ngx_array_push_n(conf->params_len,
sizeof(ngx_http_script_copy_code_t));
if (copy == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code;
@@ -1424,7 +1469,7 @@ ngx_http_scgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
copy = ngx_array_push_n(conf->params, size);
if (copy == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
copy->code = ngx_http_script_copy_code;
@@ -1443,12 +1488,12 @@ ngx_http_scgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
sc.values = &conf->params;
if (ngx_http_script_compile(&sc) != NGX_OK) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t));
if (code == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
*code = (uintptr_t) NULL;
@@ -1456,7 +1501,7 @@ ngx_http_scgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
code = ngx_array_push_n(conf->params, sizeof(uintptr_t));
if (code == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
*code = (uintptr_t) NULL;
@@ -1464,14 +1509,14 @@ ngx_http_scgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t));
if (code == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
*code = (uintptr_t) NULL;
code = ngx_array_push_n(conf->params, sizeof(uintptr_t));
if (code == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
*code = (uintptr_t) NULL;
@@ -1486,12 +1531,7 @@ ngx_http_scgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
hash.pool = cf->pool;
hash.temp_pool = NULL;
- if (ngx_hash_init(&hash, headers_names.elts, headers_names.nelts) != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
+ return ngx_hash_init(&hash, headers_names.elts, headers_names.nelts);
}
diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c
index 75a7156ef..0b8bc9bf8 100644
--- a/src/http/modules/ngx_http_ssi_filter_module.c
+++ b/src/http/modules/ngx_http_ssi_filter_module.c
@@ -139,14 +139,14 @@ static ngx_command_t ngx_http_ssi_filter_commands[] = {
NULL },
{ ngx_string("ssi_min_file_chunk"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_size_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_ssi_loc_conf_t, min_file_chunk),
NULL },
{ ngx_string("ssi_value_length"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_size_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_ssi_loc_conf_t, value_len),
diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c
index f1f6a4ae4..0ac744ca1 100644
--- a/src/http/modules/ngx_http_ssl_module.c
+++ b/src/http/modules/ngx_http_ssl_module.c
@@ -101,7 +101,7 @@ static ngx_command_t ngx_http_ssl_commands[] = {
NULL },
{ ngx_string("ssl_verify_client"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_FLAG,
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1,
ngx_conf_set_enum_slot,
NGX_HTTP_SRV_CONF_OFFSET,
offsetof(ngx_http_ssl_srv_conf_t, verify),
diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c
index 9cf0b531a..d60812932 100644
--- a/src/http/modules/ngx_http_uwsgi_module.c
+++ b/src/http/modules/ngx_http_uwsgi_module.c
@@ -50,6 +50,8 @@ static void ngx_http_uwsgi_finalize_request(ngx_http_request_t *r,
static void *ngx_http_uwsgi_create_loc_conf(ngx_conf_t *cf);
static char *ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent,
void *child);
+static ngx_int_t ngx_http_uwsgi_merge_params(ngx_conf_t *cf,
+ ngx_http_uwsgi_loc_conf_t *conf, ngx_http_uwsgi_loc_conf_t *prev);
static char *ngx_http_uwsgi_pass(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
@@ -1112,17 +1114,9 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_http_uwsgi_loc_conf_t *prev = parent;
ngx_http_uwsgi_loc_conf_t *conf = child;
- u_char *p;
size_t size;
- uintptr_t *code;
- ngx_uint_t i;
- ngx_array_t headers_names;
- ngx_keyval_t *src;
- ngx_hash_key_t *hk;
ngx_hash_init_t hash;
ngx_http_core_loc_conf_t *clcf;
- ngx_http_script_compile_t sc;
- ngx_http_script_copy_code_t *copy;
if (conf->upstream.store != 0) {
ngx_conf_merge_value(conf->upstream.store, prev->upstream.store, 0);
@@ -1365,95 +1359,146 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_uint_value(conf->modifier1, prev->modifier1, 0);
ngx_conf_merge_uint_value(conf->modifier2, prev->modifier2, 0);
- if (conf->params_source == NULL) {
- conf->flushes = prev->flushes;
- conf->params_len = prev->params_len;
- conf->params = prev->params;
- conf->params_source = prev->params_source;
- conf->headers_hash = prev->headers_hash;
+ if (ngx_http_uwsgi_merge_params(cf, conf, prev) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
-#if (NGX_HTTP_CACHE)
+ return NGX_CONF_OK;
+}
- if (conf->params_source == NULL) {
- if ((conf->upstream.cache == NULL)
- == (prev->upstream.cache == NULL))
- {
- return NGX_CONF_OK;
- }
+static ngx_int_t
+ngx_http_uwsgi_merge_params(ngx_conf_t *cf, ngx_http_uwsgi_loc_conf_t *conf,
+ ngx_http_uwsgi_loc_conf_t *prev)
+{
+ u_char *p;
+ size_t size;
+ uintptr_t *code;
+ ngx_uint_t i, nsrc;
+ ngx_array_t headers_names;
+#if (NGX_HTTP_CACHE)
+ ngx_array_t params_merged;
+#endif
+ ngx_keyval_t *src;
+ ngx_hash_key_t *hk;
+ ngx_hash_init_t hash;
+ ngx_http_script_compile_t sc;
+ ngx_http_script_copy_code_t *copy;
- /* 6 is a number of ngx_http_uwsgi_cache_headers entries */
- conf->params_source = ngx_array_create(cf->pool, 6,
- sizeof(ngx_keyval_t));
- if (conf->params_source == NULL) {
- return NGX_CONF_ERROR;
- }
- }
-#else
+ if (conf->params_source == NULL) {
+ conf->params_source = prev->params_source;
- if (conf->params_source == NULL) {
- return NGX_CONF_OK;
+ if (prev->headers_hash.buckets
+#if (NGX_HTTP_CACHE)
+ && ((conf->upstream.cache == NULL) == (prev->upstream.cache == NULL))
+#endif
+ )
+ {
+ conf->flushes = prev->flushes;
+ conf->params_len = prev->params_len;
+ conf->params = prev->params;
+ conf->headers_hash = prev->headers_hash;
+ conf->header_params = prev->header_params;
+
+ return NGX_OK;
}
+ }
+ if (conf->params_source == NULL
+#if (NGX_HTTP_CACHE)
+ && (conf->upstream.cache == NULL)
#endif
+ )
+ {
+ conf->headers_hash.buckets = (void *) 1;
+ return NGX_OK;
}
conf->params_len = ngx_array_create(cf->pool, 64, 1);
if (conf->params_len == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
conf->params = ngx_array_create(cf->pool, 512, 1);
if (conf->params == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
if (ngx_array_init(&headers_names, cf->temp_pool, 4, sizeof(ngx_hash_key_t))
!= NGX_OK)
{
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
- src = conf->params_source->elts;
+ if (conf->params_source) {
+ src = conf->params_source->elts;
+ nsrc = conf->params_source->nelts;
+
+ } else {
+ src = NULL;
+ nsrc = 0;
+ }
#if (NGX_HTTP_CACHE)
if (conf->upstream.cache) {
ngx_keyval_t *h, *s;
- for (h = ngx_http_uwsgi_cache_headers; h->key.len; h++) {
+ if (ngx_array_init(&params_merged, cf->temp_pool, 4, sizeof(ngx_keyval_t))
+ != NGX_OK)
+ {
+ return NGX_ERROR;
+ }
+
+ for (i = 0; i < nsrc; i++) {
+
+ s = ngx_array_push(&params_merged);
+ if (s == NULL) {
+ return NGX_ERROR;
+ }
+
+ *s = src[i];
+ }
- for (i = 0; i < conf->params_source->nelts; i++) {
+ h = ngx_http_uwsgi_cache_headers;
+
+ while (h->key.len) {
+
+ src = params_merged.elts;
+ nsrc = params_merged.nelts;
+
+ for (i = 0; i < nsrc; i++) {
if (ngx_strcasecmp(h->key.data, src[i].key.data) == 0) {
goto next;
}
}
- s = ngx_array_push(conf->params_source);
+ s = ngx_array_push(&params_merged);
if (s == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
*s = *h;
- src = conf->params_source->elts;
-
next:
h++;
}
+
+ src = params_merged.elts;
+ nsrc = params_merged.nelts;
}
#endif
- for (i = 0; i < conf->params_source->nelts; i++) {
+ for (i = 0; i < nsrc; i++) {
if (src[i].key.len > sizeof("HTTP_") - 1
&& ngx_strncmp(src[i].key.data, "HTTP_", sizeof("HTTP_") - 1) == 0)
{
hk = ngx_array_push(&headers_names);
if (hk == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
hk->key.len = src[i].key.len - 5;
@@ -1469,7 +1514,7 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
copy = ngx_array_push_n(conf->params_len,
sizeof(ngx_http_script_copy_code_t));
if (copy == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
copy->code = (ngx_http_script_code_pt) ngx_http_script_copy_len_code;
@@ -1482,7 +1527,7 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
copy = ngx_array_push_n(conf->params, size);
if (copy == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
copy->code = ngx_http_script_copy_code;
@@ -1501,12 +1546,12 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
sc.values = &conf->params;
if (ngx_http_script_compile(&sc) != NGX_OK) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t));
if (code == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
*code = (uintptr_t) NULL;
@@ -1514,7 +1559,7 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
code = ngx_array_push_n(conf->params, sizeof(uintptr_t));
if (code == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
*code = (uintptr_t) NULL;
@@ -1522,7 +1567,7 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
code = ngx_array_push_n(conf->params_len, sizeof(uintptr_t));
if (code == NULL) {
- return NGX_CONF_ERROR;
+ return NGX_ERROR;
}
*code = (uintptr_t) NULL;
@@ -1537,12 +1582,7 @@ ngx_http_uwsgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
hash.pool = cf->pool;
hash.temp_pool = NULL;
- if (ngx_hash_init(&hash, headers_names.elts, headers_names.nelts) != NGX_OK)
- {
- return NGX_CONF_ERROR;
- }
-
- return NGX_CONF_OK;
+ return ngx_hash_init(&hash, headers_names.elts, headers_names.nelts);
}
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index 530818c15..8a77ac601 100644
--- a/src/http/modules/perl/nginx.pm
+++ b/src/http/modules/perl/nginx.pm
@@ -48,7 +48,7 @@ our @EXPORT = qw(
HTTP_INSUFFICIENT_STORAGE
);
-our $VERSION = '1.1.7';
+our $VERSION = '1.1.8';
require XSLoader;
XSLoader::load('nginx', $VERSION);
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 7c4442265..ba5191069 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -143,7 +143,7 @@ static ngx_conf_enum_t ngx_http_core_if_modified_since[] = {
};
-static ngx_conf_enum_t ngx_http_core_keepalive_disable[] = {
+static ngx_conf_bitmask_t ngx_http_core_keepalive_disable[] = {
{ ngx_string("none"), NGX_HTTP_KEEPALIVE_DISABLE_NONE },
{ ngx_string("msie6"), NGX_HTTP_KEEPALIVE_DISABLE_MSIE6 },
{ ngx_string("safari"), NGX_HTTP_KEEPALIVE_DISABLE_SAFARI },
@@ -513,8 +513,8 @@ static ngx_command_t ngx_http_core_commands[] = {
NULL },
{ ngx_string("keepalive_disable"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_enum_slot,
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE12,
+ ngx_conf_set_bitmask_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_core_loc_conf_t, keepalive_disable),
&ngx_http_core_keepalive_disable },
@@ -3475,9 +3475,11 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_msec_value(conf->client_body_timeout,
prev->client_body_timeout, 60000);
- ngx_conf_merge_uint_value(conf->keepalive_disable, prev->keepalive_disable,
- NGX_HTTP_KEEPALIVE_DISABLE_MSIE6
- |NGX_HTTP_KEEPALIVE_DISABLE_SAFARI);
+ ngx_conf_merge_bitmask_value(conf->keepalive_disable,
+ prev->keepalive_disable,
+ (NGX_CONF_BITMASK_SET
+ |NGX_HTTP_KEEPALIVE_DISABLE_MSIE6
+ |NGX_HTTP_KEEPALIVE_DISABLE_SAFARI));
ngx_conf_merge_uint_value(conf->satisfy, prev->satisfy,
NGX_HTTP_SATISFY_ALL);
ngx_conf_merge_uint_value(conf->if_modified_since, prev->if_modified_since,
@@ -4398,7 +4400,7 @@ ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
if (ngx_strncmp(value[i].data, "max=", 4) == 0) {
max = ngx_atoi(value[i].data + 4, value[i].len - 4);
- if (max == NGX_ERROR) {
+ if (max <= 0) {
goto failed;
}
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
index 6198d7ef2..e851efa03 100644
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -480,7 +480,7 @@ struct ngx_http_request_s {
* ngx_http_limit_zone_module and ngx_http_limit_req_module
* we use the single bits in the request structure
*/
- unsigned limit_zone_set:1;
+ unsigned limit_conn_set:1;
unsigned limit_req_set:1;
#if 0
diff --git a/src/mail/ngx_mail_proxy_module.c b/src/mail/ngx_mail_proxy_module.c
index a7c4b7e48..298e8d96a 100644
--- a/src/mail/ngx_mail_proxy_module.c
+++ b/src/mail/ngx_mail_proxy_module.c
@@ -60,7 +60,7 @@ static ngx_command_t ngx_mail_proxy_commands[] = {
NULL },
{ ngx_string("proxy_pass_error_message"),
- NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1,
+ NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG,
ngx_conf_set_flag_slot,
NGX_MAIL_SRV_CONF_OFFSET,
offsetof(ngx_mail_proxy_conf_t, pass_error_message),
diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h
index af41ea38e..7c7f1fcd3 100644
--- a/src/os/unix/ngx_files.h
+++ b/src/os/unix/ngx_files.h
@@ -128,6 +128,7 @@ ngx_write_fd(ngx_fd_t fd, void *buf, size_t n)
#define ngx_linefeed(p) *p++ = LF;
#define NGX_LINEFEED_SIZE 1
+#define NGX_LINEFEED "\x0a"
#define ngx_rename_file(o, n) rename((const char *) o, (const char *) n)