summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2007-07-17 10:00:02 +0000
committerJonathan Kolb <jon@b0g.us>2007-07-17 10:00:02 +0000
commit650a43160c4432dc3d3e778ea5840600cacf958a (patch)
tree9b821c82c4e5bcdbcfe6bf99ff029f4c799d6e7e
parent7f4fcbdaef8d52d0a390c980cb1a7fa85330fecc (diff)
downloadnginx-650a43160c4432dc3d3e778ea5840600cacf958a.tar.gz
Changes with nginx 0.6.4 17 Jul 2007v0.6.4
*) Security: the "msie_refresh" directive allowed XSS. *) Change: the "proxy_store" and "fastcgi_store" directives were changed. *) Feature: the "proxy_store_access" and "fastcgi_store_access" directives. *) Bugfix: nginx did not work on Solaris/sparc64 if it was built by Sun Studio. Thanks to Andrei Nigmatulin. *) Workaround: for Sun Studio 12. Thanks to Jiang Hong.
-rw-r--r--CHANGES19
-rw-r--r--CHANGES.ru18
-rw-r--r--auto/cc/sunc67
-rw-r--r--auto/lib/pcre/conf11
-rw-r--r--src/core/nginx.h2
-rw-r--r--src/core/ngx_file.c10
-rw-r--r--src/core/ngx_string.c64
-rw-r--r--src/core/ngx_string.h20
-rw-r--r--src/http/modules/ngx_http_charset_filter_module.c23
-rw-r--r--src/http/modules/ngx_http_dav_module.c66
-rw-r--r--src/http/modules/ngx_http_fastcgi_module.c76
-rw-r--r--src/http/modules/ngx_http_proxy_module.c76
-rw-r--r--src/http/modules/ngx_http_ssl_module.c15
-rw-r--r--src/http/modules/perl/nginx.pm2
-rw-r--r--src/http/ngx_http_special_response.c24
-rw-r--r--src/http/ngx_http_upstream.c25
-rw-r--r--src/http/ngx_http_upstream.h6
-rw-r--r--src/http/ngx_http_variables.c2
-rw-r--r--src/http/ngx_http_variables.h10
-rw-r--r--src/os/unix/ngx_atomic.h20
-rw-r--r--src/os/unix/ngx_sunpro_amd64.il7
-rw-r--r--src/os/unix/ngx_sunpro_x86.il7
22 files changed, 407 insertions, 163 deletions
diff --git a/CHANGES b/CHANGES
index 8ee8b4c8d..7bfeefb2c 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,10 +1,29 @@
+Changes with nginx 0.6.4 17 Jul 2007
+
+ *) Security: the "msie_refresh" directive allowed XSS.
+
+ *) Change: the "proxy_store" and "fastcgi_store" directives were
+ changed.
+
+ *) Feature: the "proxy_store_access" and "fastcgi_store_access"
+ directives.
+
+ *) Bugfix: nginx did not work on Solaris/sparc64 if it was built by Sun
+ Studio.
+ Thanks to Andrei Nigmatulin.
+
+ *) Workaround: for Sun Studio 12.
+ Thanks to Jiang Hong.
+
+
Changes with nginx 0.6.3 12 Jul 2007
*) Feature: the "proxy_store" and "fastcgi_store" directives.
*) Bugfix: a segmentation fault might occur in worker process if the
"auth_http_header" directive was used.
+ Thanks to Maxim Dounin.
*) Bugfix: a segmentation fault occurred in worker process if the
CRAM-MD5 authentication method was used, but it was not enabled.
diff --git a/CHANGES.ru b/CHANGES.ru
index ed95f68d2..f2c71de3b 100644
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,10 +1,28 @@
+Изменения в nginx 0.6.4 17.07.2007
+
+ *) Безопасность: при использовании директивы msie_refresh был возможен
+ XSS.
+
+ *) Изменение: директивы proxy_store и fastcgi_store изменены.
+
+ *) Добавление: директивы proxy_store_access и fastcgi_store_access.
+
+ *) Исправление: nginx не работал на Solaris/sparc64, если был собран
+ Sun Studio.
+ Спасибо Андрею Нигматулину.
+
+ *) Изменение: обход ошибки в Sun Studio 12.
+ Спасибо Jiang Hong.
+
+
Изменения в nginx 0.6.3 12.07.2007
*) Добавление: директивы proxy_store и fastcgi_store.
*) Исправление: при использовании директивы auth_http_header в рабочем
процессе мог произойти segmentation fault.
+ Спасибо Максиму Дунину.
*) Исправление: если использовался метод аутентификации CRAM-MD5, но он
не был разрешён, то в рабочем процессе происходил segmentation fault.
diff --git a/auto/cc/sunc b/auto/cc/sunc
index 9edc0d098..f40d8aa7e 100644
--- a/auto/cc/sunc
+++ b/auto/cc/sunc
@@ -2,8 +2,10 @@
# Copyright (C) Igor Sysoev
-# Sun C 5.7 Patch 117837-04 2005/05/11
-# Sun C 5.8 2005/10/13
+# Sun C 5.7 Patch 117837-04 2005/05/11 Sun Studio 10
+# Sun C 5.8 2005/10/13 Sun Studio 11
+# Sun C 5.9 SunOS_i386 2007/05/03 Sun Studio 12
+# Sun C 5.9 SunOS_sparc 2007/05/03
NGX_SUNC_VER=`$CC -V 2>&1 | grep 'Sun C' 2>&1 \
| sed -e 's/^.* Sun C \(.*\)/\1/'`
@@ -13,6 +15,33 @@ echo " + Sun C version: $NGX_SUNC_VER"
have=NGX_COMPILER value="\"Sun C $NGX_SUNC_VER\"" . auto/define
+cat << END > $NGX_AUTOTEST.c
+
+int main() { printf("%d", __SUNPRO_C); }
+
+END
+
+eval "$CC -o $NGX_AUTOTEST $NGX_AUTOTEST.c >> $NGX_ERR 2>&1"
+
+if [ -x $NGX_AUTOTEST ]; then
+ ngx_sunc_ver=`$NGX_AUTOTEST`
+fi
+
+rm $NGX_AUTOTEST*
+
+# 1424 == 0x590, Sun Studio 12
+
+if [ "$ngx_sunc_ver" -ge 1424 ]; then
+ ngx_sparc32="-m32"
+ ngx_sparc64="-m64"
+ ngx_amd64="-m64"
+
+else
+ ngx_sparc32="-xarch=v8plus"
+ ngx_sparc64="-xarch=v9"
+ ngx_amd64="-amd64"
+fi
+
case "$NGX_MACHINE" in
i86pc)
@@ -35,9 +64,6 @@ case "$NGX_MACHINE" in
;;
sun4u | sun4v)
- # "-xarch=v9" enables the "casa" assembler instruction
- CFLAGS="$CFLAGS -xarch=v9"
- CORE_LINK="$CORE_LINK -xarch=v9"
NGX_AUX=" src/os/unix/ngx_sunpro_sparc64.il"
;;
@@ -46,7 +72,8 @@ esac
# optimizations
-CFLAGS="$CFLAGS -fast"
+IPO=-xipo
+CFLAGS="$CFLAGS -fast $IPO"
case $CPU in
@@ -81,11 +108,29 @@ case $CPU in
CPU_OPT="$CPU_OPT -xcache=64/64/2:1024/64/16"
;;
+ sparc32)
+ # build 32-bit UltraSparc binary
+ CPU_OPT="$ngx_sparc32"
+ CORE_LINK="$CORE_LINK $ngx_sparc32"
+ CC_AUX_FLAGS="$CC_AUX_FLAGS $ngx_sparc32"
+ NGX_CPU_CACHE_LINE=64
+ ;;
+
+ sparc64)
+ # build 64-bit UltraSparc binary
+ CPU_OPT="$ngx_sparc64"
+ CORE_LINK="$CORE_LINK $ngx_sparc64"
+ CC_AUX_FLAGS="$CC_AUX_FLAGS $ngx_sparc64"
+ NGX_CPU_CACHE_LINE=64
+ ;;
+
amd64)
# build 64-bit amd64 binary
- CPU_OPT="-xarch=amd64"
- CORE_LINK="$CORE_LINK -xarch=amd64"
+ CPU_OPT="$ngx_amd64"
+ CORE_LINK="$CORE_LINK $ngx_amd64"
+ CC_AUX_FLAGS="$CC_AUX_FLAGS $ngx_amd4"
NGX_AUX=" src/os/unix/ngx_sunpro_amd64.il"
+ NGX_CPU_CACHE_LINE=64
;;
esac
@@ -95,15 +140,15 @@ CFLAGS="$CFLAGS $CPU_OPT"
if [ ".$PCRE_OPT" = "." ]; then
- PCRE_OPT="-fast $CPU_OPT"
+ PCRE_OPT="-fast $IPO $CPU_OPT"
fi
if [ ".$MD5_OPT" = "." ]; then
- MD5_OPT="-fast $CPU_OPT"
+ MD5_OPT="-fast $IPO $CPU_OPT"
fi
if [ ".$ZLIB_OPT" = "." ]; then
- ZLIB_OPT="-fast $CPU_OPT"
+ ZLIB_OPT="-fast $IPO $CPU_OPT"
fi
diff --git a/auto/lib/pcre/conf b/auto/lib/pcre/conf
index 3b2ca1248..c966a284f 100644
--- a/auto/lib/pcre/conf
+++ b/auto/lib/pcre/conf
@@ -17,7 +17,7 @@ if [ $PCRE != NONE ]; then
CORE_LIBS="$CORE_LIBS $PCRE/pcre.lib"
;;
- icc* | sunc )
+ icc* )
have=NGX_PCRE . auto/have
CORE_DEPS="$CORE_DEPS $PCRE/pcre.h"
@@ -25,13 +25,18 @@ if [ $PCRE != NONE ]; then
echo $ngx_n "checking for PCRE library ...$ngx_c"
- if [ -e $PCRE/pcre.h ]; then
+ if [ -f $PCRE/pcre.h ]; then
ngx_pcre_ver=`grep PCRE_MAJOR $PCRE/pcre.h \
| sed -e 's/^.*PCRE_MAJOR.* \(.*\)$/\1/'`
- else
+ else if [ -f $PCRE/configure.in.h ]; then
ngx_pcre_ver=`grep PCRE_MAJOR= $PCRE/configure.in \
| sed -e 's/^.*=\(.*\)$/\1/'`
+
+ else
+ ngx_pcre_ver=`grep pcre_major, $PCRE/configure.ac \
+ | sed -e 's/^.*pcre_major,.*\[\(.*\)\].*$/\1/'`
+ fi
fi
echo " $ngx_pcre_ver major version found"
diff --git a/src/core/nginx.h b/src/core/nginx.h
index 5c52e36c2..126652560 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
#define _NGINX_H_INCLUDED_
-#define NGINX_VERSION "0.6.3"
+#define NGINX_VERSION "0.6.4"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"
diff --git a/src/core/ngx_file.c b/src/core/ngx_file.c
index 656610dc8..55cfd7ca2 100644
--- a/src/core/ngx_file.c
+++ b/src/core/ngx_file.c
@@ -303,11 +303,11 @@ ngx_conf_set_access_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_uint_t i, right, shift, *access;
access = (ngx_uint_t *) (confp + cmd->offset);
-
+
if (*access != NGX_CONF_UNSET_UINT) {
return "is duplicate";
}
-
+
value = cf->args->elts;
*access = 0600;
@@ -328,10 +328,6 @@ ngx_conf_set_access_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
shift = 0;
p += sizeof("all:") - 1;
- } else if (ngx_strncmp(p, "off", sizeof("off") - 1) == 0) {
- *access = 0;
- return NGX_CONF_OK;
-
} else {
goto invalid;
}
@@ -348,7 +344,7 @@ ngx_conf_set_access_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
*access |= right << shift;
}
-
+
return NGX_CONF_OK;
invalid:
diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c
index 7b5287f0a..6a927b03b 100644
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -105,21 +105,21 @@ ngx_snprintf(u_char *buf, size_t max, const char *fmt, ...)
u_char *
ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args)
{
- u_char *p, zero, *last, temp[NGX_INT64_LEN + 1];
+ u_char *p, zero, *last, temp[NGX_INT64_LEN + 1];
/*
* really we need temp[NGX_INT64_LEN] only,
* but icc issues the warning
*/
- int d;
- size_t len;
- uint32_t ui32;
- int64_t i64;
- uint64_t ui64;
- ngx_msec_t ms;
- ngx_str_t *s;
- ngx_uint_t width, sign, hexadecimal, max_width;
- static u_char hex[] = "0123456789abcdef";
- static u_char HEX[] = "0123456789ABCDEF";
+ int d;
+ size_t len;
+ uint32_t ui32;
+ int64_t i64;
+ uint64_t ui64;
+ ngx_msec_t ms;
+ ngx_uint_t width, sign, hexadecimal, max_width;
+ ngx_variable_value_t *v;
+ static u_char hex[] = "0123456789abcdef";
+ static u_char HEX[] = "0123456789ABCDEF";
if (max == 0) {
return buf;
@@ -188,12 +188,12 @@ ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args)
switch (*fmt) {
case 'V':
- s = va_arg(args, ngx_str_t *);
+ v = va_arg(args, ngx_variable_value_t *);
- len = s->len & 0xffff;
+ len = v->len;
len = (buf + len < last) ? len : (size_t) (last - buf);
- buf = ngx_cpymem(buf, s->data, len);
+ buf = ngx_cpymem(buf, v->data, len);
fmt++;
continue;
@@ -1025,7 +1025,7 @@ 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 */
/* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
- 0x800000ad, /* 0000 0000 0000 0000 0000 0000 1010 1101 */
+ 0x000000ad, /* 0000 0000 0000 0000 0000 0000 1010 1101 */
/* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
@@ -1039,18 +1039,30 @@ ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
};
+ /* " ", """, "'", %00-%1F, %7F-%FF */
- switch (type) {
- case NGX_ESCAPE_HTML:
- escape = html;
- break;
- case NGX_ESCAPE_ARGS:
- escape = args;
- break;
- default:
- escape = uri;
- break;
- }
+ static uint32_t refresh[] = {
+ 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
+
+ /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
+ 0x00000085, /* 0000 0000 0000 0000 0000 0000 1000 0101 */
+
+ /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
+ 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
+
+ /* ~}| {zyx wvut srqp onml kjih gfed cba` */
+ 0x80000000, /* 1000 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 */
+ };
+
+ static uint32_t *map[] = { uri, args, html, refresh };
+
+
+ escape = map[type];
if (dst == NULL) {
diff --git a/src/core/ngx_string.h b/src/core/ngx_string.h
index 18306d2d2..9e0b06394 100644
--- a/src/core/ngx_string.h
+++ b/src/core/ngx_string.h
@@ -13,17 +13,28 @@
typedef struct {
- size_t len;
- u_char *data;
+ size_t len;
+ u_char *data;
} ngx_str_t;
typedef struct {
- ngx_str_t key;
- ngx_str_t value;
+ ngx_str_t key;
+ ngx_str_t value;
} ngx_keyval_t;
+typedef struct {
+ unsigned len:29;
+
+ unsigned valid:1;
+ unsigned no_cachable:1;
+ unsigned not_found:1;
+
+ u_char *data;
+} ngx_variable_value_t;
+
+
#define ngx_string(str) { sizeof(str) - 1, (u_char *) str }
#define ngx_null_string { 0, NULL }
@@ -142,6 +153,7 @@ u_char *ngx_utf_cpystrn(u_char *dst, u_char *src, size_t n);
#define NGX_ESCAPE_URI 0
#define NGX_ESCAPE_ARGS 1
#define NGX_ESCAPE_HTML 2
+#define NGX_ESCAPE_REFRESH 3
#define NGX_UNESCAPE_URI 1
diff --git a/src/http/modules/ngx_http_charset_filter_module.c b/src/http/modules/ngx_http_charset_filter_module.c
index 0139cc671..98919ae2f 100644
--- a/src/http/modules/ngx_http_charset_filter_module.c
+++ b/src/http/modules/ngx_http_charset_filter_module.c
@@ -187,7 +187,7 @@ ngx_http_charset_header_filter(ngx_http_request_t *r)
{
u_char *ct;
ngx_int_t charset, source_charset;
- ngx_str_t *mc, *from, *to;
+ ngx_str_t *mc, *from, *to, s;
ngx_uint_t n;
ngx_http_charset_t *charsets;
ngx_http_charset_ctx_t *ctx;
@@ -256,8 +256,10 @@ ngx_http_charset_header_filter(ngx_http_request_t *r)
return NGX_ERROR;
}
- charset = ngx_http_charset_get_charset(charsets, n,
- (ngx_str_t *) vv);
+ s.len = vv->len;
+ s.data = vv->data;
+
+ charset = ngx_http_charset_get_charset(charsets, n, &s);
}
}
@@ -303,8 +305,10 @@ ngx_http_charset_header_filter(ngx_http_request_t *r)
return NGX_ERROR;
}
- source_charset = ngx_http_charset_get_charset(charsets, n,
- (ngx_str_t *) vv);
+ s.len = vv->len;
+ s.data = vv->data;
+
+ source_charset = ngx_http_charset_get_charset(charsets, n, &s);
}
if (charset != NGX_HTTP_NO_CHARSET) {
@@ -373,17 +377,16 @@ static ngx_int_t
ngx_http_charset_get_charset(ngx_http_charset_t *charsets, ngx_uint_t n,
ngx_str_t *charset)
{
- size_t len;
ngx_uint_t i;
- len = charset->len & 0xffff;
-
for (i = 0; i < n; i++) {
- if (charsets[i].name.len != len) {
+ if (charsets[i].name.len != charset->len) {
continue;
}
- if (ngx_strncasecmp(charsets[i].name.data, charset->data, len) == 0) {
+ if (ngx_strncasecmp(charsets[i].name.data, charset->data, charset->len)
+ == 0)
+ {
return i;
}
}
diff --git a/src/http/modules/ngx_http_dav_module.c b/src/http/modules/ngx_http_dav_module.c
index 5539f6195..f3fbb9731 100644
--- a/src/http/modules/ngx_http_dav_module.c
+++ b/src/http/modules/ngx_http_dav_module.c
@@ -57,8 +57,6 @@ static ngx_int_t ngx_http_dav_depth(ngx_http_request_t *r, ngx_int_t dflt);
static ngx_int_t ngx_http_dav_error(ngx_log_t *log, ngx_err_t err,
ngx_int_t not_found, char *failed, u_char *path);
static ngx_int_t ngx_http_dav_location(ngx_http_request_t *r, u_char *path);
-static char *ngx_http_dav_access(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
static void *ngx_http_dav_create_loc_conf(ngx_conf_t *cf);
static char *ngx_http_dav_merge_loc_conf(ngx_conf_t *cf,
void *parent, void *child);
@@ -94,9 +92,9 @@ static ngx_command_t ngx_http_dav_commands[] = {
{ ngx_string("dav_access"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123,
- ngx_http_dav_access,
+ ngx_conf_set_access_slot,
NGX_HTTP_LOC_CONF_OFFSET,
- 0,
+ offsetof(ngx_http_dav_loc_conf_t, access),
NULL },
ngx_null_command
@@ -1106,66 +1104,6 @@ ngx_http_dav_location(ngx_http_request_t *r, u_char *path)
}
-static char *
-ngx_http_dav_access(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_dav_loc_conf_t *lcf = conf;
-
- u_char *p;
- ngx_str_t *value;
- ngx_uint_t i, right, shift;
-
- if (lcf->access != NGX_CONF_UNSET_UINT) {
- return "is duplicate";
- }
-
- value = cf->args->elts;
-
- lcf->access = 0600;
-
- for (i = 1; i < cf->args->nelts; i++) {
-
- p = value[i].data;
-
- if (ngx_strncmp(p, "user:", sizeof("user:") - 1) == 0) {
- shift = 6;
- p += sizeof("user:") - 1;
-
- } else if (ngx_strncmp(p, "group:", sizeof("group:") - 1) == 0) {
- shift = 3;
- p += sizeof("group:") - 1;
-
- } else if (ngx_strncmp(p, "all:", sizeof("all:") - 1) == 0) {
- shift = 0;
- p += sizeof("all:") - 1;
-
- } else {
- goto invalid;
- }
-
- if (ngx_strcmp(p, "rw") == 0) {
- right = 6;
-
- } else if (ngx_strcmp(p, "r") == 0) {
- right = 4;
-
- } else {
- goto invalid;
- }
-
- lcf->access |= right << shift;
- }
-
- return NGX_CONF_OK;
-
-invalid:
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid value \"%V\"", &value[i]);
- return NGX_CONF_ERROR;
-}
-
-
static void *
ngx_http_dav_create_loc_conf(ngx_conf_t *cf)
{
diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c
index dc4a85cce..c1ce79ce7 100644
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -124,6 +124,8 @@ static ngx_int_t ngx_http_fastcgi_script_name_variable(ngx_http_request_t *r,
static char *ngx_http_fastcgi_pass(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
+static char *ngx_http_fastcgi_store(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
static char *ngx_http_fastcgi_lowat_check(ngx_conf_t *cf, void *post,
void *data);
@@ -201,10 +203,17 @@ static ngx_command_t ngx_http_fastcgi_commands[] = {
NULL },
{ ngx_string("fastcgi_store"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_http_fastcgi_store,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ 0,
+ NULL },
+
+ { ngx_string("fastcgi_store_access"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123,
ngx_conf_set_access_slot,
NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_fastcgi_loc_conf_t, upstream.store),
+ offsetof(ngx_http_fastcgi_loc_conf_t, upstream.store_access),
NULL },
{ ngx_string("fastcgi_ignore_client_abort"),
@@ -1635,12 +1644,15 @@ ngx_http_fastcgi_create_loc_conf(ngx_conf_t *cf)
* conf->upstream.schema = { 0, NULL };
* conf->upstream.uri = { 0, NULL };
* conf->upstream.location = NULL;
+ * conf->upstream.store_lengths = NULL;
+ * conf->upstream.store_values = NULL;
*
* conf->index.len = 0;
* conf->index.data = NULL;
*/
- conf->upstream.store = NGX_CONF_UNSET_UINT;
+ conf->upstream.store = NGX_CONF_UNSET;
+ conf->upstream.store_access = NGX_CONF_UNSET_UINT;
conf->upstream.buffering = NGX_CONF_UNSET;
conf->upstream.ignore_client_abort = NGX_CONF_UNSET;
@@ -1685,8 +1697,18 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_http_script_compile_t sc;
ngx_http_script_copy_code_t *copy;
- ngx_conf_merge_uint_value(conf->upstream.store,
- prev->upstream.store, 0);
+ if (conf->upstream.store != 0) {
+ ngx_conf_merge_value(conf->upstream.store,
+ prev->upstream.store, 0);
+
+ if (conf->upstream.store_lengths == NULL) {
+ conf->upstream.store_lengths = prev->upstream.store_lengths;
+ conf->upstream.store_values = prev->upstream.store_values;
+ }
+ }
+
+ ngx_conf_merge_uint_value(conf->upstream.store_access,
+ prev->upstream.store_access, 0600);
ngx_conf_merge_value(conf->upstream.buffering,
prev->upstream.buffering, 1);
@@ -2159,6 +2181,52 @@ ngx_http_fastcgi_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
static char *
+ngx_http_fastcgi_store(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_http_fastcgi_loc_conf_t *flcf = conf;
+
+ ngx_str_t *value;
+ ngx_http_script_compile_t sc;
+
+ if (flcf->upstream.store != NGX_CONF_UNSET || flcf->upstream.store_lengths)
+ {
+ return "is duplicate";
+ }
+
+ value = cf->args->elts;
+
+ if (ngx_strcmp(value[1].data, "on") == 0) {
+ flcf->upstream.store = 1;
+ return NGX_CONF_OK;
+ }
+
+ if (ngx_strcmp(value[1].data, "off") == 0) {
+ flcf->upstream.store = 0;
+ return NGX_CONF_OK;
+ }
+
+ /* include the terminating '\0' into script */
+ value[1].len++;
+
+ ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
+
+ sc.cf = cf;
+ sc.source = &value[1];
+ sc.lengths = &flcf->upstream.store_lengths;
+ sc.values = &flcf->upstream.store_values;
+ sc.variables = ngx_http_script_variables_count(&value[1]);;
+ sc.complete_lengths = 1;
+ sc.complete_values = 1;
+
+ if (ngx_http_script_compile(&sc) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ return NGX_CONF_OK;
+}
+
+
+static char *
ngx_http_fastcgi_lowat_check(ngx_conf_t *cf, void *post, void *data)
{
#if (NGX_FREEBSD)
diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c
index d77e183a3..c999adea2 100644
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -105,6 +105,8 @@ static char *ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static char *ngx_http_proxy_redirect(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
+static char *ngx_http_proxy_store(ngx_conf_t *cf, ngx_command_t *cmd,
+ void *conf);
static char *ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data);
@@ -155,10 +157,17 @@ static ngx_command_t ngx_http_proxy_commands[] = {
NULL },
{ ngx_string("proxy_store"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_http_proxy_store,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ 0,
+ NULL },
+
+ { ngx_string("proxy_store_access"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123,
ngx_conf_set_access_slot,
NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_proxy_loc_conf_t, upstream.store),
+ offsetof(ngx_http_proxy_loc_conf_t, upstream.store_access),
NULL },
{ ngx_string("proxy_buffering"),
@@ -1497,6 +1506,8 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
* conf->upstream.schema = { 0, NULL };
* conf->upstream.uri = { 0, NULL };
* conf->upstream.location = NULL;
+ * conf->upstream.store_lengths = NULL;
+ * conf->upstream.store_values = NULL;
*
* conf->method = NULL;
* conf->headers_source = NULL;
@@ -1509,7 +1520,8 @@ ngx_http_proxy_create_loc_conf(ngx_conf_t *cf)
* conf->rewrite_locations = NULL;
*/
- conf->upstream.store = NGX_CONF_UNSET_UINT;
+ conf->upstream.store = NGX_CONF_UNSET;
+ conf->upstream.store_access = NGX_CONF_UNSET_UINT;
conf->upstream.buffering = NGX_CONF_UNSET;
conf->upstream.ignore_client_abort = NGX_CONF_UNSET;
@@ -1561,8 +1573,18 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_http_script_compile_t sc;
ngx_http_script_copy_code_t *copy;
- ngx_conf_merge_uint_value(conf->upstream.store,
- prev->upstream.store, 0);
+ if (conf->upstream.store != 0) {
+ ngx_conf_merge_value(conf->upstream.store,
+ prev->upstream.store, 0);
+
+ if (conf->upstream.store_lengths == NULL) {
+ conf->upstream.store_lengths = prev->upstream.store_lengths;
+ conf->upstream.store_values = prev->upstream.store_values;
+ }
+ }
+
+ ngx_conf_merge_uint_value(conf->upstream.store_access,
+ prev->upstream.store_access, 0600);
ngx_conf_merge_value(conf->upstream.buffering,
prev->upstream.buffering, 1);
@@ -2371,6 +2393,52 @@ ngx_http_proxy_redirect(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
static char *
+ngx_http_proxy_store(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{
+ ngx_http_proxy_loc_conf_t *plcf = conf;
+
+ ngx_str_t *value;
+ ngx_http_script_compile_t sc;
+
+ if (plcf->upstream.store != NGX_CONF_UNSET || plcf->upstream.store_lengths)
+ {
+ return "is duplicate";
+ }
+
+ value = cf->args->elts;
+
+ if (ngx_strcmp(value[1].data, "on") == 0) {
+ plcf->upstream.store = 1;
+ return NGX_CONF_OK;
+ }
+
+ if (ngx_strcmp(value[1].data, "off") == 0) {
+ plcf->upstream.store = 0;
+ return NGX_CONF_OK;
+ }
+
+ /* include the terminating '\0' into script */
+ value[1].len++;
+
+ ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
+
+ sc.cf = cf;
+ sc.source = &value[1];
+ sc.lengths = &plcf->upstream.store_lengths;
+ sc.values = &plcf->upstream.store_values;
+ sc.variables = ngx_http_script_variables_count(&value[1]);;
+ sc.complete_lengths = 1;
+ sc.complete_values = 1;
+
+ if (ngx_http_script_compile(&sc) != NGX_OK) {
+ return NGX_CONF_ERROR;
+ }
+
+ return NGX_CONF_OK;
+}
+
+
+static char *
ngx_http_proxy_lowat_check(ngx_conf_t *cf, void *post, void *data)
{
#if (NGX_FREEBSD)
diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c
index 7376d1028..1ffa54fb5 100644
--- a/src/http/modules/ngx_http_ssl_module.c
+++ b/src/http/modules/ngx_http_ssl_module.c
@@ -197,11 +197,14 @@ ngx_http_ssl_static_variable(ngx_http_request_t *r,
{
ngx_ssl_variable_handler_pt handler = (ngx_ssl_variable_handler_pt) data;
- size_t len;
+ size_t len;
+ ngx_str_t s;
if (r->connection->ssl) {
- (void) handler(r->connection, NULL, (ngx_str_t *) v);
+ (void) handler(r->connection, NULL, &s);
+
+ v->data = s.data;
for (len = 0; v->data[len]; len++) { /* void */ }
@@ -225,11 +228,17 @@ ngx_http_ssl_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v,
{
ngx_ssl_variable_handler_pt handler = (ngx_ssl_variable_handler_pt) data;
+ ngx_str_t s;
+
if (r->connection->ssl) {
- if (handler(r->connection, r->pool, (ngx_str_t *) v) != NGX_OK) {
+
+ if (handler(r->connection, r->pool, &s) != NGX_OK) {
return NGX_ERROR;
}
+ v->len = s.len;
+ v->data = s.data;
+
if (v->len) {
v->valid = 1;
v->no_cachable = 0;
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index a9e9837d4..772e6cd75 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.6.3';
+our $VERSION = '0.6.4';
require XSLoader;
XSLoader::load('nginx', $VERSION);
diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c
index bb72079a9..2598116f7 100644
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -315,6 +315,7 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
{
u_char *p;
size_t msie_refresh;
+ uintptr_t escape;
ngx_int_t rc;
ngx_buf_t *b;
ngx_str_t *uri, *location;
@@ -496,17 +497,19 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
r->headers_out.content_length = NULL;
}
- msie_refresh = 0;
- location = NULL;
-
if (clcf->msie_refresh
&& r->headers_in.msie
&& (error == NGX_HTTP_MOVED_PERMANENTLY
|| error == NGX_HTTP_MOVED_TEMPORARILY))
{
+
location = &r->headers_out.location->value;
+
+ escape = 2 * ngx_escape_uri(NULL, location->data, location->len,
+ NGX_ESCAPE_REFRESH);
+
msie_refresh = sizeof(ngx_http_msie_refresh_head) - 1
- + location->len
+ + escape + location->len
+ sizeof(ngx_http_msie_refresh_tail) - 1;
r->err_status = NGX_HTTP_OK;
@@ -514,6 +517,11 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
r->headers_out.content_length_n = msie_refresh;
r->headers_out.location->hash = 0;
r->headers_out.location = NULL;
+
+ } else {
+ location = NULL;
+ escape = 0;
+ msie_refresh = 0;
}
ngx_http_clear_accept_ranges(r);
@@ -595,7 +603,13 @@ ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error)
p = ngx_cpymem(b->pos, ngx_http_msie_refresh_head,
sizeof(ngx_http_msie_refresh_head) - 1);
- p = ngx_cpymem(p, location->data, location->len);
+ if (escape == 0) {
+ p = ngx_cpymem(p, location->data, location->len);
+
+ } else {
+ p = (u_char *) ngx_escape_uri(p, location->data, location->len,
+ NGX_ESCAPE_REFRESH);
+ }
b->last = ngx_cpymem(p, ngx_http_msie_refresh_tail,
sizeof(ngx_http_msie_refresh_tail) - 1);
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index bf892fcd6..376b85fcd 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -372,7 +372,7 @@ ngx_http_upstream_init(ngx_http_request_t *r)
cln->data = r;
u->cleanup = &cln->handler;
- u->store = (u->conf->store != 0);
+ u->store = (u->conf->store || u->conf->store_lengths);
ngx_http_upstream_connect(r, u);
}
@@ -2029,7 +2029,9 @@ ngx_http_upstream_store(ngx_http_request_t *r, ngx_http_upstream_t *u)
#if !(NGX_WIN32)
- if (ngx_change_file_access(temp->data, u->conf->store) == NGX_FILE_ERROR) {
+ if (ngx_change_file_access(temp->data, u->conf->store_access)
+ == NGX_FILE_ERROR)
+ {
err = ngx_errno;
failed = ngx_change_file_access_n;
name = temp->data;
@@ -2052,13 +2054,24 @@ ngx_http_upstream_store(ngx_http_request_t *r, ngx_http_upstream_t *u)
err = ngx_errno;
failed = ngx_set_file_time_n;
name = temp->data;
-
+
goto failed;
}
}
}
- ngx_http_map_uri_to_path(r, &path, &root, 0);
+ if (u->conf->store_lengths == NULL) {
+
+ ngx_http_map_uri_to_path(r, &path, &root, 0);
+
+ } else {
+ if (ngx_http_script_run(r, &path, u->conf->store_lengths->elts, 0,
+ u->conf->store_values->elts)
+ == NULL)
+ {
+ return;
+ }
+ }
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"upstream stores \"%s\" to \"%s\"", temp->data, path.data);
@@ -2074,8 +2087,8 @@ ngx_http_upstream_store(ngx_http_request_t *r, ngx_http_upstream_t *u)
if (err == NGX_ENOENT) {
- err = ngx_create_full_path(path.data, ngx_dir_access(u->conf->store));
-
+ err = ngx_create_full_path(path.data,
+ ngx_dir_access(u->conf->store_access));
if (err == 0) {
if (ngx_rename_file(temp->data, path.data) != NGX_FILE_ERROR) {
return;
diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h
index 4ba38ec0f..b3bb1b4fd 100644
--- a/src/http/ngx_http_upstream.h
+++ b/src/http/ngx_http_upstream.h
@@ -118,7 +118,7 @@ typedef struct {
size_t temp_file_write_size_conf;
ngx_uint_t next_upstream;
- ngx_uint_t store;
+ ngx_uint_t store_access;
ngx_bufs_t bufs;
@@ -141,6 +141,10 @@ typedef struct {
ngx_str_t location;
ngx_str_t url; /* used in proxy_rewrite_location */
+ ngx_array_t *store_lengths;
+ ngx_array_t *store_values;
+
+ signed store:2;
unsigned intercept_404:1;
unsigned change_buffering:1;
diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c
index 0bd6b7ec6..6316b3d58 100644
--- a/src/http/ngx_http_variables.c
+++ b/src/http/ngx_http_variables.c
@@ -501,7 +501,7 @@ ngx_http_variable_request_set_size(ngx_http_request_t *r,
ssize_t s, *sp;
ngx_str_t val;
- val.len = v->len & 0xffff;
+ val.len = v->len;
val.data = v->data;
s = ngx_parse_size(&val);
diff --git a/src/http/ngx_http_variables.h b/src/http/ngx_http_variables.h
index df487e48e..1dc982844 100644
--- a/src/http/ngx_http_variables.h
+++ b/src/http/ngx_http_variables.h
@@ -14,15 +14,7 @@
#include <ngx_http.h>
-typedef struct {
- unsigned len:29;
-
- unsigned valid:1;
- unsigned no_cachable:1;
- unsigned not_found:1;
-
- u_char *data;
-} ngx_http_variable_value_t;
+typedef ngx_variable_value_t ngx_http_variable_value_t;
#define ngx_http_variable(v) { sizeof(v) - 1, 1, 0, 0, (u_char *) v }
diff --git a/src/os/unix/ngx_atomic.h b/src/os/unix/ngx_atomic.h
index c0734e12e..22b8b0144 100644
--- a/src/os/unix/ngx_atomic.h
+++ b/src/os/unix/ngx_atomic.h
@@ -87,10 +87,17 @@ ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
ngx_atomic_int_t
ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add);
+/*
+ * Sun Studio 12 exits with segmentation fault on '__asm ("pause")',
+ * so ngx_cpu_pause is declared in src/os/unix/ngx_sunpro_x86.il
+ */
+
+void
+ngx_cpu_pause(void);
+
/* the code in src/os/unix/ngx_sunpro_x86.il */
#define ngx_memory_barrier() __asm (".volatile"); __asm (".nonvolatile")
-#define ngx_cpu_pause() __asm ("pause")
#else /* ( __GNUC__ || __INTEL_COMPILER ) */
@@ -121,10 +128,17 @@ ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,
ngx_atomic_int_t
ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add);
+/*
+ * Sun Studio 12 exits with segmentation fault on '__asm ("pause")',
+ * so ngx_cpu_pause is declared in src/os/unix/ngx_sunpro_amd64.il
+ */
+
+void
+ngx_cpu_pause(void);
+
/* the code in src/os/unix/ngx_sunpro_amd64.il */
#define ngx_memory_barrier() __asm (".volatile"); __asm (".nonvolatile")
-#define ngx_cpu_pause() __asm ("pause")
#else /* ( __GNUC__ || __INTEL_COMPILER ) */
@@ -136,7 +150,7 @@ ngx_atomic_fetch_add(ngx_atomic_t *value, ngx_atomic_int_t add);
#endif
-#elif ( __sparc__ || __sparcv9 )
+#elif ( __sparc__ || __sparc || __sparcv9 )
#if (NGX_PTR_SIZE == 8)
diff --git a/src/os/unix/ngx_sunpro_amd64.il b/src/os/unix/ngx_sunpro_amd64.il
index 0cd94b023..c26e6f717 100644
--- a/src/os/unix/ngx_sunpro_amd64.il
+++ b/src/os/unix/ngx_sunpro_amd64.il
@@ -28,3 +28,10 @@
lock
xaddq %rax, (%rdi)
.end
+
+
+/ ngx_cpu_pause()
+
+ .inline ngx_cpu_pause,0
+ pause
+ .end
diff --git a/src/os/unix/ngx_sunpro_x86.il b/src/os/unix/ngx_sunpro_x86.il
index a16568ac8..b82a2267b 100644
--- a/src/os/unix/ngx_sunpro_x86.il
+++ b/src/os/unix/ngx_sunpro_x86.il
@@ -29,3 +29,10 @@
lock
xaddl %eax, (%ecx)
.end
+
+
+/ ngx_cpu_pause()
+
+ .inline ngx_cpu_pause,0
+ pause
+ .end