# HG changeset patch # User Igor Sysoev # Date 1330891200 -14400 # Node ID 09a689c5e494b7ec09ec885831b4fee00e0ebde7 # Parent 60344e6faa47202ebf60da92ec666402ab83c3ad nginx 1.0.13 *) Feature: the "return" and "error_page" directives can now be used to return 307 redirections. *) Bugfix: a segmentation fault might occur in a worker process if the "resolver" directive was used and there was no "error_log" directive specified at global level. Thanks to Roman Arutyunyan. *) Bugfix: memory leaks. Thanks to Lanshun Zhou. *) Bugfix: nginx might log incorrect error "upstream prematurely closed connection" instead of correct "upstream sent too big header" one. Thanks to Feibo Li. *) Bugfix: on ZFS filesystem disk cache size might be calculated incorrectly; the bug had appeared in 1.0.1. *) Bugfix: the number of internal redirects to named locations was not limited. *) Bugfix: temporary files might be not removed if the "proxy_store" directive was used with SSI includes. *) Bugfix: in some cases non-cacheable variables (such as the $args variable) returned old empty cached value. *) Bugfix: the "proxy_redirect" directives might be inherited incorrectly. *) Bugfix: nginx could not be built with the ngx_http_perl_module if the --with-openssl option was used. *) Bugfix: nginx could not be built by the icc 12.1 compiler. diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,42 @@ +Changes with nginx 1.0.13 05 Mar 2012 + + *) Feature: the "return" and "error_page" directives can now be used to + return 307 redirections. + + *) Bugfix: a segmentation fault might occur in a worker process if the + "resolver" directive was used and there was no "error_log" directive + specified at global level. + Thanks to Roman Arutyunyan. + + *) Bugfix: memory leaks. + Thanks to Lanshun Zhou. + + *) Bugfix: nginx might log incorrect error "upstream prematurely closed + connection" instead of correct "upstream sent too big header" one. + Thanks to Feibo Li. + + *) Bugfix: on ZFS filesystem disk cache size might be calculated + incorrectly; the bug had appeared in 1.0.1. + + *) Bugfix: the number of internal redirects to named locations was not + limited. + + *) Bugfix: temporary files might be not removed if the "proxy_store" + directive was used with SSI includes. + + *) Bugfix: in some cases non-cacheable variables (such as the $args + variable) returned old empty cached value. + + *) Bugfix: the "proxy_redirect" directives might be inherited + incorrectly. + + *) Bugfix: nginx could not be built with the ngx_http_perl_module if the + --with-openssl option was used. + + *) Bugfix: nginx could not be built by the icc 12.1 compiler. + + Changes with nginx 1.0.12 06 Feb 2012 *) Feature: the "TLSv1.1" and "TLSv1.2" parameters of the diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,4 +1,42 @@ +Изменения в nginx 1.0.13 05.03.2012 + + *) Добавление: директивы return и error_page теперь могут использоваться + для возврата перенаправлений с кодом 307. + + *) Исправление: в рабочем процессе мог произойти segmentation fault, + если использовалась директива resolver и на глобальном уровне не была + задана директива error_log. + Спасибо Роману Арутюняну. + + *) Исправление: утечек памяти. + Спасибо Lanshun Zhou. + + *) Исправление: nginx мог некорректно сообщать об ошибке "upstream + prematurely closed connection" вместо "upstream sent too big header". + Спасибо Feibo Li. + + *) Исправление: при использовании ZFS размер кэша на диске мог считаться + некорректно; ошибка появилась в 1.0.1. + + *) Исправление: количество внутренних перенаправлений в именованные + location'ы не ограничивалось. + + *) Исправление: при использовании директивы proxy_store с + SSI-подзапросами временные файлы могли не удаляться. + + *) Исправление: в некоторых случаях некэшируемые переменные (такие, как + $args) возвращали старое пустое закэшированное значение. + + *) Исправление: директивы proxy_redirect могли наследоваться + некорректно. + + *) Исправление: nginx не собирался с модулем ngx_http_perl_module, если + использовался параметр --with-openssl. + + *) Исправление: nginx не собирался компилятором icc 12.1. + + Изменения в nginx 1.0.12 06.02.2012 *) Добавление: параметры TLSv1.1 и TLSv1.2 в директиве ssl_protocols. diff --git a/auto/cc/name b/auto/cc/name --- a/auto/cc/name +++ b/auto/cc/name @@ -64,16 +64,16 @@ if [ "$CC" = bcc32 ]; then echo " + using Borland C++ compiler" else +if `$CC -V 2>&1 | grep '^Intel(R) C' >/dev/null 2>&1`; then + NGX_CC_NAME=icc + echo " + using Intel C++ compiler" + +else if `$CC -v 2>&1 | grep 'gcc version' >/dev/null 2>&1`; then NGX_CC_NAME=gcc echo " + using GNU C compiler" else -if `$CC -V 2>&1 | grep '^Intel(R) C' >/dev/null 2>&1`; then - NGX_CC_NAME=icc - echo " + using Intel C++ compiler" - -else if `$CC -V 2>&1 | grep 'Sun C' >/dev/null 2>&1`; then NGX_CC_NAME=sunc echo " + using Sun C compiler" diff --git a/auto/lib/perl/make b/auto/lib/perl/make --- a/auto/lib/perl/make +++ b/auto/lib/perl/make @@ -28,6 +28,7 @@ cat << END && NGX_PM_CFLAGS="\$(NGX_PM_CFLAGS) -g $NGX_CC_OPT" \ NGX_PCRE=$PCRE \ NGX_OBJS=$NGX_OBJS \ + NGX_OPENSSL=$OPENSSL \ $NGX_PERL Makefile.PL \ LIB=$NGX_PERL_MODULES \ INSTALLSITEMAN3DIR=$NGX_PERL_MODULES_MAN diff --git a/auto/unix b/auto/unix --- a/auto/unix +++ b/auto/unix @@ -707,3 +707,13 @@ ngx_feature_path= ngx_feature_libs= ngx_feature_test="struct dirent dir; dir.d_type = DT_REG" . auto/feature + + +ngx_feature="sysconf(_SC_NPROCESSORS_ONLN)" +ngx_feature_name="NGX_HAVE_SC_NPROCESSORS_ONLN" +ngx_feature_run=no +ngx_feature_incs= +ngx_feature_path= +ngx_feature_libs= +ngx_feature_test="sysconf(_SC_NPROCESSORS_ONLN)" +. auto/feature diff --git a/src/core/nginx.h b/src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1000012 -#define NGINX_VERSION "1.0.12" +#define nginx_version 1000013 +#define NGINX_VERSION "1.0.13" #define NGINX_VER "nginx/" NGINX_VERSION #define NGINX_VAR "NGINX" diff --git a/src/core/ngx_open_file_cache.c b/src/core/ngx_open_file_cache.c --- a/src/core/ngx_open_file_cache.c +++ b/src/core/ngx_open_file_cache.c @@ -837,20 +837,15 @@ ngx_open_file_lookup(ngx_open_file_cache /* hash == node->key */ - do { - file = (ngx_cached_open_file_t *) node; + file = (ngx_cached_open_file_t *) node; - rc = ngx_strcmp(name->data, file->name); + rc = ngx_strcmp(name->data, file->name); - if (rc == 0) { - return file; - } + if (rc == 0) { + return file; + } - node = (rc < 0) ? node->left : node->right; - - } while (node != sentinel && hash == node->key); - - break; + node = (rc < 0) ? node->left : node->right; } return NULL; diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c --- a/src/core/ngx_resolver.c +++ b/src/core/ngx_resolver.c @@ -152,11 +152,6 @@ ngx_resolver_create(ngx_conf_t *cf, ngx_ uc->sockaddr = addr->sockaddr; uc->socklen = addr->socklen; uc->server = addr->name; - - uc->log = cf->cycle->new_log; - uc->log.handler = ngx_resolver_log_error; - uc->log.data = uc; - uc->log.action = "resolving"; } return r; @@ -830,6 +825,12 @@ ngx_resolver_send_query(ngx_resolver_t * uc = r->udp_connection; if (uc->connection == NULL) { + + uc->log = *r->log; + uc->log.handler = ngx_resolver_log_error; + uc->log.data = uc; + uc->log.action = "resolving"; + if (ngx_udp_connect(uc) != NGX_OK) { return NGX_ERROR; } @@ -1625,20 +1626,15 @@ ngx_resolver_lookup_name(ngx_resolver_t /* hash == node->key */ - do { - rn = (ngx_resolver_node_t *) node; - - rc = ngx_memn2cmp(name->data, rn->name, name->len, rn->nlen); - - if (rc == 0) { - return rn; - } - - node = (rc < 0) ? node->left : node->right; - - } while (node != sentinel && hash == node->key); - - break; + rn = (ngx_resolver_node_t *) node; + + rc = ngx_memn2cmp(name->data, rn->name, name->len, rn->nlen); + + if (rc == 0) { + return rn; + } + + node = (rc < 0) ? node->left : node->right; } /* not found */ diff --git a/src/core/ngx_times.c b/src/core/ngx_times.c --- a/src/core/ngx_times.c +++ b/src/core/ngx_times.c @@ -287,7 +287,7 @@ ngx_gmtime(time_t t, ngx_tm_t *tp) days = n / 86400; - /* Jaunary 1, 1970 was Thursday */ + /* January 1, 1970 was Thursday */ wday = (4 + days) % 7; diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h --- a/src/event/ngx_event.h +++ b/src/event/ngx_event.h @@ -83,7 +83,7 @@ struct ngx_event_s { #endif #if (NGX_WIN32) - /* setsockopt(SO_UPDATE_ACCEPT_CONTEXT) was succesfull */ + /* setsockopt(SO_UPDATE_ACCEPT_CONTEXT) was successful */ unsigned accept_context_updated:1; #endif diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -842,7 +842,7 @@ ngx_ssl_recv(ngx_connection_t *c, u_char case NGX_ERROR: c->read->error = 1; - /* fall thruogh */ + /* fall through */ case NGX_AGAIN: return c->ssl->last; @@ -1801,44 +1801,39 @@ ngx_ssl_get_cached_session(ngx_ssl_conn_ /* hash == node->key */ - do { - sess_id = (ngx_ssl_sess_id_t *) node; - - rc = ngx_memn2cmp(id, sess_id->id, - (size_t) len, (size_t) node->data); - if (rc == 0) { - - if (sess_id->expire > ngx_time()) { - ngx_memcpy(buf, sess_id->session, sess_id->len); - - ngx_shmtx_unlock(&shpool->mutex); - - p = buf; - sess = d2i_SSL_SESSION(NULL, &p, sess_id->len); - - return sess; - } - - ngx_queue_remove(&sess_id->queue); - - ngx_rbtree_delete(&cache->session_rbtree, node); - - ngx_slab_free_locked(shpool, sess_id->session); + sess_id = (ngx_ssl_sess_id_t *) node; + + rc = ngx_memn2cmp(id, sess_id->id, (size_t) len, (size_t) node->data); + + if (rc == 0) { + + if (sess_id->expire > ngx_time()) { + ngx_memcpy(buf, sess_id->session, sess_id->len); + + ngx_shmtx_unlock(&shpool->mutex); + + p = buf; + sess = d2i_SSL_SESSION(NULL, &p, sess_id->len); + + return sess; + } + + ngx_queue_remove(&sess_id->queue); + + ngx_rbtree_delete(&cache->session_rbtree, node); + + ngx_slab_free_locked(shpool, sess_id->session); #if (NGX_PTR_SIZE == 4) - ngx_slab_free_locked(shpool, sess_id->id); + ngx_slab_free_locked(shpool, sess_id->id); #endif - ngx_slab_free_locked(shpool, sess_id); - - sess = NULL; - - goto done; - } - - node = (rc < 0) ? node->left : node->right; - - } while (node != sentinel && hash == node->key); - - break; + ngx_slab_free_locked(shpool, sess_id); + + sess = NULL; + + goto done; + } + + node = (rc < 0) ? node->left : node->right; } done: @@ -1908,31 +1903,26 @@ ngx_ssl_remove_session(SSL_CTX *ssl, ngx /* hash == node->key */ - do { - sess_id = (ngx_ssl_sess_id_t *) node; - - rc = ngx_memn2cmp(id, sess_id->id, len, (size_t) node->data); - - if (rc == 0) { - - ngx_queue_remove(&sess_id->queue); - - ngx_rbtree_delete(&cache->session_rbtree, node); - - ngx_slab_free_locked(shpool, sess_id->session); + sess_id = (ngx_ssl_sess_id_t *) node; + + rc = ngx_memn2cmp(id, sess_id->id, len, (size_t) node->data); + + if (rc == 0) { + + ngx_queue_remove(&sess_id->queue); + + ngx_rbtree_delete(&cache->session_rbtree, node); + + ngx_slab_free_locked(shpool, sess_id->session); #if (NGX_PTR_SIZE == 4) - ngx_slab_free_locked(shpool, sess_id->id); + ngx_slab_free_locked(shpool, sess_id->id); #endif - ngx_slab_free_locked(shpool, sess_id); - - goto done; - } - - node = (rc < 0) ? node->left : node->right; - - } while (node != sentinel && hash == node->key); - - break; + ngx_slab_free_locked(shpool, sess_id); + + goto done; + } + + node = (rc < 0) ? node->left : node->right; } done: diff --git a/src/event/ngx_event_pipe.c b/src/event/ngx_event_pipe.c --- a/src/event/ngx_event_pipe.c +++ b/src/event/ngx_event_pipe.c @@ -946,7 +946,7 @@ ngx_event_pipe_add_free_buf(ngx_event_pi return NGX_OK; } - /* the first free buf is partialy filled, thus add the free buf after it */ + /* the first free buf is partially filled, thus add the free buf after it */ cl->next = p->free_raw_bufs->next; p->free_raw_bufs->next = cl; diff --git a/src/http/modules/ngx_http_autoindex_module.c b/src/http/modules/ngx_http_autoindex_module.c --- a/src/http/modules/ngx_http_autoindex_module.c +++ b/src/http/modules/ngx_http_autoindex_module.c @@ -95,8 +95,8 @@ static ngx_http_module_t ngx_http_autoi NULL, /* create server configuration */ NULL, /* merge server configuration */ - ngx_http_autoindex_create_loc_conf, /* create location configration */ - ngx_http_autoindex_merge_loc_conf /* merge location configration */ + ngx_http_autoindex_create_loc_conf, /* create location configuration */ + ngx_http_autoindex_merge_loc_conf /* merge location configuration */ }; diff --git a/src/http/modules/ngx_http_headers_filter_module.c b/src/http/modules/ngx_http_headers_filter_module.c --- a/src/http/modules/ngx_http_headers_filter_module.c +++ b/src/http/modules/ngx_http_headers_filter_module.c @@ -149,7 +149,9 @@ ngx_http_headers_filter(ngx_http_request && r->headers_out.status != NGX_HTTP_PARTIAL_CONTENT && r->headers_out.status != NGX_HTTP_MOVED_PERMANENTLY && r->headers_out.status != NGX_HTTP_MOVED_TEMPORARILY - && r->headers_out.status != NGX_HTTP_NOT_MODIFIED)) + && r->headers_out.status != NGX_HTTP_SEE_OTHER + && r->headers_out.status != NGX_HTTP_NOT_MODIFIED + && r->headers_out.status != NGX_HTTP_TEMPORARY_REDIRECT)) { return ngx_http_next_header_filter(r); } diff --git a/src/http/modules/ngx_http_index_module.c b/src/http/modules/ngx_http_index_module.c --- a/src/http/modules/ngx_http_index_module.c +++ b/src/http/modules/ngx_http_index_module.c @@ -62,8 +62,8 @@ static ngx_http_module_t ngx_http_index NULL, /* create server configuration */ NULL, /* merge server configuration */ - ngx_http_index_create_loc_conf, /* create location configration */ - ngx_http_index_merge_loc_conf /* merge location configration */ + ngx_http_index_create_loc_conf, /* create location configuration */ + ngx_http_index_merge_loc_conf /* merge location configuration */ }; diff --git a/src/http/modules/ngx_http_limit_req_module.c b/src/http/modules/ngx_http_limit_req_module.c --- a/src/http/modules/ngx_http_limit_req_module.c +++ b/src/http/modules/ngx_http_limit_req_module.c @@ -112,8 +112,8 @@ static ngx_http_module_t ngx_http_limit NULL, /* create server configuration */ NULL, /* merge server configuration */ - ngx_http_limit_req_create_conf, /* create location configration */ - ngx_http_limit_req_merge_conf /* merge location configration */ + ngx_http_limit_req_create_conf, /* create location configuration */ + ngx_http_limit_req_merge_conf /* merge location configuration */ }; @@ -372,47 +372,42 @@ ngx_http_limit_req_lookup(ngx_http_limit /* hash == node->key */ - do { - lr = (ngx_http_limit_req_node_t *) &node->color; + lr = (ngx_http_limit_req_node_t *) &node->color; - rc = ngx_memn2cmp(data, lr->data, len, (size_t) lr->len); + rc = ngx_memn2cmp(data, lr->data, len, (size_t) lr->len); - if (rc == 0) { - ngx_queue_remove(&lr->queue); - ngx_queue_insert_head(&ctx->sh->queue, &lr->queue); - - tp = ngx_timeofday(); - - now = (ngx_msec_t) (tp->sec * 1000 + tp->msec); - ms = (ngx_msec_int_t) (now - lr->last); - - excess = lr->excess - ctx->rate * ngx_abs(ms) / 1000 + 1000; + if (rc == 0) { + ngx_queue_remove(&lr->queue); + ngx_queue_insert_head(&ctx->sh->queue, &lr->queue); - if (excess < 0) { - excess = 0; - } + tp = ngx_timeofday(); - *ep = excess; + now = (ngx_msec_t) (tp->sec * 1000 + tp->msec); + ms = (ngx_msec_int_t) (now - lr->last); - if ((ngx_uint_t) excess > lrcf->burst) { - return NGX_BUSY; - } + excess = lr->excess - ctx->rate * ngx_abs(ms) / 1000 + 1000; - lr->excess = excess; - lr->last = now; - - if (excess) { - return NGX_AGAIN; - } - - return NGX_OK; + if (excess < 0) { + excess = 0; } - node = (rc < 0) ? node->left : node->right; + *ep = excess; + + if ((ngx_uint_t) excess > lrcf->burst) { + return NGX_BUSY; + } + + lr->excess = excess; + lr->last = now; - } while (node != sentinel && hash == node->key); + if (excess) { + return NGX_AGAIN; + } - break; + return NGX_OK; + } + + node = (rc < 0) ? node->left : node->right; } *ep = 0; diff --git a/src/http/modules/ngx_http_limit_zone_module.c b/src/http/modules/ngx_http_limit_zone_module.c --- a/src/http/modules/ngx_http_limit_zone_module.c +++ b/src/http/modules/ngx_http_limit_zone_module.c @@ -96,8 +96,8 @@ static ngx_http_module_t ngx_http_limit NULL, /* create server configuration */ NULL, /* merge server configuration */ - ngx_http_limit_zone_create_conf, /* create location configration */ - ngx_http_limit_zone_merge_conf /* merge location configration */ + ngx_http_limit_zone_create_conf, /* create location configuration */ + ngx_http_limit_zone_merge_conf /* merge location configuration */ }; @@ -194,31 +194,26 @@ ngx_http_limit_zone_handler(ngx_http_req /* hash == node->key */ - do { - lz = (ngx_http_limit_zone_node_t *) &node->color; + lz = (ngx_http_limit_zone_node_t *) &node->color; - rc = ngx_memn2cmp(vv->data, lz->data, len, (size_t) lz->len); + rc = ngx_memn2cmp(vv->data, lz->data, len, (size_t) lz->len); - if (rc == 0) { - if ((ngx_uint_t) lz->conn < lzcf->conn) { - lz->conn++; - goto done; - } - - ngx_shmtx_unlock(&shpool->mutex); - - ngx_log_error(lzcf->log_level, r->connection->log, 0, - "limiting connections by zone \"%V\"", - &lzcf->shm_zone->shm.name); - - return NGX_HTTP_SERVICE_UNAVAILABLE; + if (rc == 0) { + if ((ngx_uint_t) lz->conn < lzcf->conn) { + lz->conn++; + goto done; } - node = (rc < 0) ? node->left : node->right; + ngx_shmtx_unlock(&shpool->mutex); - } while (node != sentinel && hash == node->key); + ngx_log_error(lzcf->log_level, r->connection->log, 0, + "limiting connections by zone \"%V\"", + &lzcf->shm_zone->shm.name); - break; + return NGX_HTTP_SERVICE_UNAVAILABLE; + } + + node = (rc < 0) ? node->left : node->right; } n = offsetof(ngx_rbtree_node_t, color) diff --git a/src/http/modules/ngx_http_log_module.c b/src/http/modules/ngx_http_log_module.c --- a/src/http/modules/ngx_http_log_module.c +++ b/src/http/modules/ngx_http_log_module.c @@ -161,8 +161,8 @@ static ngx_http_module_t ngx_http_log_m NULL, /* create server configuration */ NULL, /* merge server configuration */ - ngx_http_log_create_loc_conf, /* create location configration */ - ngx_http_log_merge_loc_conf /* merge location configration */ + ngx_http_log_create_loc_conf, /* create location configuration */ + ngx_http_log_merge_loc_conf /* merge location configuration */ }; @@ -375,10 +375,10 @@ ngx_http_log_script_write(ngx_http_reque if (!r->root_tested) { - /* test root directory existance */ + /* test root directory existence */ if (ngx_http_map_uri_to_path(r, &path, &root, 0) == NULL) { - /* simulate successfull logging */ + /* simulate successful logging */ return len; } @@ -399,14 +399,14 @@ ngx_http_log_script_write(ngx_http_reque != NGX_OK) { if (of.err == 0) { - /* simulate successfull logging */ + /* simulate successful logging */ return len; } ngx_log_error(NGX_LOG_ERR, r->connection->log, of.err, "testing \"%s\" existence failed", path.data); - /* simulate successfull logging */ + /* simulate successful logging */ return len; } @@ -414,7 +414,7 @@ ngx_http_log_script_write(ngx_http_reque ngx_log_error(NGX_LOG_ERR, r->connection->log, NGX_ENOTDIR, "testing \"%s\" existence failed", path.data); - /* simulate successfull logging */ + /* simulate successful logging */ return len; } } @@ -423,7 +423,7 @@ ngx_http_log_script_write(ngx_http_reque script->values->elts) == NULL) { - /* simulate successfull logging */ + /* simulate successful logging */ return len; } @@ -447,7 +447,7 @@ ngx_http_log_script_write(ngx_http_reque { ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, "%s \"%s\" failed", of.failed, log.data); - /* simulate successfull logging */ + /* simulate successful logging */ return len; } diff --git a/src/http/modules/ngx_http_memcached_module.c b/src/http/modules/ngx_http_memcached_module.c --- a/src/http/modules/ngx_http_memcached_module.c +++ b/src/http/modules/ngx_http_memcached_module.c @@ -115,8 +115,8 @@ static ngx_http_module_t ngx_http_memca NULL, /* create server configuration */ NULL, /* merge server configuration */ - ngx_http_memcached_create_loc_conf, /* create location configration */ - ngx_http_memcached_merge_loc_conf /* merge location configration */ + ngx_http_memcached_create_loc_conf, /* create location configuration */ + ngx_http_memcached_merge_loc_conf /* merge location configuration */ }; 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 @@ -458,8 +458,8 @@ static ngx_http_module_t ngx_http_proxy NULL, /* create server configuration */ NULL, /* merge server configuration */ - ngx_http_proxy_create_loc_conf, /* create location configration */ - ngx_http_proxy_merge_loc_conf /* merge location configration */ + ngx_http_proxy_create_loc_conf, /* create location configuration */ + ngx_http_proxy_merge_loc_conf /* merge location configuration */ }; @@ -2496,6 +2496,8 @@ ngx_http_proxy_redirect(ngx_conf_t *cf, return NGX_CONF_OK; } + plcf->redirect = 1; + value = cf->args->elts; if (cf->args->nelts == 2) { diff --git a/src/http/modules/ngx_http_random_index_module.c b/src/http/modules/ngx_http_random_index_module.c --- a/src/http/modules/ngx_http_random_index_module.c +++ b/src/http/modules/ngx_http_random_index_module.c @@ -49,8 +49,8 @@ static ngx_http_module_t ngx_http_rando NULL, /* create server configuration */ NULL, /* merge server configuration */ - ngx_http_random_index_create_loc_conf, /* create location configration */ - ngx_http_random_index_merge_loc_conf /* merge location configration */ + ngx_http_random_index_create_loc_conf, /* create location configuration */ + ngx_http_random_index_merge_loc_conf /* merge location configuration */ }; diff --git a/src/http/modules/ngx_http_range_filter_module.c b/src/http/modules/ngx_http_range_filter_module.c --- a/src/http/modules/ngx_http_range_filter_module.c +++ b/src/http/modules/ngx_http_range_filter_module.c @@ -595,15 +595,8 @@ ngx_http_range_test_overlapped(ngx_http_ buf = in->buf; if (!buf->last_buf) { - - if (buf->in_file) { - start = buf->file_pos + ctx->offset; - last = buf->file_last + ctx->offset; - - } else { - start = buf->pos - buf->start + ctx->offset; - last = buf->last - buf->start + ctx->offset; - } + start = ctx->offset; + last = ctx->offset + ngx_buf_size(buf); range = ctx->ranges.elts; for (i = 0; i < ctx->ranges.nelts; i++) { @@ -716,7 +709,6 @@ static ngx_int_t ngx_http_range_multipart_body(ngx_http_request_t *r, ngx_http_range_filter_ctx_t *ctx, ngx_chain_t *in) { - off_t body_start; ngx_buf_t *b, *buf; ngx_uint_t i; ngx_chain_t *out, *hcl, *rcl, *dcl, **ll; @@ -726,12 +718,6 @@ ngx_http_range_multipart_body(ngx_http_r buf = in->buf; range = ctx->ranges.elts; -#if (NGX_HTTP_CACHE) - body_start = r->cached ? r->cache->body_start : 0; -#else - body_start = 0; -#endif - for (i = 0; i < ctx->ranges.nelts; i++) { /* @@ -792,13 +778,13 @@ ngx_http_range_multipart_body(ngx_http_r b->file = buf->file; if (buf->in_file) { - b->file_pos = body_start + range[i].start; - b->file_last = body_start + range[i].end; + b->file_pos = buf->file_pos + range[i].start; + b->file_last = buf->file_pos + range[i].end; } if (ngx_buf_in_memory(buf)) { - b->pos = buf->start + (size_t) range[i].start; - b->last = buf->start + (size_t) range[i].end; + b->pos = buf->pos + (size_t) range[i].start; + b->last = buf->pos + (size_t) range[i].end; } dcl = ngx_alloc_chain_link(r->pool); diff --git a/src/http/modules/ngx_http_rewrite_module.c b/src/http/modules/ngx_http_rewrite_module.c --- a/src/http/modules/ngx_http_rewrite_module.c +++ b/src/http/modules/ngx_http_rewrite_module.c @@ -112,8 +112,8 @@ static ngx_http_module_t ngx_http_rewri NULL, /* create server configuration */ NULL, /* merge server configuration */ - ngx_http_rewrite_create_loc_conf, /* create location configration */ - ngx_http_rewrite_merge_loc_conf /* merge location configration */ + ngx_http_rewrite_create_loc_conf, /* create location configuration */ + ngx_http_rewrite_merge_loc_conf /* merge location configuration */ }; diff --git a/src/http/modules/ngx_http_userid_filter_module.c b/src/http/modules/ngx_http_userid_filter_module.c --- a/src/http/modules/ngx_http_userid_filter_module.c +++ b/src/http/modules/ngx_http_userid_filter_module.c @@ -166,8 +166,8 @@ static ngx_http_module_t ngx_http_useri NULL, /* create server configuration */ NULL, /* merge server configuration */ - ngx_http_userid_create_conf, /* create location configration */ - ngx_http_userid_merge_conf /* merge location configration */ + ngx_http_userid_create_conf, /* create location configuration */ + ngx_http_userid_merge_conf /* merge location configuration */ }; diff --git a/src/http/modules/perl/Makefile.PL b/src/http/modules/perl/Makefile.PL --- a/src/http/modules/perl/Makefile.PL +++ b/src/http/modules/perl/Makefile.PL @@ -25,7 +25,11 @@ WriteMakefile( "-I ../../../../../$ENV{NGX_OBJS} " . ($ENV{NGX_PCRE} =~ /^(YES|NO)/ ? "" : ($ENV{NGX_PCRE} =~ m#^/# ? "-I $ENV{NGX_PCRE} " : - "-I ../../../../../$ENV{NGX_PCRE} ")), + "-I ../../../../../$ENV{NGX_PCRE} ")) . + ($ENV{NGX_OPENSSL} =~ /^(YES|NO)/ ? "" : + ($ENV{NGX_OPENSSL} =~ m#^/# ? + "-I $ENV{NGX_OPENSSL}/.openssl/include " : + "-I ../../../../../$ENV{NGX_OPENSSL}/.openssl/include ")), depend => { 'nginx.c' => 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 @@ -21,7 +21,9 @@ our @EXPORT = qw( HTTP_MOVED_PERMANENTLY HTTP_MOVED_TEMPORARILY HTTP_REDIRECT + HTTP_SEE_OTHER HTTP_NOT_MODIFIED + HTTP_TEMPORARY_REDIRECT HTTP_BAD_REQUEST HTTP_UNAUTHORIZED @@ -48,7 +50,7 @@ our @EXPORT = qw( HTTP_INSUFFICIENT_STORAGE ); -our $VERSION = '1.0.12'; +our $VERSION = '1.0.13'; require XSLoader; XSLoader::load('nginx', $VERSION); @@ -67,7 +69,9 @@ use constant HTTP_PARTIAL_CONTENT use constant HTTP_MOVED_PERMANENTLY => 301; use constant HTTP_MOVED_TEMPORARILY => 302; use constant HTTP_REDIRECT => 302; +use constant HTTP_SEE_OTHER => 303; use constant HTTP_NOT_MODIFIED => 304; +use constant HTTP_TEMPORARY_REDIRECT => 307; use constant HTTP_BAD_REQUEST => 400; use constant HTTP_UNAUTHORIZED => 401; diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -1798,8 +1798,11 @@ ngx_http_send_response(ngx_http_request_ return NGX_HTTP_INTERNAL_SERVER_ERROR; } - if (status >= NGX_HTTP_MOVED_PERMANENTLY && status <= NGX_HTTP_SEE_OTHER) { - + if (status == NGX_HTTP_MOVED_PERMANENTLY + || status == NGX_HTTP_MOVED_TEMPORARILY + || status == NGX_HTTP_SEE_OTHER + || status == NGX_HTTP_TEMPORARY_REDIRECT) + { ngx_http_clear_location(r); r->headers_out.location = ngx_list_push(&r->headers_out.headers); @@ -2524,6 +2527,16 @@ ngx_http_named_location(ngx_http_request ngx_http_core_main_conf_t *cmcf; r->main->count++; + r->uri_changes--; + + if (r->uri_changes == 0) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "rewrite or internal redirection cycle " + "while redirect to named location \"%V\"", name); + + ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); + return NGX_DONE; + } cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); 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 @@ -673,21 +673,16 @@ ngx_http_file_cache_lookup(ngx_http_file /* node_key == node->key */ - do { - fcn = (ngx_http_file_cache_node_t *) node; + fcn = (ngx_http_file_cache_node_t *) node; - rc = ngx_memcmp(&key[sizeof(ngx_rbtree_key_t)], fcn->key, - NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t)); + rc = ngx_memcmp(&key[sizeof(ngx_rbtree_key_t)], fcn->key, + NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t)); - if (rc == 0) { - return fcn; - } + if (rc == 0) { + return fcn; + } - node = (rc < 0) ? node->left : node->right; - - } while (node != sentinel && node_key == node->key); - - break; + node = (rc < 0) ? node->left : node->right; } /* not found */ diff --git a/src/http/ngx_http_header_filter_module.c b/src/http/ngx_http_header_filter_module.c --- a/src/http/ngx_http_header_filter_module.c +++ b/src/http/ngx_http_header_filter_module.c @@ -71,12 +71,11 @@ static ngx_str_t ngx_http_status_lines[] ngx_string("302 Moved Temporarily"), ngx_string("303 See Other"), ngx_string("304 Not Modified"), + ngx_null_string, /* "305 Use Proxy" */ + ngx_null_string, /* "306 unused" */ + ngx_string("307 Temporary Redirect"), - /* ngx_null_string, */ /* "305 Use Proxy" */ - /* ngx_null_string, */ /* "306 unused" */ - /* ngx_null_string, */ /* "307 Temporary Redirect" */ - -#define NGX_HTTP_LAST_3XX 305 +#define NGX_HTTP_LAST_3XX 308 #define NGX_HTTP_OFF_4XX (NGX_HTTP_LAST_3XX - 301 + NGX_HTTP_OFF_3XX) ngx_string("400 Bad Request"), diff --git a/src/http/ngx_http_parse_time.c b/src/http/ngx_http_parse_time.c --- a/src/http/ngx_http_parse_time.c +++ b/src/http/ngx_http_parse_time.c @@ -242,7 +242,7 @@ ngx_http_parse_time(u_char *value, size_ year -= 1; } - /* Gauss' formula for Grigorian days since March 1, 1 BC */ + /* Gauss' formula for Gregorian days since March 1, 1 BC */ time = (uint64_t) ( /* days in years including leap years since March 1, 1 BC */ diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -2898,6 +2898,10 @@ ngx_http_post_action(ngx_http_request_t return NGX_DECLINED; } + if (r->post_action && r->uri_changes == 0) { + return NGX_DECLINED; + } + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "post action: \"%V\"", &clcf->post_action); diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -75,6 +75,7 @@ #define NGX_HTTP_MOVED_TEMPORARILY 302 #define NGX_HTTP_SEE_OTHER 303 #define NGX_HTTP_NOT_MODIFIED 304 +#define NGX_HTTP_TEMPORARY_REDIRECT 307 #define NGX_HTTP_BAD_REQUEST 400 #define NGX_HTTP_UNAUTHORIZED 401 diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c --- a/src/http/ngx_http_special_response.c +++ b/src/http/ngx_http_special_response.c @@ -74,6 +74,14 @@ static char ngx_http_error_303_page[] = ; +static char ngx_http_error_307_page[] = +"" CRLF +"307 Temporary Redirect" CRLF +"" CRLF +"

307 Temporary Redirect

" CRLF +; + + static char ngx_http_error_400_page[] = "" CRLF "400 Bad Request" CRLF @@ -294,16 +302,20 @@ static ngx_str_t ngx_http_error_pages[] ngx_null_string, /* 201, 204 */ -#define NGX_HTTP_LAST_LEVEL_200 202 -#define NGX_HTTP_LEVEL_200 (NGX_HTTP_LAST_LEVEL_200 - 201) +#define NGX_HTTP_LAST_2XX 202 +#define NGX_HTTP_OFF_3XX (NGX_HTTP_LAST_2XX - 201) /* ngx_null_string, */ /* 300 */ ngx_string(ngx_http_error_301_page), ngx_string(ngx_http_error_302_page), ngx_string(ngx_http_error_303_page), + ngx_null_string, /* 304 */ + ngx_null_string, /* 305 */ + ngx_null_string, /* 306 */ + ngx_string(ngx_http_error_307_page), -#define NGX_HTTP_LAST_LEVEL_300 304 -#define NGX_HTTP_LEVEL_300 (NGX_HTTP_LAST_LEVEL_300 - 301) +#define NGX_HTTP_LAST_3XX 308 +#define NGX_HTTP_OFF_4XX (NGX_HTTP_LAST_3XX - 301 + NGX_HTTP_OFF_3XX) ngx_string(ngx_http_error_400_page), ngx_string(ngx_http_error_401_page), @@ -323,8 +335,8 @@ static ngx_str_t ngx_http_error_pages[] ngx_string(ngx_http_error_415_page), ngx_string(ngx_http_error_416_page), -#define NGX_HTTP_LAST_LEVEL_400 417 -#define NGX_HTTP_LEVEL_400 (NGX_HTTP_LAST_LEVEL_400 - 400) +#define NGX_HTTP_LAST_4XX 417 +#define NGX_HTTP_OFF_5XX (NGX_HTTP_LAST_4XX - 400 + NGX_HTTP_OFF_4XX) ngx_string(ngx_http_error_494_page), /* 494, request header too large */ ngx_string(ngx_http_error_495_page), /* 495, https certificate error */ @@ -342,7 +354,7 @@ static ngx_str_t ngx_http_error_pages[] ngx_null_string, /* 506 */ ngx_string(ngx_http_error_507_page) -#define NGX_HTTP_LAST_LEVEL_500 508 +#define NGX_HTTP_LAST_5XX 508 }; @@ -428,25 +440,22 @@ ngx_http_special_response_handler(ngx_ht err = 0; } else if (error >= NGX_HTTP_MOVED_PERMANENTLY - && error < NGX_HTTP_LAST_LEVEL_300) + && error < NGX_HTTP_LAST_3XX) { /* 3XX */ - err = error - NGX_HTTP_MOVED_PERMANENTLY + NGX_HTTP_LEVEL_200; + err = error - NGX_HTTP_MOVED_PERMANENTLY + NGX_HTTP_OFF_3XX; } else if (error >= NGX_HTTP_BAD_REQUEST - && error < NGX_HTTP_LAST_LEVEL_400) + && error < NGX_HTTP_LAST_4XX) { /* 4XX */ - err = error - NGX_HTTP_BAD_REQUEST + NGX_HTTP_LEVEL_200 - + NGX_HTTP_LEVEL_300; + err = error - NGX_HTTP_BAD_REQUEST + NGX_HTTP_OFF_4XX; } else if (error >= NGX_HTTP_NGINX_CODES - && error < NGX_HTTP_LAST_LEVEL_500) + && error < NGX_HTTP_LAST_5XX) { /* 49X, 5XX */ - err = error - NGX_HTTP_NGINX_CODES + NGX_HTTP_LEVEL_200 - + NGX_HTTP_LEVEL_300 - + NGX_HTTP_LEVEL_400; + err = error - NGX_HTTP_NGINX_CODES + NGX_HTTP_OFF_5XX; switch (error) { case NGX_HTTP_TO_HTTPS: case NGX_HTTPS_CERT_ERROR: @@ -570,12 +579,11 @@ ngx_http_send_error_page(ngx_http_reques return NGX_ERROR; } - if (overwrite >= NGX_HTTP_MOVED_PERMANENTLY - && overwrite <= NGX_HTTP_SEE_OTHER) + if (overwrite != NGX_HTTP_MOVED_PERMANENTLY + && overwrite != NGX_HTTP_MOVED_TEMPORARILY + && overwrite != NGX_HTTP_SEE_OTHER + && overwrite != NGX_HTTP_TEMPORARY_REDIRECT) { - r->err_status = overwrite; - - } else { r->err_status = NGX_HTTP_MOVED_TEMPORARILY; } @@ -595,7 +603,7 @@ ngx_http_send_error_page(ngx_http_reques return ngx_http_send_special_response(r, clcf, r->err_status - NGX_HTTP_MOVED_PERMANENTLY - + NGX_HTTP_LEVEL_200); + + NGX_HTTP_OFF_3XX); } @@ -626,7 +634,7 @@ ngx_http_send_special_response(ngx_http_ if (clcf->msie_padding && (r->headers_in.msie || r->headers_in.chrome) && r->http_version >= NGX_HTTP_VERSION_10 - && err >= NGX_HTTP_LEVEL_300) + && err >= NGX_HTTP_OFF_4XX) { r->headers_out.content_length_n += sizeof(ngx_http_msie_padding) - 1; 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 @@ -1561,7 +1561,7 @@ ngx_http_upstream_process_header(ngx_htt if (rc == NGX_AGAIN) { - if (u->buffer.pos == u->buffer.end) { + if (u->buffer.last == u->buffer.end) { ngx_log_error(NGX_LOG_ERR, c->log, 0, "upstream sent too big header"); @@ -2263,7 +2263,7 @@ ngx_http_upstream_send_response(ngx_http } if (ngx_event_flags & NGX_USE_AIO_EVENT) { - /* the posted aio operation may currupt a shadow buffer */ + /* the posted aio operation may corrupt a shadow buffer */ p->single_buf = 1; } @@ -2616,7 +2616,6 @@ ngx_http_upstream_process_upstream(ngx_h static void ngx_http_upstream_process_request(ngx_http_request_t *r) { - ngx_uint_t del; ngx_temp_file_t *tf; ngx_event_pipe_t *p; ngx_http_upstream_t *u; @@ -2628,30 +2627,16 @@ ngx_http_upstream_process_request(ngx_ht if (u->store) { - del = p->upstream_error; - - tf = u->pipe->temp_file; - if (p->upstream_eof || p->upstream_done) { + tf = u->pipe->temp_file; + if (u->headers_in.status_n == NGX_HTTP_OK && (u->headers_in.content_length_n == -1 || (u->headers_in.content_length_n == tf->offset))) { ngx_http_upstream_store(r, u); - - } else { - del = 1; - } - } - - if (del && tf->file.fd != NGX_INVALID_FILE) { - - if (ngx_delete_file(tf->file.name.data) == NGX_FILE_ERROR) { - - ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, - ngx_delete_file_n " \"%s\" failed", - u->pipe->temp_file->file.name.data); + u->store = 0; } } } @@ -2994,6 +2979,18 @@ ngx_http_upstream_finalize_request(ngx_h u->pipe->temp_file->file.fd); } + if (u->store && u->pipe && u->pipe->temp_file + && u->pipe->temp_file->file.fd != NGX_INVALID_FILE) + { + if (ngx_delete_file(u->pipe->temp_file->file.name.data) + == NGX_FILE_ERROR) + { + ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, + ngx_delete_file_n " \"%s\" failed", + u->pipe->temp_file->file.name.data); + } + } + #if (NGX_HTTP_CACHE) if (r->cache) { diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c --- a/src/http/ngx_http_variables.c +++ b/src/http/ngx_http_variables.c @@ -428,7 +428,7 @@ ngx_http_get_flushed_variable(ngx_http_r v = &r->variables[index]; - if (v->valid) { + if (v->valid || v->not_found) { if (!v->no_cacheable) { return v; } diff --git a/src/mail/ngx_mail_pop3_handler.c b/src/mail/ngx_mail_pop3_handler.c --- a/src/mail/ngx_mail_pop3_handler.c +++ b/src/mail/ngx_mail_pop3_handler.c @@ -218,7 +218,7 @@ ngx_mail_pop3_auth_state(ngx_event_t *re break; - /* suppress warinings */ + /* suppress warnings */ case ngx_pop3_passwd: break; diff --git a/src/os/unix/ngx_darwin_sendfile_chain.c b/src/os/unix/ngx_darwin_sendfile_chain.c --- a/src/os/unix/ngx_darwin_sendfile_chain.c +++ b/src/os/unix/ngx_darwin_sendfile_chain.c @@ -173,7 +173,7 @@ ngx_darwin_sendfile_chain(ngx_connection if (file && header.nelts == 0) { - /* create the tailer iovec and coalesce the neighbouring bufs */ + /* create the trailer iovec and coalesce the neighbouring bufs */ prev = NULL; iov = NULL; diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h --- a/src/os/unix/ngx_files.h +++ b/src/os/unix/ngx_files.h @@ -159,7 +159,7 @@ ngx_int_t ngx_set_file_time(u_char *name #define ngx_is_exec(sb) (((sb)->st_mode & S_IXUSR) == S_IXUSR) #define ngx_file_access(sb) ((sb)->st_mode & 0777) #define ngx_file_size(sb) (sb)->st_size -#define ngx_file_fs_size(sb) ((sb)->st_blocks * 512) +#define ngx_file_fs_size(sb) ngx_max((sb)->st_size, (sb)->st_blocks * 512) #define ngx_file_mtime(sb) (sb)->st_mtime #define ngx_file_uniq(sb) (sb)->st_ino @@ -255,7 +255,8 @@ ngx_de_info(u_char *name, ngx_dir_t *dir #define ngx_de_access(dir) (((dir)->info.st_mode) & 0777) #define ngx_de_size(dir) (dir)->info.st_size -#define ngx_de_fs_size(dir) ((dir)->info.st_blocks * 512) +#define ngx_de_fs_size(dir) \ + ngx_max((dir)->info.st_size, (dir)->info.st_blocks * 512) #define ngx_de_mtime(dir) (dir)->info.st_mtime diff --git a/src/os/unix/ngx_freebsd_sendfile_chain.c b/src/os/unix/ngx_freebsd_sendfile_chain.c --- a/src/os/unix/ngx_freebsd_sendfile_chain.c +++ b/src/os/unix/ngx_freebsd_sendfile_chain.c @@ -178,7 +178,7 @@ ngx_freebsd_sendfile_chain(ngx_connectio if (file) { - /* create the tailer iovec and coalesce the neighbouring bufs */ + /* create the trailer iovec and coalesce the neighbouring bufs */ prev = NULL; iov = NULL; diff --git a/src/os/unix/ngx_posix_init.c b/src/os/unix/ngx_posix_init.c --- a/src/os/unix/ngx_posix_init.c +++ b/src/os/unix/ngx_posix_init.c @@ -47,7 +47,13 @@ ngx_os_init(ngx_log_t *log) for (n = ngx_pagesize; n >>= 1; ngx_pagesize_shift++) { /* void */ } +#if (NGX_HAVE_SC_NPROCESSORS_ONLN) if (ngx_ncpu == 0) { + ngx_ncpu = sysconf(_SC_NPROCESSORS_ONLN); + } +#endif + + if (ngx_ncpu < 1) { ngx_ncpu = 1; } diff --git a/src/os/unix/ngx_user.c b/src/os/unix/ngx_user.c --- a/src/os/unix/ngx_user.c +++ b/src/os/unix/ngx_user.c @@ -67,7 +67,7 @@ ngx_libc_crypt(ngx_pool_t *pool, u_char #if (NGX_THREADS && NGX_NONREENTRANT_CRYPT) - /* crypt() is a time consuming funtion, so we only try to lock */ + /* crypt() is a time consuming function, so we only try to lock */ if (ngx_mutex_trylock(ngx_crypt_mutex) != NGX_OK) { return NGX_AGAIN;