changeset 400:349057ecf4d5 NGINX_0_7_10

nginx 0.7.10 *) Bugfix: in the "addition_types", "charset_types", "gzip_types", "ssi_types", "sub_filter_types", and "xslt_types" directives; the bugs had appeared in 0.7.9. *) Bugfix: of recursive error_page for 500 status code. *) Bugfix: now the ngx_http_realip_module set address not for whole keepalive connection, but for each request passed via the connection.
author Igor Sysoev <http://sysoev.ru>
date Wed, 13 Aug 2008 00:00:00 +0400
parents ebf3256f0c2b
children 47d42325b5fd
files CHANGES CHANGES.ru auto/lib/libxslt/conf auto/modules auto/options src/core/nginx.h src/http/modules/ngx_http_charset_filter_module.c src/http/modules/ngx_http_realip_module.c src/http/modules/perl/nginx.pm src/http/ngx_http.c src/http/ngx_http.h src/http/ngx_http_request.h src/http/ngx_http_special_response.c
diffstat 13 files changed, 148 insertions(+), 61 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,16 @@
 
+Changes with nginx 0.7.10                                        13 Aug 2008
+
+    *) Bugfix: in the "addition_types", "charset_types", "gzip_types", 
+       "ssi_types", "sub_filter_types", and "xslt_types" directives; the 
+       bugs had appeared in 0.7.9.
+
+    *) Bugfix: of recursive error_page for 500 status code.
+
+    *) Bugfix: now the ngx_http_realip_module set address not for whole 
+       keepalive connection, but for each request passed via the connection.
+
+
 Changes with nginx 0.7.9                                         12 Aug 2008
 
     *) Change: now ngx_http_charset_module works by default with following 
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,17 @@
 
+Изменения в nginx 0.7.10                                          13.08.2008
+
+    *) Исправление: ошибок в директивах addition_types, charset_types, 
+       gzip_types, ssi_types, sub_filter_types и xslt_types; ошибки 
+       появились в 0.7.9.
+
+    *) Исправление: рекурсивной error_page для 500 ошибки.
+
+    *) Исправление: теперь модуль ngx_http_realip_module устанавливает 
+       адрес не для всего keepalive соединения, а для каждого запроса по 
+       этому соединению.
+
+
 Изменения в nginx 0.7.9                                           12.08.2008
 
     *) Изменение: теперь ngx_http_charset_module по умолчанию работает со 
--- a/auto/lib/libxslt/conf
+++ b/auto/lib/libxslt/conf
@@ -73,6 +73,18 @@ fi
 
 
 if [ $ngx_found = yes ]; then
+
     CORE_INCS="$CORE_INCS $ngx_feature_path"
     CORE_LIBS="$CORE_LIBS $ngx_feature_libs"
+
+else
+
+cat << END
+
+$0: error: the HTTP XSLT module requires the libxml2/libxslt
+libraries. You can either do not enable the module or install the libraries.
+
+END
+
+    exit 1
 fi
--- a/auto/modules
+++ b/auto/modules
@@ -392,7 +392,7 @@ if [ $NGX_GOOGLE_PERFTOOLS = YES ]; then
 fi
 
 
-if [ $NGX_CPP_TEST_MODULE = YES ]; then
+if [ $NGX_CPP_TEST = YES ]; then
     NGX_MISC_SRCS="$NGX_MISC_SRCS $NGX_CPP_TEST_SRCS"
 fi
 
--- a/auto/options
+++ b/auto/options
@@ -209,7 +209,7 @@ do
         --without-mail_smtp_module)      MAIL_SMTP=NO               ;;
 
         --with-google_perftools_module)  NGX_GOOGLE_PERFTOOLS=YES   ;;
-        --with-cpp_test_module)          NGX_CPP_TEST_MODULE=YES    ;;
+        --with-cpp_test_module)          NGX_CPP_TEST=YES           ;;
 
         --add-module=*)                  NGX_ADDONS="$NGX_ADDONS $value" ;;
 
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define NGINX_VERSION      "0.7.9"
+#define NGINX_VERSION      "0.7.10"
 #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
@@ -1484,6 +1484,14 @@ ngx_http_charset_merge_loc_conf(ngx_conf
     ngx_http_charset_recode_t     *recode;
     ngx_http_charset_main_conf_t  *mcf;
 
+    if (ngx_http_merge_types(cf, conf->types_keys, &conf->types,
+                             prev->types_keys, &prev->types,
+                             ngx_http_charset_default_types)
+        != NGX_OK)
+    {
+        return NGX_CONF_ERROR;
+    }
+
     ngx_conf_merge_value(conf->override_charset, prev->override_charset, 0);
     ngx_conf_merge_value(conf->charset, prev->charset, NGX_HTTP_NO_CHARSET);
 
@@ -1523,14 +1531,6 @@ ngx_http_charset_merge_loc_conf(ngx_conf
     recode->src = conf->source_charset;
     recode->dst = conf->charset;
 
-    if (ngx_http_merge_types(cf, conf->types_keys, &conf->types,
-                             prev->types_keys, &prev->types,
-                             ngx_http_charset_default_types)
-        != NGX_OK)
-    {
-        return NGX_CONF_ERROR;
-    }
-
     return NGX_CONF_OK;
 }
 
--- a/src/http/modules/ngx_http_realip_module.c
+++ b/src/http/modules/ngx_http_realip_module.c
@@ -12,19 +12,26 @@
 /* AF_INET only */
 
 typedef struct {
-    in_addr_t     mask;
-    in_addr_t     addr;
+    in_addr_t          mask;
+    in_addr_t          addr;
 } ngx_http_realip_from_t;
 
 
 typedef struct {
-    ngx_array_t  *from;     /* array of ngx_http_realip_from_t */
-
-    ngx_uint_t    xfwd;
+    ngx_array_t       *from;     /* array of ngx_http_realip_from_t */
+    ngx_uint_t         xfwd;
 } ngx_http_realip_loc_conf_t;
 
 
+typedef struct {
+    ngx_connection_t  *connection;
+    in_addr_t          addr;
+    ngx_str_t          addr_text;
+} ngx_http_realip_ctx_t;
+
+
 static ngx_int_t ngx_http_realip_handler(ngx_http_request_t *r);
+static void ngx_http_realip_cleanup(void *data);
 static char *ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd,
     void *conf);
 static void *ngx_http_realip_create_loc_conf(ngx_conf_t *cf);
@@ -100,13 +107,23 @@ ngx_http_realip_handler(ngx_http_request
     in_addr_t                    addr;
     ngx_uint_t                   i;
     struct sockaddr_in          *sin;
+    ngx_connection_t            *c;
+    ngx_pool_cleanup_t          *cln;
+    ngx_http_realip_ctx_t       *ctx;
     ngx_http_realip_from_t      *from;
     ngx_http_realip_loc_conf_t  *rlcf;
 
-    if (r->realip_set) {
+    ctx = ngx_http_get_module_ctx(r, ngx_http_realip_module);
+
+    if (ctx) {
         return NGX_DECLINED;
     }
 
+    cln = ngx_pool_cleanup_add(r->pool, sizeof(ngx_http_realip_ctx_t));
+    if (cln == NULL) {
+        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+    }
+
     rlcf = ngx_http_get_module_loc_conf(r, ngx_http_realip_module);
 
     if (rlcf->from == NULL) {
@@ -139,23 +156,26 @@ ngx_http_realip_handler(ngx_http_request
         }
     }
 
-    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                   "realip: \"%s\"", ip);
+    c = r->connection;
+
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "realip: \"%s\"", ip);
 
     /* AF_INET only */
 
-    sin = (struct sockaddr_in *) r->connection->sockaddr;
+    sin = (struct sockaddr_in *) c->sockaddr;
 
     from = rlcf->from->elts;
     for (i = 0; i < rlcf->from->nelts; i++) {
 
-        ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+        ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
                        "realip: %08XD %08XD %08XD",
                        sin->sin_addr.s_addr, from[i].mask, from[i].addr);
 
         if ((sin->sin_addr.s_addr & from[i].mask) == from[i].addr) {
 
-            r->realip_set = 1;
+            ctx = cln->data;
+
+            ngx_http_set_ctx(r, ctx, ngx_http_realip_module);
 
             addr = inet_addr((char *) ip);
 
@@ -163,17 +183,23 @@ ngx_http_realip_handler(ngx_http_request
                 return NGX_DECLINED;
             }
 
-            p = ngx_pnalloc(r->connection->pool, len);
+            p = ngx_pnalloc(c->pool, len);
             if (p == NULL) {
                 return NGX_HTTP_INTERNAL_SERVER_ERROR;
             }
 
             ngx_memcpy(p, ip, len);
 
+            cln->handler = ngx_http_realip_cleanup;
+
+            ctx->connection = c;
+            ctx->addr = sin->sin_addr.s_addr;
+            ctx->addr_text = c->addr_text;
+
             sin->sin_addr.s_addr = addr;
 
-            r->connection->addr_text.len = len;
-            r->connection->addr_text.data = p;
+            c->addr_text.len = len;
+            c->addr_text.data = p;
 
             return NGX_DECLINED;
         }
@@ -183,6 +209,23 @@ ngx_http_realip_handler(ngx_http_request
 }
 
 
+static void
+ngx_http_realip_cleanup(void *data)
+{
+    ngx_http_realip_ctx_t *ctx = data;
+
+    ngx_connection_t    *c;
+    struct sockaddr_in  *sin;
+
+    c = ctx->connection;
+
+    sin = (struct sockaddr_in *) c->sockaddr;
+    sin->sin_addr.s_addr = ctx->addr;
+
+    c->addr_text = ctx->addr_text;
+}
+
+
 static char *
 ngx_http_realip_from(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
 {
--- 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.9';
+our $VERSION = '0.7.10';
 
 require XSLoader;
 XSLoader::load('nginx', $VERSION);
--- a/src/http/ngx_http.c
+++ b/src/http/ngx_http.c
@@ -1761,43 +1761,60 @@ ngx_http_types_slot(ngx_conf_t *cf, ngx_
 
 char *
 ngx_http_merge_types(ngx_conf_t *cf, ngx_array_t *keys, ngx_hash_t *types_hash,
-    ngx_array_t *prev_keys, ngx_hash_t *prev_types_hash, 
+    ngx_array_t *prev_keys, ngx_hash_t *prev_types_hash,
     ngx_str_t *default_types)
 {
     ngx_hash_init_t  hash;
 
-    if (keys == NULL) {
+    if (keys) {
 
-        if (prev_keys) {
-            *types_hash = *prev_types_hash;
-            return NGX_CONF_OK;
+        hash.hash = types_hash;
+        hash.key = NULL;
+        hash.max_size = 2048;
+        hash.bucket_size = 64;
+        hash.name = "test_types_hash";
+        hash.pool = cf->pool;
+        hash.temp_pool = NULL;
+
+        if (ngx_hash_init(&hash, keys->elts, keys->nelts) != NGX_OK) {
+            return NGX_CONF_ERROR;
         }
 
-        if (ngx_http_set_default_types(cf, &keys, default_types)
-            != NGX_CONF_OK)
-        {
+        return NGX_CONF_OK;
+    }
+
+    if (prev_types_hash->buckets == NULL) {
+
+        if (prev_keys == NULL) {
+
+	    if (ngx_http_set_default_types(cf, &prev_keys, default_types)
+                != NGX_OK)
+            {
+		return NGX_CONF_ERROR;
+	    }
+        }
+
+        hash.hash = prev_types_hash;
+        hash.key = NULL;
+        hash.max_size = 2048;
+        hash.bucket_size = 64;
+        hash.name = "test_types_hash";
+        hash.pool = cf->pool;
+        hash.temp_pool = NULL;
+
+        if (ngx_hash_init(&hash, prev_keys->elts, prev_keys->nelts) != NGX_OK) {
             return NGX_CONF_ERROR;
         }
     }
 
-    hash.hash = types_hash;
-    hash.key = NULL;
-    hash.max_size = 2048;
-    hash.bucket_size = 64;
-    hash.name = "test_types_hash";
-    hash.pool = cf->pool;
-    hash.temp_pool = NULL;
-
-    if (ngx_hash_init(&hash, keys->elts, keys->nelts) != NGX_OK) {
-        return NGX_CONF_ERROR;
-    }
+    *types_hash = *prev_types_hash;
 
     return NGX_CONF_OK;
 
 }
 
 
-char *
+ngx_int_t
 ngx_http_set_default_types(ngx_conf_t *cf, ngx_array_t **types,
     ngx_str_t *default_type)
 {
@@ -1805,14 +1822,14 @@ ngx_http_set_default_types(ngx_conf_t *c
 
     *types = ngx_array_create(cf->temp_pool, 1, sizeof(ngx_hash_key_t));
     if (*types == NULL) {
-        return NGX_CONF_ERROR;
+        return NGX_ERROR;
     }
 
     while (default_type->len) {
 
         type = ngx_array_push(*types);
         if (type == NULL) {
-            return NGX_CONF_ERROR;
+            return NGX_ERROR;
         }
 
         type->key = *default_type;
@@ -1823,5 +1840,5 @@ ngx_http_set_default_types(ngx_conf_t *c
         default_type++;
     }
 
-    return NGX_CONF_OK;
+    return NGX_OK;
 }
--- a/src/http/ngx_http.h
+++ b/src/http/ngx_http.h
@@ -111,7 +111,7 @@ char *ngx_http_types_slot(ngx_conf_t *cf
 char *ngx_http_merge_types(ngx_conf_t *cf, ngx_array_t *keys,
     ngx_hash_t *types_hash, ngx_array_t *prev_keys, ngx_hash_t *prev_types_hash,
     ngx_str_t *default_types);
-char *ngx_http_set_default_types(ngx_conf_t *cf, ngx_array_t **types,
+ngx_int_t ngx_http_set_default_types(ngx_conf_t *cf, ngx_array_t **types,
     ngx_str_t *default_type);
 
 
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -436,16 +436,6 @@ struct ngx_http_request_s {
     unsigned                          bypass_cache:1;
     unsigned                          no_cache:1;
 
-#if (NGX_HTTP_REALIP)
-
-    /*
-     * instead of using the request context data in ngx_http_realip_module
-     * we use the single bit in the request structure
-     */
-    unsigned                          realip_set:1;
-
-#endif
-
     /*
      * instead of using the request context data in ngx_http_limit_zone_module
      * we use the single bit in the request structure
--- a/src/http/ngx_http_special_response.c
+++ b/src/http/ngx_http_special_response.c
@@ -371,7 +371,7 @@ ngx_http_special_response_handler(ngx_ht
 
     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
 
-    if (!r->error_page && clcf->error_pages) {
+    if (!r->error_page && clcf->error_pages && r->uri_changes != 0) {
 
         if (clcf->recursive_error_pages == 0) {
             r->error_page = 1;