changeset 630:ad6fee8052d7 NGINX_1_0_5

nginx 1.0.5 *) Change: now default SSL ciphers are "HIGH:!aNULL:!MD5". Thanks to Rob Stradling. *) Feature: the "referer_hash_max_size" and "referer_hash_bucket_size" directives. Thanks to Witold Filipczyk. *) Feature: $uid_reset variable. *) Bugfix: a segmentation fault might occur in a worker process, if a caching was used. Thanks to Lanshun Zhou. *) Bugfix: worker processes may got caught in an endless loop during reconfiguration, if a caching was used; the bug had appeared in 0.8.48. Thanks to Maxim Dounin. *) Bugfix: "stalled cache updating" alert. Thanks to Maxim Dounin.
author Igor Sysoev <http://sysoev.ru>
date Tue, 19 Jul 2011 00:00:00 +0400
parents 1c167244d2fd
children 9b978fa3cd33
files CHANGES CHANGES.ru conf/nginx.conf src/core/nginx.h src/core/ngx_md5.c src/http/modules/ngx_http_referer_module.c src/http/modules/ngx_http_ssl_module.c src/http/modules/ngx_http_userid_filter_module.c src/http/modules/perl/nginx.pm src/http/ngx_http_file_cache.c src/http/ngx_http_upstream.c src/mail/ngx_mail_ssl_module.c
diffstat 12 files changed, 201 insertions(+), 74 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,28 @@
 
+Changes with nginx 1.0.5                                         19 Jul 2011
+
+    *) Change: now default SSL ciphers are "HIGH:!aNULL:!MD5".
+       Thanks to Rob Stradling.
+
+    *) Feature: the "referer_hash_max_size" and "referer_hash_bucket_size" 
+       directives.
+       Thanks to Witold Filipczyk.
+
+    *) Feature: $uid_reset variable.
+
+    *) Bugfix: a segmentation fault might occur in a worker process, if a 
+       caching was used.
+       Thanks to Lanshun Zhou.
+
+    *) Bugfix: worker processes may got caught in an endless loop during 
+       reconfiguration, if a caching was used; the bug had appeared in 
+       0.8.48.
+       Thanks to Maxim Dounin.
+
+    *) Bugfix: "stalled cache updating" alert.
+       Thanks to Maxim Dounin.
+
+
 Changes with nginx 1.0.4                                         01 Jun 2011
 
     *) Change: now regular expressions case sensitivity in the "map" 
@@ -7,7 +31,7 @@ Changes with nginx 1.0.4                
     *) Feature: now shared zones and caches use POSIX semaphores on Linux. 
        Thanks to Denis F. Latypoff.
 
-    *) Bugfix: "stalled" cache updating" alert.
+    *) Bugfix: "stalled cache updating" alert.
 
     *) Bugfix: nginx could not be built --without-http_auth_basic_module; 
        the bug had appeared in 1.0.3.
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,28 @@
 
+Изменения в nginx 1.0.5                                           19.07.2011
+
+    *) Изменение: теперь по умолчанию используются следующие шифры SSL: 
+       "HIGH:!aNULL:!MD5".
+       Спасибо Rob Stradling.
+
+    *) Добавление: директивы referer_hash_max_size и 
+       referer_hash_bucket_size.
+       Спасибо Witold Filipczyk.
+
+    *) Добавление: переменная $uid_reset.
+
+    *) Исправление: при использовании кэширования в рабочем процессе мог 
+       произойти segmentation fault.
+       Спасибо Lanshun Zhou.
+
+    *) Исправление: при использовании кэширования рабочие процессы могли 
+       зациклиться во время переконфигурации; ошибка появилась в 0.8.48.
+       Спасибо Максиму Дунину.
+
+    *) Исправление: сообщения "stalled cache updating".
+       Спасибо Максиму Дунину.
+
+
 Изменения в nginx 1.0.4                                           01.06.2011
 
     *) Изменение: теперь в регулярных выражениях в директиве map можно 
--- a/conf/nginx.conf
+++ b/conf/nginx.conf
@@ -106,7 +106,7 @@ http {
     #    ssl_session_timeout  5m;
 
     #    ssl_protocols  SSLv2 SSLv3 TLSv1;
-    #    ssl_ciphers  ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
+    #    ssl_ciphers  HIGH:!aNULL:!MD5;
     #    ssl_prefer_server_ciphers   on;
 
     #    location / {
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,8 +8,8 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define nginx_version      1000004
-#define NGINX_VERSION      "1.0.4"
+#define nginx_version      1000005
+#define NGINX_VERSION      "1.0.5"
 #define NGINX_VER          "nginx/" NGINX_VERSION
 
 #define NGINX_VAR          "NGINX"
--- a/src/core/ngx_md5.c
+++ b/src/core/ngx_md5.c
@@ -36,7 +36,7 @@ ngx_md5_update(ngx_md5_t *ctx, const voi
 {
     size_t  used, free;
 
-    used = ctx->bytes & 0x3f;
+    used = (size_t) (ctx->bytes & 0x3f);
     ctx->bytes += size;
 
     if (used) {
@@ -66,7 +66,7 @@ ngx_md5_final(u_char result[16], ngx_md5
 {
     size_t  used, free;
 
-    used = ctx->bytes & 0x3f;
+    used = (size_t) (ctx->bytes & 0x3f);
 
     ctx->buffer[used++] = 0x80;
 
@@ -82,33 +82,33 @@ ngx_md5_final(u_char result[16], ngx_md5
     ngx_memzero(&ctx->buffer[used], free - 8);
 
     ctx->bytes <<= 3;
-    ctx->buffer[56] = ctx->bytes;
-    ctx->buffer[57] = ctx->bytes >> 8;
-    ctx->buffer[58] = ctx->bytes >> 16;
-    ctx->buffer[59] = ctx->bytes >> 24;
-    ctx->buffer[60] = ctx->bytes >> 32;
-    ctx->buffer[61] = ctx->bytes >> 40;
-    ctx->buffer[62] = ctx->bytes >> 48;
-    ctx->buffer[63] = ctx->bytes >> 56;
+    ctx->buffer[56] = (u_char) ctx->bytes;
+    ctx->buffer[57] = (u_char) (ctx->bytes >> 8);
+    ctx->buffer[58] = (u_char) (ctx->bytes >> 16);
+    ctx->buffer[59] = (u_char) (ctx->bytes >> 24);
+    ctx->buffer[60] = (u_char) (ctx->bytes >> 32);
+    ctx->buffer[61] = (u_char) (ctx->bytes >> 40);
+    ctx->buffer[62] = (u_char) (ctx->bytes >> 48);
+    ctx->buffer[63] = (u_char) (ctx->bytes >> 56);
 
     (void) ngx_md5_body(ctx, ctx->buffer, 64);
 
-    result[0] = ctx->a;
-    result[1] = ctx->a >> 8;
-    result[2] = ctx->a >> 16;
-    result[3] = ctx->a >> 24;
-    result[4] = ctx->b;
-    result[5] = ctx->b >> 8;
-    result[6] = ctx->b >> 16;
-    result[7] = ctx->b >> 24;
-    result[8] = ctx->c;
-    result[9] = ctx->c >> 8;
-    result[10] = ctx->c >> 16;
-    result[11] = ctx->c >> 24;
-    result[12] = ctx->d;
-    result[13] = ctx->d >> 8;
-    result[14] = ctx->d >> 16;
-    result[15] = ctx->d >> 24;
+    result[0] = (u_char) ctx->a;
+    result[1] = (u_char) (ctx->a >> 8);
+    result[2] = (u_char) (ctx->a >> 16);
+    result[3] = (u_char) (ctx->a >> 24);
+    result[4] = (u_char) ctx->b;
+    result[5] = (u_char) (ctx->b >> 8);
+    result[6] = (u_char) (ctx->b >> 16);
+    result[7] = (u_char) (ctx->b >> 24);
+    result[8] = (u_char) ctx->c;
+    result[9] = (u_char) (ctx->c >> 8);
+    result[10] = (u_char) (ctx->c >> 16);
+    result[11] = (u_char) (ctx->c >> 24);
+    result[12] = (u_char) ctx->d;
+    result[13] = (u_char) (ctx->d >> 8);
+    result[14] = (u_char) (ctx->d >> 16);
+    result[15] = (u_char) (ctx->d >> 24);
 
     ngx_memzero(ctx, sizeof(*ctx));
 }
--- a/src/http/modules/ngx_http_referer_module.c
+++ b/src/http/modules/ngx_http_referer_module.c
@@ -29,6 +29,9 @@ typedef struct {
     ngx_flag_t               blocked_referer;
 
     ngx_hash_keys_arrays_t  *keys;
+
+    ngx_uint_t               referer_hash_max_size;
+    ngx_uint_t               referer_hash_bucket_size;
 } ngx_http_referer_conf_t;
 
 
@@ -54,6 +57,20 @@ static ngx_command_t  ngx_http_referer_c
       0,
       NULL },
 
+    { ngx_string("referer_hash_max_size"),
+      NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_num_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_referer_conf_t, referer_hash_max_size),
+      NULL },
+
+    { ngx_string("referer_hash_bucket_size"),
+      NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_num_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_referer_conf_t, referer_hash_bucket_size),
+      NULL },
+
       ngx_null_command
 };
 
@@ -239,6 +256,8 @@ ngx_http_referer_create_conf(ngx_conf_t 
 
     conf->no_referer = NGX_CONF_UNSET;
     conf->blocked_referer = NGX_CONF_UNSET;
+    conf->referer_hash_max_size = NGX_CONF_UNSET_UINT;
+    conf->referer_hash_bucket_size = NGX_CONF_UNSET_UINT;
 
     return conf;
 }
@@ -260,6 +279,10 @@ ngx_http_referer_merge_conf(ngx_conf_t *
 #endif
         ngx_conf_merge_value(conf->no_referer, prev->no_referer, 0);
         ngx_conf_merge_value(conf->blocked_referer, prev->blocked_referer, 0);
+        ngx_conf_merge_uint_value(conf->referer_hash_max_size,
+                                  prev->referer_hash_max_size, 2048);
+        ngx_conf_merge_uint_value(conf->referer_hash_bucket_size,
+                                  prev->referer_hash_bucket_size, 64);
 
         return NGX_CONF_OK;
     }
@@ -276,9 +299,16 @@ ngx_http_referer_merge_conf(ngx_conf_t *
         return NGX_CONF_ERROR;
     }
 
+    ngx_conf_merge_uint_value(conf->referer_hash_max_size,
+                              prev->referer_hash_max_size, 2048);
+    ngx_conf_merge_uint_value(conf->referer_hash_bucket_size,
+                              prev->referer_hash_bucket_size, 64);
+    conf->referer_hash_bucket_size = ngx_align(conf->referer_hash_bucket_size,
+                                               ngx_cacheline_size);
+
     hash.key = ngx_hash_key_lc;
-    hash.max_size = 2048; /* TODO: referer_hash_max_size; */
-    hash.bucket_size = 64; /* TODO: referer_hash_bucket_size; */
+    hash.max_size = conf->referer_hash_max_size;
+    hash.bucket_size = conf->referer_hash_bucket_size;
     hash.name = "referers_hash";
     hash.pool = cf->pool;
 
--- a/src/http/modules/ngx_http_ssl_module.c
+++ b/src/http/modules/ngx_http_ssl_module.c
@@ -13,7 +13,7 @@ typedef ngx_int_t (*ngx_ssl_variable_han
     ngx_pool_t *pool, ngx_str_t *s);
 
 
-#define NGX_DEFAULT_CIPHERS  "HIGH:!ADH:!MD5"
+#define NGX_DEFAULT_CIPHERS  "HIGH:!aNULL:!MD5"
 
 
 static ngx_int_t ngx_http_ssl_static_variable(ngx_http_request_t *r,
--- a/src/http/modules/ngx_http_userid_filter_module.c
+++ b/src/http/modules/ngx_http_userid_filter_module.c
@@ -38,6 +38,7 @@ typedef struct {
     uint32_t    uid_got[4];
     uint32_t    uid_set[4];
     ngx_str_t   cookie;
+    ngx_uint_t  reset;
 } ngx_http_userid_ctx_t;
 
 
@@ -185,8 +186,10 @@ ngx_module_t  ngx_http_userid_filter_mod
 };
 
 
-static ngx_str_t  ngx_http_userid_got = ngx_string("uid_got");
-static ngx_str_t  ngx_http_userid_set = ngx_string("uid_set");
+static ngx_str_t   ngx_http_userid_got = ngx_string("uid_got");
+static ngx_str_t   ngx_http_userid_set = ngx_string("uid_set");
+static ngx_str_t   ngx_http_userid_reset = ngx_string("uid_reset");
+static ngx_uint_t  ngx_http_userid_reset_index;
 
 
 static ngx_int_t
@@ -387,7 +390,7 @@ ngx_http_userid_set_uid(ngx_http_request
     p = ngx_copy(cookie, conf->name.data, conf->name.len);
     *p++ = '=';
 
-    if (ctx->uid_got[3] == 0) {
+    if (ctx->uid_got[3] == 0 || ctx->reset) {
         src.len = 16;
         src.data = (u_char *) ctx->uid_set;
         dst.data = p;
@@ -452,11 +455,12 @@ static ngx_int_t
 ngx_http_userid_create_uid(ngx_http_request_t *r, ngx_http_userid_ctx_t *ctx,
     ngx_http_userid_conf_t *conf)
 {
-    ngx_connection_t     *c;
-    struct sockaddr_in   *sin;
+    ngx_connection_t           *c;
+    struct sockaddr_in         *sin;
+    ngx_http_variable_value_t  *vv;
 #if (NGX_HAVE_INET6)
-    u_char               *p;
-    struct sockaddr_in6  *sin6;
+    u_char                     *p;
+    struct sockaddr_in6        *sin6;
 #endif
 
     if (ctx->uid_set[3] != 0) {
@@ -465,20 +469,35 @@ ngx_http_userid_create_uid(ngx_http_requ
 
     if (ctx->uid_got[3] != 0) {
 
-        if (conf->mark == '\0'
-            || (ctx->cookie.len > 23
-                && ctx->cookie.data[22] == conf->mark
-                && ctx->cookie.data[23] == '='))
-        {
+        vv = ngx_http_get_indexed_variable(r, ngx_http_userid_reset_index);
+
+        if (vv->len == 0 || (vv->len == 1 && vv->data[0] == '0')) {
+
+            if (conf->mark == '\0'
+                || (ctx->cookie.len > 23
+                    && ctx->cookie.data[22] == conf->mark
+                    && ctx->cookie.data[23] == '='))
+            {
+                return NGX_OK;
+            }
+
+            ctx->uid_set[0] = ctx->uid_got[0];
+            ctx->uid_set[1] = ctx->uid_got[1];
+            ctx->uid_set[2] = ctx->uid_got[2];
+            ctx->uid_set[3] = ctx->uid_got[3];
+
             return NGX_OK;
+
+        } else {
+            ctx->reset = 1;
+
+            if (vv->len == 3 && ngx_strncmp(vv->data, "log", 3) == 0) {
+                ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0,
+                        "userid cookie \"%V=%08XD%08XD%08XD%08XD\" was reset",
+                        &conf->name, ctx->uid_got[0], ctx->uid_got[1],
+                        ctx->uid_got[2], ctx->uid_got[3]);
+            }
         }
-
-        ctx->uid_set[0] = ctx->uid_got[0];
-        ctx->uid_set[1] = ctx->uid_got[1];
-        ctx->uid_set[2] = ctx->uid_got[2];
-        ctx->uid_set[3] = ctx->uid_got[3];
-
-        return NGX_OK;
     }
 
     /*
@@ -566,8 +585,19 @@ ngx_http_userid_variable(ngx_http_reques
 
 
 static ngx_int_t
+ngx_http_userid_reset_variable(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data)
+{
+    *v = ngx_http_variable_null_value;
+
+    return NGX_OK;
+}
+
+
+static ngx_int_t
 ngx_http_userid_add_variables(ngx_conf_t *cf)
 {
+    ngx_int_t             n;
     ngx_http_variable_t  *var;
 
     var = ngx_http_add_variable(cf, &ngx_http_userid_got, 0);
@@ -584,6 +614,21 @@ ngx_http_userid_add_variables(ngx_conf_t
 
     var->get_handler = ngx_http_userid_set_variable;
 
+    var = ngx_http_add_variable(cf, &ngx_http_userid_reset,
+                                NGX_HTTP_VAR_CHANGEABLE);
+    if (var == NULL) {
+        return NGX_ERROR;
+    }
+
+    var->get_handler = ngx_http_userid_reset_variable;
+
+    n = ngx_http_get_variable_index(cf, &ngx_http_userid_reset);
+    if (n == NGX_ERROR) {
+        return NGX_ERROR;
+    }
+
+    ngx_http_userid_reset_index = n;
+
     return NGX_OK;
 }
 
--- a/src/http/modules/perl/nginx.pm
+++ b/src/http/modules/perl/nginx.pm
@@ -48,7 +48,7 @@ our @EXPORT = qw(
     HTTP_INSUFFICIENT_STORAGE
 );
 
-our $VERSION = '1.0.4';
+our $VERSION = '1.0.5';
 
 require XSLoader;
 XSLoader::load('nginx', $VERSION);
--- a/src/http/ngx_http_file_cache.c
+++ b/src/http/ngx_http_file_cache.c
@@ -1099,7 +1099,8 @@ ngx_http_file_cache_expire(ngx_http_file
         }
 
         if (fcn->deleting) {
-            continue;
+            wait = 1;
+            break;
         }
 
         p = ngx_hex_dump(key, (u_char *) &fcn->node.key,
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -661,6 +661,15 @@ ngx_http_upstream_cache(ngx_http_request
 
         ngx_http_file_cache_create_key(r);
 
+        if (r->cache->header_start >= u->conf->buffer_size) {
+            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+                "cache key too large, increase upstream buffer size %uz",
+                u->conf->buffer_size);
+
+            r->cache = NULL;
+            return NGX_DECLINED;
+        }
+
         switch (ngx_http_test_predicates(r, u->conf->cache_bypass)) {
 
         case NGX_ERROR:
@@ -2031,15 +2040,6 @@ ngx_http_upstream_send_response(ngx_http
             c->error = 1;
 
         } else {
-
-#if (NGX_HTTP_CACHE)
-
-            if (r->cache) {
-                ngx_http_file_cache_free(r->cache, u->pipe->temp_file);
-            }
-
-#endif
-
             ngx_http_upstream_finalize_request(r, u, rc);
             return;
         }
@@ -2991,16 +2991,19 @@ ngx_http_upstream_finalize_request(ngx_h
 
 #if (NGX_HTTP_CACHE)
 
-    if (u->cacheable && r->cache) {
-        time_t  valid;
-
-        if (rc == NGX_HTTP_BAD_GATEWAY || rc == NGX_HTTP_GATEWAY_TIME_OUT) {
-
-            valid = ngx_http_file_cache_valid(u->conf->cache_valid, rc);
-
-            if (valid) {
-                r->cache->valid_sec = ngx_time() + valid;
-                r->cache->error = rc;
+    if (r->cache) {
+
+        if (u->cacheable) {
+
+            if (rc == NGX_HTTP_BAD_GATEWAY || rc == NGX_HTTP_GATEWAY_TIME_OUT) {
+                time_t  valid;
+
+                valid = ngx_http_file_cache_valid(u->conf->cache_valid, rc);
+
+                if (valid) {
+                    r->cache->valid_sec = ngx_time() + valid;
+                    r->cache->error = rc;
+                }
             }
         }
 
--- a/src/mail/ngx_mail_ssl_module.c
+++ b/src/mail/ngx_mail_ssl_module.c
@@ -9,7 +9,7 @@
 #include <ngx_mail.h>
 
 
-#define NGX_DEFAULT_CIPHERS  "HIGH:!ADH:!MD5"
+#define NGX_DEFAULT_CIPHERS  "HIGH:!aNULL:!MD5"
 
 
 static void *ngx_mail_ssl_create_conf(ngx_conf_t *cf);