summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2011-10-17 15:16:36 +0000
committerJonathan Kolb <jon@b0g.us>2011-10-17 15:16:36 +0000
commitab0a95d65c73efb35f060e2187b21c553a8a76eb (patch)
tree43cb7d6105505710725b64de0c4fdc26e96fa416
parent770b35cc5787958e3b205bf3201558fa36fa30f9 (diff)
downloadnginx-ab0a95d65c73efb35f060e2187b21c553a8a76eb.tar.gz
Changes with nginx 1.1.6 17 Oct 2011v1.1.6
*) Change in internal API: now module context data are cleared while internal redirect to named location. Requested by Yichun Zhang. *) Change: if a server in an upstream failed, only one request will be sent to it after fail_timeout; the server will be considered alive if it will successfully respond to the request. *) Change: now the 0x7F-0x1F characters are escaped as \xXX in an access_log. *) Feature: "proxy/fastcgi/scgi/uwsgi_ignore_headers" directives support the following additional values: X-Accel-Limit-Rate, X-Accel-Buffering, X-Accel-Charset. *) Feature: decrease of memory consumption if SSL is used. *) Bugfix: some UTF-8 characters were processed incorrectly. Thanks to Alexey Kuts. *) Bugfix: the ngx_http_rewrite_module directives specified at "server" level were executed twice if no matching locations were defined. *) Bugfix: a socket leak might occurred if "aio sendfile" was used. *) Bugfix: connections with fast clients might be closed after send_timeout if file AIO was used. *) Bugfix: in the ngx_http_autoindex_module. *) Bugfix: the module ngx_http_mp4_module did not support seeking on 32-bit platforms.
-rw-r--r--CHANGES36
-rw-r--r--CHANGES.ru39
-rw-r--r--auto/install6
-rw-r--r--html/ngx_core_module.html148
-rw-r--r--src/core/nginx.h4
-rw-r--r--src/core/ngx_parse.c46
-rw-r--r--src/core/ngx_parse.h2
-rw-r--r--src/core/ngx_string.c28
-rw-r--r--src/core/ngx_string.h13
-rw-r--r--src/event/ngx_event_openssl.c8
-rw-r--r--src/http/modules/ngx_http_autoindex_module.c75
-rw-r--r--src/http/modules/ngx_http_log_module.c10
-rw-r--r--src/http/modules/ngx_http_mp4_module.c2
-rw-r--r--src/http/modules/ngx_http_proxy_module.c2
-rw-r--r--src/http/modules/ngx_http_rewrite_module.c12
-rw-r--r--src/http/modules/ngx_http_static_module.c2
-rw-r--r--src/http/modules/ngx_http_upstream_ip_hash_module.c4
-rw-r--r--src/http/modules/perl/nginx.pm2
-rw-r--r--src/http/modules/perl/nginx.xs9
-rw-r--r--src/http/ngx_http_copy_filter_module.c5
-rw-r--r--src/http/ngx_http_core_module.c40
-rw-r--r--src/http/ngx_http_core_module.h7
-rw-r--r--src/http/ngx_http_request.c18
-rw-r--r--src/http/ngx_http_script.c2
-rw-r--r--src/http/ngx_http_special_response.c4
-rw-r--r--src/http/ngx_http_upstream.c42
-rw-r--r--src/http/ngx_http_upstream.h3
-rw-r--r--src/http/ngx_http_upstream_round_robin.c21
-rw-r--r--src/http/ngx_http_upstream_round_robin.h1
29 files changed, 328 insertions, 263 deletions
diff --git a/CHANGES b/CHANGES
index c9bc84584..bd14d6077 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,40 @@
+Changes with nginx 1.1.6 17 Oct 2011
+
+ *) Change in internal API: now module context data are cleared while
+ internal redirect to named location.
+ Requested by Yichun Zhang.
+
+ *) Change: if a server in an upstream failed, only one request will be
+ sent to it after fail_timeout; the server will be considered alive if
+ it will successfully respond to the request.
+
+ *) Change: now the 0x7F-0x1F characters are escaped as \xXX in an
+ access_log.
+
+ *) Feature: "proxy/fastcgi/scgi/uwsgi_ignore_headers" directives support
+ the following additional values: X-Accel-Limit-Rate,
+ X-Accel-Buffering, X-Accel-Charset.
+
+ *) Feature: decrease of memory consumption if SSL is used.
+
+ *) Bugfix: some UTF-8 characters were processed incorrectly.
+ Thanks to Alexey Kuts.
+
+ *) Bugfix: the ngx_http_rewrite_module directives specified at "server"
+ level were executed twice if no matching locations were defined.
+
+ *) Bugfix: a socket leak might occurred if "aio sendfile" was used.
+
+ *) Bugfix: connections with fast clients might be closed after
+ send_timeout if file AIO was used.
+
+ *) Bugfix: in the ngx_http_autoindex_module.
+
+ *) Bugfix: the module ngx_http_mp4_module did not support seeking on
+ 32-bit platforms.
+
+
Changes with nginx 1.1.5 05 Oct 2011
*) Feature: the "uwsgi_buffering" and "scgi_buffering" directives.
diff --git a/CHANGES.ru b/CHANGES.ru
index c8cce4a07..873422803 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,43 @@
+Изменения в nginx 1.1.6 17.10.2011
+
+ *) Изменение во внутреннем API: теперь при внутреннем редиректе в
+ именованный location контексты модулей очищаются.
+ По запросу Yichun Zhang.
+
+ *) Изменение: теперь если сервер, описанный в блоке upstream, был
+ признан неработающим, то после истечения fail_timeout на него будет
+ отправлен только один запрос; сервер будет считаться работающим, если
+ успешно ответит на этот запрос.
+
+ *) Изменение: теперь символы 0x7F-0xFF в access_log записываются в виде
+ \xXX.
+
+ *) Добавление: директивы "proxy/fastcgi/scgi/uwsgi_ignore_headers"
+ теперь поддерживают значения X-Accel-Limit-Rate, X-Accel-Buffering и
+ X-Accel-Charset.
+
+ *) Добавление: уменьшение потребления памяти при использовании SSL.
+
+ *) Исправление: некоторые UTF-8 символы обрабатывались неправильно.
+ Спасибо Алексею Куцу.
+
+ *) Исправление: директивы модуля ngx_http_rewrite_module, заданные на
+ уровне server, применялись повторно, если для запроса не находилось
+ ни одного location'а.
+
+ *) Исправление: при использовании "aio sendfile" могла происходить
+ утечка сокетов.
+
+ *) Исправление: при использовании файлового AIO соединения с быстрыми
+ клиентами могли быть закрыты по истечению send_timeout.
+
+ *) Исправление: в модуле ngx_http_autoindex_module.
+
+ *) Исправление: модуль ngx_http_mp4_module не поддерживал перемотку на
+ 32-битных платформах.
+
+
Изменения в nginx 1.1.5 05.10.2011
*) Добавление: директивы uwsgi_buffering и scgi_buffering.
diff --git a/auto/install b/auto/install
index 6cf217e73..d77efbf74 100644
--- a/auto/install
+++ b/auto/install
@@ -53,7 +53,7 @@ esac
case ".$NGX_ERROR_LOG_PATH" in
- ./*)
+ ./* | .)
;;
*)
@@ -80,7 +80,7 @@ $NGX_OBJS/nginx.8: man/nginx.8 $NGX_AUTO_CONFIG_H
sed -e "s|%%PREFIX%%|$NGX_PREFIX|" \\
-e "s|%%PID_PATH%%|$NGX_PID_PATH|" \\
-e "s|%%CONF_PATH%%|$NGX_CONF_PATH|" \\
- -e "s|%%ERROR_LOG_PATH%%|$NGX_ERROR_LOG_PATH|" \\
+ -e "s|%%ERROR_LOG_PATH%%|${NGX_ERROR_LOG_PATH:-stderr}|" \\
< man/nginx.8 > $NGX_OBJS/nginx.8
install: $NGX_OBJS${ngx_dirsep}nginx${ngx_binext} \
@@ -139,7 +139,7 @@ install: $NGX_OBJS${ngx_dirsep}nginx${ngx_binext} \
END
-if test -n "\$(DESTDIR)$NGX_ERROR_LOG_PATH"; then
+if test -n "$NGX_ERROR_LOG_PATH"; then
cat << END >> $NGX_MAKEFILE
test -d '\$(DESTDIR)`dirname "$NGX_ERROR_LOG_PATH"`' || \
diff --git a/html/ngx_core_module.html b/html/ngx_core_module.html
deleted file mode 100644
index 4c5e8d8ac..000000000
--- a/html/ngx_core_module.html
+++ /dev/null
@@ -1,148 +0,0 @@
-<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>Core Module</title></head><body><center><h3>Core Module</h3></center><a name="example"></a><center><h4>Example Configuration</h4></center><p><blockquote><pre>
-user www www;
-worker_processes 2;
-
-error_log /var/log/nginx-error.log info;
-
-events {
- use kqueue;
- worker_connections 2048;
-}
-
-...
-</pre></blockquote></p><a name="directives"></a><center><h4>Directives</h4></center><hr><a name="daemon"></a><strong>syntax</strong>:
- <code>daemon <code>on</code> | <code>off</code></code><br><strong>default</strong>:
- <code>daemon on</code><br><strong>context</strong>:
- <code>main</code><br><p>
-Determines whether nginx should become a daemon.
-Mainly used during development.
-</p><hr><a name="env"></a><strong>syntax</strong>:
- <code>env <code><i>VAR</i></code>[=<code><i>VALUE</i></code>]</code><br><strong>default</strong>:
- <code>env TZ</code><br><strong>context</strong>:
- <code>main</code><br><p>
-Allows to limit a set of environment variables, change their values,
-or create new environment variables, for the following cases:
-<ul><li>
-variable inheritance during a
-<a href="control.html#upgrade">live upgrade</a>
-of an executable file;
-</li><li>
-use of variables by the module
-<a href="http/ngx_http_perl_module.html">ngx_http_perl_module</a>;
-</li><li>
-use of variables by worker processes.
-Please bear in mind that controlling system libraries in this way
-is not always possible as it is not uncommon for libraries to check
-variables only during initialization, well before they can be set
-using this directive.
-An exception from this is an above mentioned
-<a href="control.html#upgrade">live upgrade</a>
-of an executable file.
-</li></ul></p><p>
-The TZ variable is always inherited and made available to the module
-<a href="http/ngx_http_perl_module.html">ngx_http_perl_module</a>,
-unless configured explicitly.
-</p><p>
-Usage example:
-<blockquote><pre>
-env MALLOC_OPTIONS;
-env PERL5LIB=/data/site/modules;
-env OPENSSL_ALLOW_PROXY_CERTS=1;
-</pre></blockquote></p><hr><a name="include"></a><strong>syntax</strong>:
- <code>include <code><i>file</i></code> | <code><i>mask</i></code></code><br><strong>default</strong>:
- <strong>none</strong><br><strong>context</strong>:
- <strong>any</strong><br><p>
-Includes another <code><i>file</i></code>, or files matching the
-specified <code><i>mask</i></code>, into configuration.
-Included files should consist of
-syntactically correct directives and blocks.
-</p><p>
-Usage example:
-<blockquote><pre>
-include mime.types;
-include vhosts/*.conf;
-</pre></blockquote></p><hr><a name="master_process"></a><strong>syntax</strong>:
- <code>master_process <code>on</code> | <code>off</code></code><br><strong>default</strong>:
- <code>master_process on</code><br><strong>context</strong>:
- <code>main</code><br><p>
-Determines whether worker processes are started.
-This directive is intended for nginx developers.
-</p><hr><a name="pid"></a><strong>syntax</strong>:
- <code>pid <code><i>file</i></code></code><br><strong>default</strong>:
- <code>pid nginx.pid</code><br><strong>context</strong>:
- <code>main</code><br><p>
-Defines a <code><i>file</i></code> which will store the process ID of the main process.
-</p><hr><a name="ssl_engine"></a><strong>syntax</strong>:
- <code>ssl_engine <code><i>device</i></code></code><br><strong>default</strong>:
- <strong>none</strong><br><strong>context</strong>:
- <code>main</code><br><p>
-Defines the name of the hardware SSL accelerator.
-</p><hr><a name="user"></a><strong>syntax</strong>:
- <code>user <code><i>user</i></code> [<code><i>group</i></code>]</code><br><strong>default</strong>:
- <code>user nobody nobody</code><br><strong>context</strong>:
- <code>main</code><br><p>
-Defines <code><i>user</i></code> and <code><i>group</i></code>
-credentials used by worker processes.
-If <code><i>group</i></code> is omitted, a group whose name equals
-that of <code><i>user</i></code> is used.
-</p><hr><a name="timer_resolution"></a><strong>syntax</strong>:
- <code>timer_resolution <code><i>interval</i></code></code><br><strong>default</strong>:
- <strong>none</strong><br><strong>context</strong>:
- <code>main</code><br><p>
-Reduces timer resolution in worker processes, thus reducing the
-number of <code>gettimeofday()</code> system calls made.
-By default, <code>gettimeofday()</code> is called each time
-on receiving a kernel event.
-With reduced resolution, <code>gettimeofday()</code> is only
-called once per specified <code><i>interval</i></code>.
-</p><p>
-Example:
-<blockquote><pre>
-timer_resolution 100ms;
-</pre></blockquote></p><p>
-An internal implementation of interval depends on the method used:
-<ul><li>
-an <code>EVFILT_TIMER</code> filter if <code>kqueue</code> is used;
-</li><li><code>timer_create()</code> if <code>eventport</code> is used;
-</li><li><code>setitimer()</code> otherwise.
-</li></ul></p><hr><a name="worker_rlimit_core"></a><strong>syntax</strong>:
- <code>worker_rlimit_core <code><i>size</i></code></code><br><strong>default</strong>:
- <strong>none</strong><br><strong>context</strong>:
- <code>main</code><br><p>
-Changes the limit on the largest size of a core file
-(<code>RLIMIT_CORE</code>) for worker processes.
-Used to increase the limit without restarting the main process.
-</p><hr><a name="worker_rlimit_nofile"></a><strong>syntax</strong>:
- <code>worker_rlimit_nofile <code><i>number</i></code></code><br><strong>default</strong>:
- <strong>none</strong><br><strong>context</strong>:
- <code>main</code><br><p>
-Changes the limit on the maximum number of open files
-(<code>RLIMIT_NOFILE</code>) for worker processes.
-Used to increase the limit without restarting the main process.
-</p><hr><a name="worker_priority"></a><strong>syntax</strong>:
- <code>worker_priority <code><i>number</i></code></code><br><strong>default</strong>:
- <code>worker_priority 0</code><br><strong>context</strong>:
- <code>main</code><br><p>
-Defines a scheduling priority for worker processes like is
-done by the <code>nice</code>: a negative
-<code><i>number</i></code>
-means higher priority.
-Allowed range normally varies from -20 to 20.
-</p><p>
-Example:
-<blockquote><pre>
-worker_priority -10;
-</pre></blockquote></p><hr><a name="worker_processes"></a><strong>syntax</strong>:
- <code>worker_processes <code><i>number</i></code></code><br><strong>default</strong>:
- <code>worker_processes 1</code><br><strong>context</strong>:
- <code>main</code><br><p>
-Defines the number of worker processes.
-</p><hr><a name="working_directory"></a><strong>syntax</strong>:
- <code>working_directory <code><i>directory</i></code></code><br><strong>default</strong>:
- <strong>none</strong><br><strong>context</strong>:
- <code>main</code><br><p>
-Defines a current working directory for a worker process.
-It is primarily used when writing a core-file, in which case
-a working process should have write permission for the
-specified directory.
-</p></body></html>
diff --git a/src/core/nginx.h b/src/core/nginx.h
index a5d945d49..4ce316b5d 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,8 +8,8 @@
#define _NGINX_H_INCLUDED_
-#define nginx_version 1001005
-#define NGINX_VERSION "1.1.5"
+#define nginx_version 1001006
+#define NGINX_VERSION "1.1.6"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
diff --git a/src/core/ngx_parse.c b/src/core/ngx_parse.c
index 6c4640cf7..dff59ff60 100644
--- a/src/core/ngx_parse.c
+++ b/src/core/ngx_parse.c
@@ -93,7 +93,7 @@ ngx_parse_offset(ngx_str_t *line)
ngx_int_t
-ngx_parse_time(ngx_str_t *line, ngx_uint_t sec)
+ngx_parse_time(ngx_str_t *line, ngx_uint_t is_sec)
{
u_char *p, *last;
ngx_int_t value, total, scale;
@@ -114,8 +114,8 @@ ngx_parse_time(ngx_str_t *line, ngx_uint_t sec)
valid = 0;
value = 0;
total = 0;
- step = sec ? st_start : st_month;
- scale = sec ? 1 : 1000;
+ step = is_sec ? st_start : st_month;
+ scale = is_sec ? 1 : 1000;
p = line->data;
last = p + line->len;
@@ -135,81 +135,81 @@ ngx_parse_time(ngx_str_t *line, ngx_uint_t sec)
return NGX_ERROR;
}
step = st_year;
- max = 68;
+ max = NGX_MAX_INT32_VALUE / (60 * 60 * 24 * 365);
scale = 60 * 60 * 24 * 365;
break;
case 'M':
- if (step > st_year) {
+ if (step >= st_month) {
return NGX_ERROR;
}
step = st_month;
- max = 828;
+ max = NGX_MAX_INT32_VALUE / (60 * 60 * 24 * 30);
scale = 60 * 60 * 24 * 30;
break;
case 'w':
- if (step > st_month) {
+ if (step >= st_week) {
return NGX_ERROR;
}
step = st_week;
- max = 3550;
+ max = NGX_MAX_INT32_VALUE / (60 * 60 * 24 * 7);
scale = 60 * 60 * 24 * 7;
break;
case 'd':
- if (step > st_week) {
+ if (step >= st_day) {
return NGX_ERROR;
}
step = st_day;
- max = 24855;
+ max = NGX_MAX_INT32_VALUE / (60 * 60 * 24);
scale = 60 * 60 * 24;
break;
case 'h':
- if (step > st_day) {
+ if (step >= st_hour) {
return NGX_ERROR;
}
step = st_hour;
- max = 596523;
+ max = NGX_MAX_INT32_VALUE / (60 * 60);
scale = 60 * 60;
break;
case 'm':
if (*p == 's') {
- if (sec || step > st_sec) {
+ if (is_sec || step >= st_msec) {
return NGX_ERROR;
}
p++;
step = st_msec;
- max = 2147483647;
+ max = NGX_MAX_INT32_VALUE;
scale = 1;
break;
}
- if (step > st_hour) {
+ if (step >= st_min) {
return NGX_ERROR;
}
step = st_min;
- max = 35791394;
+ max = NGX_MAX_INT32_VALUE / 60;
scale = 60;
break;
case 's':
- if (step > st_min) {
+ if (step >= st_sec) {
return NGX_ERROR;
}
step = st_sec;
- max = 2147483647;
+ max = NGX_MAX_INT32_VALUE;
scale = 1;
break;
case ' ':
- if (step > st_min) {
+ if (step >= st_sec) {
return NGX_ERROR;
}
step = st_last;
- max = 2147483647;
+ max = NGX_MAX_INT32_VALUE;
scale = 1;
break;
@@ -217,7 +217,7 @@ ngx_parse_time(ngx_str_t *line, ngx_uint_t sec)
return NGX_ERROR;
}
- if (step != st_msec && !sec) {
+ if (step != st_msec && !is_sec) {
scale *= 1000;
max /= 1000;
}
@@ -228,12 +228,12 @@ ngx_parse_time(ngx_str_t *line, ngx_uint_t sec)
total += value * scale;
- if ((ngx_uint_t) total > 2147483647) {
+ if ((ngx_uint_t) total > NGX_MAX_INT32_VALUE) {
return NGX_ERROR;
}
value = 0;
- scale = sec ? 1 : 1000;
+ scale = is_sec ? 1 : 1000;
while (p < last && *p == ' ') {
p++;
diff --git a/src/core/ngx_parse.h b/src/core/ngx_parse.h
index c25a3a023..e770623fd 100644
--- a/src/core/ngx_parse.h
+++ b/src/core/ngx_parse.h
@@ -17,7 +17,7 @@
ssize_t ngx_parse_size(ngx_str_t *line);
off_t ngx_parse_offset(ngx_str_t *line);
-ngx_int_t ngx_parse_time(ngx_str_t *line, ngx_uint_t sec);
+ngx_int_t ngx_parse_time(ngx_str_t *line, ngx_uint_t is_sec);
#endif /* _NGX_PARSE_H_INCLUDED_ */
diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c
index 75bc6578d..29f8e0d67 100644
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -1211,19 +1211,19 @@ ngx_utf8_decode(u_char **p, size_t n)
u = **p;
- if (u > 0xf0) {
+ if (u >= 0xf0) {
u &= 0x07;
valid = 0xffff;
len = 3;
- } else if (u > 0xe0) {
+ } else if (u >= 0xe0) {
u &= 0x0f;
valid = 0x7ff;
len = 2;
- } else if (u > 0xc0) {
+ } else if (u >= 0xc2) {
u &= 0x1f;
valid = 0x7f;
@@ -1380,6 +1380,26 @@ ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
};
+ /* not ALPHA, DIGIT, "-", ".", "_", "~" */
+
+ static uint32_t uri_component[] = {
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+
+ /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
+ 0xfc009fff, /* 1111 1100 0000 0000 1001 1111 1111 1111 */
+
+ /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
+ 0x78000001, /* 0111 1000 0000 0000 0000 0000 0000 0001 */
+
+ /* ~}| {zyx wvut srqp onml kjih gfed cba` */
+ 0xb8000001, /* 1011 1000 0000 0000 0000 0000 0000 0001 */
+
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ };
+
/* " ", "#", """, "%", "'", %00-%1F, %7F-%FF */
static uint32_t html[] = {
@@ -1443,7 +1463,7 @@ ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
/* mail_auth is the same as memcached */
static uint32_t *map[] =
- { uri, args, html, refresh, memcached, memcached };
+ { uri, args, uri_component, html, refresh, memcached, memcached };
escape = map[type];
diff --git a/src/core/ngx_string.h b/src/core/ngx_string.h
index 2030988d8..2b9c59a5e 100644
--- a/src/core/ngx_string.h
+++ b/src/core/ngx_string.h
@@ -189,12 +189,13 @@ size_t ngx_utf8_length(u_char *p, size_t n);
u_char *ngx_utf8_cpystrn(u_char *dst, u_char *src, size_t n, size_t len);
-#define NGX_ESCAPE_URI 0
-#define NGX_ESCAPE_ARGS 1
-#define NGX_ESCAPE_HTML 2
-#define NGX_ESCAPE_REFRESH 3
-#define NGX_ESCAPE_MEMCACHED 4
-#define NGX_ESCAPE_MAIL_AUTH 5
+#define NGX_ESCAPE_URI 0
+#define NGX_ESCAPE_ARGS 1
+#define NGX_ESCAPE_URI_COMPONENT 2
+#define NGX_ESCAPE_HTML 3
+#define NGX_ESCAPE_REFRESH 4
+#define NGX_ESCAPE_MEMCACHED 5
+#define NGX_ESCAPE_MAIL_AUTH 6
#define NGX_UNESCAPE_URI 1
#define NGX_UNESCAPE_REDIRECT 2
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index 259b1d8f2..bbec1db0e 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -175,6 +175,14 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data)
SSL_CTX_set_options(ssl->ctx, ngx_ssl_protocols[protocols >> 1]);
}
+#ifdef SSL_OP_NO_COMPRESSION
+ SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_COMPRESSION);
+#endif
+
+#ifdef SSL_MODE_RELEASE_BUFFERS
+ SSL_CTX_set_mode(ssl->ctx, SSL_MODE_RELEASE_BUFFERS);
+#endif
+
SSL_CTX_set_read_ahead(ssl->ctx, 1);
SSL_CTX_set_info_callback(ssl->ctx, ngx_ssl_info_callback);
diff --git a/src/http/modules/ngx_http_autoindex_module.c b/src/http/modules/ngx_http_autoindex_module.c
index b67931806..bd7388126 100644
--- a/src/http/modules/ngx_http_autoindex_module.c
+++ b/src/http/modules/ngx_http_autoindex_module.c
@@ -26,9 +26,9 @@ typedef struct {
ngx_str_t name;
size_t utf_len;
size_t escape;
+ size_t escape_html;
unsigned dir:1;
- unsigned colon:1;
time_t mtime;
off_t size;
@@ -138,7 +138,7 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
{
u_char *last, *filename, scale;
off_t length;
- size_t len, utf_len, allocated, root;
+ size_t len, char_len, escape_html, allocated, root;
ngx_tm_t tm;
ngx_err_t err;
ngx_buf_t *b;
@@ -338,7 +338,10 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
ngx_cpystrn(entry->name.data, ngx_de_name(&dir), len + 1);
entry->escape = 2 * ngx_escape_uri(NULL, ngx_de_name(&dir), len,
- NGX_ESCAPE_HTML);
+ NGX_ESCAPE_URI_COMPONENT);
+
+ entry->escape_html = ngx_escape_html(NULL, entry->name.data,
+ entry->name.len);
if (utf8) {
entry->utf_len = ngx_utf8_length(entry->name.data, entry->name.len);
@@ -346,8 +349,6 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
entry->utf_len = len;
}
- entry->colon = (ngx_strchr(entry->name.data, ':') != NULL);
-
entry->dir = ngx_de_is_dir(&dir);
entry->mtime = ngx_de_mtime(&dir);
entry->size = ngx_de_size(&dir);
@@ -358,10 +359,12 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
ngx_close_dir_n " \"%s\" failed", &path);
}
+ escape_html = ngx_escape_html(NULL, r->uri.data, r->uri.len);
+
len = sizeof(title) - 1
- + r->uri.len
+ + r->uri.len + escape_html
+ sizeof(header) - 1
- + r->uri.len
+ + r->uri.len + escape_html
+ sizeof("</h1>") - 1
+ sizeof("<hr><pre><a href=\"../\">../</a>" CRLF) - 1
+ sizeof("</pre><hr>") - 1
@@ -373,7 +376,8 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
+ entry[i].name.len + entry[i].escape
+ 1 /* 1 is for "/" */
+ sizeof("\">") - 1
- + entry[i].name.len - entry[i].utf_len + entry[i].colon * 2
+ + entry[i].name.len - entry[i].utf_len
+ + entry[i].escape_html
+ NGX_HTTP_AUTOINDEX_NAME_LEN + sizeof("&gt;") - 2
+ sizeof("</a>") - 1
+ sizeof(" 28-Sep-1970 12:00 ") - 1
@@ -393,9 +397,18 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
}
b->last = ngx_cpymem(b->last, title, sizeof(title) - 1);
- b->last = ngx_cpymem(b->last, r->uri.data, r->uri.len);
- b->last = ngx_cpymem(b->last, header, sizeof(header) - 1);
- b->last = ngx_cpymem(b->last, r->uri.data, r->uri.len);
+
+ if (escape_html) {
+ b->last = (u_char *) ngx_escape_html(b->last, r->uri.data, r->uri.len);
+ b->last = ngx_cpymem(b->last, header, sizeof(header) - 1);
+ b->last = (u_char *) ngx_escape_html(b->last, r->uri.data, r->uri.len);
+
+ } else {
+ b->last = ngx_cpymem(b->last, r->uri.data, r->uri.len);
+ b->last = ngx_cpymem(b->last, header, sizeof(header) - 1);
+ b->last = ngx_cpymem(b->last, r->uri.data, r->uri.len);
+ }
+
b->last = ngx_cpymem(b->last, "</h1>", sizeof("</h1>") - 1);
b->last = ngx_cpymem(b->last, "<hr><pre><a href=\"../\">../</a>" CRLF,
@@ -406,14 +419,9 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
for (i = 0; i < entries.nelts; i++) {
b->last = ngx_cpymem(b->last, "<a href=\"", sizeof("<a href=\"") - 1);
- if (entry[i].colon) {
- *b->last++ = '.';
- *b->last++ = '/';
- }
-
if (entry[i].escape) {
ngx_escape_uri(b->last, entry[i].name.data, entry[i].name.len,
- NGX_ESCAPE_HTML);
+ NGX_ESCAPE_URI_COMPONENT);
b->last += entry[i].name.len + entry[i].escape;
@@ -433,20 +441,41 @@ ngx_http_autoindex_handler(ngx_http_request_t *r)
if (entry[i].name.len != len) {
if (len > NGX_HTTP_AUTOINDEX_NAME_LEN) {
- utf_len = NGX_HTTP_AUTOINDEX_NAME_LEN - 3 + 1;
+ char_len = NGX_HTTP_AUTOINDEX_NAME_LEN - 3 + 1;
} else {
- utf_len = NGX_HTTP_AUTOINDEX_NAME_LEN + 1;
+ char_len = NGX_HTTP_AUTOINDEX_NAME_LEN + 1;
}
+ last = b->last;
b->last = ngx_utf8_cpystrn(b->last, entry[i].name.data,
- utf_len, entry[i].name.len + 1);
+ char_len, entry[i].name.len + 1);
+
+ if (entry[i].escape_html) {
+ b->last = (u_char *) ngx_escape_html(last, entry[i].name.data,
+ b->last - last);
+ }
+
last = b->last;
} else {
- b->last = ngx_cpystrn(b->last, entry[i].name.data,
- NGX_HTTP_AUTOINDEX_NAME_LEN + 1);
- last = b->last - 3;
+ if (entry[i].escape_html) {
+ if (len > NGX_HTTP_AUTOINDEX_NAME_LEN) {
+ char_len = NGX_HTTP_AUTOINDEX_NAME_LEN - 3;
+
+ } else {
+ char_len = len;
+ }
+
+ b->last = (u_char *) ngx_escape_html(b->last,
+ entry[i].name.data, char_len);
+ last = b->last;
+
+ } else {
+ b->last = ngx_cpystrn(b->last, entry[i].name.data,
+ NGX_HTTP_AUTOINDEX_NAME_LEN + 1);
+ last = b->last - 3;
+ }
}
if (len > NGX_HTTP_AUTOINDEX_NAME_LEN) {
diff --git a/src/http/modules/ngx_http_log_module.c b/src/http/modules/ngx_http_log_module.c
index 9728d5411..da6fbb619 100644
--- a/src/http/modules/ngx_http_log_module.c
+++ b/src/http/modules/ngx_http_log_module.c
@@ -690,12 +690,12 @@ ngx_http_log_escape(u_char *dst, u_char *src, size_t size)
0x10000000, /* 0001 0000 0000 0000 0000 0000 0000 0000 */
/* ~}| {zyx wvut srqp onml kjih gfed cba` */
- 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
+ 0x80000000, /* 1000 0000 0000 0000 0000 0000 0000 0000 */
- 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
- 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
- 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
- 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
};
diff --git a/src/http/modules/ngx_http_mp4_module.c b/src/http/modules/ngx_http_mp4_module.c
index 1140d9174..a6752123a 100644
--- a/src/http/modules/ngx_http_mp4_module.c
+++ b/src/http/modules/ngx_http_mp4_module.c
@@ -1882,7 +1882,7 @@ ngx_http_mp4_update_stts_atom(ngx_http_mp4_file_t *mp4,
}
entries = trak->time_to_sample_entries;
- start_time = mp4->start * trak->timescale / 1000;
+ start_time = (uint64_t) mp4->start * trak->timescale / 1000;
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
"time-to-sample start_time:%uL", start_time);
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index a8bbff6b9..24fbc2f79 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -1560,7 +1560,7 @@ ngx_http_proxy_copy_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
p->upstream_done = 1;
ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
- "upstream sent too many data");
+ "upstream sent too much data");
}
return NGX_OK;
diff --git a/src/http/modules/ngx_http_rewrite_module.c b/src/http/modules/ngx_http_rewrite_module.c
index 5164734f2..2ef24405c 100644
--- a/src/http/modules/ngx_http_rewrite_module.c
+++ b/src/http/modules/ngx_http_rewrite_module.c
@@ -135,10 +135,22 @@ ngx_module_t ngx_http_rewrite_module = {
static ngx_int_t
ngx_http_rewrite_handler(ngx_http_request_t *r)
{
+ ngx_int_t index;
ngx_http_script_code_pt code;
ngx_http_script_engine_t *e;
+ ngx_http_core_srv_conf_t *cscf;
+ ngx_http_core_main_conf_t *cmcf;
ngx_http_rewrite_loc_conf_t *rlcf;
+ cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
+ cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
+ index = cmcf->phase_engine.location_rewrite_index;
+
+ if (r->phase_handler == index && r->loc_conf == cscf->ctx->loc_conf) {
+ /* skipping location rewrite phase for server null location */
+ return NGX_DECLINED;
+ }
+
rlcf = ngx_http_get_module_loc_conf(r, ngx_http_rewrite_module);
if (rlcf->codes == NULL) {
diff --git a/src/http/modules/ngx_http_static_module.c b/src/http/modules/ngx_http_static_module.c
index 57b5130d4..cea050a94 100644
--- a/src/http/modules/ngx_http_static_module.c
+++ b/src/http/modules/ngx_http_static_module.c
@@ -139,6 +139,8 @@ ngx_http_static_handler(ngx_http_request_t *r)
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, log, 0, "http dir");
+ ngx_http_clear_location(r);
+
r->headers_out.location = ngx_palloc(r->pool, sizeof(ngx_table_elt_t));
if (r->headers_out.location == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
diff --git a/src/http/modules/ngx_http_upstream_ip_hash_module.c b/src/http/modules/ngx_http_upstream_ip_hash_module.c
index dffbf22b2..4c031eb47 100644
--- a/src/http/modules/ngx_http_upstream_ip_hash_module.c
+++ b/src/http/modules/ngx_http_upstream_ip_hash_module.c
@@ -185,8 +185,8 @@ ngx_http_upstream_get_ip_hash_peer(ngx_peer_connection_t *pc, void *data)
break;
}
- if (now - peer->accessed > peer->fail_timeout) {
- peer->fails = 0;
+ if (now - peer->checked > peer->fail_timeout) {
+ peer->checked = now;
break;
}
}
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index 126d29c93..07ad21473 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.5';
+our $VERSION = '1.1.6';
require XSLoader;
XSLoader::load('nginx', $VERSION);
diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs
index 035e261eb..e3a9dd5c9 100644
--- a/src/http/modules/perl/nginx.xs
+++ b/src/http/modules/perl/nginx.xs
@@ -474,6 +474,13 @@ header_out(r, key, value)
r->headers_out.content_length = header;
}
+ if (header->key.len == sizeof("Content-Encoding") - 1
+ && ngx_strncasecmp(header->key.data, "Content-Encoding",
+ sizeof("Content-Encoding") - 1) == 0)
+ {
+ r->headers_out.content_encoding = header;
+ }
+
void
filename(r)
@@ -836,7 +843,7 @@ variable(r, name, value = NULL)
var.len = len;
var.data = lowcase;
- #if (NGX_LOG_DEBUG)
+ #if (NGX_DEBUG)
if (value) {
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
diff --git a/src/http/ngx_http_copy_filter_module.c b/src/http/ngx_http_copy_filter_module.c
index 2eb6487d8..0f9917e2e 100644
--- a/src/http/ngx_http_copy_filter_module.c
+++ b/src/http/ngx_http_copy_filter_module.c
@@ -158,6 +158,11 @@ ngx_http_copy_filter(ngx_http_request_t *r, ngx_chain_t *in)
ngx_file_t *file;
ngx_http_ephemeral_t *e;
+ if (r->aio) {
+ c->busy_sendfile = NULL;
+ return rc;
+ }
+
file = c->busy_sendfile->file;
offset = c->busy_sendfile->file_pos;
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 3056e8470..c6909cd2e 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -983,6 +983,8 @@ ngx_http_core_find_config_phase(ngx_http_request_t *r,
}
if (rc == NGX_DONE) {
+ ngx_http_clear_location(r);
+
r->headers_out.location = ngx_list_push(&r->headers_out.headers);
if (r->headers_out.location == NULL) {
ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
@@ -1796,6 +1798,8 @@ ngx_http_send_response(ngx_http_request_t *r, ngx_uint_t status,
if (status >= NGX_HTTP_MOVED_PERMANENTLY && status <= NGX_HTTP_SEE_OTHER) {
+ ngx_http_clear_location(r);
+
r->headers_out.location = ngx_list_push(&r->headers_out.headers);
if (r->headers_out.location == NULL) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
@@ -2542,6 +2546,9 @@ ngx_http_named_location(ngx_http_request_t *r, ngx_str_t *name)
r->content_handler = NULL;
r->loc_conf = (*clcfp)->loc_conf;
+ /* clear the modules contexts */
+ ngx_memzero(r->ctx, sizeof(void *) * ngx_http_max_module);
+
ngx_http_update_location_config(r);
cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
@@ -2994,6 +3001,12 @@ ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
value = cf->args->elts;
if (ngx_strcmp(value[0].data, "include") == 0) {
+ if (cf->args->nelts != 2) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid number of arguments"
+ " in \"include\" directive");
+ return NGX_CONF_ERROR;
+ }
file = value[1];
if (ngx_conf_full_name(cf->cycle, &file, 1) != NGX_OK) {
@@ -3027,7 +3040,7 @@ ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
"content type: \"%V\", "
"previous content type: \"%V\"",
&value[i], content_type, old);
- continue;
+ goto next;
}
}
@@ -3040,6 +3053,9 @@ ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
type->key = value[i];
type->key_hash = hash;
type->value = content_type;
+
+ next:
+ continue;
}
return NGX_CONF_OK;
@@ -3373,7 +3389,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_cacheline_size);
/*
- * the special handling the "types" directive in the "http" section
+ * the special handling of the "types" directive in the "http" section
* to inherit the http's conf->types_hash to all servers
*/
@@ -3400,7 +3416,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
}
if (conf->types == NULL) {
- conf->types = ngx_array_create(cf->pool, 4, sizeof(ngx_hash_key_t));
+ conf->types = ngx_array_create(cf->pool, 3, sizeof(ngx_hash_key_t));
if (conf->types == NULL) {
return NGX_CONF_ERROR;
}
@@ -3425,7 +3441,7 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
types_hash.key = ngx_hash_key_lc;
types_hash.max_size = conf->types_hash_max_size;
types_hash.bucket_size = conf->types_hash_bucket_size;
- types_hash.name = "mime_types_hash";
+ types_hash.name = "types_hash";
types_hash.pool = cf->pool;
types_hash.temp_pool = NULL;
@@ -3467,9 +3483,10 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_uint_value(conf->if_modified_since, prev->if_modified_since,
NGX_HTTP_IMS_EXACT);
ngx_conf_merge_uint_value(conf->max_ranges, prev->max_ranges,
- 0x7fffffff);
+ NGX_MAX_INT32_VALUE);
ngx_conf_merge_uint_value(conf->client_body_in_file_only,
- prev->client_body_in_file_only, 0);
+ prev->client_body_in_file_only,
+ NGX_HTTP_REQUEST_BODY_FILE_OFF);
ngx_conf_merge_value(conf->client_body_in_single_buffer,
prev->client_body_in_single_buffer, 0);
ngx_conf_merge_value(conf->internal, prev->internal, 0);
@@ -3477,11 +3494,11 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_size_value(conf->sendfile_max_chunk,
prev->sendfile_max_chunk, 0);
#if (NGX_HAVE_FILE_AIO)
- ngx_conf_merge_value(conf->aio, prev->aio, 0);
+ ngx_conf_merge_value(conf->aio, prev->aio, NGX_HTTP_AIO_OFF);
#endif
ngx_conf_merge_size_value(conf->read_ahead, prev->read_ahead, 0);
ngx_conf_merge_off_value(conf->directio, prev->directio,
- NGX_MAX_OFF_T_VALUE);
+ NGX_OPEN_FILE_DIRECTIO_OFF);
ngx_conf_merge_off_value(conf->directio_alignment, prev->directio_alignment,
512);
ngx_conf_merge_value(conf->tcp_nopush, prev->tcp_nopush, 0);
@@ -3839,13 +3856,6 @@ ngx_http_core_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
&value[i]);
}
- if (value[i].len == 1 && ch == '*') {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "\"server_name *\" is unsupported, use "
- "\"server_name_in_redirect off\" instead");
- return NGX_CONF_ERROR;
- }
-
sn = ngx_array_push(&cscf->server_names);
if (sn == NULL) {
return NGX_CONF_ERROR;
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index df20b5d3a..d2764fe0d 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -529,5 +529,12 @@ extern ngx_str_t ngx_http_core_get_method;
r->headers_out.last_modified = NULL; \
}
+#define ngx_http_clear_location(r) \
+ \
+ if (r->headers_out.location) { \
+ r->headers_out.location->hash = 0; \
+ r->headers_out.location = NULL; \
+ }
+
#endif /* _NGX_HTTP_CORE_H_INCLUDED_ */
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index ac54b1f5a..c0d56ecaa 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -2248,17 +2248,17 @@ ngx_http_writer(ngx_http_request_t *r)
return;
}
- } else {
- if (wev->delayed || r->aio) {
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0,
- "http writer delayed");
+ }
- if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
- ngx_http_close_request(r, 0);
- }
+ if (wev->delayed || r->aio) {
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0,
+ "http writer delayed");
- return;
+ if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
+ ngx_http_close_request(r, 0);
}
+
+ return;
}
rc = ngx_http_output_filter(r, NULL);
@@ -2274,7 +2274,7 @@ ngx_http_writer(ngx_http_request_t *r)
if (r->buffered || r->postponed || (r == r->main && c->buffered)) {
- if (!wev->ready && !wev->delayed) {
+ if (!wev->delayed) {
ngx_add_timer(wev, clcf->send_timeout);
}
diff --git a/src/http/ngx_http_script.c b/src/http/ngx_http_script.c
index a703f0837..6d81b4435 100644
--- a/src/http/ngx_http_script.c
+++ b/src/http/ngx_http_script.c
@@ -1106,6 +1106,8 @@ ngx_http_script_regex_end_code(ngx_http_script_engine_t *e)
"rewritten redirect: \"%V\"", &e->buf);
}
+ ngx_http_clear_location(r);
+
r->headers_out.location = ngx_list_push(&r->headers_out.headers);
if (r->headers_out.location == NULL) {
e->ip = ngx_http_script_exit;
diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c
index 0d66a4b6b..d30b781e5 100644
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -375,7 +375,7 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
}
}
- if (r->lingering_close == 1) {
+ if (r->lingering_close) {
switch (error) {
case NGX_HTTP_BAD_REQUEST:
case NGX_HTTP_TO_HTTPS:
@@ -582,6 +582,8 @@ ngx_http_send_error_page(ngx_http_request_t *r, ngx_http_err_page_t *err_page)
ngx_str_set(&location->key, "Location");
location->value = uri;
+ ngx_http_clear_location(r);
+
r->headers_out.location = location;
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index 89d21d860..3645d3bd4 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -369,6 +369,9 @@ ngx_conf_bitmask_t ngx_http_upstream_cache_method_mask[] = {
ngx_conf_bitmask_t ngx_http_upstream_ignore_headers_masks[] = {
{ ngx_string("X-Accel-Redirect"), NGX_HTTP_UPSTREAM_IGN_XA_REDIRECT },
{ ngx_string("X-Accel-Expires"), NGX_HTTP_UPSTREAM_IGN_XA_EXPIRES },
+ { ngx_string("X-Accel-Limit-Rate"), NGX_HTTP_UPSTREAM_IGN_XA_LIMIT_RATE },
+ { ngx_string("X-Accel-Buffering"), NGX_HTTP_UPSTREAM_IGN_XA_BUFFERING },
+ { ngx_string("X-Accel-Charset"), NGX_HTTP_UPSTREAM_IGN_XA_CHARSET },
{ ngx_string("Expires"), NGX_HTTP_UPSTREAM_IGN_EXPIRES },
{ ngx_string("Cache-Control"), NGX_HTTP_UPSTREAM_IGN_CACHE_CONTROL },
{ ngx_string("Set-Cookie"), NGX_HTTP_UPSTREAM_IGN_SET_COOKIE },
@@ -999,7 +1002,7 @@ ngx_http_upstream_check_broken_connection(ngx_http_request_t *r,
if (!u->cacheable && u->peer.connection) {
ngx_log_error(NGX_LOG_INFO, ev->log, ev->kq_errno,
- "kevent() reported that client closed prematurely "
+ "kevent() reported that client prematurely closed "
"connection, so upstream connection is closed too");
ngx_http_upstream_finalize_request(r, u,
NGX_HTTP_CLIENT_CLOSED_REQUEST);
@@ -1007,8 +1010,8 @@ ngx_http_upstream_check_broken_connection(ngx_http_request_t *r,
}
ngx_log_error(NGX_LOG_INFO, ev->log, ev->kq_errno,
- "kevent() reported that client closed "
- "prematurely connection");
+ "kevent() reported that client prematurely closed "
+ "connection");
if (u->peer.connection == NULL) {
ngx_http_upstream_finalize_request(r, u,
@@ -1062,7 +1065,7 @@ ngx_http_upstream_check_broken_connection(ngx_http_request_t *r,
if (!u->cacheable && u->peer.connection) {
ngx_log_error(NGX_LOG_INFO, ev->log, err,
- "client closed prematurely connection, "
+ "client prematurely closed connection, "
"so upstream connection is closed too");
ngx_http_upstream_finalize_request(r, u,
NGX_HTTP_CLIENT_CLOSED_REQUEST);
@@ -1070,7 +1073,7 @@ ngx_http_upstream_check_broken_connection(ngx_http_request_t *r,
}
ngx_log_error(NGX_LOG_INFO, ev->log, err,
- "client closed prematurely connection");
+ "client prematurely closed connection");
if (u->peer.connection == NULL) {
ngx_http_upstream_finalize_request(r, u,
@@ -3328,9 +3331,15 @@ static ngx_int_t
ngx_http_upstream_process_limit_rate(ngx_http_request_t *r, ngx_table_elt_t *h,
ngx_uint_t offset)
{
- ngx_int_t n;
+ ngx_int_t n;
+ ngx_http_upstream_t *u;
- r->upstream->headers_in.x_accel_limit_rate = h;
+ u = r->upstream;
+ u->headers_in.x_accel_limit_rate = h;
+
+ if (u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_XA_LIMIT_RATE) {
+ return NGX_OK;
+ }
n = ngx_atoi(h->value.data, h->value.len);
@@ -3346,16 +3355,23 @@ static ngx_int_t
ngx_http_upstream_process_buffering(ngx_http_request_t *r, ngx_table_elt_t *h,
ngx_uint_t offset)
{
- u_char c0, c1, c2;
+ u_char c0, c1, c2;
+ ngx_http_upstream_t *u;
+
+ u = r->upstream;
+
+ if (u->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_XA_BUFFERING) {
+ return NGX_OK;
+ }
- if (r->upstream->conf->change_buffering) {
+ if (u->conf->change_buffering) {
if (h->value.len == 2) {
c0 = ngx_tolower(h->value.data[0]);
c1 = ngx_tolower(h->value.data[1]);
if (c0 == 'n' && c1 == 'o') {
- r->upstream->buffering = 0;
+ u->buffering = 0;
}
} else if (h->value.len == 3) {
@@ -3364,7 +3380,7 @@ ngx_http_upstream_process_buffering(ngx_http_request_t *r, ngx_table_elt_t *h,
c2 = ngx_tolower(h->value.data[2]);
if (c0 == 'y' && c1 == 'e' && c2 == 's') {
- r->upstream->buffering = 1;
+ u->buffering = 1;
}
}
}
@@ -3377,6 +3393,10 @@ static ngx_int_t
ngx_http_upstream_process_charset(ngx_http_request_t *r, ngx_table_elt_t *h,
ngx_uint_t offset)
{
+ if (r->upstream->conf->ignore_headers & NGX_HTTP_UPSTREAM_IGN_XA_CHARSET) {
+ return NGX_OK;
+ }
+
r->headers_out.override_charset = &h->value;
return NGX_OK;
diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h
index bcdd64b16..aea9466a2 100644
--- a/src/http/ngx_http_upstream.h
+++ b/src/http/ngx_http_upstream.h
@@ -44,6 +44,9 @@
#define NGX_HTTP_UPSTREAM_IGN_EXPIRES 0x00000008
#define NGX_HTTP_UPSTREAM_IGN_CACHE_CONTROL 0x00000010
#define NGX_HTTP_UPSTREAM_IGN_SET_COOKIE 0x00000020
+#define NGX_HTTP_UPSTREAM_IGN_XA_LIMIT_RATE 0x00000040
+#define NGX_HTTP_UPSTREAM_IGN_XA_BUFFERING 0x00000080
+#define NGX_HTTP_UPSTREAM_IGN_XA_CHARSET 0x00000100
typedef struct {
diff --git a/src/http/ngx_http_upstream_round_robin.c b/src/http/ngx_http_upstream_round_robin.c
index bb9a704b8..138872c5f 100644
--- a/src/http/ngx_http_upstream_round_robin.c
+++ b/src/http/ngx_http_upstream_round_robin.c
@@ -443,8 +443,8 @@ ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data)
break;
}
- if (now - peer->accessed > peer->fail_timeout) {
- peer->fails = 0;
+ if (now - peer->checked > peer->fail_timeout) {
+ peer->checked = now;
break;
}
@@ -491,8 +491,8 @@ ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc, void *data)
break;
}
- if (now - peer->accessed > peer->fail_timeout) {
- peer->fails = 0;
+ if (now - peer->checked > peer->fail_timeout) {
+ peer->checked = now;
break;
}
@@ -663,15 +663,16 @@ ngx_http_upstream_free_round_robin_peer(ngx_peer_connection_t *pc, void *data,
return;
}
+ peer = &rrp->peers->peer[rrp->current];
+
if (state & NGX_PEER_FAILED) {
now = ngx_time();
- peer = &rrp->peers->peer[rrp->current];
-
/* ngx_lock_mutex(rrp->peers->mutex); */
peer->fails++;
peer->accessed = now;
+ peer->checked = now;
if (peer->max_fails) {
peer->current_weight -= peer->weight / peer->max_fails;
@@ -686,6 +687,14 @@ ngx_http_upstream_free_round_robin_peer(ngx_peer_connection_t *pc, void *data,
}
/* ngx_unlock_mutex(rrp->peers->mutex); */
+
+ } else {
+
+ /* mark peer live if check passed */
+
+ if (peer->accessed < peer->checked) {
+ peer->fails = 0;
+ }
}
rrp->current++;
diff --git a/src/http/ngx_http_upstream_round_robin.h b/src/http/ngx_http_upstream_round_robin.h
index a9cb257c7..195f4d8ca 100644
--- a/src/http/ngx_http_upstream_round_robin.h
+++ b/src/http/ngx_http_upstream_round_robin.h
@@ -23,6 +23,7 @@ typedef struct {
ngx_uint_t fails;
time_t accessed;
+ time_t checked;
ngx_uint_t max_fails;
time_t fail_timeout;