changeset 494:499474178a11 NGINX_0_7_59

nginx 0.7.59 *) Feature: the "proxy_cache_methods" and "fastcgi_cache_methods" directives. *) Bugfix: socket leak; the bug had appeared in 0.7.25. Thanks to Maxim Dounin. *) Bugfix: a segmentation fault occurred in worker process, if a request had no body and the $request_body variable was used; the bug had appeared in 0.7.58. *) Bugfix: the SSL modules might not built on Solaris and Linux; the bug had appeared in 0.7.58. *) Bugfix: ngx_http_xslt_filter_module responses were not handled by SSI, charset, and gzip filters. *) Bugfix: a "charset" directive did not set a charset to ngx_http_gzip_static_module responses.
author Igor Sysoev <http://sysoev.ru>
date Mon, 25 May 2009 00:00:00 +0400
parents d13d7ebf1370
children 6d9fb4461113
files CHANGES CHANGES.ru auto/lib/openssl/conf auto/lib/openssl/make auto/options auto/os/features auto/unix src/core/nginx.h src/http/modules/ngx_http_charset_filter_module.c src/http/modules/ngx_http_fastcgi_module.c src/http/modules/ngx_http_gzip_static_module.c src/http/modules/ngx_http_image_filter_module.c src/http/modules/ngx_http_proxy_module.c src/http/modules/ngx_http_range_filter_module.c src/http/modules/ngx_http_xslt_filter_module.c src/http/modules/perl/nginx.pm src/http/ngx_http_core_module.c src/http/ngx_http_request.c src/http/ngx_http_request.h src/http/ngx_http_special_response.c src/http/ngx_http_upstream.c src/http/ngx_http_upstream.h src/http/ngx_http_variables.c
diffstat 23 files changed, 175 insertions(+), 75 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,26 @@
 
+Changes with nginx 0.7.59                                        25 May 2009
+
+    *) Feature: the "proxy_cache_methods" and "fastcgi_cache_methods" 
+       directives.
+
+    *) Bugfix: socket leak; the bug had appeared in 0.7.25.
+       Thanks to Maxim Dounin.
+
+    *) Bugfix: a segmentation fault occurred in worker process, 
+       if a request had no body and the $request_body variable was used;
+       the bug had appeared in 0.7.58.
+
+    *) Bugfix: the SSL modules might not built on Solaris and Linux;
+       the bug had appeared in 0.7.58.
+
+    *) Bugfix: ngx_http_xslt_filter_module responses were not handled by 
+       SSI, charset, and gzip filters.
+
+    *) Bugfix: a "charset" directive did not set a charset to 
+       ngx_http_gzip_static_module responses.
+
+
 Changes with nginx 0.7.58                                        18 May 2009
 
     *) Feature: a "listen" directive of the mail proxy module supports IPv6.
@@ -19,7 +41,7 @@ Changes with nginx 0.7.58               
 
 Changes with nginx 0.7.57                                        12 May 2009
 
-    *) Bugfix: a segmentation fault occurred in worker process, if the 
+    *) Bugfix: a floating-point fault occurred in worker process, if the 
        ngx_http_image_filter_module errors were redirected to named 
        location; the bug had appeared in 0.7.56.
 
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,25 @@
 
+Изменения в nginx 0.7.59                                          25.05.2009
+
+    *) Добавление: директивы proxy_cache_methods и fastcgi_cache_methods.
+
+    *) Исправление: утечки сокетов; ошибка появилась в 0.7.25.
+       Спасибо Максиму Дунину.
+
+    *) Исправление: при использовании переменной $request_body в рабочем 
+       процессе происходил segmentation fault, если в запросе не было тела; 
+       ошибка появилась в 0.7.58.
+
+    *) Исправление: SSL-модули могли не собираться на Solaris и Linux; 
+       ошибка появилась в 0.7.56.
+
+    *) Исправление: ответы модуля ngx_http_xslt_filter_module не 
+       обрабатывались SSI-, charset- и gzip-фильтрами.
+
+    *) Исправление: директива charset не ставила кодировку для ответов 
+       модуля ngx_http_gzip_static_module.
+
+
 Изменения в nginx 0.7.58                                          18.05.2009
 
     *) Добавление: директива listen почтового прокси-сервера поддерживает 
@@ -1381,7 +1402,7 @@
     *) Добавление: директивы open_file_cache, open_file_cache_retest и 
        open_file_cache_errors.
 
-    *) Исправление: утечка сокетов; ошибка появилась в 0.6.7.
+    *) Исправление: утечки сокетов; ошибка появилась в 0.6.7.
 
     *) Исправление: В строку заголовка ответа "Content-Type", указанную в 
        методе $r->send_http_header(), не добавлялась кодировка, указанная в 
--- a/auto/lib/openssl/conf
+++ b/auto/lib/openssl/conf
@@ -25,19 +25,14 @@ if [ $OPENSSL != NONE ]; then
             have=NGX_OPENSSL . auto/have
             have=NGX_SSL . auto/have
 
-            CORE_INCS="$CORE_INCS $OPENSSL/include"
-            LINK_DEPS="$LINK_DEPS $OPENSSL/libssl.a $OPENSSL/libcrypto.a"
-            CORE_LIBS="$CORE_LIBS $OPENSSL/libssl.a $OPENSSL/libcrypto.a"
-        ;;
-    esac
-
-    case "$NGX_SYSTEM" in
-        SunOS|Linux)
+            CORE_INCS="$CORE_INCS $OPENSSL/openssl/include"
+            CORE_DEPS="$CORE_DEPS $OPENSSL/openssl/include/openssl/ssl.h"
+            CORE_LIBS="$CORE_LIBS $OPENSSL/openssl/lib/libssl.a"
+            CORE_LIBS="$CORE_LIBS $OPENSSL/openssl/lib/libcrypto.a"
             CORE_LIBS="$CORE_LIBS $NGX_LIBDL"
         ;;
     esac
 
-
 else
 
     case "$NGX_PLATFORM" in
@@ -69,14 +64,8 @@ else
 
             if [ $ngx_found = yes ]; then
                 have=NGX_SSL . auto/have
-                CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
+                CORE_LIBS="$CORE_LIBS $ngx_feature_libs $NGX_LIBDL"
                 OPENSSL=YES
-
-                case "$NGX_SYSTEM" in
-                    SunOS)
-                        CORE_LIBS="$CORE_LIBS $NGX_LIBDL"
-                    ;;
-                esac
             fi
         ;;
 
--- a/auto/lib/openssl/make
+++ b/auto/lib/openssl/make
@@ -2,15 +2,9 @@
 # Copyright (C) Igor Sysoev
 
 
-if test -n "$OPENSSL_OPT"; then
-    NGX_OPENSSL_CONFIG="./Configure $OPENSSL_OPT"
-else
-    NGX_OPENSSL_CONFIG="./config"
-fi
-
 case $USE_THREADS in
-    NO) NGX_OPENSSL_CONFIG="$NGX_OPENSSL_CONFIG no-threads" ;;
-    *)  NGX_OPENSSL_CONFIG="$NGX_OPENSSL_CONFIG threads" ;;
+    NO) OPENSSL_OPT="$OPENSSL_OPT no-threads" ;;
+    *)  OPENSSL_OPT="$OPENSSL_OPT threads" ;;
 esac
 
 case "$CC" in
@@ -51,13 +45,26 @@ END
     ;;
 
     *)
+        case $OPENSSL in
+
+        /*)
+            ngx_prefix="$OPENSSL/openssl"
+        ;;
+
+        *)
+            ngx_prefix="$PWD/$OPENSSL/openssl"
+        ;;
+
+        esac
+
         cat << END                                            >> $NGX_MAKEFILE
 
-$OPENSSL/libssl.a:	$NGX_MAKEFILE
+$OPENSSL/openssl/include/openssl/ssl.h:	$NGX_MAKEFILE
 	cd $OPENSSL \\
 	&& \$(MAKE) clean \\
-	&& $NGX_OPENSSL_CONFIG no-shared \\
-	&& \$(MAKE)
+	&& ./config --prefix=$ngx_prefix no-shared $OPENSSL_OPT \\
+	&& \$(MAKE) \\
+	&& \$(MAKE) install
 
 END
 
--- a/auto/options
+++ b/auto/options
@@ -135,7 +135,7 @@ opt=
 
 for option
 do
-     opt="$opt `echo $option | sed -e \"s/\(--[^=]*=\)\(.* .*\)/\1'\2'/\"`"
+    opt="$opt `echo $option | sed -e \"s/\(--[^=]*=\)\(.* .*\)/\1'\2'/\"`"
 
     case "$option" in
         -*=*) value=`echo "$option" | sed -e 's/[-_a-zA-Z0-9]*=//'` ;;
--- a/auto/os/features
+++ b/auto/os/features
@@ -230,3 +230,25 @@ ngx_feature_libs=
 ngx_feature_test="struct statvfs  fs;
                   statvfs(NULL, &fs);"
 . auto/feature
+
+
+ngx_feature="dlopen()"
+ngx_feature_name=
+ngx_feature_run=no
+ngx_feature_incs="#include <dlfcn.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="dlopen(NULL, 0)"
+. auto/feature
+
+
+if [ $ngx_found != yes ]; then
+
+    ngx_feature="dlopen() in libdl"
+    ngx_feature_libs="-ldl"
+    . auto/feature
+
+    if [ $ngx_found = yes ]; then
+        NGX_LIBDL="-ldl"
+    fi
+fi
--- a/auto/unix
+++ b/auto/unix
@@ -185,28 +185,6 @@ if [ $ngx_found != yes ]; then
 fi
 
 
-ngx_feature="dlopen()"
-ngx_feature_name=
-ngx_feature_run=no
-ngx_feature_incs="#include <dlfcn.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="dlopen(NULL, 0)"
-. auto/feature
-
-
-if [ $ngx_found != yes ]; then
-
-    ngx_feature="dlopen() in libdl"
-    ngx_feature_libs="-ldl"
-    . auto/feature
-
-    if [ $ngx_found = yes ]; then
-        NGX_LIBDL="-ldl"
-    fi
-fi
-
-
 ngx_feature="mmap(MAP_ANON|MAP_SHARED)"
 ngx_feature_name="NGX_HAVE_MAP_ANON"
 ngx_feature_run=yes
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,8 +8,8 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define nginx_version         7058
-#define NGINX_VERSION      "0.7.58"
+#define nginx_version         7059
+#define NGINX_VERSION      "0.7.59"
 #define NGINX_VER          "nginx/" NGINX_VERSION
 
 #define NGINX_VAR          "NGINX"
--- a/src/http/modules/ngx_http_charset_filter_module.c
+++ b/src/http/modules/ngx_http_charset_filter_module.c
@@ -224,7 +224,8 @@ ngx_http_charset_header_filter(ngx_http_
 
     if (r == r->main) {
 
-        if (r->headers_out.content_encoding
+        if (!r->ignore_content_encoding
+            && r->headers_out.content_encoding
             && r->headers_out.content_encoding->value.len)
         {
             return ngx_http_next_header_filter(r);
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -353,6 +353,13 @@ static ngx_command_t  ngx_http_fastcgi_c
       offsetof(ngx_http_fastcgi_loc_conf_t, upstream.cache_use_stale),
       &ngx_http_fastcgi_next_upstream_masks },
 
+    { ngx_string("fastcgi_cache_methods"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
+      ngx_conf_set_bitmask_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_fastcgi_loc_conf_t, upstream.cache_methods),
+      &ngx_http_upstream_cache_method_mask },
+
 #endif
 
     { ngx_string("fastcgi_temp_path"),
@@ -1835,7 +1842,8 @@ ngx_http_fastcgi_create_loc_conf(ngx_con
      *     conf->upstream.bufs.num = 0;
      *     conf->upstream.ignore_headers = 0;
      *     conf->upstream.next_upstream = 0;
-     *     conf->upstream.use_stale_cache = 0;
+     *     conf->upstream.cache_use_stale = 0;
+     *     conf->upstream.cache_methods = 0;
      *     conf->upstream.temp_path = NULL;
      *     conf->upstream.hide_headers_hash = { NULL, 0 };
      *     conf->upstream.uri = { 0, NULL };
@@ -2083,6 +2091,12 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf
                                          |NGX_HTTP_UPSTREAM_FT_OFF;
     }
 
+    if (conf->upstream.cache_methods == 0) {
+        conf->upstream.cache_methods = prev->upstream.cache_methods;
+    }
+
+    conf->upstream.cache_methods |= NGX_HTTP_GET|NGX_HTTP_HEAD;
+
     ngx_conf_merge_ptr_value(conf->upstream.cache_valid,
                              prev->upstream.cache_valid, NULL);
 
--- a/src/http/modules/ngx_http_gzip_static_module.c
+++ b/src/http/modules/ngx_http_gzip_static_module.c
@@ -205,6 +205,7 @@ ngx_http_gzip_static_handler(ngx_http_re
     h->value.data = (u_char *) "gzip";
 
     r->headers_out.content_encoding = h;
+    r->ignore_content_encoding = 1;
 
     /* we need to allocate all before the header would be sent */
 
--- a/src/http/modules/ngx_http_image_filter_module.c
+++ b/src/http/modules/ngx_http_image_filter_module.c
@@ -282,6 +282,7 @@ ngx_http_image_body_filter(ngx_http_requ
         ct = &ngx_http_image_types[ctx->type - 1];
         r->headers_out.content_type_len = ct->len;
         r->headers_out.content_type = *ct;
+        r->headers_out.content_type_lowcase = NULL;
 
         if (conf->filter == NGX_HTTP_IMAGE_TEST) {
             ctx->phase = NGX_HTTP_IMAGE_PASS;
@@ -502,6 +503,7 @@ ngx_http_image_json(ngx_http_request_t *
     r->headers_out.status = NGX_HTTP_OK;
     r->headers_out.content_type.len = sizeof("text/plain") - 1;
     r->headers_out.content_type.data = (u_char *) "text/plain";
+    r->headers_out.content_type_lowcase = NULL;
 
     if (ctx == NULL) {
         b->pos = (u_char *) "{}" CRLF;
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -377,6 +377,13 @@ static ngx_command_t  ngx_http_proxy_com
       offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_use_stale),
       &ngx_http_proxy_next_upstream_masks },
 
+    { ngx_string("proxy_cache_methods"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
+      ngx_conf_set_bitmask_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_proxy_loc_conf_t, upstream.cache_methods),
+      &ngx_http_upstream_cache_method_mask },
+
 #endif
 
     { ngx_string("proxy_temp_path"),
@@ -1885,7 +1892,8 @@ ngx_http_proxy_create_loc_conf(ngx_conf_
      *     conf->upstream.bufs.num = 0;
      *     conf->upstream.ignore_headers = 0;
      *     conf->upstream.next_upstream = 0;
-     *     conf->upstream.use_stale_cache = 0;
+     *     conf->upstream.cache_use_stale = 0;
+     *     conf->upstream.cache_methods = 0;
      *     conf->upstream.temp_path = NULL;
      *     conf->upstream.hide_headers_hash = { NULL, 0 };
      *     conf->upstream.uri = { 0, NULL };
@@ -2139,6 +2147,12 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t
                               (NGX_CONF_BITMASK_SET
                                |NGX_HTTP_UPSTREAM_FT_OFF));
 
+    if (conf->upstream.cache_methods == 0) {
+        conf->upstream.cache_methods = prev->upstream.cache_methods;
+    }
+
+    conf->upstream.cache_methods |= NGX_HTTP_GET|NGX_HTTP_HEAD;
+
     if (conf->upstream.cache_use_stale & NGX_HTTP_UPSTREAM_FT_OFF) {
         conf->upstream.cache_use_stale = NGX_CONF_BITMASK_SET
                                          |NGX_HTTP_UPSTREAM_FT_OFF;
--- a/src/http/modules/ngx_http_range_filter_module.c
+++ b/src/http/modules/ngx_http_range_filter_module.c
@@ -456,6 +456,8 @@ ngx_http_range_multipart_header(ngx_http
         return NGX_ERROR;
     }
 
+    r->headers_out.content_type_lowcase = NULL;
+
     /* "Content-Type: multipart/byteranges; boundary=0123456789" */
 
     r->headers_out.content_type.len =
@@ -464,6 +466,7 @@ ngx_http_range_multipart_header(ngx_http
                                        boundary)
                            - r->headers_out.content_type.data;
 
+    r->headers_out.content_type_len = r->headers_out.content_type.len;
 
     /* the size of the last boundary CRLF "--0123456789--" CRLF */
 
--- a/src/http/modules/ngx_http_xslt_filter_module.c
+++ b/src/http/modules/ngx_http_xslt_filter_module.c
@@ -837,6 +837,8 @@ ngx_http_xslt_apply_stylesheet(ngx_http_
         r->headers_out.content_type.data = (u_char *) "text/html";
     }
 
+    r->headers_out.content_type_lowcase = NULL;
+
     return b;
 }
 
--- 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.7.58';
+our $VERSION = '0.7.59';
 
 require XSLoader;
 XSLoader::load('nginx', $VERSION);
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -1530,38 +1530,38 @@ ngx_http_core_find_static_location(ngx_h
 void *
 ngx_http_test_content_type(ngx_http_request_t *r, ngx_hash_t *types_hash)
 {
-    u_char       c, *p;
-    ngx_uint_t   i, hash;
+    u_char      c, *lowcase;
+    size_t      len;
+    ngx_uint_t  i, hash;
 
     if (r->headers_out.content_type.len == 0) {
         return NULL;
     }
 
+    len = r->headers_out.content_type_len;
+
     if (r->headers_out.content_type_lowcase == NULL) {
 
-        p = ngx_pnalloc(r->pool, r->headers_out.content_type_len);
-
-        if (p == NULL) {
+        lowcase = ngx_pnalloc(r->pool, len);
+        if (lowcase == NULL) {
             return NULL;
         }
 
-        r->headers_out.content_type_lowcase = p;
+        r->headers_out.content_type_lowcase = lowcase;
 
         hash = 0;
 
-        for (i = 0; i < r->headers_out.content_type_len; i++) {
+        for (i = 0; i < len; i++) {
             c = ngx_tolower(r->headers_out.content_type.data[i]);
             hash = ngx_hash(hash, c);
-            *p++ = c;
+            lowcase[i] = c;
         }
 
         r->headers_out.content_type_hash = hash;
     }
 
-    return ngx_hash_find(types_hash,
-                         r->headers_out.content_type_hash,
-                         r->headers_out.content_type_lowcase,
-                         r->headers_out.content_type_len);
+    return ngx_hash_find(types_hash, r->headers_out.content_type_hash,
+                         r->headers_out.content_type_lowcase, len);
 }
 
 
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -2098,6 +2098,11 @@ ngx_http_writer(ngx_http_request_t *r)
                    "http writer output filter: %d, \"%V?%V\"",
                    rc, &r->uri, &r->args);
 
+    if (rc == NGX_ERROR) {
+        ngx_http_finalize_request(r, rc);
+        return;
+    }
+
     if (r->buffered || r->postponed || (r == r->main && c->buffered)) {
 
         if (!wev->ready && !wev->delayed) {
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -478,6 +478,7 @@ struct ngx_http_request_s {
     unsigned                          discard_body:1;
     unsigned                          internal:1;
     unsigned                          error_page:1;
+    unsigned                          ignore_content_encoding:1;
     unsigned                          filter_finalize:1;
     unsigned                          post_action:1;
     unsigned                          request_complete:1;
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -610,6 +610,7 @@ ngx_http_send_special_response(ngx_http_
             r->headers_out.content_type_len = sizeof("text/html") - 1;
             r->headers_out.content_type.len = sizeof("text/html") - 1;
             r->headers_out.content_type.data = (u_char *) "text/html";
+            r->headers_out.content_type_lowcase = NULL;
 
         } else {
             r->headers_out.content_length_n = -1;
@@ -712,6 +713,7 @@ ngx_http_send_refresh(ngx_http_request_t
     r->headers_out.content_type_len = sizeof("text/html") - 1;
     r->headers_out.content_type.len = sizeof("text/html") - 1;
     r->headers_out.content_type.data = (u_char *) "text/html";
+    r->headers_out.content_type_lowcase = NULL;
 
     r->headers_out.location->hash = 0;
     r->headers_out.location = NULL;
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -329,6 +329,15 @@ static ngx_http_upstream_next_t  ngx_htt
     { 0, 0 }
 };
 
+
+ngx_conf_bitmask_t  ngx_http_upstream_cache_method_mask[] = {
+   { ngx_string("GET"),  NGX_HTTP_GET},
+   { ngx_string("HEAD"), NGX_HTTP_HEAD },
+   { ngx_string("POST"), NGX_HTTP_POST },
+   { ngx_null_string, 0 }
+};
+
+
 void
 ngx_http_upstream_init(ngx_http_request_t *r)
 {
@@ -532,7 +541,7 @@ ngx_http_upstream_cache(ngx_http_request
     ngx_int_t          rc;
     ngx_http_cache_t  *c;
 
-    if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
+    if (!(r->method & u->conf->cache_methods)) {
         return NGX_DECLINED;
     }
 
@@ -562,8 +571,8 @@ ngx_http_upstream_cache(ngx_http_request
 
     u->cacheable = 1;
 
-    c->min_uses = r->upstream->conf->cache_min_uses;
-    c->body_start = r->upstream->conf->buffer_size;
+    c->min_uses = u->conf->cache_min_uses;
+    c->body_start = u->conf->buffer_size;
     c->file_cache = u->conf->cache->data;
 
     rc = ngx_http_file_cache_open(r);
@@ -3165,6 +3174,7 @@ ngx_http_upstream_copy_content_type(ngx_
 
     r->headers_out.content_type_len = h->value.len;
     r->headers_out.content_type = h->value;
+    r->headers_out.content_type_lowcase = NULL;
 
     for (p = h->value.data; *p; p++) {
 
--- a/src/http/ngx_http_upstream.h
+++ b/src/http/ngx_http_upstream.h
@@ -156,6 +156,7 @@ typedef struct {
 
     ngx_uint_t                       cache_min_uses;
     ngx_uint_t                       cache_use_stale;
+    ngx_uint_t                       cache_methods;
 
     ngx_array_t                     *cache_valid;
 #endif
@@ -327,7 +328,9 @@ ngx_int_t ngx_http_upstream_hide_headers
     uscf->srv_conf[module.ctx_index]
 
 
-extern ngx_module_t  ngx_http_upstream_module;
+extern ngx_module_t        ngx_http_upstream_module;
+extern ngx_conf_bitmask_t  ngx_http_upstream_cache_method_mask[];
+
 
 
 #endif /* _NGX_HTTP_UPSTREAM_H_INCLUDED_ */
--- a/src/http/ngx_http_variables.c
+++ b/src/http/ngx_http_variables.c
@@ -1492,7 +1492,10 @@ ngx_http_variable_request_body(ngx_http_
     ngx_buf_t    *buf, *next;
     ngx_chain_t  *cl;
 
-    if (r->request_body == NULL || r->request_body->temp_file) {
+    if (r->request_body == NULL
+        || r->request_body->bufs == NULL
+        || r->request_body->temp_file)
+    {
         v->not_found = 1;
 
         return NGX_OK;