# HG changeset patch # User Igor Sysoev # Date 1244404800 -14400 # Node ID 207ae3ff044452b1fb8ad28951ff566615a51939 # Parent 77fae36a61b37a72501d40fadc7c607e3bd2d7ca 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. diff --git a/CHANGES b/CHANGES --- 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. diff --git a/CHANGES.ru b/CHANGES.ru --- 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 кэш не кэшировал ответы, состоящие только из diff --git a/auto/os/features b/auto/os/features --- 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 " +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 diff --git a/auto/unix b/auto/unix --- 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 " -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 diff --git a/src/core/nginx.c b/src/core/nginx.c --- 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) { diff --git a/src/core/nginx.h b/src/core/nginx.h --- 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" diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c --- 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; } } diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c --- 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; } diff --git a/src/core/ngx_palloc.c b/src/core/ngx_palloc.c --- 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); diff --git a/src/core/ngx_palloc.h b/src/core/ngx_palloc.h --- 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; diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c --- 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'; diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c --- 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 } }; diff --git a/src/http/modules/ngx_http_image_filter_module.c b/src/http/modules/ngx_http_image_filter_module.c --- 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) diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c --- 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; } diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm --- 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); diff --git a/src/http/ngx_http_cache.h b/src/http/ngx_http_cache.h --- a/src/http/ngx_http_cache.h +++ b/src/http/ngx_http_cache.h @@ -13,11 +13,8 @@ #include -/**/ #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; diff --git a/src/http/ngx_http_file_cache.c b/src/http/ngx_http_file_cache.c --- 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) { diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c --- 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; } diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h --- 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