changeset 507:207ae3ff0444 NGINX_0_8_1

nginx 0.8.1 *) Feature: the "updating" parameter in "proxy_cache_use_stale" and "fastcgi_cache_use_stale" directives. *) Bugfix: the "If-Modified-Since", "If-Range", etc. client request header lines were passed to backend while caching if no "proxy_set_header" directive was used with any parameters. *) Bugfix: the "Set-Cookie" and "P3P" response header lines were not hidden while caching if no "proxy_hide_header/fastcgi_hide_header" directives were used with any parameters. *) Bugfix: the ngx_http_image_filter_module did not support GIF87a format. Thanks to Denis Ilyinyh. *) Bugfix: nginx could not be built modules on Solaris 10 and early; the bug had appeared in 0.7.56.
author Igor Sysoev <http://sysoev.ru>
date Mon, 08 Jun 2009 00:00:00 +0400
parents 77fae36a61b3
children 2db7806a88bc
files CHANGES CHANGES.ru auto/os/features auto/unix src/core/nginx.c src/core/nginx.h src/core/ngx_connection.c src/core/ngx_cycle.c src/core/ngx_palloc.c src/core/ngx_palloc.h src/core/ngx_string.c src/http/modules/ngx_http_fastcgi_module.c src/http/modules/ngx_http_image_filter_module.c src/http/modules/ngx_http_proxy_module.c src/http/modules/perl/nginx.pm src/http/ngx_http_cache.h src/http/ngx_http_file_cache.c src/http/ngx_http_upstream.c src/http/ngx_http_upstream.h
diffstat 19 files changed, 159 insertions(+), 71 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,25 @@
 
+Changes with nginx 0.8.1                                         08 Jun 2009
+
+    *) Feature: the "updating" parameter in "proxy_cache_use_stale" and 
+       "fastcgi_cache_use_stale" directives.
+
+    *) Bugfix: the "If-Modified-Since", "If-Range", etc. client request 
+       header lines were passed to backend while caching if no 
+       "proxy_set_header" directive was used with any parameters.
+
+    *) Bugfix: the "Set-Cookie" and "P3P" response header lines were not 
+       hidden while caching if no "proxy_hide_header/fastcgi_hide_header" 
+       directives were used with any parameters.
+
+    *) Bugfix: the ngx_http_image_filter_module did not support GIF87a 
+       format.
+       Thanks to Denis Ilyinyh.
+
+    *) Bugfix: nginx could not be built modules on Solaris 10 and early; 
+       the bug had appeared in 0.7.56.
+
+
 Changes with nginx 0.8.0                                         02 Jun 2009
 
     *) Feature: the "keepalive_requests" directive.
@@ -30,7 +51,7 @@ Changes with nginx 0.7.59               
        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.
+       the bug had appeared in 0.7.56.
 
     *) Bugfix: ngx_http_xslt_filter_module responses were not handled by 
        SSI, charset, and gzip filters.
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,25 @@
 
+Изменения в nginx 0.8.1                                           08.06.2009
+
+    *) Добавление: параметр updating в директивах proxy_cache_use_stale и 
+       fastcgi_cache_use_stale.
+
+    *) Исправление: строки "If-Modified-Since", "If-Range" и им подобные в 
+       заголовке запроса клиента передавались бэкенду при кэшировании, если 
+       не использовалась директива proxy_set_header с любыми параметрами.
+
+    *) Исправление: строки "Set-Cookie" и "P3P" в заголовке ответа бэкенда 
+       не скрывались при кэшировании, если не использовались директивы 
+       proxy_hide_header/fastcgi_hide_header с любыми параметрами.
+
+    *) Исправление: модуль ngx_http_image_filter_module не понимал формат 
+       GIF87a.
+       Спасибо Денис Ильиных.
+
+    *) Исправление: nginx не собирался на Solaris 10 и более ранних; ошибка 
+       появилась в 0.7.56.
+
+
 Изменения в nginx 0.8.0                                           02.06.2009
 
     *) Добавление: директива keepalive_requests.
@@ -8,7 +29,7 @@
 
     *) Исправление: XSLT-фильтр не работал в подзапросах.
 
-    *) Исправление: обработке относительных путей в in nginx/Windows.
+    *) Исправление: обработке относительных путей в nginx/Windows.
 
     *) Исправление: в proxy_store, fastcgi_store, proxy_cache и 
        fastcgi_cache в nginx/Windows.
@@ -74,7 +95,7 @@
 
 Изменения в nginx 0.7.55                                          06.05.2009
 
-    *) Исправление: параметры http_XXX в директиве proxy_cache_use_stale и 
+    *) Исправление: параметры http_XXX в директивах proxy_cache_use_stale и 
        fastcgi_cache_use_stale не работали.
 
     *) Исправление: fastcgi кэш не кэшировал ответы, состоящие только из 
--- a/auto/os/features
+++ b/auto/os/features
@@ -252,3 +252,25 @@ if [ $ngx_found != yes ]; then
         NGX_LIBDL="-ldl"
     fi
 fi
+
+
+ngx_feature="sched_yield()"
+ngx_feature_name="NGX_HAVE_SCHED_YIELD"
+ngx_feature_run=no
+ngx_feature_incs="#include <sched.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="sched_yield()"
+. auto/feature
+
+
+if [ $ngx_found != yes ]; then
+
+    ngx_feature="sched_yield() in librt"
+    ngx_feature_libs="-lrt"
+    . auto/feature
+
+    if [ $ngx_found = yes ]; then
+        CORE_LIBS="$CORE_LIBS -lrt"
+    fi
+fi
--- a/auto/unix
+++ b/auto/unix
@@ -163,28 +163,6 @@ ngx_feature_test="void *p; p = memalign(
 . auto/feature
 
 
-ngx_feature="sched_yield()"
-ngx_feature_name="NGX_HAVE_SCHED_YIELD"
-ngx_feature_run=no
-ngx_feature_incs="#include <sched.h>"
-ngx_feature_path=
-ngx_feature_libs=
-ngx_feature_test="sched_yield()"
-. auto/feature
-
-
-if [ $ngx_found != yes ]; then
-
-    ngx_feature="sched_yield() in librt"
-    ngx_feature_libs="-lrt"
-    . auto/feature
-
-    if [ $ngx_found = yes ]; then
-        CORE_LIBS="$CORE_LIBS -lrt"
-    fi
-fi
-
-
 ngx_feature="mmap(MAP_ANON|MAP_SHARED)"
 ngx_feature_name="NGX_HAVE_MAP_ANON"
 ngx_feature_run=yes
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -330,6 +330,10 @@ main(int argc, char *const *argv)
         return 0;
     }
 
+    if (ngx_signal) {
+        return ngx_signal_process(cycle, ngx_signal);
+    }
+
     ngx_os_status(cycle->log);
 
     ngx_cycle = cycle;
@@ -340,10 +344,6 @@ main(int argc, char *const *argv)
         ngx_process = NGX_PROCESS_MASTER;
     }
 
-    if (ngx_signal) {
-        return ngx_signal_process(cycle, ngx_signal);
-    }
-
 #if !(NGX_WIN32)
 
     if (ngx_init_signals(cycle->log) != NGX_OK) {
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,8 +8,8 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define nginx_version         8000
-#define NGINX_VERSION      "0.8.0"
+#define nginx_version         8001
+#define NGINX_VERSION      "0.8.1"
 #define NGINX_VER          "nginx/" NGINX_VERSION
 
 #define NGINX_VAR          "NGINX"
--- a/src/core/ngx_connection.c
+++ b/src/core/ngx_connection.c
@@ -603,6 +603,8 @@ ngx_close_listening_sockets(ngx_cycle_t 
             ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_socket_errno,
                           ngx_close_socket_n " %V failed", &ls[i].addr_text);
         }
+
+        ls[i].fd = (ngx_socket_t) -1;
     }
 }
 
--- a/src/core/ngx_cycle.c
+++ b/src/core/ngx_cycle.c
@@ -269,7 +269,6 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
                        cycle->conf_file.data);
     }
 
-
     for (i = 0; ngx_modules[i]; i++) {
         if (ngx_modules[i]->type != NGX_CORE_MODULE) {
             continue;
@@ -287,6 +286,9 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
         }
     }
 
+    if (ngx_process == NGX_PROCESS_SIGNALLER) {
+        return cycle;
+    }
 
     ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module);
 
@@ -564,14 +566,12 @@ ngx_init_cycle(ngx_cycle_t *old_cycle)
         }
     }
 
-    if (ngx_process != NGX_PROCESS_SIGNALLER) {
-        if (ngx_open_listening_sockets(cycle) != NGX_OK) {
-            goto failed;
-        }
+    if (ngx_open_listening_sockets(cycle) != NGX_OK) {
+        goto failed;
+    }
 
-        if (!ngx_test_config) {
-            ngx_configure_listening_sockets(cycle);
-        }
+    if (!ngx_test_config) {
+        ngx_configure_listening_sockets(cycle);
     }
 
 
@@ -653,7 +653,8 @@ old_shm_zone_done:
 
     ls = old_cycle->listening.elts;
     for (i = 0; i < old_cycle->listening.nelts; i++) {
-        if (ls[i].remain) {
+
+        if (ls[i].remain || ls[i].fd == -1) {
             continue;
         }
 
--- a/src/core/ngx_palloc.c
+++ b/src/core/ngx_palloc.c
@@ -25,6 +25,7 @@ ngx_create_pool(size_t size, ngx_log_t *
     p->d.last = (u_char *) p + sizeof(ngx_pool_t);
     p->d.end = (u_char *) p + size;
     p->d.next = NULL;
+    p->d.failed = 0;
 
     size = size - sizeof(ngx_pool_t);
     p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL;
@@ -189,6 +190,7 @@ ngx_palloc_block(ngx_pool_t *pool, size_
 
     new->d.end = m + psize;
     new->d.next = NULL;
+    new->d.failed = 0;
 
     m += sizeof(ngx_pool_data_t);
     m = ngx_align_ptr(m, NGX_ALIGNMENT);
@@ -197,7 +199,7 @@ ngx_palloc_block(ngx_pool_t *pool, size_
     current = pool->current;
 
     for (p = current; p->d.next; p = p->d.next) {
-        if ((size_t) (p->d.end - p->d.last) < NGX_ALIGNMENT) {
+        if (p->d.failed++ > 4) {
             current = p->d.next;
         }
     }
@@ -214,6 +216,7 @@ static void *
 ngx_palloc_large(ngx_pool_t *pool, size_t size)
 {
     void              *p;
+    ngx_uint_t         n;
     ngx_pool_large_t  *large;
 
     p = ngx_alloc(size, pool->log);
@@ -221,6 +224,19 @@ ngx_palloc_large(ngx_pool_t *pool, size_
         return NULL;
     }
 
+    n = 0;
+
+    for (large = pool->large; large; large = large->next) {
+        if (large->alloc == NULL) {
+            large->alloc = p;
+            return p;
+        }
+
+        if (n++ > 3) {
+            break;
+        }
+    }
+
     large = ngx_palloc(pool, sizeof(ngx_pool_large_t));
     if (large == NULL) {
         ngx_free(p);
--- a/src/core/ngx_palloc.h
+++ b/src/core/ngx_palloc.h
@@ -46,6 +46,7 @@ typedef struct {
     u_char               *last;
     u_char               *end;
     ngx_pool_t           *next;
+    ngx_uint_t            failed;
 } ngx_pool_data_t;
 
 
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -30,12 +30,15 @@ ngx_cpystrn(u_char *dst, u_char *src, si
         return dst;
     }
 
-    for ( /* void */ ; --n; dst++, src++) {
+    while (--n) {
         *dst = *src;
 
         if (*dst == '\0') {
             return dst;
         }
+
+        dst++;
+        src++;
     }
 
     *dst = '\0';
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -178,6 +178,7 @@ static ngx_conf_bitmask_t  ngx_http_fast
     { ngx_string("http_500"), NGX_HTTP_UPSTREAM_FT_HTTP_500 },
     { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 },
     { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
+    { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING },
     { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
     { ngx_null_string, 0 }
 };
--- a/src/http/modules/ngx_http_image_filter_module.c
+++ b/src/http/modules/ngx_http_image_filter_module.c
@@ -383,11 +383,12 @@ ngx_http_image_test(ngx_http_request_t *
         return NGX_HTTP_IMAGE_JPEG;
 
     } else if (p[0] == 'G' && p[1] == 'I' && p[2] == 'F' && p[3] == '8'
-               && p[4] == '9' && p[5] == 'a')
+               && p[5] == 'a')
     {
-        /* GIF */
-
-        return NGX_HTTP_IMAGE_GIF;
+        if (p[4] == '9' || p[4] == '7') {
+            /* GIF */
+            return NGX_HTTP_IMAGE_GIF;
+        }
 
     } else if (p[0] == 0x89 && p[1] == 'P' && p[2] == 'N' && p[3] == 'G'
                && p[4] == 0x0d && p[5] == 0x0a && p[6] == 0x1a && p[7] == 0x0a)
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -167,6 +167,7 @@ static ngx_conf_bitmask_t  ngx_http_prox
     { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 },
     { ngx_string("http_504"), NGX_HTTP_UPSTREAM_FT_HTTP_504 },
     { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
+    { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING },
     { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
     { ngx_null_string, 0 }
 };
@@ -2341,7 +2342,9 @@ ngx_http_proxy_merge_headers(ngx_conf_t 
         conf->headers_source = prev->headers_source;
     }
 
-    if (conf->headers_set_hash.buckets) {
+    if (conf->headers_set_hash.buckets
+        && ((conf->upstream.cache == NULL) == (prev->upstream.cache == NULL)))
+    {
         return NGX_OK;
     }
 
--- 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.8.0';
+our $VERSION = '0.8.1';
 
 require XSLoader;
 XSLoader::load('nginx', $VERSION);
--- a/src/http/ngx_http_cache.h
+++ b/src/http/ngx_http_cache.h
@@ -13,11 +13,8 @@
 #include <ngx_http.h>
 
 
-/**/
 #define NGX_HTTP_CACHE_STALE         1
-#define NGX_HTTP_CACHE_AGED          2
-#define NGX_HTTP_CACHE_THE_SAME      3
-/**/
+#define NGX_HTTP_CACHE_UPDATING      2
 
 #define NGX_HTTP_CACHE_KEY_LEN       16
 
@@ -28,8 +25,6 @@ typedef struct {
 } ngx_http_cache_valid_t;
 
 
-/* ngx_http_file_cache_node_t takes exactly 64 bytes on FreeBSD/i386 */
-
 typedef struct {
     ngx_rbtree_node_t                node;
     ngx_queue_t                      queue;
@@ -41,8 +36,9 @@ typedef struct {
     unsigned                         uses:10;
     unsigned                         valid_msec:10;
     unsigned                         error:10;
-                                     /* 7 unused bits */
     unsigned                         exists:1;
+    unsigned                         updating:1;
+                                     /* 12 unused bits */
 
     ngx_file_uniq_t                  uniq;
     time_t                           expire;
@@ -68,7 +64,6 @@ struct ngx_http_cache_s {
     off_t                            length;
 
     ngx_uint_t                       min_uses;
-    ngx_uint_t                       uses;
     ngx_uint_t                       error;
     ngx_uint_t                       valid_msec;
 
--- a/src/http/ngx_http_file_cache.c
+++ b/src/http/ngx_http_file_cache.c
@@ -172,9 +172,8 @@ ngx_http_file_cache_open(ngx_http_reques
 
     rc = ngx_http_file_cache_exists(cache, c);
 
-    ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                   "http file cache exists: %i u:%ui e:%d",
-                   rc, c->uses, c->exists);
+    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "http file cache exists: %i e:%d", rc, c->exists);
 
     if (rc == NGX_ERROR) {
         return rc;
@@ -332,16 +331,25 @@ ngx_http_file_cache_open(ngx_http_reques
 
     if (c->valid_sec < now) {
 
-        c->uses = c->min_uses;
+        ngx_shmtx_lock(&cache->shpool->mutex);
 
-        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                       "http file cache expired: %T %T", c->valid_sec, now);
+        if (c->node->updating) {
+            rc = NGX_HTTP_CACHE_UPDATING;
 
-        return NGX_HTTP_CACHE_STALE;
+        } else {
+            c->node->updating = 1;
+            rc = NGX_HTTP_CACHE_STALE;
+        }
+
+        ngx_shmtx_unlock(&cache->shpool->mutex);
+
+        ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                       "http file cache expired: %i %T %T",
+                       rc, c->valid_sec, now);
+
+        return rc;
     }
 
-    /* TODO: NGX_HTTP_CACHE_AGED */
-
     return NGX_OK;
 }
 
@@ -442,7 +450,6 @@ done:
     ngx_queue_insert_head(&cache->sh->queue, &fcn->queue);
 
     c->uniq = fcn->uniq;
-    c->uses = fcn->uses;
     c->error = fcn->error;
     c->node = fcn;
 
@@ -654,6 +661,8 @@ ngx_http_file_cache_update(ngx_http_requ
         c->node->exists = 1;
     }
 
+    c->node->updating = 0;
+
     ngx_shmtx_unlock(&cache->shpool->mutex);
 }
 
@@ -736,6 +745,8 @@ ngx_http_file_cache_free(ngx_http_reques
         c->node->error = c->error;
     }
 
+    c->node->updating = 0;
+
     ngx_shmtx_unlock(&cache->shpool->mutex);
 
     if (c->temp_file) {
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -577,8 +577,17 @@ ngx_http_upstream_cache(ngx_http_request
 
     rc = ngx_http_file_cache_open(r);
 
-    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                   "http upstream cache: %i u:%ui", rc, c->uses);
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "http upstream cache: %i", rc);
+
+    if (rc == NGX_HTTP_CACHE_UPDATING) {
+        if (u->conf->cache_use_stale & NGX_HTTP_UPSTREAM_FT_UPDATING) {
+            rc = NGX_OK;
+
+        } else {
+            rc = NGX_HTTP_CACHE_STALE;
+        }
+    }
 
     if (rc == NGX_OK) {
 
@@ -4076,7 +4085,9 @@ ngx_http_upstream_hide_headers_hash(ngx_
     {
         conf->hide_headers_hash = prev->hide_headers_hash;
 
-        if (conf->hide_headers_hash.buckets) {
+        if (conf->hide_headers_hash.buckets
+            && ((conf->cache == NULL) == (prev->cache == NULL)))
+        {
             return NGX_OK;
         }
 
--- a/src/http/ngx_http_upstream.h
+++ b/src/http/ngx_http_upstream.h
@@ -24,8 +24,9 @@
 #define NGX_HTTP_UPSTREAM_FT_HTTP_503        0x00000040
 #define NGX_HTTP_UPSTREAM_FT_HTTP_504        0x00000080
 #define NGX_HTTP_UPSTREAM_FT_HTTP_404        0x00000100
-#define NGX_HTTP_UPSTREAM_FT_BUSY_LOCK       0x00000200
-#define NGX_HTTP_UPSTREAM_FT_MAX_WAITING     0x00000400
+#define NGX_HTTP_UPSTREAM_FT_UPDATING        0x00000200
+#define NGX_HTTP_UPSTREAM_FT_BUSY_LOCK       0x00000400
+#define NGX_HTTP_UPSTREAM_FT_MAX_WAITING     0x00000800
 #define NGX_HTTP_UPSTREAM_FT_NOLIVE          0x40000000
 #define NGX_HTTP_UPSTREAM_FT_OFF             0x80000000