summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2009-11-16 13:47:17 +0000
committerJonathan Kolb <jon@b0g.us>2009-11-16 13:47:17 +0000
commitcd5717636b57c376dab42994e210a64ac2b4314a (patch)
tree5481a266148dbd5376b6fd1c94a90d5f970353e5
parent2aa2ddb37720134ff5c09e0e23cea8a9cf6da00e (diff)
downloadnginx-cd5717636b57c376dab42994e210a64ac2b4314a.tar.gz
Changes with nginx 0.8.25 16 Nov 2009v0.8.25
*) Change: now no message is written in an error log if a variable is not found by $r->variable() method. *) Feature: the ngx_http_degradation_module. *) Feature: regular expression named captures. *) Feature: now URI part is not required a "proxy_pass" directive if variables are used. *) Feature: now the "msie_padding" directive works for Chrome too. *) Bugfix: a segmentation fault occurred in a worker process on low memory condition; the bug had appeared in 0.8.18. *) Bugfix: nginx sent gzipped responses to clients those do not support gzip, if "gzip_static on" and "gzip_vary off"; the bug had appeared in 0.8.16.
-rw-r--r--CHANGES22
-rw-r--r--CHANGES.ru22
-rw-r--r--auto/modules5
-rw-r--r--auto/options3
-rw-r--r--auto/sources4
-rw-r--r--src/core/nginx.h4
-rw-r--r--src/core/ngx_core.h4
-rw-r--r--src/core/ngx_palloc.c6
-rw-r--r--src/core/ngx_regex.c141
-rw-r--r--src/core/ngx_regex.h35
-rw-r--r--src/http/modules/ngx_http_degradation_module.c223
-rw-r--r--src/http/modules/ngx_http_fastcgi_module.c61
-rw-r--r--src/http/modules/ngx_http_gzip_filter_module.c16
-rw-r--r--src/http/modules/ngx_http_gzip_static_module.c11
-rw-r--r--src/http/modules/ngx_http_proxy_module.c23
-rw-r--r--src/http/modules/ngx_http_referer_module.c24
-rw-r--r--src/http/modules/ngx_http_rewrite_module.c64
-rw-r--r--src/http/modules/ngx_http_ssi_filter_module.c25
-rw-r--r--src/http/modules/perl/nginx.pm2
-rw-r--r--src/http/modules/perl/nginx.xs3
-rw-r--r--src/http/ngx_http_core_module.c374
-rw-r--r--src/http/ngx_http_core_module.h7
-rw-r--r--src/http/ngx_http_header_filter_module.c11
-rw-r--r--src/http/ngx_http_request.c38
-rw-r--r--src/http/ngx_http_request.h9
-rw-r--r--src/http/ngx_http_script.c26
-rw-r--r--src/http/ngx_http_script.h3
-rw-r--r--src/http/ngx_http_special_response.c22
-rw-r--r--src/http/ngx_http_variables.c151
-rw-r--r--src/http/ngx_http_variables.h21
-rw-r--r--src/os/unix/ngx_alloc.c20
-rw-r--r--src/os/unix/ngx_files.c20
-rw-r--r--src/os/unix/ngx_files.h2
33 files changed, 928 insertions, 474 deletions
diff --git a/CHANGES b/CHANGES
index 37f39a118..8e72c9259 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,26 @@
+Changes with nginx 0.8.25 16 Nov 2009
+
+ *) Change: now no message is written in an error log if a variable is
+ not found by $r->variable() method.
+
+ *) Feature: the ngx_http_degradation_module.
+
+ *) Feature: regular expression named captures.
+
+ *) Feature: now URI part is not required a "proxy_pass" directive if
+ variables are used.
+
+ *) Feature: now the "msie_padding" directive works for Chrome too.
+
+ *) Bugfix: a segmentation fault occurred in a worker process on low
+ memory condition; the bug had appeared in 0.8.18.
+
+ *) Bugfix: nginx sent gzipped responses to clients those do not support
+ gzip, if "gzip_static on" and "gzip_vary off"; the bug had appeared
+ in 0.8.16.
+
+
Changes with nginx 0.8.24 11 Nov 2009
*) Bugfix: nginx always added "Content-Encoding: gzip" response header
diff --git a/CHANGES.ru b/CHANGES.ru
index 9da1cd140..11472b759 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,26 @@
+Изменения в nginx 0.8.25 16.11.2009
+
+ *) Изменение: теперь в лог ошибок не пишется сообщение, если переменная
+ не найдена с помощью метода $r->variable().
+
+ *) Добавление: модуль ngx_http_degradation_module.
+
+ *) Добавление: именованные выделения в регулярных выражениях.
+
+ *) Добавление: теперь при использовании переменных в директиве
+ proxy_pass не требуется задавать URI.
+
+ *) Добавление: теперь директива msie_padding работает и для Chrome.
+
+ *) Исправление: в рабочем процессе происходил segmentation fault при
+ недостатке памяти; ошибка появилась в 0.8.18.
+
+ *) Исправление: nginx передавал сжатые ответы клиентам, не
+ поддерживающим сжатие при настройках gzip_static on и gzip_vary off;
+ ошибка появилась в 0.8.16.
+
+
Изменения в nginx 0.8.24 11.11.2009
*) Исправление: nginx всегда добавлял строку "Content-Encoding: gzip" в
diff --git a/auto/modules b/auto/modules
index 146b7d7f2..57b657848 100644
--- a/auto/modules
+++ b/auto/modules
@@ -316,6 +316,11 @@ if [ $HTTP_SECURE_LINK = YES ]; then
HTTP_SRCS="$HTTP_SRCS $HTTP_SECURE_LINK_SRCS"
fi
+if [ $HTTP_DEGRADATION = YES ]; then
+ HTTP_MODULES="$HTTP_MODULES $HTTP_DEGRADATION_MODULE"
+ HTTP_SRCS="$HTTP_SRCS $HTTP_DEGRADATION_SRCS"
+fi
+
if [ $HTTP_FLV = YES ]; then
HTTP_MODULES="$HTTP_MODULES $HTTP_FLV_MODULE"
HTTP_SRCS="$HTTP_SRCS $HTTP_FLV_SRCS"
diff --git a/auto/options b/auto/options
index 6bc01cd9f..a7c33c7b1 100644
--- a/auto/options
+++ b/auto/options
@@ -85,6 +85,7 @@ HTTP_LIMIT_REQ=YES
HTTP_EMPTY_GIF=YES
HTTP_BROWSER=YES
HTTP_SECURE_LINK=NO
+HTTP_DEGRADATION=NO
HTTP_FLV=NO
HTTP_GZIP_STATIC=NO
HTTP_UPSTREAM_IP_HASH=YES
@@ -194,6 +195,7 @@ do
--with-http_gzip_static_module) HTTP_GZIP_STATIC=YES ;;
--with-http_random_index_module) HTTP_RANDOM_INDEX=YES ;;
--with-http_secure_link_module) HTTP_SECURE_LINK=YES ;;
+ --with-http_degradation_module) HTTP_DEGRADATION=YES ;;
--without-http_charset_module) HTTP_CHARSET=NO ;;
--without-http_gzip_module) HTTP_GZIP=NO ;;
@@ -322,6 +324,7 @@ cat << END
--with-http_gzip_static_module enable ngx_http_gzip_static_module
--with-http_random_index_module enable ngx_http_random_index_module
--with-http_secure_link_module enable ngx_http_secure_link_module
+ --with-http_degradation_module enable ngx_http_degradation_module
--with-http_stub_status_module enable ngx_http_stub_status_module
--without-http_charset_module disable ngx_http_charset_module
diff --git a/auto/sources b/auto/sources
index 73afc9276..69488d2f5 100644
--- a/auto/sources
+++ b/auto/sources
@@ -438,6 +438,10 @@ HTTP_SECURE_LINK_MODULE=ngx_http_secure_link_module
HTTP_SECURE_LINK_SRCS=src/http/modules/ngx_http_secure_link_module.c
+HTTP_DEGRADATION_MODULE=ngx_http_degradation_module
+HTTP_DEGRADATION_SRCS=src/http/modules/ngx_http_degradation_module.c
+
+
HTTP_FLV_MODULE=ngx_http_flv_module
HTTP_FLV_SRCS=src/http/modules/ngx_http_flv_module.c
diff --git a/src/core/nginx.h b/src/core/nginx.h
index c57c52bee..375442288 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,8 +8,8 @@
#define _NGINX_H_INCLUDED_
-#define nginx_version 8024
-#define NGINX_VERSION "0.8.24"
+#define nginx_version 8025
+#define NGINX_VERSION "0.8.25"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
diff --git a/src/core/ngx_core.h b/src/core/ngx_core.h
index 58d0b8030..5939166af 100644
--- a/src/core/ngx_core.h
+++ b/src/core/ngx_core.h
@@ -83,7 +83,9 @@ typedef void (*ngx_connection_handler_pt)(ngx_connection_t *c);
#define CRLF "\x0d\x0a"
-#define ngx_abs(value) (((value) >= 0) ? (value) : - (value))
+#define ngx_abs(value) (((value) >= 0) ? (value) : - (value))
+#define ngx_max(val1, val2) ((val1 < val2) ? (val2) : (val1))
+#define ngx_min(val1, val2) ((val1 > val2) ? (val2) : (val1))
void ngx_cpuinfo(void);
diff --git a/src/core/ngx_palloc.c b/src/core/ngx_palloc.c
index ca59f6260..7db0d7da4 100644
--- a/src/core/ngx_palloc.c
+++ b/src/core/ngx_palloc.c
@@ -17,7 +17,7 @@ ngx_create_pool(size_t size, ngx_log_t *log)
{
ngx_pool_t *p;
- p = ngx_memalign(ngx_pagesize, size, log);
+ p = ngx_memalign(ngx_min(ngx_pagesize, size), size, log);
if (p == NULL) {
return NULL;
}
@@ -181,7 +181,7 @@ ngx_palloc_block(ngx_pool_t *pool, size_t size)
psize = (size_t) (pool->d.end - (u_char *) pool);
- m = ngx_memalign(ngx_pagesize, psize, pool->log);
+ m = ngx_memalign(ngx_min(ngx_pagesize, psize), psize, pool->log);
if (m == NULL) {
return NULL;
}
@@ -219,7 +219,7 @@ ngx_palloc_large(ngx_pool_t *pool, size_t size)
ngx_uint_t n;
ngx_pool_large_t *large;
- p = ngx_memalign(ngx_pagesize, size, pool->log);
+ p = ngx_alloc(size, pool->log);
if (p == NULL) {
return NULL;
}
diff --git a/src/core/ngx_regex.c b/src/core/ngx_regex.c
index be2dae79b..18e3c26c5 100644
--- a/src/core/ngx_regex.c
+++ b/src/core/ngx_regex.c
@@ -23,25 +23,16 @@ ngx_regex_init(void)
}
-ngx_regex_t *
-ngx_regex_compile(ngx_str_t *pattern, ngx_int_t options, ngx_pool_t *pool,
- ngx_str_t *err)
+static ngx_inline void
+ngx_regex_malloc_init(ngx_pool_t *pool)
{
- int erroff;
- const char *errstr;
- ngx_regex_t *re;
#if (NGX_THREADS)
ngx_core_tls_t *tls;
-#if (NGX_SUPPRESS_WARN)
- tls = NULL;
-#endif
-
if (ngx_threaded) {
tls = ngx_thread_get_tls(ngx_core_tls_key);
tls->pool = pool;
- } else {
- ngx_pcre_pool = pool;
+ return;
}
#else
@@ -49,68 +40,120 @@ ngx_regex_compile(ngx_str_t *pattern, ngx_int_t options, ngx_pool_t *pool,
ngx_pcre_pool = pool;
#endif
+}
- re = pcre_compile((const char *) pattern->data, (int) options,
- &errstr, &erroff, NULL);
-
- if (re == NULL) {
- if ((size_t) erroff == pattern->len) {
- ngx_snprintf(err->data, err->len - 1,
- "pcre_compile() failed: %s in \"%s\"%Z",
- errstr, pattern->data);
- } else {
- ngx_snprintf(err->data, err->len - 1,
- "pcre_compile() failed: %s in \"%s\" at \"%s\"%Z",
- errstr, pattern->data, pattern->data + erroff);
- }
- }
-
- /* ensure that there is no current pool */
+static ngx_inline void
+ngx_regex_malloc_done(void)
+{
#if (NGX_THREADS)
+ ngx_core_tls_t *tls;
+
if (ngx_threaded) {
+ tls = ngx_thread_get_tls(ngx_core_tls_key);
tls->pool = NULL;
- } else {
- ngx_pcre_pool = NULL;
+ return;
}
+
#else
+
ngx_pcre_pool = NULL;
-#endif
- return re;
+#endif
}
ngx_int_t
-ngx_regex_capture_count(ngx_regex_t *re)
+ngx_regex_compile(ngx_regex_compile_t *rc)
{
- int rc, n;
+ int n, erroff;
+ char *p;
+ const char *errstr;
+ ngx_regex_t *re;
- n = 0;
+ ngx_regex_malloc_init(rc->pool);
- rc = pcre_fullinfo(re, NULL, PCRE_INFO_CAPTURECOUNT, &n);
+ re = pcre_compile((const char *) rc->pattern.data, (int) rc->options,
+ &errstr, &erroff, NULL);
- if (rc < 0) {
- return (ngx_int_t) rc;
+ /* ensure that there is no current pool */
+ ngx_regex_malloc_done();
+
+ if (re == NULL) {
+ if ((size_t) erroff == rc->pattern.len) {
+ rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
+ "pcre_compile() failed: %s in \"%V\"",
+ errstr, &rc->pattern)
+ - rc->err.data;
+
+ } else {
+ rc->err.len = ngx_snprintf(rc->err.data, rc->err.len,
+ "pcre_compile() failed: %s in \"%V\" at \"%s\"",
+ errstr, &rc->pattern, rc->pattern.data + erroff)
+ - rc->err.data;
+ }
+
+ return NGX_ERROR;
}
- return (ngx_int_t) n;
+ rc->regex = re;
+
+ n = pcre_fullinfo(re, NULL, PCRE_INFO_CAPTURECOUNT, &rc->captures);
+ if (n < 0) {
+ p = "pcre_fullinfo(\"%V\", PCRE_INFO_CAPTURECOUNT) failed: %d";
+ goto failed;
+ }
+
+ if (rc->captures == 0) {
+ return NGX_OK;
+ }
+
+ n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMECOUNT, &rc->named_captures);
+ if (n < 0) {
+ p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMECOUNT) failed: %d";
+ goto failed;
+ }
+
+ if (rc->named_captures == 0) {
+ return NGX_OK;
+ }
+
+ n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &rc->name_size);
+ if (n < 0) {
+ p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMEENTRYSIZE) failed: %d";
+ goto failed;
+ }
+
+ n = pcre_fullinfo(re, NULL, PCRE_INFO_NAMETABLE, &rc->names);
+ if (n < 0) {
+ p = "pcre_fullinfo(\"%V\", PCRE_INFO_NAMETABLE) failed: %d";
+ goto failed;
+ }
+
+ return NGX_OK;
+
+failed:
+
+ rc->err.len = ngx_snprintf(rc->err.data, rc->err.len, p, &rc->pattern, n)
+ - rc->err.data;
+ return NGX_OK;
}
ngx_int_t
-ngx_regex_exec(ngx_regex_t *re, ngx_str_t *s, int *captures, ngx_int_t size)
+ngx_regex_capture_count(ngx_regex_t *re)
{
- int rc;
+ int rc, n;
+
+ n = 0;
- rc = pcre_exec(re, NULL, (const char *) s->data, s->len, 0, 0,
- captures, size);
+ rc = pcre_fullinfo(re, NULL, PCRE_INFO_CAPTURECOUNT, &n);
- if (rc == -1) {
- return NGX_REGEX_NO_MATCHED;
+ if (rc < 0) {
+ return (ngx_int_t) rc;
}
- return rc;
+ return (ngx_int_t) n;
}
@@ -133,7 +176,7 @@ ngx_regex_exec_array(ngx_array_t *a, ngx_str_t *s, ngx_log_t *log)
if (n < 0) {
ngx_log_error(NGX_LOG_ALERT, log, 0,
- ngx_regex_exec_n " failed: %d on \"%V\" using \"%s\"",
+ ngx_regex_exec_n " failed: %i on \"%V\" using \"%s\"",
n, s, re[i].name);
return NGX_ERROR;
}
@@ -157,11 +200,15 @@ ngx_regex_malloc(size_t size)
if (ngx_threaded) {
tls = ngx_thread_get_tls(ngx_core_tls_key);
pool = tls->pool;
+
} else {
pool = ngx_pcre_pool;
}
+
#else
+
pool = ngx_pcre_pool;
+
#endif
if (pool) {
diff --git a/src/core/ngx_regex.h b/src/core/ngx_regex.h
index e31470f9f..fc35059b3 100644
--- a/src/core/ngx_regex.h
+++ b/src/core/ngx_regex.h
@@ -14,29 +14,42 @@
#include <pcre.h>
-#define NGX_REGEX_NO_MATCHED -1000
+#define NGX_REGEX_NO_MATCHED PCRE_ERROR_NOMATCH /* -1 */
#define NGX_REGEX_CASELESS PCRE_CASELESS
typedef pcre ngx_regex_t;
+
typedef struct {
- ngx_regex_t *regex;
- u_char *name;
+ ngx_str_t pattern;
+ ngx_pool_t *pool;
+ ngx_int_t options;
+
+ ngx_regex_t *regex;
+ int captures;
+ int named_captures;
+ int name_size;
+ u_char *names;
+ ngx_str_t err;
+} ngx_regex_compile_t;
+
+
+typedef struct {
+ ngx_regex_t *regex;
+ u_char *name;
} ngx_regex_elt_t;
void ngx_regex_init(void);
-ngx_regex_t *ngx_regex_compile(ngx_str_t *pattern, ngx_int_t options,
- ngx_pool_t *pool, ngx_str_t *err);
-ngx_int_t ngx_regex_capture_count(ngx_regex_t *re);
-ngx_int_t ngx_regex_exec(ngx_regex_t *re, ngx_str_t *s, int *captures,
- ngx_int_t size);
-ngx_int_t ngx_regex_exec_array(ngx_array_t *a, ngx_str_t *s, ngx_log_t *log);
+ngx_int_t ngx_regex_compile(ngx_regex_compile_t *rc);
+#define ngx_regex_exec(re, s, captures, size) \
+ pcre_exec(re, NULL, (const char *) (s)->data, (s)->len, 0, 0, \
+ captures, size)
+#define ngx_regex_exec_n "pcre_exec()"
-#define ngx_regex_exec_n "pcre_exec()"
-#define ngx_regex_capture_count_n "pcre_fullinfo()"
+ngx_int_t ngx_regex_exec_array(ngx_array_t *a, ngx_str_t *s, ngx_log_t *log);
#endif /* _NGX_REGEX_H_INCLUDED_ */
diff --git a/src/http/modules/ngx_http_degradation_module.c b/src/http/modules/ngx_http_degradation_module.c
new file mode 100644
index 000000000..53fde211f
--- /dev/null
+++ b/src/http/modules/ngx_http_degradation_module.c
@@ -0,0 +1,223 @@
+
+/*
+ * Copyright (C) Igor Sysoev
+ */
+
+
+#include <ngx_config.h>
+#include <ngx_core.h>
+#include <ngx_http.h>
+
+
+typedef struct {
+ size_t sbrk_size;
+} ngx_http_degradation_main_conf_t;
+
+
+typedef struct {
+ ngx_uint_t degrade;
+} ngx_http_degradation_loc_conf_t;
+
+
+static ngx_conf_enum_t ngx_http_degrade[] = {
+ { ngx_string("204"), 204 },
+ { ngx_string("444"), 444 },
+ { ngx_null_string, 0 }
+};
+
+
+static void *ngx_http_degradation_create_main_conf(ngx_conf_t *cf);
+static void *ngx_http_degradation_create_loc_conf(ngx_conf_t *cf);
+static char *ngx_http_degradation_merge_loc_conf(ngx_conf_t *cf, void *parent,
+ void *child);
+static char *ngx_http_degradation(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
+static ngx_int_t ngx_http_degradation_init(ngx_conf_t *cf);
+
+
+static ngx_command_t ngx_http_degradation_commands[] = {
+
+ { ngx_string("degradation"),
+ NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
+ ngx_http_degradation,
+ NGX_HTTP_MAIN_CONF_OFFSET,
+ 0,
+ NULL },
+
+ { ngx_string("degrade"),
+ 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_degradation_loc_conf_t, degrade),
+ &ngx_http_degrade },
+
+ ngx_null_command
+};
+
+
+static ngx_http_module_t ngx_http_degradation_module_ctx = {
+ NULL, /* preconfiguration */
+ ngx_http_degradation_init, /* postconfiguration */
+
+ ngx_http_degradation_create_main_conf, /* create main configuration */
+ NULL, /* init main configuration */
+
+ NULL, /* create server configuration */
+ NULL, /* merge server configuration */
+
+ ngx_http_degradation_create_loc_conf, /* create location configuration */
+ ngx_http_degradation_merge_loc_conf /* merge location configuration */
+};
+
+
+ngx_module_t ngx_http_degradation_module = {
+ NGX_MODULE_V1,
+ &ngx_http_degradation_module_ctx, /* module context */
+ ngx_http_degradation_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_degradation_handler(ngx_http_request_t *r)
+{
+ time_t now;
+ static size_t sbrk_size;
+ static time_t sbrk_time;
+ ngx_http_degradation_loc_conf_t *dlcf;
+ ngx_http_degradation_main_conf_t *dmcf;
+
+ dlcf = ngx_http_get_module_loc_conf(r, ngx_http_degradation_module);
+
+ if (dlcf->degrade == 0) {
+ return NGX_DECLINED;
+ }
+
+ dmcf = ngx_http_get_module_main_conf(r, ngx_http_degradation_module);
+
+ if (dmcf->sbrk_size) {
+
+ now = ngx_time();
+
+ /* lock mutex */
+
+ if (now != sbrk_time) {
+
+ /*
+ * ELF/i386 is loaded at 0x08000000, 128M
+ * ELF/amd64 is loaded at 0x00400000, 4M
+ *
+ * use a function address to substract the loading address
+ */
+
+ sbrk_size = (size_t) sbrk(0) - ((uintptr_t) ngx_palloc & ~0x3FFFFF);
+ sbrk_time = now;
+ }
+
+ /* unlock mutex */
+
+ if (sbrk_size >= dmcf->sbrk_size) {
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "degradation sbrk: %uz", sbrk_size);
+
+ return dlcf->degrade;
+ }
+ }
+
+ return NGX_DECLINED;
+}
+
+
+static void *
+ngx_http_degradation_create_main_conf(ngx_conf_t *cf)
+{
+ ngx_http_degradation_main_conf_t *dmcf;
+
+ dmcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_degradation_main_conf_t));
+ if (dmcf == NULL) {
+ return NULL;
+ }
+
+ return dmcf;
+}
+
+
+static void *
+ngx_http_degradation_create_loc_conf(ngx_conf_t *cf)
+{
+ ngx_http_degradation_loc_conf_t *conf;
+
+ conf = ngx_palloc(cf->pool, sizeof(ngx_http_degradation_loc_conf_t));
+ if (conf == NULL) {
+ return NULL;
+ }
+
+ conf->degrade = NGX_CONF_UNSET_UINT;
+
+ return conf;
+}
+
+
+static char *
+ngx_http_degradation_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
+{
+ ngx_http_degradation_loc_conf_t *prev = parent;
+ ngx_http_degradation_loc_conf_t *conf = child;
+
+ ngx_conf_merge_uint_value(conf->degrade, prev->degrade, 0);
+
+ return NGX_CONF_OK;
+}
+
+
+static char *
+ngx_http_degradation(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_http_degradation_main_conf_t *dmcf = conf;
+
+ ngx_str_t *value, s;
+
+ value = cf->args->elts;
+
+ if (ngx_strncmp(value[1].data, "sbrk=", 5) == 0) {
+
+ s.len = value[1].len - 5;
+ s.data = value[1].data + 5;
+
+ dmcf->sbrk_size = ngx_parse_size(&s);
+ if (dmcf->sbrk_size == (size_t) NGX_ERROR) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid sbrk size \"%V\"", &value[1]);
+ return NGX_CONF_ERROR;
+ }
+ }
+
+ return NGX_CONF_OK;
+}
+
+
+static ngx_int_t
+ngx_http_degradation_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_degradation_handler;
+
+ return NGX_OK;
+}
diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c
index ba79cea0f..d7aa9b259 100644
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -2407,27 +2407,25 @@ ngx_http_fastcgi_split(ngx_http_request_t *r, ngx_http_fastcgi_loc_conf_t *flcf)
n = ngx_regex_exec(flcf->split_regex, &r->uri, captures, (1 + 2) * 3);
- if (n == NGX_REGEX_NO_MATCHED) {
- f->script_name = r->uri;
+ if (n >= 0) { /* match */
+ f->script_name.len = captures[3] - captures[2];
+ f->script_name.data = r->uri.data;
+
+ f->path_info.len = captures[5] - captures[4];
+ f->path_info.data = r->uri.data + f->script_name.len;
+
return f;
}
- if (n < 0) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- ngx_regex_exec_n " failed: %d on \"%V\" using \"%V\"",
- n, &r->uri, &flcf->split_name);
- return NULL;
+ if (n == NGX_REGEX_NO_MATCHED) {
+ f->script_name = r->uri;
+ return f;
}
- /* match */
-
- f->script_name.len = captures[3] - captures[2];
- f->script_name.data = r->uri.data;
-
- f->path_info.len = captures[5] - captures[4];
- f->path_info.data = r->uri.data + f->script_name.len;
-
- return f;
+ ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+ ngx_regex_exec_n " failed: %i on \"%V\" using \"%V\"",
+ n, &r->uri, &flcf->split_name);
+ return NULL;
#else
@@ -2518,39 +2516,34 @@ ngx_http_fastcgi_split_path_info(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
#if (NGX_PCRE)
ngx_http_fastcgi_loc_conf_t *flcf = conf;
- ngx_int_t n;
- ngx_str_t *value, err;
- u_char errstr[NGX_MAX_CONF_ERRSTR];
+ ngx_str_t *value;
+ ngx_regex_compile_t rc;
+ u_char errstr[NGX_MAX_CONF_ERRSTR];
value = cf->args->elts;
flcf->split_name = value[1];
- err.len = NGX_MAX_CONF_ERRSTR;
- err.data = errstr;
-
- flcf->split_regex = ngx_regex_compile(&value[1], 0, cf->pool, &err);
-
- if (flcf->split_regex == NULL) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
- return NGX_CONF_ERROR;
- }
+ ngx_memzero(&rc, sizeof(ngx_regex_compile_t));
- n = ngx_regex_capture_count(flcf->split_regex);
+ rc.pattern = value[1];
+ rc.pool = cf->pool;
+ rc.err.len = NGX_MAX_CONF_ERRSTR;
+ rc.err.data = errstr;
- if (n < 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- ngx_regex_capture_count_n " failed for "
- "pattern \"%V\"", &value[1]);
+ if (ngx_regex_compile(&rc) != NGX_OK) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc.err);
return NGX_CONF_ERROR;
}
- if (n != 2) {
+ if (rc.captures != 2) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"pattern \"%V\" must have 2 captures", &value[1]);
return NGX_CONF_ERROR;
}
+ flcf->split_regex = rc.regex;
+
return NGX_CONF_OK;
#else
diff --git a/src/http/modules/ngx_http_gzip_filter_module.c b/src/http/modules/ngx_http_gzip_filter_module.c
index 62b430b71..337700c0d 100644
--- a/src/http/modules/ngx_http_gzip_filter_module.c
+++ b/src/http/modules/ngx_http_gzip_filter_module.c
@@ -243,20 +243,30 @@ ngx_http_gzip_header_filter(ngx_http_request_t *r)
conf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_filter_module);
if (!conf->enable
+ || r->header_only
|| (r->headers_out.status != NGX_HTTP_OK
&& r->headers_out.status != NGX_HTTP_FORBIDDEN
&& r->headers_out.status != NGX_HTTP_NOT_FOUND)
- || r->header_only
|| (r->headers_out.content_encoding
&& r->headers_out.content_encoding->value.len)
|| (r->headers_out.content_length_n != -1
&& r->headers_out.content_length_n < conf->min_length)
- || ngx_http_test_content_type(r, &conf->types) == NULL
- || ngx_http_gzip_ok(r) != NGX_OK)
+ || ngx_http_test_content_type(r, &conf->types) == NULL)
{
return ngx_http_next_header_filter(r);
}
+ r->gzip_vary = 1;
+
+ if (!r->gzip_tested) {
+ if (ngx_http_gzip_ok(r) != NGX_OK) {
+ return ngx_http_next_header_filter(r);
+ }
+
+ } else if (!r->gzip_ok) {
+ return ngx_http_next_header_filter(r);
+ }
+
ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_gzip_ctx_t));
if (ctx == NULL) {
return NGX_ERROR;
diff --git a/src/http/modules/ngx_http_gzip_static_module.c b/src/http/modules/ngx_http_gzip_static_module.c
index 25ab64ca4..a928d16ae 100644
--- a/src/http/modules/ngx_http_gzip_static_module.c
+++ b/src/http/modules/ngx_http_gzip_static_module.c
@@ -99,9 +99,11 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r)
return NGX_DECLINED;
}
+ rc = ngx_http_gzip_ok(r);
+
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
- if (clcf->gzip_vary && ngx_http_gzip_ok(r) != NGX_OK) {
+ if (!clcf->gzip_vary && rc != NGX_OK) {
return NGX_DECLINED;
}
@@ -143,7 +145,6 @@ 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:
@@ -163,6 +164,12 @@ ngx_http_gzip_static_handler(ngx_http_request_t *r)
return NGX_DECLINED;
}
+ r->gzip_vary = 1;
+
+ if (rc != NGX_OK) {
+ return NGX_DECLINED;
+ }
+
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, "http static fd: %d", of.fd);
if (of.is_dir) {
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index 8f169fe43..e0f17e70a 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -724,17 +724,22 @@ ngx_http_proxy_eval(ngx_http_request_t *r, ngx_http_proxy_ctx_t *ctx,
return NGX_ERROR;
}
- if (url.uri.len && url.uri.data[0] == '?') {
- p = ngx_pnalloc(r->pool, url.uri.len + 1);
- if (p == NULL) {
- return NGX_ERROR;
- }
+ if (url.uri.len) {
+ if (url.uri.data[0] == '?') {
+ p = ngx_pnalloc(r->pool, url.uri.len + 1);
+ if (p == NULL) {
+ return NGX_ERROR;
+ }
- *p++ = '/';
- ngx_memcpy(p, url.uri.data, url.uri.len);
+ *p++ = '/';
+ ngx_memcpy(p, url.uri.data, url.uri.len);
- url.uri.len++;
- url.uri.data = p - 1;
+ url.uri.len++;
+ url.uri.data = p - 1;
+ }
+
+ } else {
+ url.uri = r->unparsed_uri;
}
ctx->vars.key_start = u->schema;
diff --git a/src/http/modules/ngx_http_referer_module.c b/src/http/modules/ngx_http_referer_module.c
index 8daa399bd..e655be967 100644
--- a/src/http/modules/ngx_http_referer_module.c
+++ b/src/http/modules/ngx_http_referer_module.c
@@ -412,7 +412,7 @@ ngx_http_valid_referers(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
if (sn[n].regex) {
if (ngx_http_add_regex_referer(cf, rlcf, &sn[n].name,
- sn[n].regex)
+ sn[n].regex->regex)
!= NGX_OK)
{
return NGX_CONF_ERROR;
@@ -502,9 +502,9 @@ ngx_http_add_regex_referer(ngx_conf_t *cf, ngx_http_referer_conf_t *rlcf,
ngx_str_t *name, ngx_regex_t *regex)
{
#if (NGX_PCRE)
- ngx_str_t err;
- ngx_regex_elt_t *re;
- u_char errstr[NGX_MAX_CONF_ERRSTR];
+ ngx_regex_elt_t *re;
+ ngx_regex_compile_t rc;
+ u_char errstr[NGX_MAX_CONF_ERRSTR];
if (name->len == 1) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "empty regex in \"%V\"", name);
@@ -530,19 +530,23 @@ ngx_http_add_regex_referer(ngx_conf_t *cf, ngx_http_referer_conf_t *rlcf,
return NGX_CONF_OK;
}
- err.len = NGX_MAX_CONF_ERRSTR;
- err.data = errstr;
-
name->len--;
name->data++;
- re->regex = ngx_regex_compile(name, NGX_REGEX_CASELESS, cf->pool, &err);
+ ngx_memzero(&rc, sizeof(ngx_regex_compile_t));
+
+ rc.pattern = *name;
+ rc.pool = cf->pool;
+ rc.options = NGX_REGEX_CASELESS;
+ rc.err.len = NGX_MAX_CONF_ERRSTR;
+ rc.err.data = errstr;
- if (re->regex == NULL) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
+ if (ngx_regex_compile(&rc) != NGX_OK) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc.err);
return NGX_CONF_ERROR;
}
+ re->regex = rc.regex;
re->name = name->data;
return NGX_CONF_OK;
diff --git a/src/http/modules/ngx_http_rewrite_module.c b/src/http/modules/ngx_http_rewrite_module.c
index 1f98cf829..b07eedc78 100644
--- a/src/http/modules/ngx_http_rewrite_module.c
+++ b/src/http/modules/ngx_http_rewrite_module.c
@@ -294,9 +294,9 @@ ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_rewrite_loc_conf_t *lcf = conf;
- ngx_str_t *value, err;
- ngx_int_t n;
+ ngx_str_t *value;
ngx_uint_t last;
+ ngx_regex_compile_t rc;
ngx_http_script_code_pt *code;
ngx_http_script_compile_t sc;
ngx_http_script_regex_code_t *regex;
@@ -313,15 +313,16 @@ ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
value = cf->args->elts;
- err.len = NGX_MAX_CONF_ERRSTR;
- err.data = errstr;
+ ngx_memzero(&rc, sizeof(ngx_regex_compile_t));
- /* TODO: NGX_REGEX_CASELESS */
+ rc.pattern = value[1];
+ rc.err.len = NGX_MAX_CONF_ERRSTR;
+ rc.err.data = errstr;
- regex->regex = ngx_regex_compile(&value[1], 0, cf->pool, &err);
+ /* TODO: NGX_REGEX_CASELESS */
+ regex->regex = ngx_http_regex_compile(cf, &rc);
if (regex->regex == NULL) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
return NGX_CONF_ERROR;
}
@@ -394,7 +395,6 @@ ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
regex = sc.main;
- regex->ncaptures = sc.ncaptures;
regex->size = sc.size;
regex->args = sc.args;
@@ -402,31 +402,6 @@ ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
regex->lengths = NULL;
}
- n = ngx_regex_capture_count(regex->regex);
-
- if (n < 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- ngx_regex_capture_count_n " failed for "
- "pattern \"%V\"", &value[1]);
- return NGX_CONF_ERROR;
- }
-
- if (regex->ncaptures > (ngx_uint_t) n) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "pattern \"%V\" has less captures "
- "than referrenced in substitution \"%V\"",
- &value[1], &value[2]);
- return NGX_CONF_ERROR;
- }
-
- if (regex->ncaptures < (ngx_uint_t) n) {
- regex->ncaptures = (ngx_uint_t) n;
- }
-
- if (regex->ncaptures) {
- regex->ncaptures = (regex->ncaptures + 1) * 3;
- }
-
regex_end = ngx_http_script_add_code(lcf->codes,
sizeof(ngx_http_script_regex_end_code_t),
&regex);
@@ -624,8 +599,9 @@ ngx_http_rewrite_if_condition(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf)
{
u_char *p;
size_t len;
- ngx_str_t *value, err;
- ngx_uint_t cur, last, n;
+ ngx_str_t *value;
+ ngx_uint_t cur, last;
+ ngx_regex_compile_t rc;
ngx_http_script_code_pt *code;
ngx_http_script_file_code_t *fop;
ngx_http_script_regex_code_t *regex;
@@ -733,15 +709,15 @@ ngx_http_rewrite_if_condition(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf)
ngx_memzero(regex, sizeof(ngx_http_script_regex_code_t));
- err.len = NGX_MAX_CONF_ERRSTR;
- err.data = errstr;
+ ngx_memzero(&rc, sizeof(ngx_regex_compile_t));
- regex->regex = ngx_regex_compile(&value[last],
- (p[len - 1] == '*') ? NGX_REGEX_CASELESS : 0,
- cf->pool, &err);
+ rc.pattern = value[last];
+ rc.options = (p[len - 1] == '*') ? NGX_REGEX_CASELESS : 0;
+ rc.err.len = NGX_MAX_CONF_ERRSTR;
+ rc.err.data = errstr;
+ regex->regex = ngx_http_regex_compile(cf, &rc);
if (regex->regex == NULL) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
return NGX_CONF_ERROR;
}
@@ -753,12 +729,6 @@ ngx_http_rewrite_if_condition(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf)
}
regex->name = value[last];
- n = ngx_regex_capture_count(regex->regex);
-
- if (n) {
- regex->ncaptures = (n + 1) * 3;
- }
-
return NGX_CONF_OK;
}
diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c
index d03e58407..1b9a3a037 100644
--- a/src/http/modules/ngx_http_ssi_filter_module.c
+++ b/src/http/modules/ngx_http_ssi_filter_module.c
@@ -2450,27 +2450,28 @@ ngx_http_ssi_if(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
} else {
#if (NGX_PCRE)
- ngx_str_t err;
- ngx_regex_t *regex;
- u_char errstr[NGX_MAX_CONF_ERRSTR];
-
- err.len = NGX_MAX_CONF_ERRSTR;
- err.data = errstr;
+ ngx_regex_compile_t rgc;
+ u_char errstr[NGX_MAX_CONF_ERRSTR];
right.data[right.len] = '\0';
- regex = ngx_regex_compile(&right, 0, r->pool, &err);
+ ngx_memzero(&rgc, sizeof(ngx_regex_compile_t));
+
+ rgc.pattern = right;
+ rgc.pool = r->pool;
+ rgc.err.len = NGX_MAX_CONF_ERRSTR;
+ rgc.err.data = errstr;
- if (regex == NULL) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "%s", err.data);
+ if (ngx_regex_compile(&rgc) != NGX_OK) {
+ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "%V", &rgc.err);
return NGX_HTTP_SSI_ERROR;
}
- rc = ngx_regex_exec(regex, &left, NULL, 0);
+ rc = ngx_regex_exec(rgc.regex, &left, NULL, 0);
- if (rc != NGX_REGEX_NO_MATCHED && rc < 0) {
+ if (rc < NGX_REGEX_NO_MATCHED) {
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- ngx_regex_exec_n " failed: %d on \"%V\" using \"%V\"",
+ ngx_regex_exec_n " failed: %i on \"%V\" using \"%V\"",
rc, &left, &right);
return NGX_HTTP_SSI_ERROR;
}
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index aadc2f870..c9e3cd25f 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.8.24';
+our $VERSION = '0.8.25';
require XSLoader;
XSLoader::load('nginx', $VERSION);
diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs
index 8a20c4373..0c2c9b617 100644
--- a/src/http/modules/perl/nginx.xs
+++ b/src/http/modules/perl/nginx.xs
@@ -902,9 +902,6 @@ variable(r, name, value = NULL)
XSRETURN_UNDEF;
}
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "variable \"%V\" not found", &var);
-
XSRETURN_UNDEF;
}
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 9cce2d547..7ae49a686 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -812,7 +812,11 @@ ngx_http_handler(ngx_http_request_t *r)
}
r->valid_location = 1;
- r->gzip = 0;
+#if (NGX_HTTP_GZIP)
+ r->gzip_tested = 0;
+ r->gzip_ok = 0;
+ r->gzip_vary = 0;
+#endif
r->write_event_handler = ngx_http_core_run_phases;
ngx_http_core_run_phases(r);
@@ -1416,7 +1420,7 @@ ngx_http_core_find_location(ngx_http_request_t *r)
ngx_int_t rc;
ngx_http_core_loc_conf_t *pclcf;
#if (NGX_PCRE)
- ngx_int_t n, len;
+ ngx_int_t n;
ngx_uint_t noregex;
ngx_http_core_loc_conf_t *clcf, **clcfp;
@@ -1450,51 +1454,28 @@ ngx_http_core_find_location(ngx_http_request_t *r)
if (noregex == 0 && pclcf->regex_locations) {
- len = 0;
-
for (clcfp = pclcf->regex_locations; *clcfp; clcfp++) {
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"test location: ~ \"%V\"", &(*clcfp)->name);
- if ((*clcfp)->captures) {
+ n = ngx_http_regex_exec(r, (*clcfp)->regex, &r->uri);
- len = (NGX_HTTP_MAX_CAPTURES + 1) * 3;
+ if (n == NGX_OK) {
+ r->loc_conf = (*clcfp)->loc_conf;
- if (r->captures == NULL) {
- r->captures = ngx_palloc(r->pool, len * sizeof(int));
- if (r->captures == NULL) {
- return NGX_ERROR;
- }
- }
- }
+ /* look up nested locations */
- n = ngx_regex_exec((*clcfp)->regex, &r->uri, r->captures, len);
+ rc = ngx_http_core_find_location(r);
- if (n == NGX_REGEX_NO_MATCHED) {
- continue;
+ return (rc == NGX_ERROR) ? rc : NGX_OK;
}
- if (n < 0) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- ngx_regex_exec_n
- " failed: %d on \"%V\" using \"%V\"",
- n, &r->uri, &(*clcfp)->name);
- return NGX_ERROR;
+ if (n == NGX_DECLINED) {
+ continue;
}
- /* match */
-
- r->loc_conf = (*clcfp)->loc_conf;
-
- r->ncaptures = len;
- r->captures_data = r->uri.data;
-
- /* look up nested locations */
-
- rc = ngx_http_core_find_location(r);
-
- return (rc == NGX_ERROR) ? rc : NGX_OK;
+ return NGX_ERROR;
}
}
#endif
@@ -1774,7 +1755,7 @@ ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *path,
#if (NGX_PCRE)
ngx_uint_t captures;
- captures = alias && clcf->captures;
+ captures = alias && clcf->regex;
reserved += captures ? 1 : r->uri.len - alias + 1;
#else
reserved += r->uri.len - alias + 1;
@@ -1891,15 +1872,7 @@ ngx_http_gzip_ok(ngx_http_request_t *r)
ngx_table_elt_t *e, *d;
ngx_http_core_loc_conf_t *clcf;
- if (r->gzip == 1) {
- return NGX_OK;
- }
-
- if (r->gzip == 2) {
- return NGX_DECLINED;
- }
-
- r->gzip = 2;
+ r->gzip_tested = 1;
if (r != r->main
|| r->headers_in.accept_encoding == NULL
@@ -2034,7 +2007,7 @@ ok:
#endif
- r->gzip = 1;
+ r->gzip_ok = 1;
return NGX_OK;
}
@@ -2600,26 +2573,25 @@ ngx_http_core_regex_location(ngx_conf_t *cf, ngx_http_core_loc_conf_t *clcf,
ngx_str_t *regex, ngx_uint_t caseless)
{
#if (NGX_PCRE)
- ngx_str_t err;
- u_char errstr[NGX_MAX_CONF_ERRSTR];
+ ngx_regex_compile_t rc;
+ u_char errstr[NGX_MAX_CONF_ERRSTR];
+
+ ngx_memzero(&rc, sizeof(ngx_regex_compile_t));
- err.len = NGX_MAX_CONF_ERRSTR;
- err.data = errstr;
+ rc.pattern = *regex;
+ rc.err.len = NGX_MAX_CONF_ERRSTR;
+ rc.err.data = errstr;
#if (NGX_HAVE_CASELESS_FILESYSTEM)
- caseless = 1;
+ rc.options = NGX_REGEX_CASELESS;
#endif
- clcf->regex = ngx_regex_compile(regex, caseless ? NGX_REGEX_CASELESS: 0,
- cf->pool, &err);
-
+ clcf->regex = ngx_http_regex_compile(cf, &rc);
if (clcf->regex == NULL) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
return NGX_ERROR;
}
clcf->name = *regex;
- clcf->captures = (ngx_regex_capture_count(clcf->regex) > 0);
return NGX_OK;
@@ -2637,14 +2609,14 @@ ngx_http_core_regex_location(ngx_conf_t *cf, ngx_http_core_loc_conf_t *clcf,
static char *
ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
- ngx_http_core_loc_conf_t *lcf = conf;
+ ngx_http_core_loc_conf_t *clcf = conf;
char *rv;
ngx_conf_t save;
- if (lcf->types == NULL) {
- lcf->types = ngx_array_create(cf->pool, 64, sizeof(ngx_hash_key_t));
- if (lcf->types == NULL) {
+ if (clcf->types == NULL) {
+ clcf->types = ngx_array_create(cf->pool, 64, sizeof(ngx_hash_key_t));
+ if (clcf->types == NULL) {
return NGX_CONF_ERROR;
}
}
@@ -2664,7 +2636,7 @@ ngx_http_core_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
static char *
ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
{
- ngx_http_core_loc_conf_t *lcf = conf;
+ ngx_http_core_loc_conf_t *clcf = conf;
ngx_str_t *value, *content_type, *old, file;
ngx_uint_t i, n, hash;
@@ -2695,8 +2667,8 @@ ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
hash = ngx_hash_strlow(value[i].data, value[i].data, value[i].len);
- type = lcf->types->elts;
- for (n = 0; n < lcf->types->nelts; n++) {
+ type = clcf->types->elts;
+ for (n = 0; n < clcf->types->nelts; n++) {
if (ngx_strcmp(value[i].data, type[n].key.data) == 0) {
old = type[n].value;
type[n].value = content_type;
@@ -2711,7 +2683,7 @@ ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
}
- type = ngx_array_push(lcf->types);
+ type = ngx_array_push(clcf->types);
if (type == NULL) {
return NGX_CONF_ERROR;
}
@@ -2916,89 +2888,89 @@ ngx_http_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
static void *
ngx_http_core_create_loc_conf(ngx_conf_t *cf)
{
- ngx_http_core_loc_conf_t *lcf;
+ ngx_http_core_loc_conf_t *clcf;
- lcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_loc_conf_t));
- if (lcf == NULL) {
+ clcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_core_loc_conf_t));
+ if (clcf == NULL) {
return NULL;
}
/*
* set by ngx_pcalloc():
*
- * lcf->root = { 0, NULL };
- * lcf->limit_except = 0;
- * lcf->post_action = { 0, NULL };
- * lcf->types = NULL;
- * lcf->default_type = { 0, NULL };
- * lcf->error_log = NULL;
- * lcf->error_pages = NULL;
- * lcf->try_files = NULL;
- * lcf->client_body_path = NULL;
- * lcf->regex = NULL;
- * lcf->exact_match = 0;
- * lcf->auto_redirect = 0;
- * lcf->alias = 0;
- * lcf->gzip_proxied = 0;
+ * clcf->root = { 0, NULL };
+ * clcf->limit_except = 0;
+ * clcf->post_action = { 0, NULL };
+ * clcf->types = NULL;
+ * clcf->default_type = { 0, NULL };
+ * clcf->error_log = NULL;
+ * clcf->error_pages = NULL;
+ * clcf->try_files = NULL;
+ * clcf->client_body_path = NULL;
+ * clcf->regex = NULL;
+ * clcf->exact_match = 0;
+ * clcf->auto_redirect = 0;
+ * clcf->alias = 0;
+ * clcf->gzip_proxied = 0;
*/
- lcf->client_max_body_size = NGX_CONF_UNSET;
- lcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE;
- lcf->client_body_timeout = NGX_CONF_UNSET_MSEC;
- lcf->satisfy = NGX_CONF_UNSET_UINT;
- lcf->if_modified_since = NGX_CONF_UNSET_UINT;
- lcf->client_body_in_file_only = NGX_CONF_UNSET_UINT;
- lcf->client_body_in_single_buffer = NGX_CONF_UNSET;
- lcf->internal = NGX_CONF_UNSET;
- lcf->sendfile = NGX_CONF_UNSET;
- lcf->sendfile_max_chunk = NGX_CONF_UNSET_SIZE;
+ clcf->client_max_body_size = NGX_CONF_UNSET;
+ clcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE;
+ clcf->client_body_timeout = NGX_CONF_UNSET_MSEC;
+ clcf->satisfy = NGX_CONF_UNSET_UINT;
+ clcf->if_modified_since = NGX_CONF_UNSET_UINT;
+ clcf->client_body_in_file_only = NGX_CONF_UNSET_UINT;
+ clcf->client_body_in_single_buffer = NGX_CONF_UNSET;
+ clcf->internal = NGX_CONF_UNSET;
+ clcf->sendfile = NGX_CONF_UNSET;
+ clcf->sendfile_max_chunk = NGX_CONF_UNSET_SIZE;
#if (NGX_HAVE_FILE_AIO)
- lcf->aio = NGX_CONF_UNSET;
+ clcf->aio = NGX_CONF_UNSET;
#endif
- lcf->read_ahead = NGX_CONF_UNSET_SIZE;
- lcf->directio = NGX_CONF_UNSET;
- lcf->directio_alignment = NGX_CONF_UNSET;
- lcf->tcp_nopush = NGX_CONF_UNSET;
- lcf->tcp_nodelay = NGX_CONF_UNSET;
- lcf->send_timeout = NGX_CONF_UNSET_MSEC;
- 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;
- lcf->lingering_time = NGX_CONF_UNSET_MSEC;
- lcf->lingering_timeout = NGX_CONF_UNSET_MSEC;
- lcf->resolver_timeout = NGX_CONF_UNSET_MSEC;
- lcf->reset_timedout_connection = NGX_CONF_UNSET;
- lcf->server_name_in_redirect = NGX_CONF_UNSET;
- lcf->port_in_redirect = NGX_CONF_UNSET;
- lcf->msie_padding = NGX_CONF_UNSET;
- lcf->msie_refresh = NGX_CONF_UNSET;
- lcf->log_not_found = NGX_CONF_UNSET;
- lcf->log_subrequest = NGX_CONF_UNSET;
- lcf->recursive_error_pages = NGX_CONF_UNSET;
- lcf->server_tokens = NGX_CONF_UNSET;
- lcf->types_hash_max_size = NGX_CONF_UNSET_UINT;
- lcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT;
-
- lcf->open_file_cache = NGX_CONF_UNSET_PTR;
- lcf->open_file_cache_valid = NGX_CONF_UNSET;
- lcf->open_file_cache_min_uses = NGX_CONF_UNSET_UINT;
- lcf->open_file_cache_errors = NGX_CONF_UNSET;
- lcf->open_file_cache_events = NGX_CONF_UNSET;
+ clcf->read_ahead = NGX_CONF_UNSET_SIZE;
+ clcf->directio = NGX_CONF_UNSET;
+ clcf->directio_alignment = NGX_CONF_UNSET;
+ clcf->tcp_nopush = NGX_CONF_UNSET;
+ clcf->tcp_nodelay = NGX_CONF_UNSET;
+ clcf->send_timeout = NGX_CONF_UNSET_MSEC;
+ clcf->send_lowat = NGX_CONF_UNSET_SIZE;
+ clcf->postpone_output = NGX_CONF_UNSET_SIZE;
+ clcf->limit_rate = NGX_CONF_UNSET_SIZE;
+ clcf->limit_rate_after = NGX_CONF_UNSET_SIZE;
+ clcf->keepalive_timeout = NGX_CONF_UNSET_MSEC;
+ clcf->keepalive_header = NGX_CONF_UNSET;
+ clcf->keepalive_requests = NGX_CONF_UNSET_UINT;
+ clcf->lingering_time = NGX_CONF_UNSET_MSEC;
+ clcf->lingering_timeout = NGX_CONF_UNSET_MSEC;
+ clcf->resolver_timeout = NGX_CONF_UNSET_MSEC;
+ clcf->reset_timedout_connection = NGX_CONF_UNSET;
+ clcf->server_name_in_redirect = NGX_CONF_UNSET;
+ clcf->port_in_redirect = NGX_CONF_UNSET;
+ clcf->msie_padding = NGX_CONF_UNSET;
+ clcf->msie_refresh = NGX_CONF_UNSET;
+ clcf->log_not_found = NGX_CONF_UNSET;
+ clcf->log_subrequest = NGX_CONF_UNSET;
+ clcf->recursive_error_pages = NGX_CONF_UNSET;
+ clcf->server_tokens = NGX_CONF_UNSET;
+ clcf->types_hash_max_size = NGX_CONF_UNSET_UINT;
+ clcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT;
+
+ clcf->open_file_cache = NGX_CONF_UNSET_PTR;
+ clcf->open_file_cache_valid = NGX_CONF_UNSET;
+ clcf->open_file_cache_min_uses = NGX_CONF_UNSET_UINT;
+ clcf->open_file_cache_errors = NGX_CONF_UNSET;
+ clcf->open_file_cache_events = NGX_CONF_UNSET;
#if (NGX_HTTP_GZIP)
- lcf->gzip_vary = NGX_CONF_UNSET;
- lcf->gzip_http_version = NGX_CONF_UNSET_UINT;
+ clcf->gzip_vary = NGX_CONF_UNSET;
+ clcf->gzip_http_version = NGX_CONF_UNSET_UINT;
#if (NGX_PCRE)
- lcf->gzip_disable = NGX_CONF_UNSET_PTR;
- lcf->gzip_disable_msie6 = 3;
+ clcf->gzip_disable = NGX_CONF_UNSET_PTR;
+ clcf->gzip_disable_msie6 = 3;
#endif
#endif
- return lcf;
+ return clcf;
}
@@ -3539,8 +3511,8 @@ ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
#if (NGX_PCRE)
{
- ngx_str_t err;
- u_char errstr[NGX_MAX_CONF_ERRSTR];
+ ngx_regex_compile_t rc;
+ u_char errstr[NGX_MAX_CONF_ERRSTR];
if (value[i].len == 1) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
@@ -3548,21 +3520,22 @@ ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}
- err.len = NGX_MAX_CONF_ERRSTR;
- err.data = errstr;
-
value[i].len--;
value[i].data++;
- sn->regex = ngx_regex_compile(&value[i], 0, cf->pool, &err);
+ ngx_memzero(&rc, sizeof(ngx_regex_compile_t));
+ rc.pattern = value[i];
+ rc.err.len = NGX_MAX_CONF_ERRSTR;
+ rc.err.data = errstr;
+
+ sn->regex = ngx_http_regex_compile(cf, &rc);
if (sn->regex == NULL) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
return NGX_CONF_ERROR;
}
sn->name = value[i];
- cscf->captures = (ngx_regex_capture_count(sn->regex) > 0);
+ cscf->captures = (rc.captures > 0);
}
#else
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
@@ -3580,7 +3553,7 @@ ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
static char *
ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
- ngx_http_core_loc_conf_t *lcf = conf;
+ ngx_http_core_loc_conf_t *clcf = conf;
ngx_str_t *value;
ngx_uint_t alias, n;
@@ -3588,11 +3561,11 @@ ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
alias = (cmd->name.len == sizeof("alias") - 1) ? 1 : 0;
- if (lcf->root.data) {
+ if (clcf->root.data) {
/* the (ngx_uint_t) cast is required by gcc 2.7.2.3 */
- if ((ngx_uint_t) lcf->alias == alias) {
+ if ((ngx_uint_t) clcf->alias == alias) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"\"%V\" directive is duplicate",
&cmd->name);
@@ -3600,13 +3573,13 @@ ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"\"%V\" directive is duplicate, "
"\"%s\" directive is specified before",
- &cmd->name, lcf->alias ? "alias" : "root");
+ &cmd->name, clcf->alias ? "alias" : "root");
}
return NGX_CONF_ERROR;
}
- if (lcf->named && alias) {
+ if (clcf->named && alias) {
ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
"the \"alias\" directive may not be used "
"inside named location");
@@ -3638,28 +3611,28 @@ ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}
- lcf->alias = alias;
- lcf->root = value[1];
+ clcf->alias = alias;
+ clcf->root = value[1];
- if (!alias && lcf->root.data[lcf->root.len - 1] == '/') {
- lcf->root.len--;
+ if (!alias && clcf->root.data[clcf->root.len - 1] == '/') {
+ clcf->root.len--;
}
- if (lcf->root.data[0] != '$') {
- if (ngx_conf_full_name(cf->cycle, &lcf->root, 0) != NGX_OK) {
+ if (clcf->root.data[0] != '$') {
+ if (ngx_conf_full_name(cf->cycle, &clcf->root, 0) != NGX_OK) {
return NGX_CONF_ERROR;
}
}
- n = ngx_http_script_variables_count(&lcf->root);
+ n = ngx_http_script_variables_count(&clcf->root);
ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
if (n) {
sc.cf = cf;
- sc.source = &lcf->root;
- sc.lengths = &lcf->root_lengths;
- sc.values = &lcf->root_values;
+ sc.source = &clcf->root;
+ sc.lengths = &clcf->root_lengths;
+ sc.values = &clcf->root_values;
sc.variables = n;
sc.complete_lengths = 1;
sc.complete_values = 1;
@@ -3669,20 +3642,6 @@ ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
}
-#if (NGX_PCRE)
-
- if (alias && lcf->regex
- && (ngx_regex_capture_count(lcf->regex) <= 0 || sc.ncaptures == 0))
- {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "the \"alias\" directive must use captures "
- "inside location given by regular expression");
-
- return NGX_CONF_ERROR;
- }
-
-#endif
-
return NGX_CONF_OK;
}
@@ -3834,7 +3793,7 @@ ngx_http_core_directio(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
static char *
ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
- ngx_http_core_loc_conf_t *lcf = conf;
+ ngx_http_core_loc_conf_t *clcf = conf;
u_char *p;
ngx_int_t overwrite;
@@ -3844,10 +3803,10 @@ ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_http_complex_value_t cv;
ngx_http_compile_complex_value_t ccv;
- if (lcf->error_pages == NULL) {
- lcf->error_pages = ngx_array_create(cf->pool, 4,
- sizeof(ngx_http_err_page_t));
- if (lcf->error_pages == NULL) {
+ if (clcf->error_pages == NULL) {
+ clcf->error_pages = ngx_array_create(cf->pool, 4,
+ sizeof(ngx_http_err_page_t));
+ if (clcf->error_pages == NULL) {
return NGX_CONF_ERROR;
}
}
@@ -3911,7 +3870,7 @@ ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
}
for (i = 1; i < cf->args->nelts - n; i++) {
- err = ngx_array_push(lcf->error_pages);
+ err = ngx_array_push(clcf->error_pages);
if (err == NULL) {
return NGX_CONF_ERROR;
}
@@ -4039,14 +3998,14 @@ ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
static char *
ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
- ngx_http_core_loc_conf_t *lcf = conf;
+ ngx_http_core_loc_conf_t *clcf = conf;
time_t inactive;
ngx_str_t *value, s;
ngx_int_t max;
ngx_uint_t i;
- if (lcf->open_file_cache != NGX_CONF_UNSET_PTR) {
+ if (clcf->open_file_cache != NGX_CONF_UNSET_PTR) {
return "is duplicate";
}
@@ -4082,7 +4041,7 @@ ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
if (ngx_strcmp(value[i].data, "off") == 0) {
- lcf->open_file_cache = NULL;
+ clcf->open_file_cache = NULL;
continue;
}
@@ -4095,7 +4054,7 @@ ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}
- if (lcf->open_file_cache == NULL) {
+ if (clcf->open_file_cache == NULL) {
return NGX_CONF_OK;
}
@@ -4105,8 +4064,8 @@ ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}
- lcf->open_file_cache = ngx_open_file_cache_init(cf->pool, max, inactive);
- if (lcf->open_file_cache) {
+ clcf->open_file_cache = ngx_open_file_cache_init(cf->pool, max, inactive);
+ if (clcf->open_file_cache) {
return NGX_CONF_OK;
}
@@ -4117,50 +4076,50 @@ ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
static char *
ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
- ngx_http_core_loc_conf_t *lcf = conf;
+ ngx_http_core_loc_conf_t *clcf = conf;
ngx_str_t *value;
- if (lcf->error_log) {
+ if (clcf->error_log) {
return "is duplicate";
}
value = cf->args->elts;
- lcf->error_log = ngx_log_create(cf->cycle, &value[1]);
- if (lcf->error_log == NULL) {
+ clcf->error_log = ngx_log_create(cf->cycle, &value[1]);
+ if (clcf->error_log == NULL) {
return NGX_CONF_ERROR;
}
if (cf->args->nelts == 2) {
- lcf->error_log->log_level = NGX_LOG_ERR;
+ clcf->error_log->log_level = NGX_LOG_ERR;
return NGX_CONF_OK;
}
- return ngx_log_set_levels(cf, lcf->error_log);
+ return ngx_log_set_levels(cf, clcf->error_log);
}
static char *
ngx_http_core_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
- ngx_http_core_loc_conf_t *lcf = conf;
+ ngx_http_core_loc_conf_t *clcf = conf;
ngx_str_t *value;
- if (lcf->keepalive_timeout != NGX_CONF_UNSET_MSEC) {
+ if (clcf->keepalive_timeout != NGX_CONF_UNSET_MSEC) {
return "is duplicate";
}
value = cf->args->elts;
- lcf->keepalive_timeout = ngx_parse_time(&value[1], 0);
+ clcf->keepalive_timeout = ngx_parse_time(&value[1], 0);
- if (lcf->keepalive_timeout == (ngx_msec_t) NGX_ERROR) {
+ if (clcf->keepalive_timeout == (ngx_msec_t) NGX_ERROR) {
return "invalid value";
}
- if (lcf->keepalive_timeout == (ngx_msec_t) NGX_PARSE_LARGE_TIME) {
+ if (clcf->keepalive_timeout == (ngx_msec_t) NGX_PARSE_LARGE_TIME) {
return "value must be less than 597 hours";
}
@@ -4168,13 +4127,13 @@ ngx_http_core_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_OK;
}
- lcf->keepalive_header = ngx_parse_time(&value[2], 1);
+ clcf->keepalive_header = ngx_parse_time(&value[2], 1);
- if (lcf->keepalive_header == NGX_ERROR) {
+ if (clcf->keepalive_header == NGX_ERROR) {
return "invalid value";
}
- if (lcf->keepalive_header == NGX_PARSE_LARGE_TIME) {
+ if (clcf->keepalive_header == NGX_PARSE_LARGE_TIME) {
return "value must be less than 68 years";
}
@@ -4185,13 +4144,13 @@ ngx_http_core_keepalive(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
static char *
ngx_http_core_internal(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
- ngx_http_core_loc_conf_t *lcf = conf;
+ ngx_http_core_loc_conf_t *clcf = conf;
- if (lcf->internal != NGX_CONF_UNSET) {
+ if (clcf->internal != NGX_CONF_UNSET) {
return "is duplicate";
}
- lcf->internal = 1;
+ clcf->internal = 1;
return NGX_CONF_OK;
}
@@ -4239,10 +4198,11 @@ ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
#if (NGX_PCRE)
- ngx_str_t err, *value;
- ngx_uint_t i;
- ngx_regex_elt_t *re;
- u_char errstr[NGX_MAX_CONF_ERRSTR];
+ ngx_str_t *value;
+ ngx_uint_t i;
+ ngx_regex_elt_t *re;
+ ngx_regex_compile_t rc;
+ u_char errstr[NGX_MAX_CONF_ERRSTR];
if (clcf->gzip_disable == NGX_CONF_UNSET_PTR) {
clcf->gzip_disable = ngx_array_create(cf->pool, 2,
@@ -4254,8 +4214,11 @@ ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
value = cf->args->elts;
- err.len = NGX_MAX_CONF_ERRSTR;
- err.data = errstr;
+ ngx_memzero(&rc, sizeof(ngx_regex_compile_t));
+
+ rc.pool = cf->pool;
+ rc.err.len = NGX_MAX_CONF_ERRSTR;
+ rc.err.data = errstr;
for (i = 1; i < cf->args->nelts; i++) {
@@ -4269,14 +4232,15 @@ ngx_http_gzip_disable(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
return NGX_CONF_ERROR;
}
- re->regex = ngx_regex_compile(&value[i], NGX_REGEX_CASELESS, cf->pool,
- &err);
+ rc.pattern = value[1];
+ rc.options = NGX_REGEX_CASELESS;
- if (re->regex == NULL) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%s", err.data);
+ if (ngx_regex_compile(&rc) != NGX_OK) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc.err);
return NGX_CONF_ERROR;
}
+ re->regex = rc.regex;
re->name = value[i].data;
}
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index 2b8d8bb31..c240f252c 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -126,6 +126,7 @@ typedef struct {
ngx_hash_t variables_hash;
ngx_array_t variables; /* ngx_http_variable_t */
+ ngx_uint_t ncaptures;
ngx_uint_t server_names_hash_max_size;
ngx_uint_t server_names_hash_bucket_size;
@@ -238,7 +239,7 @@ typedef struct {
struct ngx_http_server_name_s {
#if (NGX_PCRE)
- ngx_regex_t *regex;
+ ngx_http_regex_t *regex;
#endif
ngx_http_core_srv_conf_t *server; /* virtual name server conf */
ngx_str_t name;
@@ -267,9 +268,7 @@ struct ngx_http_core_loc_conf_s {
ngx_str_t name; /* location name */
#if (NGX_PCRE)
- ngx_regex_t *regex;
-
- unsigned captures:1;
+ ngx_http_regex_t *regex;
#endif
unsigned noname:1; /* "if () {}" block or limit_except */
diff --git a/src/http/ngx_http_header_filter_module.c b/src/http/ngx_http_header_filter_module.c
index 9044c4040..0f6f1731a 100644
--- a/src/http/ngx_http_header_filter_module.c
+++ b/src/http/ngx_http_header_filter_module.c
@@ -399,8 +399,13 @@ ngx_http_header_filter(ngx_http_request_t *r)
}
#if (NGX_HTTP_GZIP)
- if (r->gzip && clcf->gzip_vary) {
- len += sizeof("Vary: Accept-Encoding" CRLF) - 1;
+ if (r->gzip_vary) {
+ if (clcf->gzip_vary) {
+ len += sizeof("Vary: Accept-Encoding" CRLF) - 1;
+
+ } else {
+ r->gzip_vary = 0;
+ }
}
#endif
@@ -559,7 +564,7 @@ ngx_http_header_filter(ngx_http_request_t *r)
}
#if (NGX_HTTP_GZIP)
- if (r->gzip && clcf->gzip_vary) {
+ if (r->gzip_vary) {
b->last = ngx_cpymem(b->last, "Vary: Accept-Encoding" CRLF,
sizeof("Vary: Accept-Encoding" CRLF) - 1);
}
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index 56eee2643..30639810d 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -1445,6 +1445,9 @@ ngx_http_process_user_agent(ngx_http_request_t *r, ngx_table_elt_t *h,
if (ngx_strstrn(user_agent, "Gecko/", 6 - 1)) {
r->headers_in.gecko = 1;
+ } else if (ngx_strstrn(user_agent, "Chrome/", 7 - 1)) {
+ r->headers_in.chrome = 1;
+
} else if (ngx_strstrn(user_agent, "Konqueror", 9 - 1)) {
r->headers_in.konqueror = 1;
}
@@ -1697,7 +1700,6 @@ ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len)
#if (NGX_PCRE)
if (len && r->virtual_names->nregex) {
- size_t ncaptures;
ngx_int_t n;
ngx_uint_t i;
ngx_str_t name;
@@ -1706,44 +1708,22 @@ ngx_http_find_virtual_server(ngx_http_request_t *r, u_char *host, size_t len)
name.len = len;
name.data = host;
- ncaptures = 0;
-
sn = r->virtual_names->regex;
for (i = 0; i < r->virtual_names->nregex; i++) {
- if (sn[i].server->captures && r->captures == NULL) {
-
- ncaptures = (NGX_HTTP_MAX_CAPTURES + 1) * 3;
+ n = ngx_http_regex_exec(r, sn[i].regex, &name);
- r->captures = ngx_palloc(r->pool, ncaptures * sizeof(int));
- if (r->captures == NULL) {
- return NGX_ERROR;
- }
+ if (n == NGX_OK) {
+ cscf = sn[i].server;
+ goto found;
}
- n = ngx_regex_exec(sn[i].regex, &name, r->captures, ncaptures);
-
- if (n == NGX_REGEX_NO_MATCHED) {
+ if (n == NGX_DECLINED) {
continue;
}
- if (n < 0) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- ngx_regex_exec_n
- " failed: %d on \"%V\" using \"%V\"",
- n, &name, &sn[i].name);
- return NGX_ERROR;
- }
-
- /* match */
-
- cscf = sn[i].server;
-
- r->ncaptures = ncaptures;
- r->captures_data = host;
-
- goto found;
+ return NGX_ERROR;
}
}
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
index 8f348154c..79ec02873 100644
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -10,7 +10,6 @@
#define NGX_HTTP_MAX_URI_CHANGES 10
#define NGX_HTTP_MAX_SUBREQUESTS 50
-#define NGX_HTTP_MAX_CAPTURES 9
/* must be 2^n */
#define NGX_HTTP_LC_HEADER_LEN 32
@@ -220,6 +219,7 @@ typedef struct {
unsigned msie6:1;
unsigned opera:1;
unsigned gecko:1;
+ unsigned chrome:1;
unsigned konqueror:1;
} ngx_http_headers_in_t;
@@ -457,7 +457,12 @@ struct ngx_http_request_s {
#if (NGX_HTTP_CACHE)
unsigned cached:1;
#endif
- unsigned gzip:2;
+
+#if (NGX_HTTP_GZIP)
+ unsigned gzip_tested:1;
+ unsigned gzip_ok:1;
+ unsigned gzip_vary:1;
+#endif
unsigned proxy:1;
unsigned bypass_cache:1;
diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c
index f79345715..b809e2b98 100644
--- a/src/http/ngx_http_script.c
+++ b/src/http/ngx_http_script.c
@@ -251,8 +251,6 @@ ngx_http_script_compile(ngx_http_script_compile_t *sc)
{
ngx_uint_t n;
- /* NGX_HTTP_MAX_CAPTURES is 9 */
-
if (sc->source->data[i] >= '1' && sc->source->data[i] <= '9') {
n = sc->source->data[i] - '0';
@@ -828,20 +826,9 @@ ngx_http_script_regex_start_code(ngx_http_script_engine_t *e)
e->line.data = e->sp->data;
}
- if (code->ncaptures && r->captures == NULL) {
-
- r->captures = ngx_palloc(r->pool,
- (NGX_HTTP_MAX_CAPTURES + 1) * 3 * sizeof(int));
- if (r->captures == NULL) {
- e->ip = ngx_http_script_exit;
- e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
- return;
- }
- }
-
- rc = ngx_regex_exec(code->regex, &e->line, r->captures, code->ncaptures);
+ rc = ngx_http_regex_exec(r, code->regex, &e->line);
- if (rc == NGX_REGEX_NO_MATCHED) {
+ if (rc == NGX_DECLINED) {
if (e->log || (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP)) {
ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
"\"%V\" does not match \"%V\"",
@@ -870,11 +857,7 @@ ngx_http_script_regex_start_code(ngx_http_script_engine_t *e)
return;
}
- if (rc < 0) {
- ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
- ngx_regex_exec_n " failed: %d on \"%V\" using \"%V\"",
- rc, &e->line, &code->name);
-
+ if (rc == NGX_ERROR) {
e->ip = ngx_http_script_exit;
e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
return;
@@ -885,9 +868,6 @@ ngx_http_script_regex_start_code(ngx_http_script_engine_t *e)
"\"%V\" matches \"%V\"", &code->name, &e->line);
}
- r->ncaptures = code->ncaptures;
- r->captures_data = e->line.data;
-
if (code->test) {
if (code->negative_test) {
e->sp->len = 0;
diff --git a/src/http/ngx_http_script.h b/src/http/ngx_http_script.h
index ea97069e6..90a4e1a06 100644
--- a/src/http/ngx_http_script.h
+++ b/src/http/ngx_http_script.h
@@ -114,10 +114,9 @@ typedef struct {
typedef struct {
ngx_http_script_code_pt code;
- ngx_regex_t *regex;
+ ngx_http_regex_t *regex;
ngx_array_t *lengths;
uintptr_t size;
- uintptr_t ncaptures;
uintptr_t status;
uintptr_t next;
diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c
index 62f71a3ef..060cc9934 100644
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -31,13 +31,13 @@ static u_char ngx_http_error_tail[] =
;
-static u_char ngx_http_msie_stub[] =
-"<!-- The padding to disable MSIE's friendly error page -->" CRLF
-"<!-- The padding to disable MSIE's friendly error page -->" CRLF
-"<!-- The padding to disable MSIE's friendly error page -->" CRLF
-"<!-- The padding to disable MSIE's friendly error page -->" CRLF
-"<!-- The padding to disable MSIE's friendly error page -->" CRLF
-"<!-- The padding to disable MSIE's friendly error page -->" CRLF
+static u_char ngx_http_msie_padding[] =
+"<!-- a padding to disable MSIE and Chrome friendly error page -->" CRLF
+"<!-- a padding to disable MSIE and Chrome friendly error page -->" CRLF
+"<!-- a padding to disable MSIE and Chrome friendly error page -->" CRLF
+"<!-- a padding to disable MSIE and Chrome friendly error page -->" CRLF
+"<!-- a padding to disable MSIE and Chrome friendly error page -->" CRLF
+"<!-- a padding to disable MSIE and Chrome friendly error page -->" CRLF
;
@@ -598,12 +598,12 @@ ngx_http_send_special_response(ngx_http_request_t *r,
r->headers_out.content_length_n = ngx_http_error_pages[err].len
+ len;
if (clcf->msie_padding
- && r->headers_in.msie
+ && (r->headers_in.msie || r->headers_in.chrome)
&& r->http_version >= NGX_HTTP_VERSION_10
&& err >= NGX_HTTP_LEVEL_300)
{
r->headers_out.content_length_n +=
- sizeof(ngx_http_msie_stub) - 1;
+ sizeof(ngx_http_msie_padding) - 1;
msie_padding = 1;
}
@@ -671,8 +671,8 @@ ngx_http_send_special_response(ngx_http_request_t *r,
}
b->memory = 1;
- b->pos = ngx_http_msie_stub;
- b->last = ngx_http_msie_stub + sizeof(ngx_http_msie_stub) - 1;
+ b->pos = ngx_http_msie_padding;
+ b->last = ngx_http_msie_padding + sizeof(ngx_http_msie_padding) - 1;
out[1].next = &out[2];
out[2].buf = b;
diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c
index cf87f3fac..633b31084 100644
--- a/src/http/ngx_http_variables.c
+++ b/src/http/ngx_http_variables.c
@@ -1666,6 +1666,157 @@ ngx_http_variable_pid(ngx_http_request_t *r,
}
+static ngx_int_t
+ngx_http_variable_not_found(ngx_http_request_t *r, ngx_http_variable_value_t *v,
+ uintptr_t data)
+{
+ v->not_found = 1;
+ return NGX_OK;
+}
+
+
+ngx_http_regex_t *
+ngx_http_regex_compile(ngx_conf_t *cf, ngx_regex_compile_t *rc)
+{
+ u_char *p;
+ size_t size;
+ ngx_str_t name;
+ ngx_uint_t i, n;
+ ngx_http_variable_t *v;
+ ngx_http_regex_t *re;
+ ngx_http_regex_variable_t *rv;
+ ngx_http_core_main_conf_t *cmcf;
+
+ rc->pool = cf->pool;
+
+ if (ngx_regex_compile(rc) != NGX_OK) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "%V", &rc->err);
+ return NULL;
+ }
+
+ re = ngx_pcalloc(cf->pool, sizeof(ngx_http_regex_t));
+ if (re == NULL) {
+ return NULL;
+ }
+
+ re->regex = rc->regex;
+ re->ncaptures = rc->captures;
+
+ cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
+ cmcf->ncaptures = ngx_max(cmcf->ncaptures, re->ncaptures);
+
+ n = (ngx_uint_t) rc->named_captures;
+
+ if (n == 0) {
+ return re;
+ }
+
+ rv = ngx_palloc(rc->pool, n * sizeof(ngx_http_regex_variable_t));
+ if (rv == NULL) {
+ return NULL;
+ }
+
+ re->variables = rv;
+ re->nvariables = n;
+ re->name = rc->pattern;
+
+ size = rc->name_size;
+ p = rc->names;
+
+ for (i = 0; i < n; i++) {
+ rv[i].capture = 2 * ((p[0] << 8) + p[1]);
+
+ name.data = &p[2];
+ name.len = ngx_strlen(name.data);
+
+ v = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGEABLE);
+ if (v == NULL) {
+ return NULL;
+ }
+
+ rv[i].index = ngx_http_get_variable_index(cf, &name);
+ if (rv[i].index == NGX_ERROR) {
+ return NULL;
+ }
+
+ v->get_handler = ngx_http_variable_not_found;
+
+ p += i + size;
+ }
+
+ return re;
+}
+
+
+ngx_int_t
+ngx_http_regex_exec(ngx_http_request_t *r, ngx_http_regex_t *re, ngx_str_t *s)
+{
+ ngx_int_t rc, index;
+ ngx_uint_t i, n, len;
+ ngx_http_variable_value_t *vv;
+ ngx_http_core_main_conf_t *cmcf;
+
+ cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
+
+ if (re->ncaptures) {
+ len = (cmcf->ncaptures + 1) * 3;
+
+ if (r->captures == NULL) {
+ r->captures = ngx_palloc(r->pool, len * sizeof(int));
+ if (r->captures == NULL) {
+ return NGX_ERROR;
+ }
+ }
+
+ } else {
+ len = 0;
+ }
+
+ rc = ngx_regex_exec(re->regex, s, r->captures, len);
+
+ if (rc == NGX_REGEX_NO_MATCHED) {
+ return NGX_DECLINED;
+ }
+
+ if (rc < 0) {
+ ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
+ ngx_regex_exec_n " failed: %i on \"%V\" using \"%V\"",
+ rc, s, &re->name);
+ return NGX_ERROR;
+ }
+
+ for (i = 0; i < re->nvariables; i++) {
+
+ n = re->variables[i].capture;
+ index = re->variables[i].index;
+ vv = &r->variables[index];
+
+ vv->len = r->captures[n + 1] - r->captures[n];
+ vv->valid = 1;
+ vv->no_cacheable = 0;
+ vv->not_found = 0;
+ vv->data = &s->data[r->captures[n]];
+
+#if (NGX_DEBUG)
+ {
+ ngx_http_variable_t *v;
+
+ v = cmcf->variables.elts;
+
+ ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+ "http regex set $%V to \"%*s\"",
+ &v[index].name, vv->len, vv->data);
+ }
+#endif
+ }
+
+ r->ncaptures = len;
+ r->captures_data = s->data;
+
+ return NGX_OK;
+}
+
+
ngx_int_t
ngx_http_variables_add_core_vars(ngx_conf_t *cf)
{
diff --git a/src/http/ngx_http_variables.h b/src/http/ngx_http_variables.h
index 0e86aaf3d..2056befc5 100644
--- a/src/http/ngx_http_variables.h
+++ b/src/http/ngx_http_variables.h
@@ -41,6 +41,21 @@ struct ngx_http_variable_s {
};
+typedef struct {
+ ngx_uint_t capture;
+ ngx_int_t index;
+} ngx_http_regex_variable_t;
+
+
+typedef struct {
+ ngx_regex_t *regex;
+ ngx_uint_t ncaptures;
+ ngx_http_regex_variable_t *variables;
+ ngx_uint_t nvariables;
+ ngx_str_t name;
+} ngx_http_regex_t;
+
+
ngx_http_variable_t *ngx_http_add_variable(ngx_conf_t *cf, ngx_str_t *name,
ngx_uint_t flags);
ngx_int_t ngx_http_get_variable_index(ngx_conf_t *cf, ngx_str_t *name);
@@ -59,6 +74,12 @@ ngx_int_t ngx_http_variable_unknown_header(ngx_http_variable_value_t *v,
#define ngx_http_clear_variable(r, index) r->variables0[index].text.data = NULL;
+ngx_http_regex_t *ngx_http_regex_compile(ngx_conf_t *cf,
+ ngx_regex_compile_t *rc);
+ngx_int_t ngx_http_regex_exec(ngx_http_request_t *r, ngx_http_regex_t *re,
+ ngx_str_t *s);
+
+
ngx_int_t ngx_http_variables_add_core_vars(ngx_conf_t *cf);
ngx_int_t ngx_http_variables_init_vars(ngx_conf_t *cf);
diff --git a/src/os/unix/ngx_alloc.c b/src/os/unix/ngx_alloc.c
index c38d7d27e..860666a65 100644
--- a/src/os/unix/ngx_alloc.c
+++ b/src/os/unix/ngx_alloc.c
@@ -21,7 +21,7 @@ ngx_alloc(size_t size, ngx_log_t *log)
p = malloc(size);
if (p == NULL) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
- "malloc() %uz bytes failed", size);
+ "malloc(%uz) failed", size);
}
ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, log, 0, "malloc: %p:%uz", p, size);
@@ -51,15 +51,18 @@ void *
ngx_memalign(size_t alignment, size_t size, ngx_log_t *log)
{
void *p;
+ int err;
- if (posix_memalign(&p, alignment, size) == -1) {
- ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
- "posix_memalign() %uz bytes aligned to %uz failed",
- size, alignment);
+ err = posix_memalign(&p, alignment, size);
+
+ if (err) {
+ ngx_log_error(NGX_LOG_EMERG, log, err,
+ "posix_memalign(%uz, %uz) failed", alignment, size);
+ p = NULL;
}
ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, log, 0,
- "posix_memalign: %p:%uz", p, size);
+ "posix_memalign: %p:%uz @%uz", p, size, alignment);
return p;
}
@@ -74,12 +77,11 @@ ngx_memalign(size_t alignment, size_t size, ngx_log_t *log)
p = memalign(alignment, size);
if (p == NULL) {
ngx_log_error(NGX_LOG_EMERG, log, ngx_errno,
- "memalign() %uz bytes aligned to %uz failed",
- size, alignment);
+ "memalign(%uz, %uz) failed", alignment, size);
}
ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, log, 0,
- "memalign: %p:%uz", p, size);
+ "memalign: %p:%uz @%uz", p, size, alignment);
return p;
}
diff --git a/src/os/unix/ngx_files.c b/src/os/unix/ngx_files.c
index 2264cc13e..0ef083824 100644
--- a/src/os/unix/ngx_files.c
+++ b/src/os/unix/ngx_files.c
@@ -402,6 +402,26 @@ ngx_unlock_fd(ngx_fd_t fd)
}
+#if (NGX_HAVE_POSIX_FADVISE)
+
+ngx_int_t
+ngx_read_ahead(ngx_fd_t fd, size_t n)
+{
+ int err;
+
+ err = posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL);
+
+ if (err == 0) {
+ return 0;
+ }
+
+ ngx_set_errno(err);
+ return NGX_FILE_ERROR;
+}
+
+#endif
+
+
#if (NGX_HAVE_O_DIRECT)
ngx_int_t
diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h
index 2efd24778..ccaf44a93 100644
--- a/src/os/unix/ngx_files.h
+++ b/src/os/unix/ngx_files.h
@@ -264,7 +264,7 @@ ngx_err_t ngx_unlock_fd(ngx_fd_t fd);
#define NGX_HAVE_READ_AHEAD 1
-#define ngx_read_ahead(fd, n) posix_fadvise(fd, 0, 0, POSIX_FADV_SEQUENTIAL)
+ngx_int_t ngx_read_ahead(ngx_fd_t fd, size_t n);
#define ngx_read_ahead_n "posix_fadvise(POSIX_FADV_SEQUENTIAL)"
#else