changeset 64:5db440287648 NGINX_0_1_32

nginx 0.1.32 *) Bugfix: the arguments were omitted in the redirects, issued by the "rewrite" directive; bug appeared in 0.1.29. *) Feature: the "if" directive supports the captures in regular expressions. *) Feature: the "set" directive supports the variables and the captures of regular expressions. *) Feature: the "X-Accel-Redirect" response header line is supported in proxy and FastCGI mode.
author Igor Sysoev <http://sysoev.ru>
date Thu, 19 May 2005 00:00:00 +0400
parents e42867135781
children 5d92e3f1fb4e
files CHANGES CHANGES.ru auto/cc/acc auto/cc/ccc auto/cc/conf auto/os/conf auto/os/features auto/os/freebsd auto/os/linux auto/unix configure src/core/nginx.h src/core/ngx_inet.c src/core/ngx_log.h src/core/ngx_string.h src/event/ngx_event_timer.c src/http/modules/ngx_http_fastcgi_module.c src/http/modules/ngx_http_proxy_module.c src/http/modules/ngx_http_rewrite_module.c src/http/ngx_http_script.c src/http/ngx_http_script.h src/http/ngx_http_upstream.c src/http/ngx_http_upstream.h src/http/ngx_http_variables.c src/os/unix/ngx_os.h src/os/unix/ngx_posix_config.h src/os/unix/ngx_process.c src/os/unix/ngx_setproctitle.h
diffstat 28 files changed, 608 insertions(+), 254 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,18 @@
+
+Changes with nginx 0.1.32                                        19 May 2005
+
+    *) Bugfix: the arguments were omitted in the redirects, issued by the 
+       "rewrite" directive; bug appeared in 0.1.29.
+
+    *) Feature: the "if" directive supports the captures in regular 
+       expressions.
+
+    *) Feature: the "set" directive supports the variables and the captures 
+       of regular expressions.
+
+    *) Feature: the "X-Accel-Redirect" response header line is supported in 
+       proxy and FastCGI mode.
+
 
 Changes with nginx 0.1.31                                        16 May 2005
 
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,3 +1,18 @@
+
+Изменения в nginx 0.1.32                                          19.05.2005
+
+    *) Исправление: в редиректах, выдаваемых с помощью директивы rewrite, 
+       не передавались аргументы; ошибка появилась в 0.1.29.
+
+    *) Добавление: директива if поддерживает выделения в регулярных 
+       выражениях.
+
+    *) Добавление: директива set поддерживает переменные и выделения из 
+       регулярных выражений.
+
+    *) Добавление: в режиме прокси и FastCGI поддерживается строка 
+       заголовка X-Accel-Redirect в ответе бэкенда.
+
 
 Изменения в nginx 0.1.31                                          16.05.2005
 
new file mode 100644
--- /dev/null
+++ b/auto/cc/acc
@@ -0,0 +1,14 @@
+
+# Copyright (C) Igor Sysoev
+
+
+# aCC: HP ANSI C++ B3910B A.03.55.02
+
+# C89 mode
+
+CFLAGS="$CFLAGS -Ae"
+CC_TEST_FLAGS="-Ae"
+
+PCRE_OPT="$PCRE_OPT -Ae"
+ZLIB_OPT="$ZLIB_OPT -Ae"
+MD5_OPT="$MD5_OPT -Ae"
new file mode 100644
--- /dev/null
+++ b/auto/cc/ccc
@@ -0,0 +1,41 @@
+
+# Copyright (C) Igor Sysoev
+
+
+# Compaq C V6.5-207
+
+ngx_include_opt="-I"
+
+# warnings
+
+CFLAGS="$CFLAGS -msg_enable level6 -msg_fatal level6"
+
+CFLAGS="$CFLAGS -msg_disable unnecincl"
+CFLAGS="$CFLAGS -msg_disable nestincl"
+CFLAGS="$CFLAGS -msg_disable unusedincl"
+CFLAGS="$CFLAGS -msg_disable unknownmacro"
+CFLAGS="$CFLAGS -msg_disable strctpadding"
+CFLAGS="$CFLAGS -msg_disable ansialiascast"
+CFLAGS="$CFLAGS -msg_disable inlinestoclsmod"
+CFLAGS="$CFLAGS -msg_disable cxxkeyword"
+CFLAGS="$CFLAGS -msg_disable longlongsufx"
+
+# STUB
+CFLAGS="$CFLAGS -msg_disable truncintcast"
+CFLAGS="$CFLAGS -msg_disable trunclongcast"
+CFLAGS="$CFLAGS -msg_disable truncintasn"
+CFLAGS="$CFLAGS -msg_disable trunclongint"
+CFLAGS="$CFLAGS -msg_disable intconcastsgn"
+CFLAGS="$CFLAGS -msg_disable intconstsign"
+CFLAGS="$CFLAGS -msg_disable hexoctunsign"
+CFLAGS="$CFLAGS -msg_disable switchlong"
+CFLAGS="$CFLAGS -msg_disable valuepres"
+CFLAGS="$CFLAGS -msg_disable subscrbounds2"
+CFLAGS="$CFLAGS -msg_disable ignorecallval"
+CFLAGS="$CFLAGS -msg_disable nonstandcast"
+CFLAGS="$CFLAGS -msg_disable embedcomment"
+CFLAGS="$CFLAGS -msg_disable unreachcode"
+CFLAGS="$CFLAGS -msg_disable questcompare2"
+CFLAGS="$CFLAGS -msg_disable unusedtop"
+CFLAGS="$CFLAGS -msg_disable unrefdecl"
+CFLAGS="$CFLAGS -msg_disable bitnotint"
--- a/auto/cc/conf
+++ b/auto/cc/conf
@@ -42,30 +42,30 @@ else
 
     case $NGX_CC_NAME in
         gcc)
-            # gcc 2.7.2.3, 2.8.1, 2.95.4,
-            #     3.0.4, 3.1.1, 3.2.3, 3.3.2, 3.3.3, 3.3.4, 3.4
+            # gcc 2.7.2.3, 2.8.1, 2.95.4, egcs-1.1.2
+            #     3.0.4, 3.1.1, 3.2.3, 3.3.2, 3.3.3, 3.3.4, 3.4.0, 3.4.2
+            #     4.0.0
 
             . auto/cc/gcc
         ;;
 
         icc)
-            # Intel C++ compiler 7.1, 8.0
+            # Intel C++ compiler 7.1, 8.0, 8.1
 
             . auto/cc/icc
         ;;
 
         ccc)
-#            # Compaq C V6.5-207
-#
-#            . auto/cc/ccc
-             ngx_include_opt="-I"
+            # Compaq C V6.5-207
+
+            . auto/cc/ccc
         ;;
 
-#        acc)
-#            # aCC: HP ANSI C++ B3910B A.03.55.02
-#
-#            . auto/cc/acc
-#        ;;
+        acc)
+            # aCC: HP ANSI C++ B3910B A.03.55.02
+
+            . auto/cc/acc
+        ;;
 
         msvc*)
             # MSVC++ 6.0 SP2, MSVC++ Toolkit 2003
@@ -87,7 +87,7 @@ else
 
     esac
 
-    CC_TEST_FLAGS=$NGX_CC_OPT
+    CC_TEST_FLAGS="$CC_TEST_FLAGS $NGX_CC_OPT"
 
 fi
 
@@ -124,16 +124,20 @@ if [ "$NGX_PLATFORM" != win32 ]; then
     . auto/feature
 
 
-    ngx_feature="C99 variadic macros"
-    ngx_feature_name="NGX_HAVE_C99_VARIADIC_MACROS"
-    ngx_feature_run=yes
-    ngx_feature_incs="#include <stdio.h>
-#define var(dummy, ...) sprintf(__VA_ARGS__)"
-    ngx_feature_libs=
-    ngx_feature_test="char  buf[30]; buf[0] = '0';
-                      var(0, buf, \"%d\", 1);
-                      if (buf[0] != '1') return 1"
-    . auto/feature
+    if [ $NGX_CC_NAME = 'ccc' ]; then
+        echo "checking for C99 variadic macros ... disabled"
+    else
+        ngx_feature="C99 variadic macros"
+        ngx_feature_name="NGX_HAVE_C99_VARIADIC_MACROS"
+        ngx_feature_run=yes
+        ngx_feature_incs="#include <stdio.h>
+#define var(dummy, ...)  sprintf(__VA_ARGS__)"
+        ngx_feature_libs=
+        ngx_feature_test="char  buf[30]; buf[0] = '0';
+                          var(0, buf, \"%d\", 1);
+                          if (buf[0] != '1') return 1"
+        . auto/feature
+     fi
 
 
 #    ngx_feature="inline"
--- a/auto/os/conf
+++ b/auto/os/conf
@@ -23,15 +23,6 @@ case "$NGX_PLATFORM" in
         . auto/os/freebsd
     ;;
 
-    Darwin:*)
-        have=NGX_DARWIN . auto/have_headers
-        have=NGX_HAVE_INHERITED_NONBLOCK . auto/have
-        CORE_INCS="$UNIX_INCS"
-        CORE_DEPS="$UNIX_DEPS $POSIX_DEPS"
-        CORE_SRCS="$UNIX_SRCS"
-        CRYPT_LIB=
-    ;;
-
     Linux:*)
         . auto/os/linux
     ;;
@@ -44,11 +35,35 @@ case "$NGX_PLATFORM" in
         . auto/os/win32
     ;;
 
+    Darwin:*)
+        have=NGX_DARWIN . auto/have_headers
+        have=NGX_HAVE_INHERITED_NONBLOCK . auto/have
+        CORE_INCS="$UNIX_INCS"
+        CORE_DEPS="$UNIX_DEPS $POSIX_DEPS"
+        CORE_SRCS="$UNIX_SRCS"
+    ;;
+
+    HP-UX:*)
+        # HP/UX
+        have=NGX_HPUX . auto/have_headers
+        CORE_INCS="$UNIX_INCS"
+        CORE_DEPS="$UNIX_DEPS $POSIX_DEPS"
+        CORE_SRCS="$UNIX_SRCS"
+        CC_AUX_FLAGS="$CC_AUX_FLAGS -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED=1"
+    ;;
+
+    OSF1:*)
+        # HP Tru64
+        have=NGX_TRU64 . auto/have_headers
+        CORE_INCS="$UNIX_INCS"
+        CORE_DEPS="$UNIX_DEPS $POSIX_DEPS"
+        CORE_SRCS="$UNIX_SRCS"
+    ;;
+
     *)
         CORE_INCS="$UNIX_INCS"
         CORE_DEPS="$UNIX_DEPS $POSIX_DEPS"
         CORE_SRCS="$UNIX_SRCS"
-        CRYPT_LIB="-lcrypt"
     ;;
 
 esac
@@ -56,119 +71,8 @@ esac
 
 case "$NGX_MACHINE" in
 
-    i386|i686|i86pc|amd64)
+    i386 | i686 | i86pc | amd64)
         have=NGX_HAVE_NONALIGNED . auto/have
     ;;
 
 esac
-
-
-if [ "$NGX_PLATFORM" != win32 ]; then
-
-    NGX_USER=${NGX_USER:-nobody}
-
-    if [ -z "$NGX_GROUP" -a $NGX_USER = nobody ] ; then
-       if grep nobody /etc/group 2>&1 >/dev/null; then
-           echo "checking for nobody group ... found"
-           NGX_GROUP=nobody
-       else
-           echo "checking for nobody group ... not found"
-
-           if grep nogroup /etc/group 2>&1 >/dev/null; then
-               echo "checking for nogroup group ... found"
-               NGX_GROUP=nogroup
-           else 
-               echo "checking for nogroup group ... not found"
-               NGX_GROUP=nobody
-           fi
-       fi
-
-    else
-        NGX_GROUP=$NGX_USER
-    fi
-
-
-    ngx_feature="poll()"
-    ngx_feature_name=
-    ngx_feature_run=no
-    ngx_feature_incs="#include <poll.h>"
-    ngx_feature_libs=
-    ngx_feature_test="int  n, dp; struct pollfd  pl;
-                      dp = 0;
-                      pl.fd = 0;
-                      pl.events = 0;
-                      pl.revents = 0;
-                      n = poll(&pl, 1, 0)"
-    . auto/feature
-
-    if [ $ngx_found = no ]; then
-        EVENT_POLL=NONE
-    fi
-
-
-    ngx_feature="/dev/poll"
-    ngx_feature_name="NGX_HAVE_DEVPOLL"
-    ngx_feature_run=no
-    ngx_feature_incs="#include <sys/devpoll.h>"
-    ngx_feature_libs=
-    ngx_feature_test="int  n, dp; struct dvpoll  dvp;
-                      dp = 0;
-                      dvp.dp_fds = NULL;
-                      dvp.dp_nfds = 0;
-                      dvp.dp_timeout = 0;
-                      n = ioctl(dp, DP_POLL, &dvp)"
-    . auto/feature
-
-    if [ $ngx_found = yes ]; then
-        CORE_SRCS="$CORE_SRCS $DEVPOLL_SRCS"
-        EVENT_MODULES="$EVENT_MODULES $DEVPOLL_MODULE"
-        EVENT_FOUND=YES
-    fi
-
-
-    if test -z "$NGX_KQUEUE_CHECKED"; then
-        ngx_feature="kqueue"
-        ngx_feature_name="NGX_HAVE_KQUEUE"
-        ngx_feature_run=no
-        ngx_feature_incs="#include <sys/event.h>"
-        ngx_feature_libs=
-        ngx_feature_test="int kq; kq = kqueue()"
-        . auto/feature
-
-        if [ $ngx_found = yes ]; then
-
-            have=NGX_HAVE_CLEAR_EVENT . auto/have
-            EVENT_MODULES="$EVENT_MODULES $KQUEUE_MODULE"
-            CORE_SRCS="$CORE_SRCS $KQUEUE_SRCS"
-            EVENT_FOUND=YES
-
-            ngx_feature="kqueue's NOTE_LOWAT"
-            ngx_feature_name="NGX_HAVE_LOWAT_EVENT"
-            ngx_feature_run=no
-            ngx_feature_incs="#include <sys/event.h>"
-            ngx_feature_libs=
-            ngx_feature_test="struct kevent  kev;
-                              kev.fflags = NOTE_LOWAT;"
-            . auto/feature
-        fi
-    fi
-
-    if [ "$NGX_SYSTEM" = "NetBSD" ]; then
-
-        # NetBSD 2.0 incompatibly defines kevent.udata as "intptr_t"
-
-        cat << END >> $NGX_AUTO_CONFIG_H
-
-#define NGX_KQUEUE_UDATA_T
-
-END
-
-    else
-        cat << END >> $NGX_AUTO_CONFIG_H
-
-#define NGX_KQUEUE_UDATA_T  (void *)
-
-END
-
-    fi
-fi
new file mode 100644
--- /dev/null
+++ b/auto/os/features
@@ -0,0 +1,131 @@
+
+# Copyright (C) Igor Sysoev
+
+
+NGX_USER=${NGX_USER:-nobody}
+
+if [ -z "$NGX_GROUP" -a $NGX_USER = nobody ] ; then
+    if grep nobody /etc/group 2>&1 >/dev/null; then
+        echo "checking for nobody group ... found"
+        NGX_GROUP=nobody
+    else
+        echo "checking for nobody group ... not found"
+
+        if grep nogroup /etc/group 2>&1 >/dev/null; then
+            echo "checking for nogroup group ... found"
+            NGX_GROUP=nogroup
+        else 
+            echo "checking for nogroup group ... not found"
+            NGX_GROUP=nobody
+        fi
+    fi
+
+else
+    NGX_GROUP=$NGX_USER
+fi
+    
+
+ngx_feature="poll()"
+ngx_feature_name=
+ngx_feature_run=no
+ngx_feature_incs="#include <poll.h>"
+ngx_feature_libs=
+ngx_feature_test="int  n, dp; struct pollfd  pl;
+                  dp = 0; 
+                  pl.fd = 0;
+                  pl.events = 0;
+                  pl.revents = 0;
+                  n = poll(&pl, 1, 0)"
+. auto/feature
+    
+if [ $ngx_found = no ]; then
+    EVENT_POLL=NONE
+fi
+    
+
+ngx_feature="/dev/poll"
+ngx_feature_name="NGX_HAVE_DEVPOLL"
+ngx_feature_run=no
+ngx_feature_incs="#include <sys/devpoll.h>"
+ngx_feature_libs=
+ngx_feature_test="int  n, dp; struct dvpoll  dvp;
+                  dp = 0;
+                  dvp.dp_fds = NULL;
+                  dvp.dp_nfds = 0;
+                  dvp.dp_timeout = 0;
+                  n = ioctl(dp, DP_POLL, &dvp)"
+. auto/feature
+
+if [ $ngx_found = yes ]; then
+    CORE_SRCS="$CORE_SRCS $DEVPOLL_SRCS"
+    EVENT_MODULES="$EVENT_MODULES $DEVPOLL_MODULE"
+    EVENT_FOUND=YES
+fi
+
+
+if test -z "$NGX_KQUEUE_CHECKED"; then
+    ngx_feature="kqueue"
+    ngx_feature_name="NGX_HAVE_KQUEUE"
+    ngx_feature_run=no
+    ngx_feature_incs="#include <sys/event.h>"
+    ngx_feature_libs=
+    ngx_feature_test="int kq; kq = kqueue()"
+    . auto/feature
+
+    if [ $ngx_found = yes ]; then
+
+        have=NGX_HAVE_CLEAR_EVENT . auto/have
+        EVENT_MODULES="$EVENT_MODULES $KQUEUE_MODULE"
+        CORE_SRCS="$CORE_SRCS $KQUEUE_SRCS"
+        EVENT_FOUND=YES
+
+        ngx_feature="kqueue's NOTE_LOWAT"
+        ngx_feature_name="NGX_HAVE_LOWAT_EVENT"
+        ngx_feature_run=no
+        ngx_feature_incs="#include <sys/event.h>"
+        ngx_feature_libs=
+        ngx_feature_test="struct kevent  kev;
+                          kev.fflags = NOTE_LOWAT;"
+        . auto/feature
+    fi
+fi
+
+if [ "$NGX_SYSTEM" = "NetBSD" ]; then
+
+    # NetBSD 2.0 incompatibly defines kevent.udata as "intptr_t"
+
+    cat << END >> $NGX_AUTO_CONFIG_H
+
+#define NGX_KQUEUE_UDATA_T
+
+END
+
+else
+    cat << END >> $NGX_AUTO_CONFIG_H
+
+#define NGX_KQUEUE_UDATA_T  (void *)
+
+END
+
+fi
+
+
+ngx_feature="crypt()"
+ngx_feature_name=
+ngx_feature_run=no
+ngx_feature_incs=
+ngx_feature_libs=
+ngx_feature_test="crypt(\"test\", \"salt\");"
+. auto/feature
+
+
+if [ $ngx_found = no ]; then
+
+    ngx_feature="crypt() in libcrypt"
+    ngx_feature_libs=-lcrypt
+    . auto/feature
+
+    if [ $ngx_found = yes ]; then
+        CRYPT_LIB="-lcrypt"
+    fi
+fi
--- a/auto/os/freebsd
+++ b/auto/os/freebsd
@@ -7,7 +7,6 @@ have=NGX_FREEBSD . auto/have_headers
 CORE_INCS="$UNIX_INCS"
 CORE_DEPS="$UNIX_DEPS $FREEBSD_DEPS"
 CORE_SRCS="$UNIX_SRCS $FREEBSD_SRCS"
-CRYPT_LIB="-lcrypt"
 
 ngx_spacer='
 '
--- a/auto/os/linux
+++ b/auto/os/linux
@@ -7,7 +7,6 @@ have=NGX_LINUX . auto/have_headers
 CORE_INCS="$UNIX_INCS"
 CORE_DEPS="$UNIX_DEPS $LINUX_DEPS"
 CORE_SRCS="$UNIX_SRCS $LINUX_SRCS"
-CRYPT_LIB="-lcrypt"
 
 ngx_spacer='
 '
--- a/auto/unix
+++ b/auto/unix
@@ -32,7 +32,7 @@ ngx_type="sig_atomic_t"; ngx_types="int"
 . auto/types/sizeof
 ngx_param=NGX_SIG_ATOMIC_T_SIZE; ngx_value=$ngx_size; . auto/types/value
 
-ngx_type="socklen_t"; ngx_types="uint32_t"; . auto/types/typedef
+ngx_type="socklen_t"; ngx_types="int"; . auto/types/typedef
 
 ngx_type="in_addr_t"; ngx_types="uint32_t"; . auto/types/typedef
 
--- a/configure
+++ b/configure
@@ -27,6 +27,7 @@ fi
 . auto/os/conf
 
 if [ "$NGX_PLATFORM" != win32 ]; then
+    . auto/os/features
     . auto/threads
 fi
 
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define NGINX_VER          "nginx/0.1.31"
+#define NGINX_VER          "nginx/0.1.32"
 
 #define NGINX_VAR          "NGINX"
 #define NGX_NEWPID_EXT     ".newbin"
--- a/src/core/ngx_inet.c
+++ b/src/core/ngx_inet.c
@@ -419,7 +419,7 @@ ngx_inet_parse_host_port(ngx_inet_upstre
     u->host.data = url->data;
     u->host_header = *url;
 
-    for (/* void */; i < url->len; i++) {
+    for ( /* void */ ; i < url->len; i++) {
 
         if (url->data[i] == ':') {
             u->port_text.data = &url->data[i] + 1;
--- a/src/core/ngx_log.h
+++ b/src/core/ngx_log.h
@@ -130,6 +130,7 @@ void ngx_cdecl ngx_log_debug_core(ngx_lo
 #define ngx_log_debug7  ngx_log_debug
 #define ngx_log_debug8  ngx_log_debug
 
+
 #else /* NO VARIADIC MACROS */
 
 #define ngx_log_debug0(level, log, err, fmt)                                  \
--- a/src/core/ngx_string.h
+++ b/src/core/ngx_string.h
@@ -59,12 +59,12 @@ typedef struct {
  * while ZeroMemory() and bzero() are the calls.
  * icc may also inline several mov's of a zeroed register for small blocks.
  */
-#define ngx_memzero(buf, n)       memset(buf, 0, n)
-#define ngx_memset(buf, c, n)     memset(buf, c, n)
+#define ngx_memzero(buf, n)       (void) memset(buf, 0, n)
+#define ngx_memset(buf, c, n)     (void) memset(buf, c, n)
 
 
 /* msvc and icc compile memcpy() to the inline "rep movs" */
-#define ngx_memcpy(dst, src, n)   memcpy(dst, src, n)
+#define ngx_memcpy(dst, src, n)   (void) memcpy(dst, src, n)
 #define ngx_cpymem(dst, src, n)   ((u_char *) memcpy(dst, src, n)) + (n)
 
 
--- a/src/event/ngx_event_timer.c
+++ b/src/event/ngx_event_timer.c
@@ -121,7 +121,7 @@ ngx_event_expire_timers(ngx_msec_t timer
 
             ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
                            "event timer del: %d: %i",
-                            ngx_event_ident(ev->data), ev->rbtree_key);
+                           ngx_event_ident(ev->data), ev->rbtree_key);
 
             ngx_rbtree_delete((ngx_rbtree_t **) &ngx_event_timer_rbtree,
                               &ngx_event_timer_sentinel,
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -33,7 +33,7 @@ typedef enum {
     ngx_http_fastcgi_st_padding_length,
     ngx_http_fastcgi_st_reserved,
     ngx_http_fastcgi_st_data,
-    ngx_http_fastcgi_st_padding,
+    ngx_http_fastcgi_st_padding
 } ngx_http_fastcgi_state_e;
 
 
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -542,7 +542,9 @@ ngx_http_proxy_create_request(ngx_http_r
 
     while (*(uintptr_t *) le.ip) {
         lcode = *(ngx_http_script_len_code_pt *) le.ip;
-        lcode(&le);
+
+        /* skip the header line name length */
+        (void) lcode(&le);
 
         if (*(ngx_http_script_len_code_pt *) le.ip) {
 
--- a/src/http/modules/ngx_http_rewrite_module.c
+++ b/src/http/modules/ngx_http_rewrite_module.c
@@ -16,16 +16,10 @@ typedef struct {
 
 
 typedef struct {
-    ngx_str_t                  *name;
-    ngx_http_variable_value_t  *value;
-} ngx_http_rewrite_variable_t;
-
-
-typedef struct {
     ngx_array_t                *codes;        /* uintptr_t */
     ngx_array_t                *referers;     /* ngx_http_rewrite_referer_t */
 
-    ngx_uint_t                  max_captures;
+    ngx_uint_t                  captures;
     ngx_uint_t                  stack_size;
 
     ngx_flag_t                  log;
@@ -159,8 +153,8 @@ ngx_http_rewrite_handler(ngx_http_reques
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     }
 
-    if (cf->max_captures) {
-        e->captures = ngx_palloc(r->pool, cf->max_captures * sizeof(int));
+    if (cf->captures) {
+        e->captures = ngx_palloc(r->pool, cf->captures * sizeof(int));
         if (e->captures == NULL) {
             return NGX_HTTP_INTERNAL_SERVER_ERROR;
         }
@@ -542,10 +536,10 @@ ngx_http_rewrite(ngx_conf_t *cf, ngx_com
 
     if (regex->ncaptures) {
         regex->ncaptures = (regex->ncaptures + 1) * 3;
-    }
 
-    if (lcf->max_captures < regex->ncaptures) {
-        lcf->max_captures = regex->ncaptures;
+        if (lcf->captures < regex->ncaptures) {
+            lcf->captures = regex->ncaptures;
+        }
     }
 
     regex_end = ngx_http_script_add_code(lcf->codes,
@@ -735,7 +729,7 @@ static char *
 ngx_http_rewrite_if_condition(ngx_conf_t *cf, ngx_http_rewrite_loc_conf_t *lcf)
 {
     ngx_str_t                     *value, err;
-    ngx_uint_t                     cur, last;
+    ngx_uint_t                     cur, last, n;
     ngx_http_script_regex_code_t  *regex;
     u_char                         errstr[NGX_MAX_CONF_ERRSTR];
 
@@ -823,6 +817,16 @@ ngx_http_rewrite_if_condition(ngx_conf_t
         regex->test = 1;
         regex->name = value[last];
 
+        n = ngx_regex_capture_count(regex->regex);
+
+        if (n) {
+            regex->ncaptures = (n + 1) * 3;
+
+            if (lcf->captures < regex->ncaptures) {
+                lcf->captures = regex->ncaptures;
+            }
+        }
+
         return NGX_CONF_OK;
     }
 
@@ -977,11 +981,13 @@ ngx_http_rewrite_set(ngx_conf_t *cf, ngx
 {
     ngx_http_rewrite_loc_conf_t *lcf = conf;
 
-    ngx_int_t                      n, index;
-    ngx_str_t                     *value;
-    ngx_http_variable_t           *v;
-    ngx_http_script_var_code_t    *var;
-    ngx_http_script_value_code_t  *val;
+    ngx_int_t                              n, index;
+    ngx_str_t                             *value;
+    ngx_http_variable_t                   *v;
+    ngx_http_script_compile_t              sc;
+    ngx_http_script_var_code_t            *var;
+    ngx_http_script_value_code_t          *val;
+    ngx_http_script_complex_value_code_t  *complex;
 
     value = cf->args->elts;
 
@@ -1007,22 +1013,49 @@ ngx_http_rewrite_set(ngx_conf_t *cf, ngx
     v->handler = ngx_http_rewrite_var;
     v->data = index;
 
-    val = ngx_http_script_start_code(cf->pool, &lcf->codes,
-                                     sizeof(ngx_http_script_value_code_t));
-    if (val == NULL) {
-        return NGX_CONF_ERROR;
-    }
+    n = ngx_http_script_variables_count(&value[2]);
+
+    if (n == 0) {
+        val = ngx_http_script_start_code(cf->pool, &lcf->codes,
+                                         sizeof(ngx_http_script_value_code_t));
+        if (val == NULL) {
+            return NGX_CONF_ERROR;
+        }
 
-    n = ngx_atoi(value[2].data, value[2].len);
+        n = ngx_atoi(value[2].data, value[2].len);
+
+        if (n == NGX_ERROR) {
+            n = 0;
+        }
+
+        val->code = ngx_http_script_value_code;
+        val->value = (uintptr_t) n;
+        val->text_len = (uintptr_t) value[2].len;
+        val->text_data = (uintptr_t) value[2].data;
 
-    if (n == NGX_ERROR) {
-        n = 0;
-    }
+    } else {
+        complex = ngx_http_script_start_code(cf->pool, &lcf->codes,
+                                 sizeof(ngx_http_script_complex_value_code_t));
+        if (complex == NULL) {
+            return NGX_CONF_ERROR;
+        }
+
+        complex->code = ngx_http_script_complex_value_code;
+        complex->lengths = NULL;
+
+        ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
 
-    val->code = ngx_http_script_value_code;
-    val->value = (uintptr_t) n;
-    val->text_len = (uintptr_t) value[2].len;
-    val->text_data = (uintptr_t) value[2].data;
+        sc.cf = cf; 
+        sc.source = &value[2];
+        sc.lengths = &complex->lengths;
+        sc.values = &lcf->codes;
+        sc.variables = n;
+        sc.complete_lengths = 1;
+
+        if (ngx_http_script_compile(&sc) != NGX_OK) {
+            return NGX_CONF_ERROR;
+        }
+    }
 
     var = ngx_http_script_start_code(cf->pool, &lcf->codes,
                                      sizeof(ngx_http_script_var_code_t));
--- a/src/http/ngx_http_script.c
+++ b/src/http/ngx_http_script.c
@@ -405,17 +405,21 @@ ngx_http_script_copy_capture_len_code(ng
 
     e->ip += sizeof(ngx_http_script_copy_capture_code_t);
 
-    if ((e->args || e->quote)
-        && (e->request->quoted_uri || e->request->plus_in_uri))
-    {
-        return e->captures[code->n + 1] - e->captures[code->n]
-               + ngx_escape_uri(NULL,
-                                &e->line->data[e->captures[code->n]],
+    if (code->n < e->ncaptures) {
+        if ((e->args || e->quote)
+            && (e->request->quoted_uri || e->request->plus_in_uri))
+        {
+            return e->captures[code->n + 1] - e->captures[code->n]
+                   + ngx_escape_uri(NULL,
+                                &e->line.data[e->captures[code->n]],
                                 e->captures[code->n + 1] - e->captures[code->n],
                                 NGX_ESCAPE_ARGS);
-    } else {
-        return e->captures[code->n + 1] - e->captures[code->n];
+        } else {
+            return e->captures[code->n + 1] - e->captures[code->n];
+        }
     }
+
+    return 0;
 }
 
 
@@ -428,17 +432,19 @@ ngx_http_script_copy_capture_code(ngx_ht
 
     e->ip += sizeof(ngx_http_script_copy_capture_code_t);
 
-    if ((e->args || e->quote)
-        && (e->request->quoted_uri || e->request->plus_in_uri))
-    {
-        e->pos = (u_char *) ngx_escape_uri(e->pos,
-                                &e->line->data[e->captures[code->n]],
+    if (code->n < e->ncaptures) {
+        if ((e->args || e->quote)
+            && (e->request->quoted_uri || e->request->plus_in_uri))
+        {
+            e->pos = (u_char *) ngx_escape_uri(e->pos,
+                                &e->line.data[e->captures[code->n]],
                                 e->captures[code->n + 1] - e->captures[code->n],
                                 NGX_ESCAPE_ARGS);
-    } else {
-        e->pos = ngx_cpymem(e->pos,
-                            &e->line->data[e->captures[code->n]],
-                            e->captures[code->n + 1] - e->captures[code->n]);
+        } else {
+            e->pos = ngx_cpymem(e->pos,
+                               &e->line.data[e->captures[code->n]],
+                               e->captures[code->n + 1] - e->captures[code->n]);
+        }
     }
 
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
@@ -476,20 +482,23 @@ ngx_http_script_regex_start_code(ngx_htt
                    "http script regex: \"%V\"", &code->name);
 
     if (code->uri) {
-        e->line = &r->uri;
+        e->line = r->uri;
     } else {
         e->sp--;
-        e->line = &e->sp->text;
+        e->line = e->sp->text;
     }
 
-    rc = ngx_regex_exec(code->regex, e->line, e->captures, code->ncaptures);
+    rc = ngx_regex_exec(code->regex, &e->line, e->captures, code->ncaptures);
 
     if (rc == NGX_REGEX_NO_MATCHED) {
         if (e->log) {
             ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
-                          "\"%V\" does not match \"%V\"", &code->name, e->line);
+                          "\"%V\" does not match \"%V\"",
+                          &code->name, &e->line);
         }
 
+        e->ncaptures = 0;
+
         if (code->test) {
             e->sp->value = 0; 
             e->sp->text.len = 0;
@@ -507,7 +516,7 @@ ngx_http_script_regex_start_code(ngx_htt
     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);
+                      rc, &e->line, &code->name);
 
         e->ip = ngx_http_script_exit;
         e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
@@ -516,9 +525,11 @@ ngx_http_script_regex_start_code(ngx_htt
 
     if (e->log) {
         ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
-                      "\"%V\" matches \"%V\"", &code->name, e->line);
+                      "\"%V\" matches \"%V\"", &code->name, &e->line);
     }
 
+    e->ncaptures = code->ncaptures;
+
     if (code->test) {
         e->sp->value = 1; 
         e->sp->text.len = 1;
@@ -570,6 +581,7 @@ ngx_http_script_regex_start_code(ngx_htt
         le.ip = code->lengths->elts;
         le.request = r;
         le.captures = e->captures;
+        le.ncaptures = e->ncaptures;
 
         len = 1;  /* reserve 1 byte for possible "?" */
 
@@ -581,7 +593,7 @@ ngx_http_script_regex_start_code(ngx_htt
         e->buf.len = len;
     }
 
-    if (code->args && code->add_args && r->args.len) {
+    if (code->add_args && r->args.len) {
         e->buf.len += r->args.len + 1;
     }
 
@@ -724,6 +736,48 @@ ngx_http_script_if_code(ngx_http_script_
 
 
 void
+ngx_http_script_complex_value_code(ngx_http_script_engine_t *e)
+{
+    size_t                                 len;
+    ngx_http_script_engine_t               le;
+    ngx_http_script_len_code_pt            lcode;
+    ngx_http_script_complex_value_code_t  *code;
+
+    code = (ngx_http_script_complex_value_code_t *) e->ip;
+
+    e->ip += sizeof(ngx_http_script_complex_value_code_t);
+
+    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
+                   "http script complex value");
+
+    ngx_memzero(&le, sizeof(ngx_http_script_engine_t));
+
+    le.ip = code->lengths->elts;
+    le.request = e->request;
+    le.captures = e->captures;
+    le.ncaptures = e->ncaptures;
+
+    for (len = 0; *(uintptr_t *) le.ip; len += lcode(&le)) {
+        lcode = *(ngx_http_script_len_code_pt *) le.ip;
+    }
+
+    e->buf.len = len;
+    e->buf.data = ngx_palloc(e->request->pool, len);
+    if (e->buf.data == NULL) {
+        e->ip = ngx_http_script_exit;
+        e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
+        return;
+    }
+
+    e->pos = e->buf.data;
+
+    e->sp->value = 0;
+    e->sp->text = e->buf;
+    e->sp++;
+}
+
+
+void
 ngx_http_script_value_code(ngx_http_script_engine_t *e)
 {
     ngx_http_script_value_code_t  *code;
--- a/src/http/ngx_http_script.h
+++ b/src/http/ngx_http_script.h
@@ -19,7 +19,7 @@ typedef struct {
     ngx_http_variable_value_t      *sp;
 
     ngx_str_t                       buf;
-    ngx_str_t                      *line;
+    ngx_str_t                       line;
 
     /* the start of the rewritten arguments */
     u_char                         *args;
@@ -29,6 +29,7 @@ typedef struct {
     unsigned                        log:1;
 
     int                            *captures;
+    ngx_uint_t                      ncaptures;
 
     ngx_int_t                       status;
     ngx_http_request_t             *request;
@@ -130,6 +131,12 @@ typedef struct {
 
 typedef struct {
     ngx_http_script_code_pt          code;
+    ngx_array_t                     *lengths;
+} ngx_http_script_complex_value_code_t;
+
+
+typedef struct {
+    ngx_http_script_code_pt          code;
     uintptr_t                        value;
     uintptr_t                        text_len;
     uintptr_t                        text_data;
@@ -155,6 +162,7 @@ void ngx_http_script_copy_capture_code(n
 void ngx_http_script_start_args_code(ngx_http_script_engine_t *e);
 void ngx_http_script_return_code(ngx_http_script_engine_t *e);
 void ngx_http_script_if_code(ngx_http_script_engine_t *e);
+void ngx_http_script_complex_value_code(ngx_http_script_engine_t *e);
 void ngx_http_script_value_code(ngx_http_script_engine_t *e);
 void ngx_http_script_set_var_code(ngx_http_script_engine_t *e);
 void ngx_http_script_var_code(ngx_http_script_engine_t *e);
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -77,71 +77,80 @@ ngx_http_upstream_header_t  ngx_http_ups
     { ngx_string("Status"),
                  ngx_http_upstream_process_header_line,
                  offsetof(ngx_http_upstream_headers_in_t, status),
-                 /* STUB */ ngx_http_upstream_ignore_header_line, 0 },
+                 /* STUB */ ngx_http_upstream_ignore_header_line, 0, 0 },
 
     { ngx_string("Content-Type"),
                  ngx_http_upstream_process_header_line,
                  offsetof(ngx_http_upstream_headers_in_t, content_type),
-                 ngx_http_upstream_copy_content_type, 0 },
+                 ngx_http_upstream_copy_content_type, 0, 0 },
 
     { ngx_string("Content-Length"),
                  ngx_http_upstream_process_header_line,
                  offsetof(ngx_http_upstream_headers_in_t, content_length),
-                 ngx_http_upstream_copy_content_length, 0 },
+                 ngx_http_upstream_copy_content_length, 0, 0 },
 
     { ngx_string("Date"),
                  ngx_http_upstream_process_header_line,
                  offsetof(ngx_http_upstream_headers_in_t, date),
                  ngx_http_upstream_conditional_copy_header_line,
-                 offsetof(ngx_http_upstream_conf_t, pass_date) },
+                 offsetof(ngx_http_upstream_conf_t, pass_date), 0 },
 
     { ngx_string("Server"),
                  ngx_http_upstream_process_header_line,
                  offsetof(ngx_http_upstream_headers_in_t, server),
                  ngx_http_upstream_conditional_copy_header_line,
-                 offsetof(ngx_http_upstream_conf_t, pass_server) },
+                 offsetof(ngx_http_upstream_conf_t, pass_server), 0 },
 
     { ngx_string("Location"),
                  ngx_http_upstream_ignore_header_line, 0,
-                 ngx_http_upstream_rewrite_location, 0 },
+                 ngx_http_upstream_rewrite_location, 0, 0 },
 
     { ngx_string("Refresh"),
                  ngx_http_upstream_ignore_header_line, 0,
-                 ngx_http_upstream_rewrite_refresh, 0 },
+                 ngx_http_upstream_rewrite_refresh, 0, 0 },
+
+    { ngx_string("Set-Cookie"),
+                 ngx_http_upstream_ignore_header_line, 0,
+                 ngx_http_upstream_copy_header_line, 0, 1 },
 
     { ngx_string("Cache-Control"),
                  ngx_http_upstream_process_multi_header_lines,
                  offsetof(ngx_http_upstream_headers_in_t, cache_control),
                  ngx_http_upstream_copy_multi_header_lines,
-                 offsetof(ngx_http_headers_out_t, cache_control) },
+                 offsetof(ngx_http_headers_out_t, cache_control), 1 },
 
     { ngx_string("Connection"),
                  ngx_http_upstream_ignore_header_line, 0,
-                 ngx_http_upstream_ignore_header_line, 0 },
+                 ngx_http_upstream_ignore_header_line, 0, 0 },
 
     { ngx_string("X-Pad"),
                  ngx_http_upstream_ignore_header_line, 0,
-                 ngx_http_upstream_ignore_header_line, 0 },
+                 ngx_http_upstream_ignore_header_line, 0, 0 },
 
     { ngx_string("X-Powered-By"),
                  ngx_http_upstream_ignore_header_line, 0,
                  ngx_http_upstream_conditional_copy_header_line,
-                 offsetof(ngx_http_upstream_conf_t, pass_x_powered_by) },
+                 offsetof(ngx_http_upstream_conf_t, pass_x_powered_by), 0 },
 
     { ngx_string("X-Accel-Expires"),
                  ngx_http_upstream_process_header_line,
                  offsetof(ngx_http_upstream_headers_in_t, x_accel_expires),
                  ngx_http_upstream_conditional_copy_header_line,
-                 offsetof(ngx_http_upstream_conf_t, pass_x_accel_expires) },
+                 offsetof(ngx_http_upstream_conf_t, pass_x_accel_expires), 0 },
+
+    { ngx_string("X-Accel-Redirect"),
+                 ngx_http_upstream_process_header_line,
+                 offsetof(ngx_http_upstream_headers_in_t, x_accel_redirect),
+                 ngx_http_upstream_ignore_header_line, 0, 0 },
 
 #if (NGX_HTTP_GZIP)
     { ngx_string("Content-Encoding"),
                  ngx_http_upstream_process_header_line,
                  offsetof(ngx_http_upstream_headers_in_t, content_encoding),
-                 ngx_http_upstream_copy_content_encoding, 0 },
+                 ngx_http_upstream_copy_content_encoding, 0, 0 },
 #endif
 
-    { ngx_null_string, NULL, 0, NULL, 0 }
+    { ngx_null_string, NULL, 0, NULL, 0, 0 }
 };
 
 
@@ -698,14 +707,18 @@ ngx_http_upstream_send_request_handler(n
 static void
 ngx_http_upstream_process_header(ngx_event_t *rev)
 {
-    ssize_t                    n;
-    ngx_int_t                  rc;
-    ngx_uint_t                 i;
-    ngx_connection_t          *c;
-    ngx_http_request_t        *r;
-    ngx_http_upstream_t       *u;
-    ngx_http_err_page_t       *err_page;
-    ngx_http_core_loc_conf_t  *clcf;
+    ssize_t                         n;
+    ngx_int_t                       rc;
+    ngx_uint_t                      i, key;
+    ngx_list_part_t                *part;
+    ngx_table_elt_t                *h;
+    ngx_connection_t               *c;
+    ngx_http_request_t             *r;
+    ngx_http_upstream_t            *u;
+    ngx_http_err_page_t            *err_page;
+    ngx_http_core_loc_conf_t       *clcf;
+    ngx_http_upstream_header_t     *hh;
+    ngx_http_upstream_main_conf_t  *umcf;
 
     c = rev->data;
     r = c->data;
@@ -875,6 +888,48 @@ ngx_http_upstream_process_header(ngx_eve
         }
     }
 
+    if (r->upstream->headers_in.x_accel_redirect) {
+        ngx_http_upstream_finalize_request(r, u, NGX_DECLINED);
+
+        umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);
+        hh = (ngx_http_upstream_header_t *) umcf->headers_in_hash.buckets;
+
+        part = &r->upstream->headers_in.headers.part;
+        h = part->elts;
+
+        for (i = 0; /* void */; i++) {
+
+            if (i >= part->nelts) {
+                if (part->next == NULL) {
+                    break;
+                }
+    
+                part = part->next;
+                h = part->elts;
+                i = 0;
+            }
+
+            key = h[i].hash % umcf->headers_in_hash.hash_size;
+
+            if (hh[key].redirect
+                && hh[key].name.len == h[i].key.len
+                && ngx_strcasecmp(hh[key].name.data, h[i].key.data) == 0)
+            {
+                if (hh[key].copy_handler(r, &h[i], hh[key].conf) != NGX_OK) {
+                    ngx_http_upstream_finalize_request(r, u,
+                                               NGX_HTTP_INTERNAL_SERVER_ERROR);
+                    return;
+                }
+
+            }
+        }
+
+        ngx_http_internal_redirect(r,
+                              &r->upstream->headers_in.x_accel_redirect->value,
+                              NULL);
+        return;
+    }
+
     ngx_http_upstream_send_response(r, u);
 }
 
@@ -1307,6 +1362,11 @@ ngx_http_upstream_finalize_request(ngx_h
 #endif
 
     r->log_handler = u->saved_log_handler;
+
+    if (rc == NGX_DECLINED) {
+        return;
+    }
+
     r->connection->log->action = "sending to client";
 
     if (rc == 0 && r->main == NULL) {
--- a/src/http/ngx_http_upstream.h
+++ b/src/http/ngx_http_upstream.h
@@ -87,6 +87,7 @@ typedef struct {
     ngx_uint_t                      offset;
     ngx_http_header_handler_pt      copy_handler;
     ngx_uint_t                      conf;
+    ngx_uint_t                      redirect;  /* unsigned   redirect:1; */
 } ngx_http_upstream_header_t;
 
 
@@ -101,6 +102,7 @@ typedef struct {
     ngx_table_elt_t                *expires;
     ngx_table_elt_t                *etag;
     ngx_table_elt_t                *x_accel_expires;
+    ngx_table_elt_t                *x_accel_redirect;
 
     ngx_table_elt_t                *content_type;
     ngx_table_elt_t                *content_length;
--- a/src/http/ngx_http_variables.c
+++ b/src/http/ngx_http_variables.c
@@ -15,6 +15,8 @@ static ngx_http_variable_value_t *
 static ngx_http_variable_value_t *
     ngx_http_variable_header(ngx_http_request_t *r, uintptr_t data);
 static ngx_http_variable_value_t *
+    ngx_http_variable_headers(ngx_http_request_t *r, uintptr_t data);
+static ngx_http_variable_value_t *
     ngx_http_variable_unknown_header(ngx_http_request_t *r, uintptr_t data);
 static ngx_http_variable_value_t *
     ngx_http_variable_host(ngx_http_request_t *r, uintptr_t data);
@@ -63,6 +65,9 @@ static ngx_http_variable_t  ngx_http_cor
       offsetof(ngx_http_request_t, headers_in.x_forwarded_for), 0 },
 #endif
 
+    { ngx_string("http_cookie"), ngx_http_variable_headers,
+      offsetof(ngx_http_request_t, headers_in.cookies), 0 },
+
     { ngx_string("content_length"), ngx_http_variable_header,
       offsetof(ngx_http_request_t, headers_in.content_length), 0 },
 
@@ -334,6 +339,62 @@ ngx_http_variable_header(ngx_http_reques
 
 
 static ngx_http_variable_value_t *
+ngx_http_variable_headers(ngx_http_request_t *r, uintptr_t data)
+{
+    u_char                      *p;
+    ngx_uint_t                   i;
+    ngx_array_t                 *a;
+    ngx_table_elt_t            **h;
+    ngx_http_variable_value_t   *vv;
+
+    a = (ngx_array_t *) ((char *) r + data);
+
+    if (a->nelts == 0) {
+        return NGX_HTTP_VAR_NOT_FOUND;
+    }
+
+    vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t));
+    if (vv == NULL) {
+        return NULL;
+    }
+
+    vv->value = 0;
+
+    h = a->elts;
+
+    if (a->nelts == 1) {
+        vv->text = (*h)->value;
+        return vv;
+    }
+
+    vv->text.len = (size_t) - (ssize_t) (sizeof("; ") - 1);
+
+    for (i = 0; i < a->nelts; i++) {
+        vv->text.len += h[i]->value.len + sizeof("; ") - 1;
+    }
+
+    vv->text.data = ngx_palloc(r->pool, vv->text.len);
+    if (vv->text.data == NULL) {
+        return NULL;
+    }
+
+    p = vv->text.data;
+
+    for (i = 0; /* void */ ; i++) {
+        p = ngx_cpymem(p, h[i]->value.data, h[i]->value.len);
+
+        if (i == a->nelts - 1) {
+            break;
+        }
+
+        *p++ = ';'; *p++ = ' ';
+    }
+
+    return vv;
+}
+
+
+static ngx_http_variable_value_t *
 ngx_http_variable_unknown_header(ngx_http_request_t *r, uintptr_t data)
 {
     ngx_str_t  *var = (ngx_str_t *) data;
--- a/src/os/unix/ngx_os.h
+++ b/src/os/unix/ngx_os.h
@@ -31,7 +31,7 @@ typedef struct {
 } ngx_os_io_t;
 
 
-void ngx_debug_init();
+void ngx_debug_init(void);
 ngx_int_t ngx_os_init(ngx_log_t *log);
 void ngx_os_status(ngx_log_t *log);
 ngx_int_t ngx_daemon(ngx_log_t *log);
--- a/src/os/unix/ngx_posix_config.h
+++ b/src/os/unix/ngx_posix_config.h
@@ -8,13 +8,13 @@
 #define _NGX_POSIX_CONFIG_H_INCLUDED_
 
 
-#if 0
+#if (NGX_HPUX)
 #define _XOPEN_SOURCE
 #define _XOPEN_SOURCE_EXTENDED  1
 #endif
 
 
-#if 0
+#if (NGX_TRU64)
 #define _REENTRANT
 #endif
 
--- a/src/os/unix/ngx_process.c
+++ b/src/os/unix/ngx_process.c
@@ -23,9 +23,9 @@ ngx_int_t        ngx_last_process;
 ngx_process_t    ngx_processes[NGX_MAX_PROCESSES];
 
 
-ngx_pid_t ngx_spawn_process(ngx_cycle_t *cycle,
-                            ngx_spawn_proc_pt proc, void *data,
-                            char *name, ngx_int_t respawn)
+ngx_pid_t
+ngx_spawn_process(ngx_cycle_t *cycle, ngx_spawn_proc_pt proc, void *data,
+    char *name, ngx_int_t respawn)
 {
     u_long     on;
     ngx_pid_t  pid;
@@ -185,14 +185,16 @@ ngx_pid_t ngx_spawn_process(ngx_cycle_t 
 }
 
 
-ngx_pid_t ngx_execute(ngx_cycle_t *cycle, ngx_exec_ctx_t *ctx)
+ngx_pid_t
+ngx_execute(ngx_cycle_t *cycle, ngx_exec_ctx_t *ctx)
 {
     return ngx_spawn_process(cycle, ngx_execute_proc, ctx, ctx->name,
                              NGX_PROCESS_DETACHED);
 }
 
 
-static void ngx_execute_proc(ngx_cycle_t *cycle, void *data)
+static void
+ngx_execute_proc(ngx_cycle_t *cycle, void *data)
 {
     ngx_exec_ctx_t  *ctx = data;
 
@@ -206,7 +208,8 @@ static void ngx_execute_proc(ngx_cycle_t
 }
 
 
-void ngx_process_get_status()
+void
+ngx_process_get_status(void)
 {
     int              status;
     char            *process;
@@ -301,7 +304,8 @@ void ngx_process_get_status()
 }
 
 
-void ngx_debug_point()
+void
+ngx_debug_point(void)
 {
     ngx_core_conf_t  *ccf;
 
--- a/src/os/unix/ngx_setproctitle.h
+++ b/src/os/unix/ngx_setproctitle.h
@@ -16,30 +16,36 @@
 #define ngx_setproctitle           setproctitle
 
 
-#elif !defined NGX_SETPROCTITLE_USES_ENV
+#else /* !NGX_HAVE_SETPROCTITLE */
 
-#define NGX_SETPROCTITLE_USES_ENV  1
+#if !defined NGX_SETPROCTITLE_USES_ENV
 
 #if (NGX_SOLARIS)
 
+#define NGX_SETPROCTITLE_USES_ENV  1
 #define NGX_SETPROCTITLE_PAD       ' '
 
-#elif (NGX_LINUX) || (NGX_DARWIN)
-
-#define NGX_SETPROCTITLE_PAD       '\0'
-
-#endif
-
 ngx_int_t ngx_init_setproctitle(ngx_log_t *log);
 void ngx_setproctitle(char *title);
 
+#elif (NGX_LINUX) || (NGX_DARWIN)
 
-#else /* !NGX_SETPROCTITLE_USES_ENV */
+#define NGX_SETPROCTITLE_USES_ENV  1
+#define NGX_SETPROCTITLE_PAD       '\0'
+
+ngx_int_t ngx_init_setproctitle(ngx_log_t *log);
+void ngx_setproctitle(char *title);
+
+#else
 
 #define ngx_init_setproctitle(log)
 #define ngx_setproctitle(title)
 
-#endif
+#endif /* OSes */
+
+#endif /* NGX_SETPROCTITLE_USES_ENV */
+
+#endif /* NGX_HAVE_SETPROCTITLE */
 
 
 #endif /* _NGX_SETPROCTITLE_H_INCLUDED_ */