# HG changeset patch # User Igor Sysoev # Date 1198011600 -10800 # Node ID b743d290eb3bdec9f8f8ccdcaea8e899b5d781bc # Parent 3ac45897a61c30b4f89f1253a8169c0bdfb48e08 nginx 0.6.22 *) Change: now all ngx_http_perl_module methods return values copied to perl's allocated memory. *) Bugfix: if nginx was built with ngx_http_perl_module, the perl before 5.8.6 was used, and perl supported threads, then during reconfiguration the master process aborted; bug appeared in 0.5.9. Thanks to Boris Zhmurov. *) Bugfix: the ngx_http_perl_module methods may get invalid values of the regex captures. *) Bugfix: a segmentation fault occurred in worker process, if the $r->has_request_body() method was called for a request whose small request body was already received. *) Bugfix: large_client_header_buffers did not freed before going to keep-alive state. Thanks to Olexander Shtepa. *) Bugfix: the last address was missed in the $upstream_addr variable; bug appeared in 0.6.18. *) Bugfix: the "fastcgi_catch_stderr" directive did return error code; now it returns 502 code, that can be rerouted to a next server using the "fastcgi_next_upstream invalid_header" directive. *) Bugfix: a segmentation fault occurred in master process if the "fastcgi_catch_stderr" directive was used; bug appeared in 0.6.10. Thanks to Manlio Perillo. diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,39 @@ +Changes with nginx 0.6.22 19 Dec 2007 + + *) Change: now all ngx_http_perl_module methods return values copied to + perl's allocated memory. + + *) Bugfix: if nginx was built with ngx_http_perl_module, the perl + before 5.8.6 was used, and perl supported threads, then during + reconfiguration the master process aborted; bug appeared in + 0.5.9. + Thanks to Boris Zhmurov. + + *) Bugfix: the ngx_http_perl_module methods may get invalid values of + the regex captures. + + *) Bugfix: a segmentation fault occurred in worker process, if the + $r->has_request_body() method was called for a request whose small + request body was already received. + + *) Bugfix: large_client_header_buffers did not freed before going to + keep-alive state. + Thanks to Olexander Shtepa. + + *) Bugfix: the last address was missed in the $upstream_addr variable; + bug appeared in 0.6.18. + + *) Bugfix: the "fastcgi_catch_stderr" directive did return error code; + now it returns 502 code, that can be rerouted to a next server using + the "fastcgi_next_upstream invalid_header" directive. + + *) Bugfix: a segmentation fault occurred in master process if the + "fastcgi_catch_stderr" directive was used; bug appeared in + 0.6.10. + Thanks to Manlio Perillo. + + Changes with nginx 0.6.21 03 Dec 2007 *) Change: if variable values used in a "proxy_pass" directive contain diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,4 +1,39 @@ +Изменения в nginx 0.6.22 19.12.2007 + + *) Изменение: теперь все методы модуля ngx_http_perl_module возвращают + значения, скопированные в память, выделенную perl'ом. + + *) Исправление: если nginx был собран с модулем ngx_http_perl_module, + использовался perl до версии 5.8.6 и perl поддерживал потоки, то во + время переконфигурации основной процесс аварийно выходил; ошибка + появилась в 0.5.9. + Спасибо Борису Жмурову. + + *) Исправление: в методы модуля ngx_http_perl_module могли передаваться + неверные результаты выделения в регулярных выражениях. + + *) Исправление: если метод $r->has_request_body() вызывался для + запроса, у которого небольшое тело запроса было уже полностью + получено, то в рабочем процессе происходил segmentation fault. + + *) Исправление: large_client_header_buffers не освобождались перед + переходом в состояние keep-alive. + Спасибо Олександру Штепе. + + *) Исправление: в переменной $upstream_addr не записывался последний + адрес; ошибка появилась в 0.6.18. + + *) Исправление: директива fastcgi_catch_stderr не возвращала ошибку; + теперь она возвращает ошибку 502, которую можно направить на + следующий сервер с помощью "fastcgi_next_upstream invalid_header". + + *) Исправление: при использовании директивы fastcgi_catch_stderr в + основном процессе происходил segmentation fault; ошибка появилась в + 0.6.10. + Спасибо Manlio Perillo. + + Изменения в nginx 0.6.21 03.12.2007 *) Изменение: если в значениях переменных директивы proxy_pass diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -273,9 +273,11 @@ main(int argc, char *const *argv) return 1; } - /* ngx_crc32_init() requires ngx_cacheline_size set in ngx_os_init() */ + /* + * ngx_crc32_table_init() requires ngx_cacheline_size set in ngx_os_init() + */ - if (ngx_crc32_init() != NGX_OK) { + if (ngx_crc32_table_init() != NGX_OK) { return 1; } @@ -756,12 +758,6 @@ ngx_core_module_init_conf(ngx_cycle_t *c { ngx_core_conf_t *ccf = conf; -#if !(NGX_WIN32) - ngx_str_t lock_file; - struct group *grp; - struct passwd *pwd; -#endif - ngx_conf_init_value(ccf->daemon, 1); ngx_conf_init_value(ccf->master, 1); ngx_conf_init_msec_value(ccf->timer_resolution, 0); @@ -794,6 +790,8 @@ ngx_core_module_init_conf(ngx_cycle_t *c #if !(NGX_WIN32) if (ccf->user == (uid_t) NGX_CONF_UNSET_UINT && geteuid() == 0) { + struct group *grp; + struct passwd *pwd; ngx_set_errno(0); pwd = getpwnam(NGX_USER); @@ -846,6 +844,9 @@ ngx_core_module_init_conf(ngx_cycle_t *c return NGX_CONF_ERROR; } + { + ngx_str_t lock_file; + lock_file = cycle->old_cycle->lock_file; if (lock_file.len) { @@ -879,6 +880,7 @@ ngx_core_module_init_conf(ngx_cycle_t *c ccf->lock_file.len), ".accept", sizeof(".accept")); } + } #endif diff --git a/src/core/nginx.h b/src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -8,7 +8,7 @@ #define _NGINX_H_INCLUDED_ -#define NGINX_VERSION "0.6.21" +#define NGINX_VERSION "0.6.22" #define NGINX_VER "nginx/" NGINX_VERSION #define NGINX_VAR "NGINX" diff --git a/src/core/ngx_conf_file.c b/src/core/ngx_conf_file.c --- a/src/core/ngx_conf_file.c +++ b/src/core/ngx_conf_file.c @@ -934,7 +934,7 @@ ngx_conf_set_str_array_slot(ngx_conf_t * a = (ngx_array_t **) (p + cmd->offset); - if (*a == NULL) { + if (*a == NGX_CONF_UNSET_PTR) { *a = ngx_array_create(cf->pool, 4, sizeof(ngx_str_t)); if (*a == NULL) { return NGX_CONF_ERROR; diff --git a/src/core/ngx_crc32.c b/src/core/ngx_crc32.c --- a/src/core/ngx_crc32.c +++ b/src/core/ngx_crc32.c @@ -102,7 +102,7 @@ uint32_t *ngx_crc32_table_short = ngx_cr ngx_int_t -ngx_crc32_init(void) +ngx_crc32_table_init(void) { void *p; diff --git a/src/core/ngx_crc32.h b/src/core/ngx_crc32.h --- a/src/core/ngx_crc32.h +++ b/src/core/ngx_crc32.h @@ -49,7 +49,30 @@ ngx_crc32_long(u_char *p, size_t len) } -ngx_int_t ngx_crc32_init(void); +#define ngx_crc32_init(crc) \ + crc = 0xffffffff + + +static ngx_inline void +ngx_crc32_update(uint32_t *crc, u_char *p, size_t len) +{ + uint32_t c; + + c = *crc; + + while (len--) { + c = ngx_crc32_table256[(c ^ *p++) & 0xff] ^ (c >> 8); + } + + *crc = c; +} + + +#define ngx_crc32_final(crc) \ + crc ^= 0xffffffff + + +ngx_int_t ngx_crc32_table_init(void); #endif /* _NGX_CRC32_H_INCLUDED_ */ 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 @@ -42,20 +42,21 @@ static ngx_str_t error_log = ngx_null_s ngx_cycle_t * ngx_init_cycle(ngx_cycle_t *old_cycle) { - void *rv; - u_char *lock_file; - ngx_uint_t i, n; - ngx_log_t *log; - ngx_conf_t conf; - ngx_pool_t *pool; - ngx_cycle_t *cycle, **old; - ngx_shm_zone_t *shm_zone, *oshm_zone; - ngx_slab_pool_t *shpool; - ngx_list_part_t *part, *opart; - ngx_open_file_t *file; - ngx_listening_t *ls, *nls; - ngx_core_conf_t *ccf, *old_ccf; - ngx_core_module_t *module; + void *rv; + char **senv, **env; + u_char *lock_file; + ngx_uint_t i, n; + ngx_log_t *log; + ngx_conf_t conf; + ngx_pool_t *pool; + ngx_cycle_t *cycle, **old; + ngx_shm_zone_t *shm_zone, *oshm_zone; + ngx_slab_pool_t *shpool; + ngx_list_part_t *part, *opart; + ngx_open_file_t *file; + ngx_listening_t *ls, *nls; + ngx_core_conf_t *ccf, *old_ccf; + ngx_core_module_t *module; log = old_cycle->log; @@ -187,6 +188,9 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) } + senv = environ; + + ngx_memzero(&conf, sizeof(ngx_conf_t)); /* STUB: init array ? */ conf.args = ngx_array_create(pool, 10, sizeof(ngx_str_t)); @@ -694,9 +698,20 @@ old_shm_zone_done: if (ngx_process == NGX_PROCESS_MASTER || ngx_is_init_cycle(old_cycle)) { + /* + * perl_destruct() frees environ if it is not the same as it was at + * perl_construct() time. So we have saved an previous cycle + * environment before ngx_conf_parse() where it will be changed. + */ + + env = environ; + environ = senv; + ngx_destroy_pool(old_cycle->pool); cycle->old_cycle = NULL; + environ = env; + return cycle; } @@ -938,9 +953,6 @@ ngx_reopen_files(ngx_cycle_t *cycle, ngx ngx_uint_t i; ngx_list_part_t *part; ngx_open_file_t *file; -#if !(NGX_WIN32) - ngx_file_info_t fi; -#endif part = &cycle->open_files.part; file = part->elts; @@ -996,6 +1008,7 @@ ngx_reopen_files(ngx_cycle_t *cycle, ngx } #else if (user != (ngx_uid_t) NGX_CONF_UNSET_UINT) { + ngx_file_info_t fi; if (ngx_file_info((const char *) file[i].name.data, &fi) == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, diff --git a/src/core/ngx_file.c b/src/core/ngx_file.c --- a/src/core/ngx_file.c +++ b/src/core/ngx_file.c @@ -61,16 +61,19 @@ ngx_create_temp_file(ngx_file_t *file, n n = (uint32_t) ngx_next_temp_number(0); + cln = ngx_pool_cleanup_add(pool, sizeof(ngx_pool_cleanup_file_t)); + if (cln == NULL) { + return NGX_ERROR; + } + for ( ;; ) { (void) ngx_sprintf(file->name.data + path->name.len + 1 + path->len, "%010uD%Z", n); - ngx_create_hashed_filename(file, path); + ngx_create_hashed_filename(path, file->name.data, file->name.len); - cln = ngx_pool_cleanup_add(pool, sizeof(ngx_pool_cleanup_file_t)); - if (cln == NULL) { - return NGX_ERROR; - } + ngx_log_debug1(NGX_LOG_DEBUG_CORE, file->log, 0, + "hashed path: %s", file->name.data); file->fd = ngx_open_tempfile(file->name.data, persistent, access); @@ -117,31 +120,27 @@ ngx_create_temp_file(ngx_file_t *file, n void -ngx_create_hashed_filename(ngx_file_t *file, ngx_path_t *path) +ngx_create_hashed_filename(ngx_path_t *path, u_char *file, size_t len) { - size_t name, pos, level; - ngx_uint_t i; + size_t i, level; + ngx_uint_t n; - name = file->name.len; - pos = path->name.len + 1; + i = path->name.len + 1; - file->name.data[path->name.len + path->len] = '/'; + file[path->name.len + path->len] = '/'; - for (i = 0; i < 3; i++) { - level = path->level[i]; + for (n = 0; n < 3; n++) { + level = path->level[n]; if (level == 0) { break; } - name -= level; - file->name.data[pos - 1] = '/'; - ngx_memcpy(&file->name.data[pos], &file->name.data[name], level); - pos += level + 1; + len -= level; + file[i - 1] = '/'; + ngx_memcpy(&file[i], &file[len], level); + i += level + 1; } - - ngx_log_debug1(NGX_LOG_DEBUG_CORE, file->log, 0, - "hashed path: %s", file->name.data); } @@ -425,9 +424,6 @@ ngx_create_pathes(ngx_cycle_t *cycle, ng ngx_err_t err; ngx_uint_t i; ngx_path_t **path; -#if !(NGX_WIN32) - ngx_file_info_t fi; -#endif path = cycle->pathes.elts; for (i = 0; i < cycle->pathes.nelts; i++) { @@ -447,6 +443,8 @@ ngx_create_pathes(ngx_cycle_t *cycle, ng } #if !(NGX_WIN32) + { + ngx_file_info_t fi; if (ngx_file_info((const char *) path[i]->name.data, &fi) == -1) { ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, @@ -474,7 +472,7 @@ ngx_create_pathes(ngx_cycle_t *cycle, ng return NGX_ERROR; } } - + } #endif } @@ -483,6 +481,107 @@ ngx_create_pathes(ngx_cycle_t *cycle, ng ngx_int_t +ngx_create_path_and_rename_file(ngx_str_t *src, ngx_str_t *to, + ngx_uint_t access, ngx_uint_t full_path, ngx_uint_t delete, ngx_log_t *log) +{ + ngx_err_t err; + +#if !(NGX_WIN32) + + if (ngx_change_file_access(src->data, access) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_CRIT, log, ngx_errno, + ngx_change_file_access_n " \"%s\" failed", src->data); + err = 0; + goto failed; + } + +#endif + + if (ngx_rename_file(src->data, to->data) != NGX_FILE_ERROR) { + return NGX_OK; + } + + err = ngx_errno; + + if (err == NGX_ENOENT) { + + if (!full_path) { + goto failed; + } + + err = ngx_create_full_path(to->data, ngx_dir_access(access)); + + if (err) { + ngx_log_error(NGX_LOG_CRIT, log, err, + ngx_create_dir_n " \"%s\" failed", to->data); + err = 0; + goto failed; + } + + if (ngx_rename_file(src->data, to->data) != NGX_FILE_ERROR) { + return NGX_OK; + } + + err = ngx_errno; + goto failed; + } + +#if (NGX_WIN32) + + if (err == NGX_EEXIST) { + if (ngx_win32_rename_file(src, to, log) == NGX_OK) { + + if (ngx_rename_file(src->data, to->data) != NGX_FILE_ERROR) { + return NGX_OK; + } + + err = ngx_errno; + + } else { + err = 0; + } + } + +#endif + +failed: + + if (delete) { + if (ngx_delete_file(src->data) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_CRIT, log, ngx_errno, + ngx_delete_file_n " \"%s\" failed", src->data); + } + } + + if (err) { + ngx_log_error(NGX_LOG_CRIT, log, err, + ngx_rename_file_n " \"%s\" to \"%s\" failed", + src->data, to->data); + } + + return NGX_ERROR; +} + + +/* + * ctx->init_handler() - see ctx->alloc + * ctx->file_handler() - file handler + * ctx->pre_tree_handler() - handler is called before entering directory + * ctx->post_tree_handler() - handler is called after leaving directory + * ctx->spec_handler() - special (socket, FIFO, etc.) file handler + * + * ctx->data - some data structure, it may be the same on all levels, or + * reallocated if ctx->alloc is nonzero + * + * ctx->alloc - a size of data structure that is allocated at every level + * and is initilialized by ctx->init_handler() + * + * ctx->log - a log + * + * on fatal (memory) error handler must return NGX_ABORT to stop walking tree + */ + +ngx_int_t ngx_walk_tree(ngx_tree_ctx_t *ctx, ngx_str_t *tree) { void *data, *prev; diff --git a/src/core/ngx_file.h b/src/core/ngx_file.h --- a/src/core/ngx_file.h +++ b/src/core/ngx_file.h @@ -84,11 +84,13 @@ ssize_t ngx_write_chain_to_temp_file(ngx ngx_int_t ngx_create_temp_file(ngx_file_t *file, ngx_path_t *path, ngx_pool_t *pool, ngx_uint_t persistent, ngx_uint_t clean, ngx_uint_t access); -void ngx_create_hashed_filename(ngx_file_t *file, ngx_path_t *path); +void ngx_create_hashed_filename(ngx_path_t *path, u_char *file, size_t len); ngx_int_t ngx_create_path(ngx_file_t *file, ngx_path_t *path); ngx_err_t ngx_create_full_path(u_char *dir, ngx_uint_t access); ngx_int_t ngx_add_path(ngx_conf_t *cf, ngx_path_t **slot); ngx_int_t ngx_create_pathes(ngx_cycle_t *cycle, ngx_uid_t user); +ngx_int_t ngx_create_path_and_rename_file(ngx_str_t *src, ngx_str_t *to, + ngx_uint_t access, ngx_uint_t full_path, ngx_uint_t delete, ngx_log_t *log); ngx_int_t ngx_walk_tree(ngx_tree_ctx_t *ctx, ngx_str_t *tree); void ngx_init_temp_number(void); 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 @@ -53,11 +53,8 @@ ngx_open_file_cache_init(ngx_pool_t *poo return NULL; } - ngx_rbtree_sentinel_init(sentinel); - - cache->rbtree.root = sentinel; - cache->rbtree.sentinel = sentinel; - cache->rbtree.insert = ngx_open_file_cache_rbtree_insert_value; + ngx_rbtree_init(&cache->rbtree, sentinel, + ngx_open_file_cache_rbtree_insert_value); cache->current = 0; cache->max = max; 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 @@ -40,6 +40,8 @@ ngx_destroy_pool(ngx_pool_t *pool) for (c = pool->cleanup; c; c = c->next) { if (c->handler) { + ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, + "run cleanup: %p", c); c->handler(c->data); } } @@ -245,8 +247,8 @@ ngx_pool_cleanup_file(void *data) { ngx_pool_cleanup_file_t *c = data; - ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, c->log, 0, "run cleanup: %p, fd:%d", - c, c->fd); + ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, c->log, 0, "file cleanup: fd:%d", + c->fd); if (ngx_close_file(c->fd) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, @@ -262,8 +264,8 @@ ngx_pool_delete_file(void *data) ngx_err_t err; - ngx_log_debug3(NGX_LOG_DEBUG_ALLOC, c->log, 0, "run cleanup: %p, fd:%d %s", - c, c->fd, c->name); + ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, c->log, 0, "file cleanup: fd:%d %s", + c->fd, c->name); if (ngx_delete_file(c->name) == NGX_FILE_ERROR) { err = ngx_errno; diff --git a/src/core/ngx_rbtree.c b/src/core/ngx_rbtree.c --- a/src/core/ngx_rbtree.c +++ b/src/core/ngx_rbtree.c @@ -97,28 +97,20 @@ void ngx_rbtree_insert_value(ngx_rbtree_node_t *temp, ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel) { + ngx_rbtree_node_t **p; + for ( ;; ) { - if (node->key < temp->key) { - - if (temp->left == sentinel) { - temp->left = node; - break; - } - - temp = temp->left; + p = (node->key < temp->key) ? &temp->left : &temp->right; - } else { + if (*p == sentinel) { + break; + } - if (temp->right == sentinel) { - temp->right = node; - break; - } - - temp = temp->right; - } + temp = *p; } + *p = node; node->parent = temp; node->left = sentinel; node->right = sentinel; @@ -130,6 +122,8 @@ void ngx_rbtree_insert_timer_value(ngx_rbtree_node_t *temp, ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel) { + ngx_rbtree_node_t **p; + for ( ;; ) { /* @@ -139,29 +133,20 @@ ngx_rbtree_insert_timer_value(ngx_rbtree * The comparison takes into account that overflow. */ - if ((ngx_rbtree_key_int_t) node->key - (ngx_rbtree_key_int_t) temp->key - < 0) - { - /* node->key < temp->key */ + /* node->key < temp->key */ - if (temp->left == sentinel) { - temp->left = node; - break; - } + p = ((ngx_rbtree_key_int_t) node->key - (ngx_rbtree_key_int_t) temp->key + < 0) + ? &temp->left : &temp->right; - temp = temp->left; - - } else { + if (*p == sentinel) { + break; + } - if (temp->right == sentinel) { - temp->right = node; - break; - } - - temp = temp->right; - } + temp = *p; } + *p = node; node->parent = temp; node->left = sentinel; node->right = sentinel; 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 @@ -67,9 +67,9 @@ static void ngx_resolver_read_response(n static void ngx_resolver_process_response(ngx_resolver_t *r, u_char *buf, size_t n); static void ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t n, - ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan, ngx_uint_t i); + ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan, ngx_uint_t ans); static void ngx_resolver_process_ptr(ngx_resolver_t *r, u_char *buf, size_t n, - ngx_uint_t ident, ngx_uint_t code); + ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan); static ngx_resolver_node_t *ngx_resolver_lookup_name(ngx_resolver_t *r, ngx_str_t *name, uint32_t hash); static ngx_resolver_node_t *ngx_resolver_lookup_addr(ngx_resolver_t *r, @@ -884,11 +884,6 @@ ngx_resolver_process_response(ngx_resolv goto done; } - if (code == 0 && nan == 0) { - err = "no answers in DNS response"; - goto done; - } - i = sizeof(ngx_resolver_query_t); while (i < (ngx_uint_t) n) { @@ -934,13 +929,13 @@ found: case NGX_RESOLVE_A: ngx_resolver_process_a(r, buf, n, ident, code, nan, - i + sizeof(ngx_resolver_qs_t)); + i + sizeof(ngx_resolver_qs_t)); break; case NGX_RESOLVE_PTR: - ngx_resolver_process_ptr(r, buf, n, ident, code); + ngx_resolver_process_ptr(r, buf, n, ident, code, nan); break; @@ -1006,6 +1001,10 @@ ngx_resolver_process_a(ngx_resolver_t *r goto failed; } + if (code == 0 && nan == 0) { + code = 3; /* NXDOMAIN */ + } + if (code) { next = rn->waiting; rn->waiting = NULL; @@ -1204,6 +1203,8 @@ ngx_resolver_process_a(ngx_resolver_t *r ngx_log_debug1(NGX_LOG_DEBUG_CORE, r->log, 0, "resolver cname:\"%V\"", &name); + ngx_queue_remove(&rn->queue); + rn->cnlen = (u_short) name.len; rn->u.cname = name.data; rn->valid = ngx_time() + r->valid; @@ -1250,7 +1251,7 @@ failed: static void ngx_resolver_process_ptr(ngx_resolver_t *r, u_char *buf, size_t n, - ngx_uint_t ident, ngx_uint_t code) + ngx_uint_t ident, ngx_uint_t code, ngx_uint_t nan) { char *err; size_t len; @@ -1307,6 +1308,10 @@ ngx_resolver_process_ptr(ngx_resolver_t goto failed; } + if (code == 0 && nan == 0) { + code = 3; /* NXDOMAIN */ + } + if (code) { next = rn->waiting; rn->waiting = NULL; 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 @@ -816,18 +816,17 @@ ngx_hextoi(u_char *line, size_t n) } -void -ngx_md5_text(u_char *text, u_char *md5) +u_char * +ngx_hex_dump(u_char *dst, u_char *src, size_t len) { - int i; static u_char hex[] = "0123456789abcdef"; - for (i = 0; i < 16; i++) { - *text++ = hex[md5[i] >> 4]; - *text++ = hex[md5[i] & 0xf]; + while (len--) { + *dst++ = hex[*src >> 4]; + *dst++ = hex[*src++ & 0xf]; } - *text = '\0'; + return dst; } diff --git a/src/core/ngx_string.h b/src/core/ngx_string.h --- a/src/core/ngx_string.h +++ b/src/core/ngx_string.h @@ -141,7 +141,7 @@ off_t ngx_atoof(u_char *line, size_t n); time_t ngx_atotm(u_char *line, size_t n); ngx_int_t ngx_hextoi(u_char *line, size_t n); -void ngx_md5_text(u_char *text, u_char *md5); +u_char *ngx_hex_dump(u_char *dst, u_char *src, size_t len); #define ngx_base64_encoded_length(len) (((len + 2) / 3) * 4) diff --git a/src/event/modules/ngx_select_module.c b/src/event/modules/ngx_select_module.c --- a/src/event/modules/ngx_select_module.c +++ b/src/event/modules/ngx_select_module.c @@ -254,9 +254,6 @@ ngx_select_process_events(ngx_cycle_t *c ngx_event_t *ev, **queue; ngx_connection_t *c; struct timeval tv, *tp; -#if !(NGX_WIN32) - ngx_uint_t level; -#endif #if !(NGX_WIN32) @@ -348,6 +345,8 @@ ngx_select_process_events(ngx_cycle_t *c #else if (err) { + ngx_uint_t level; + if (err == NGX_EINTR) { if (ngx_event_timer_alarm) { diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -428,13 +428,9 @@ ngx_event_module_init(ngx_cycle_t *cycle void ***cf; u_char *shared; size_t size, cl; - ngx_event_conf_t *ecf; + ngx_shm_t shm; ngx_core_conf_t *ccf; - ngx_shm_t shm; -#if !(NGX_WIN32) - ngx_int_t limit; - struct rlimit rlmt; -#endif + ngx_event_conf_t *ecf; cf = ngx_get_conf(cycle->conf_ctx, ngx_events_module); @@ -456,6 +452,9 @@ ngx_event_module_init(ngx_cycle_t *cycle ngx_timer_resolution = ccf->timer_resolution; #if !(NGX_WIN32) + { + ngx_int_t limit; + struct rlimit rlmt; if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, @@ -475,7 +474,7 @@ ngx_event_module_init(ngx_cycle_t *cycle ecf->connections, limit); } } - + } #endif /* !(NGX_WIN32) */ @@ -573,13 +572,6 @@ ngx_event_process_init(ngx_cycle_t *cycl ngx_core_conf_t *ccf; ngx_event_conf_t *ecf; ngx_event_module_t *module; -#if (NGX_WIN32) - ngx_iocp_conf_t *iocpcf; -#else - struct rlimit rlmt; - struct sigaction sa; - struct itimerval itv; -#endif ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); ecf = ngx_event_get_conf(cycle->conf_ctx, ngx_event_core_module); @@ -625,6 +617,8 @@ ngx_event_process_init(ngx_cycle_t *cycl #if !(NGX_WIN32) if (ngx_timer_resolution && !(ngx_event_flags & NGX_USE_TIMER_EVENT)) { + struct sigaction sa; + struct itimerval itv; ngx_memzero(&sa, sizeof(struct sigaction)); sa.sa_handler = ngx_timer_signal_handler; @@ -648,6 +642,7 @@ ngx_event_process_init(ngx_cycle_t *cycl } if (ngx_event_flags & NGX_USE_FD_EVENT) { + struct rlimit rlmt; if (getrlimit(RLIMIT_NOFILE, &rlmt) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, @@ -774,6 +769,8 @@ ngx_event_process_init(ngx_cycle_t *cycl #if (NGX_WIN32) if (ngx_event_flags & NGX_USE_IOCP_EVENT) { + ngx_iocp_conf_t *iocpcf; + rev->handler = ngx_event_acceptex; if (ngx_add_event(rev, 0, NGX_IOCP_ACCEPT) == NGX_ERROR) { 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 @@ -1241,11 +1241,8 @@ ngx_ssl_session_cache_init(ngx_shm_zone_ return NGX_ERROR; } - ngx_rbtree_sentinel_init(sentinel); - - cache->session_rbtree->root = sentinel; - cache->session_rbtree->sentinel = sentinel; - cache->session_rbtree->insert = ngx_ssl_session_rbtree_insert_value; + ngx_rbtree_init(cache->session_rbtree, sentinel, + ngx_ssl_session_rbtree_insert_value); shm_zone->data = cache; @@ -1625,56 +1622,37 @@ static void ngx_ssl_session_rbtree_insert_value(ngx_rbtree_node_t *temp, ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel) { - ngx_ssl_sess_id_t *sess_id, *sess_id_temp; + ngx_rbtree_node_t **p; + ngx_ssl_sess_id_t *sess_id, *sess_id_temp; for ( ;; ) { if (node->key < temp->key) { - if (temp->left == sentinel) { - temp->left = node; - break; - } - - temp = temp->left; + p = &temp->left; } else if (node->key > temp->key) { - if (temp->right == sentinel) { - temp->right = node; - break; - } - - temp = temp->right; + p = &temp->right; } else { /* node->key == temp->key */ sess_id = (ngx_ssl_sess_id_t *) node; sess_id_temp = (ngx_ssl_sess_id_t *) temp; - if (ngx_memn2cmp(sess_id->id, sess_id_temp->id, - (size_t) node->data, (size_t) temp->data) - < 0) - { - if (temp->left == sentinel) { - temp->left = node; - break; - } - - temp = temp->left; - - } else { - - if (temp->right == sentinel) { - temp->right = node; - break; - } - - temp = temp->right; - } + p = (ngx_memn2cmp(sess_id->id, sess_id_temp->id, + (size_t) node->data, (size_t) temp->data) + < 0) ? &temp->left : &temp->right; } + + if (*p == sentinel) { + break; + } + + temp = *p; } + *p = node; node->parent = temp; node->left = sentinel; node->right = sentinel; diff --git a/src/event/ngx_event_timer.c b/src/event/ngx_event_timer.c --- a/src/event/ngx_event_timer.c +++ b/src/event/ngx_event_timer.c @@ -26,9 +26,8 @@ static ngx_rbtree_node_t ngx_ev ngx_int_t ngx_event_timer_init(ngx_log_t *log) { - ngx_event_timer_rbtree.root = &ngx_event_timer_sentinel; - ngx_event_timer_rbtree.sentinel = &ngx_event_timer_sentinel; - ngx_event_timer_rbtree.insert = ngx_rbtree_insert_timer_value; + ngx_rbtree_init(&ngx_event_timer_rbtree, &ngx_event_timer_sentinel, + ngx_rbtree_insert_timer_value); #if (NGX_THREADS) diff --git a/src/http/modules/ngx_http_dav_module.c b/src/http/modules/ngx_http_dav_module.c --- a/src/http/modules/ngx_http_dav_module.c +++ b/src/http/modules/ngx_http_dav_module.c @@ -295,7 +295,7 @@ ngx_http_dav_put_handler(ngx_http_reques #if (NGX_WIN32) if (err == NGX_EEXIST) { - if (ngx_win32_rename_file(temp, &path, r->pool) != NGX_ERROR) { + if (ngx_win32_rename_file(temp, &path, r->connection->log) == NGX_OK) { if (ngx_rename_file(temp->data, path.data) != NGX_FILE_ERROR) { goto ok; @@ -969,7 +969,7 @@ ngx_http_dav_delete_path(ngx_http_reques tree.alloc = 0; tree.log = r->connection->log; - /* todo: 207 */ + /* TODO: 207 */ if (ngx_walk_tree(&tree, path) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; 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 @@ -887,7 +887,7 @@ ngx_http_fastcgi_process_header(ngx_http if (f == NULL) { f = ngx_pcalloc(r->pool, sizeof(ngx_http_fastcgi_ctx_t)); if (f == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + return NGX_ERROR; } ngx_http_set_ctx(r, f, ngx_http_fastcgi_module); @@ -995,7 +995,7 @@ ngx_http_fastcgi_process_header(ngx_http for (i = 0; i < flcf->catch_stderr->nelts; i++) { if (ngx_strstr(line.data, pattern[i].data)) { - return NGX_HTTP_BAD_GATEWAY; + return NGX_HTTP_UPSTREAM_INVALID_HEADER; } } } @@ -1063,7 +1063,7 @@ ngx_http_fastcgi_process_header(ngx_http h = ngx_list_push(&u->headers_in.headers); if (h == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + return NGX_ERROR; } if (f->split_parts && f->split_parts->nelts) { @@ -1077,7 +1077,7 @@ ngx_http_fastcgi_process_header(ngx_http p = ngx_palloc(r->pool, size); if (p == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + return NGX_ERROR; } buf.pos = p; @@ -1105,7 +1105,7 @@ ngx_http_fastcgi_process_header(ngx_http h->lowcase_key = ngx_palloc(r->pool, h->key.len); if (h->lowcase_key == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + return NGX_ERROR; } } else { @@ -1117,7 +1117,7 @@ ngx_http_fastcgi_process_header(ngx_http h->key.len + 1 + h->value.len + 1 + h->key.len); if (h->key.data == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + return NGX_ERROR; } h->value.data = h->key.data + h->key.len + 1; @@ -1145,7 +1145,7 @@ ngx_http_fastcgi_process_header(ngx_http h->lowcase_key, h->key.len); if (hh && hh->handler(r, h, hh->offset) != NGX_OK) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + return NGX_ERROR; } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, @@ -1174,7 +1174,10 @@ ngx_http_fastcgi_process_header(ngx_http status = ngx_atoi(status_line->data, 3); if (status == NGX_ERROR) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "upstream sent invalid status \"%V\"", + status_line); + return NGX_HTTP_UPSTREAM_INVALID_HEADER; } u->headers_in.status_n = status; @@ -1235,7 +1238,7 @@ ngx_http_fastcgi_process_header(ngx_http f->split_parts = ngx_array_create(r->pool, 1, sizeof(ngx_http_fastcgi_split_part_t)); if (f->split_parts == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + return NGX_ERROR; } } @@ -1640,8 +1643,6 @@ ngx_http_fastcgi_create_loc_conf(ngx_con * conf->upstream.next_upstream = 0; * conf->upstream.temp_path = NULL; * conf->upstream.hide_headers_hash = { NULL, 0 }; - * conf->upstream.hide_headers = NULL; - * conf->upstream.pass_headers = NULL; * conf->upstream.schema = { 0, NULL }; * conf->upstream.uri = { 0, NULL }; * conf->upstream.location = NULL; @@ -1671,6 +1672,9 @@ ngx_http_fastcgi_create_loc_conf(ngx_con conf->upstream.pass_request_headers = NGX_CONF_UNSET; conf->upstream.pass_request_body = NGX_CONF_UNSET; + conf->upstream.hide_headers = NGX_CONF_UNSET_PTR; + conf->upstream.pass_headers = NGX_CONF_UNSET_PTR; + conf->upstream.intercept_errors = NGX_CONF_UNSET; /* "fastcgi_cyclic_temp_file" is disabled */ @@ -1691,11 +1695,8 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf u_char *p; size_t size; uintptr_t *code; - ngx_str_t *header; - ngx_uint_t i, j; - ngx_array_t hide_headers; + ngx_uint_t i; ngx_keyval_t *src; - ngx_hash_key_t *hk; ngx_hash_init_t hash; ngx_http_script_compile_t sc; ngx_http_script_copy_code_t *copy; @@ -1857,108 +1858,19 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf ngx_conf_merge_str_value(conf->index, prev->index, ""); - if (conf->upstream.hide_headers == NULL - && conf->upstream.pass_headers == NULL) - { - conf->upstream.hide_headers = prev->upstream.hide_headers; - conf->upstream.pass_headers = prev->upstream.pass_headers; - conf->upstream.hide_headers_hash = prev->upstream.hide_headers_hash; - - if (conf->upstream.hide_headers_hash.buckets) { - goto peers; - } - - } else { - if (conf->upstream.hide_headers == NULL) { - conf->upstream.hide_headers = prev->upstream.hide_headers; - } - - if (conf->upstream.pass_headers == NULL) { - conf->upstream.pass_headers = prev->upstream.pass_headers; - } - } - - if (ngx_array_init(&hide_headers, cf->temp_pool, 4, sizeof(ngx_hash_key_t)) + hash.max_size = 512; + hash.bucket_size = ngx_align(64, ngx_cacheline_size); + hash.name = "fastcgi_hide_headers_hash"; + + if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream, + &prev->upstream, + ngx_http_fastcgi_hide_headers, + &hash) != NGX_OK) { return NGX_CONF_ERROR; } - for (header = ngx_http_fastcgi_hide_headers; header->len; header++) { - hk = ngx_array_push(&hide_headers); - if (hk == NULL) { - return NGX_CONF_ERROR; - } - - hk->key = *header; - hk->key_hash = ngx_hash_key_lc(header->data, header->len); - hk->value = (void *) 1; - } - - if (conf->upstream.hide_headers) { - - header = conf->upstream.hide_headers->elts; - - for (i = 0; i < conf->upstream.hide_headers->nelts; i++) { - - hk = hide_headers.elts; - - for (j = 0; j < hide_headers.nelts; j++) { - if (ngx_strcasecmp(header[i].data, hk[j].key.data) == 0) { - goto exist; - } - } - - hk = ngx_array_push(&hide_headers); - if (hk == NULL) { - return NGX_CONF_ERROR; - } - - hk->key = header[i]; - hk->key_hash = ngx_hash_key_lc(header[i].data, header[i].len); - hk->value = (void *) 1; - - exist: - - continue; - } - } - - if (conf->upstream.pass_headers) { - - hk = hide_headers.elts; - header = conf->upstream.pass_headers->elts; - - for (i = 0; i < conf->upstream.pass_headers->nelts; i++) { - - for (j = 0; j < hide_headers.nelts; j++) { - - if (hk[j].key.data == NULL) { - continue; - } - - if (ngx_strcasecmp(header[i].data, hk[j].key.data) == 0) { - hk[j].key.data = NULL; - break; - } - } - } - } - - hash.hash = &conf->upstream.hide_headers_hash; - hash.key = ngx_hash_key_lc; - hash.max_size = 512; - hash.bucket_size = ngx_align(64, ngx_cacheline_size); - hash.name = "fastcgi_hide_headers_hash"; - hash.pool = cf->pool; - hash.temp_pool = NULL; - - if (ngx_hash_init(&hash, hide_headers.elts, hide_headers.nelts) != NGX_OK) { - return NGX_CONF_ERROR; - } - -peers: - if (conf->upstream.upstream == NULL) { conf->upstream.upstream = prev->upstream.upstream; conf->upstream.schema = prev->upstream.schema; diff --git a/src/http/modules/ngx_http_flv_module.c b/src/http/modules/ngx_http_flv_module.c --- a/src/http/modules/ngx_http_flv_module.c +++ b/src/http/modules/ngx_http_flv_module.c @@ -63,7 +63,6 @@ ngx_http_flv_handler(ngx_http_request_t u_char *p, *last; off_t start, len; size_t root; - ngx_fd_t fd; ngx_int_t rc; ngx_uint_t level, i; ngx_str_t path; @@ -149,11 +148,9 @@ ngx_http_flv_handler(ngx_http_request_t return rc; } - fd = of.fd; - if (!of.is_file) { - if (ngx_close_file(fd) == NGX_FILE_ERROR) { + if (ngx_close_file(of.fd) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, ngx_close_file_n " \"%s\" failed", path.data); } @@ -235,7 +232,7 @@ ngx_http_flv_handler(ngx_http_request_t b->last_buf = 1; b->last_in_chain = 1; - b->file->fd = fd; + b->file->fd = of.fd; b->file->name = path; b->file->log = log; 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 @@ -239,54 +239,36 @@ static void ngx_http_limit_zone_rbtree_insert_value(ngx_rbtree_node_t *temp, ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel) { - ngx_http_limit_zone_node_t *lzn, *lznt; + ngx_rbtree_node_t **p; + ngx_http_limit_zone_node_t *lzn, *lznt; for ( ;; ) { if (node->key < temp->key) { - if (temp->left == sentinel) { - temp->left = node; - break; - } - - temp = temp->left; + p = &temp->left; } else if (node->key > temp->key) { - if (temp->right == sentinel) { - temp->right = node; - break; - } - - temp = temp->right; + p = &temp->right; } else { /* node->key == temp->key */ lzn = (ngx_http_limit_zone_node_t *) &node->color; lznt = (ngx_http_limit_zone_node_t *) &temp->color; - if (ngx_memn2cmp(lzn->data, lznt->data, lzn->len, lznt->len) < 0) { - - if (temp->left == sentinel) { - temp->left = node; - break; - } - - temp = temp->left; + p = (ngx_memn2cmp(lzn->data, lznt->data, lzn->len, lznt->len) < 0) + ? &temp->left : &temp->right; + } - } else { + if (*p == sentinel) { + break; + } - if (temp->right == sentinel) { - temp->right = node; - break; - } - - temp = temp->right; - } - } + temp = *p; } + *p = node; node->parent = temp; node->left = sentinel; node->right = sentinel; @@ -362,11 +344,8 @@ ngx_http_limit_zone_init_zone(ngx_shm_zo return NGX_ERROR; } - ngx_rbtree_sentinel_init(sentinel); - - ctx->rbtree->root = sentinel; - ctx->rbtree->sentinel = sentinel; - ctx->rbtree->insert = ngx_http_limit_zone_rbtree_insert_value; + ngx_rbtree_init(ctx->rbtree, sentinel, + ngx_http_limit_zone_rbtree_insert_value); return NGX_OK; } 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 @@ -959,7 +959,7 @@ ngx_http_proxy_process_status_line(ngx_h ctx = ngx_http_get_module_ctx(r, ngx_http_proxy_module); if (ctx == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + return NGX_ERROR; } rc = ngx_http_proxy_parse_status_line(r, ctx); @@ -994,7 +994,7 @@ ngx_http_proxy_process_status_line(ngx_h u->headers_in.status_line.data = ngx_palloc(r->pool, u->headers_in.status_line.len); if (u->headers_in.status_line.data == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + return NGX_ERROR; } ngx_memcpy(u->headers_in.status_line.data, ctx->status_start, @@ -1239,7 +1239,7 @@ ngx_http_proxy_process_header(ngx_http_r h = ngx_list_push(&r->upstream->headers_in.headers); if (h == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + return NGX_ERROR; } h->hash = r->header_hash; @@ -1250,7 +1250,7 @@ ngx_http_proxy_process_header(ngx_http_r h->key.data = ngx_palloc(r->pool, h->key.len + 1 + h->value.len + 1 + h->key.len); if (h->key.data == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + return NGX_ERROR; } h->value.data = h->key.data + h->key.len + 1; @@ -1272,7 +1272,7 @@ ngx_http_proxy_process_header(ngx_http_r h->lowcase_key, h->key.len); if (hh && hh->handler(r, h, hh->offset) != NGX_OK) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + return NGX_ERROR; } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, @@ -1297,7 +1297,7 @@ ngx_http_proxy_process_header(ngx_http_r if (r->upstream->headers_in.server == NULL) { h = ngx_list_push(&r->upstream->headers_in.headers); if (h == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + return NGX_ERROR; } h->hash = ngx_hash(ngx_hash(ngx_hash(ngx_hash( @@ -1313,7 +1313,7 @@ ngx_http_proxy_process_header(ngx_http_r if (r->upstream->headers_in.date == NULL) { h = ngx_list_push(&r->upstream->headers_in.headers); if (h == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + return NGX_ERROR; } h->hash = ngx_hash(ngx_hash(ngx_hash('d', 'a'), 't'), 'e'); @@ -1634,8 +1634,6 @@ ngx_http_proxy_create_loc_conf(ngx_conf_ * conf->upstream.next_upstream = 0; * conf->upstream.temp_path = NULL; * conf->upstream.hide_headers_hash = { NULL, 0 }; - * conf->upstream.hide_headers = NULL; - * conf->upstream.pass_headers = NULL; * conf->upstream.schema = { 0, NULL }; * conf->upstream.uri = { 0, NULL }; * conf->upstream.location = NULL; @@ -1672,6 +1670,9 @@ ngx_http_proxy_create_loc_conf(ngx_conf_ conf->upstream.pass_request_headers = NGX_CONF_UNSET; conf->upstream.pass_request_body = NGX_CONF_UNSET; + conf->upstream.hide_headers = NGX_CONF_UNSET_PTR; + conf->upstream.pass_headers = NGX_CONF_UNSET_PTR; + conf->upstream.intercept_errors = NGX_CONF_UNSET; /* "proxy_cyclic_temp_file" is disabled */ @@ -1696,9 +1697,7 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t u_char *p; size_t size; uintptr_t *code; - ngx_str_t *header; - ngx_uint_t i, j; - ngx_array_t hide_headers; + ngx_uint_t i; ngx_keyval_t *src, *s, *h; ngx_hash_key_t *hk; ngx_hash_init_t hash; @@ -1913,107 +1912,18 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t conf->headers_hash_bucket_size = ngx_align(conf->headers_hash_bucket_size, ngx_cacheline_size); - if (conf->upstream.hide_headers == NULL - && conf->upstream.pass_headers == NULL) - { - conf->upstream.hide_headers = prev->upstream.hide_headers; - conf->upstream.pass_headers = prev->upstream.pass_headers; - conf->upstream.hide_headers_hash = prev->upstream.hide_headers_hash; - - if (conf->upstream.hide_headers_hash.buckets) { - goto peers; - } - - } else { - if (conf->upstream.hide_headers == NULL) { - conf->upstream.hide_headers = prev->upstream.hide_headers; - } - - if (conf->upstream.pass_headers == NULL) { - conf->upstream.pass_headers = prev->upstream.pass_headers; - } - } - - if (ngx_array_init(&hide_headers, cf->temp_pool, 4, sizeof(ngx_hash_key_t)) + hash.max_size = conf->headers_hash_max_size; + hash.bucket_size = conf->headers_hash_bucket_size; + hash.name = "proxy_headers_hash"; + + if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream, + &prev->upstream, + ngx_http_proxy_hide_headers, &hash) != NGX_OK) { return NGX_CONF_ERROR; } - for (header = ngx_http_proxy_hide_headers; header->len; header++) { - hk = ngx_array_push(&hide_headers); - if (hk == NULL) { - return NGX_CONF_ERROR; - } - - hk->key = *header; - hk->key_hash = ngx_hash_key_lc(header->data, header->len); - hk->value = (void *) 1; - } - - if (conf->upstream.hide_headers) { - - header = conf->upstream.hide_headers->elts; - - for (i = 0; i < conf->upstream.hide_headers->nelts; i++) { - - hk = hide_headers.elts; - - for (j = 0; j < hide_headers.nelts; j++) { - if (ngx_strcasecmp(header[i].data, hk[j].key.data) == 0) { - goto exist; - } - } - - hk = ngx_array_push(&hide_headers); - if (hk == NULL) { - return NGX_CONF_ERROR; - } - - hk->key = header[i]; - hk->key_hash = ngx_hash_key_lc(header[i].data, header[i].len); - hk->value = (void *) 1; - - exist: - - continue; - } - } - - if (conf->upstream.pass_headers) { - - hk = hide_headers.elts; - header = conf->upstream.pass_headers->elts; - - for (i = 0; i < conf->upstream.pass_headers->nelts; i++) { - for (j = 0; j < hide_headers.nelts; j++) { - - if (hk[j].key.data == NULL) { - continue; - } - - if (ngx_strcasecmp(header[i].data, hk[j].key.data) == 0) { - hk[j].key.data = NULL; - break; - } - } - } - } - - hash.hash = &conf->upstream.hide_headers_hash; - hash.key = ngx_hash_key_lc; - hash.max_size = conf->headers_hash_max_size; - hash.bucket_size = conf->headers_hash_bucket_size; - hash.name = "proxy_headers_hash"; - hash.pool = cf->pool; - hash.temp_pool = NULL; - - if (ngx_hash_init(&hash, hide_headers.elts, hide_headers.nelts) != NGX_OK) { - return NGX_CONF_ERROR; - } - -peers: - if (conf->upstream.upstream == NULL) { conf->upstream.upstream = prev->upstream.upstream; diff --git a/src/http/modules/ngx_http_referer_module.c b/src/http/modules/ngx_http_referer_module.c --- a/src/http/modules/ngx_http_referer_module.c +++ b/src/http/modules/ngx_http_referer_module.c @@ -106,11 +106,6 @@ ngx_http_referer_variable(ngx_http_reque ngx_uint_t i, key; ngx_http_referer_conf_t *rlcf; u_char buf[256]; -#if (NGX_PCRE) - ngx_int_t n; - ngx_str_t referer; - ngx_http_referer_regex_t *regex; -#endif rlcf = ngx_http_get_module_loc_conf(r, ngx_http_referer_module); @@ -173,6 +168,9 @@ ngx_http_referer_variable(ngx_http_reque #if (NGX_PCRE) if (rlcf->regex) { + ngx_int_t n; + ngx_str_t referer; + ngx_http_referer_regex_t *regex; referer.len = len - 7; referer.data = ref; diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c --- a/src/http/modules/ngx_http_ssi_filter_module.c +++ b/src/http/modules/ngx_http_ssi_filter_module.c @@ -2373,11 +2373,6 @@ ngx_http_ssi_if(ngx_http_request_t *r, n ngx_str_t *expr, left, right; ngx_int_t rc; ngx_uint_t negative, noregex, flags; -#if (NGX_PCRE) - ngx_str_t err; - ngx_regex_t *regex; - u_char errstr[NGX_MAX_CONF_ERRSTR]; -#endif if (ctx->command.len == 2) { if (ctx->conditional) { @@ -2511,6 +2506,10 @@ ngx_http_ssi_if(ngx_http_request_t *r, n } else { #if (NGX_PCRE) + ngx_str_t err; + ngx_regex_t *regex; + u_char errstr[NGX_MAX_CONF_ERRSTR]; + err.len = NGX_MAX_CONF_ERRSTR; err.data = errstr; diff --git a/src/http/modules/ngx_http_static_module.c b/src/http/modules/ngx_http_static_module.c --- a/src/http/modules/ngx_http_static_module.c +++ b/src/http/modules/ngx_http_static_module.c @@ -49,7 +49,6 @@ ngx_http_static_handler(ngx_http_request { u_char *last, *location; size_t root; - ngx_fd_t fd; ngx_str_t path; ngx_int_t rc; ngx_uint_t level; @@ -140,9 +139,7 @@ ngx_http_static_handler(ngx_http_request return rc; } - fd = of.fd; - - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, "http static fd: %d", fd); + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, "http static fd: %d", of.fd); if (of.is_dir) { @@ -230,7 +227,7 @@ ngx_http_static_handler(ngx_http_request b->last_buf = (r == r->main) ? 1: 0; b->last_in_chain = 1; - b->file->fd = fd; + b->file->fd = of.fd; b->file->name = path; b->file->log = log; 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.6.21'; +our $VERSION = '0.6.22'; require XSLoader; XSLoader::load('nginx', $VERSION); diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs --- a/src/http/modules/perl/nginx.xs +++ b/src/http/modules/perl/nginx.xs @@ -13,19 +13,16 @@ #include "XSUB.h" + #define ngx_http_perl_set_request(r) \ r = INT2PTR(ngx_http_request_t *, SvIV((SV *) SvRV(ST(0)))) -#define ngx_http_perl_set_targ(p, len, z) \ +#define ngx_http_perl_set_targ(p, len) \ \ - sv_upgrade(TARG, SVt_PV); \ + SvUPGRADE(TARG, SVt_PV); \ SvPOK_on(TARG); \ - SvPV_set(TARG, (char *) p); \ - SvLEN_set(TARG, len + z); \ - SvCUR_set(TARG, len); \ - SvFAKE_on(TARG); \ - SvREADONLY_on(TARG); \ + sv_setpvn(TARG, (char *) p, len) static ngx_int_t @@ -42,8 +39,12 @@ ngx_http_perl_sv2str(pTHX_ ngx_http_requ s->len = len; - if (SvREADONLY(sv)) { + if (SvREADONLY(sv) && SvPOK(sv)) { s->data = p; + + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "perl sv2str: %08XD \"%V\"", sv->sv_flags, s); + return NGX_OK; } @@ -54,6 +55,9 @@ ngx_http_perl_sv2str(pTHX_ ngx_http_requ ngx_memcpy(s->data, p, len); + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "perl sv2str: %08XD \"%V\"", sv->sv_flags, s); + return NGX_OK; } @@ -165,7 +169,7 @@ uri(r) ngx_http_request_t *r; ngx_http_perl_set_request(r); - ngx_http_perl_set_targ(r->uri.data, r->uri.len, 0); + ngx_http_perl_set_targ(r->uri.data, r->uri.len); ST(0) = TARG; @@ -178,7 +182,7 @@ args(r) ngx_http_request_t *r; ngx_http_perl_set_request(r); - ngx_http_perl_set_targ(r->args.data, r->args.len, 0); + ngx_http_perl_set_targ(r->args.data, r->args.len); ST(0) = TARG; @@ -191,7 +195,7 @@ request_method(r) ngx_http_request_t *r; ngx_http_perl_set_request(r); - ngx_http_perl_set_targ(r->method_name.data, r->method_name.len, 0); + ngx_http_perl_set_targ(r->method_name.data, r->method_name.len); ST(0) = TARG; @@ -205,7 +209,7 @@ remote_addr(r) ngx_http_perl_set_request(r); ngx_http_perl_set_targ(r->connection->addr_text.data, - r->connection->addr_text.len, 1); + r->connection->addr_text.len); ST(0) = TARG; @@ -259,7 +263,7 @@ header_in(r, key) ph = (ngx_table_elt_t **) ((char *) &r->headers_in + hh->offset); if (*ph) { - ngx_http_perl_set_targ((*ph)->value.data, (*ph)->value.len, 0); + ngx_http_perl_set_targ((*ph)->value.data, (*ph)->value.len); goto done; } @@ -278,7 +282,7 @@ header_in(r, key) ph = r->headers_in.cookies.elts; if (n == 1) { - ngx_http_perl_set_targ((*ph)->value.data, (*ph)->value.len, 0); + ngx_http_perl_set_targ((*ph)->value.data, (*ph)->value.len); goto done; } @@ -306,7 +310,7 @@ header_in(r, key) *p++ = ';'; *p++ = ' '; } - ngx_http_perl_set_targ(cookie, size, 0); + ngx_http_perl_set_targ(cookie, size); goto done; } @@ -334,7 +338,7 @@ header_in(r, key) continue; } - ngx_http_perl_set_targ(h[i].value.data, h[i].value.len, 0); + ngx_http_perl_set_targ(h[i].value.data, h[i].value.len); goto done; } @@ -402,7 +406,7 @@ request_body(r) XSRETURN_UNDEF; } - ngx_http_perl_set_targ(r->request_body->bufs->buf->pos, len, 0); + ngx_http_perl_set_targ(r->request_body->bufs->buf->pos, len); ST(0) = TARG; @@ -421,7 +425,7 @@ request_body_file(r) } ngx_http_perl_set_targ(r->request_body->temp_file->file.name.data, - r->request_body->temp_file->file.name.len, 1); + r->request_body->temp_file->file.name.len); ST(0) = TARG; @@ -500,7 +504,7 @@ filename(r) done: - ngx_http_perl_set_targ(ctx->filename.data, ctx->filename.len, 1); + ngx_http_perl_set_targ(ctx->filename.data, ctx->filename.len); ST(0) = TARG; @@ -532,7 +536,7 @@ print(r, ...) sv = SvRV(sv); } - if (SvREADONLY(sv)) { + if (SvREADONLY(sv) && SvPOK(sv)) { p = (u_char *) SvPV(sv, len); @@ -778,7 +782,7 @@ unescape(r, text, type = 0) ngx_unescape_uri(&dst, &src, len, (ngx_uint_t) type); *dst = '\0'; - ngx_http_perl_set_targ(p, dst - p, 1); + ngx_http_perl_set_targ(p, dst - p); ST(0) = TARG; @@ -875,7 +879,7 @@ variable(r, name, value = NULL) XSRETURN_UNDEF; } - ngx_http_perl_set_targ(v[i].value.data, v[i].value.len, 0); + ngx_http_perl_set_targ(v[i].value.data, v[i].value.len); goto done; } @@ -919,7 +923,7 @@ variable(r, name, value = NULL) XSRETURN_UNDEF; } - ngx_http_perl_set_targ(vv->data, vv->len, 0); + ngx_http_perl_set_targ(vv->data, vv->len); done: diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c --- a/src/http/modules/perl/ngx_http_perl_module.c +++ b/src/http/modules/perl/ngx_http_perl_module.c @@ -230,6 +230,10 @@ ngx_http_perl_handle_request(ngx_http_re } + if (rc == NGX_DONE) { + return; + } + if (rc > 600) { rc = NGX_OK; } @@ -627,12 +631,13 @@ static ngx_int_t ngx_http_perl_call_handler(pTHX_ ngx_http_request_t *r, HV *nginx, SV *sub, ngx_str_t **args, ngx_str_t *handler, ngx_str_t *rv) { - SV *sv; - int n, status; - char *line; - STRLEN len, n_a; - ngx_str_t err; - ngx_uint_t i; + SV *sv; + int n, status; + char *line; + STRLEN len, n_a; + ngx_str_t err; + ngx_uint_t i; + ngx_connection_t *c; dSP; @@ -658,15 +663,26 @@ ngx_http_perl_call_handler(pTHX_ ngx_htt PUTBACK; + c = r->connection; + n = call_sv(sub, G_EVAL); SPAGAIN; + if (c->destroyed) { + PUTBACK; + + FREETMPS; + LEAVE; + + return NGX_DONE; + } + if (n) { if (rv == NULL) { status = POPi; - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "call_sv: %d", status); } else { @@ -697,9 +713,8 @@ ngx_http_perl_call_handler(pTHX_ ngx_htt } err.len = len + 1; - ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, - "call_sv(\"%V\") failed: \"%V\"", - handler, &err); + ngx_log_error(NGX_LOG_ERR, c->log, 0, + "call_sv(\"%V\") failed: \"%V\"", handler, &err); if (rv) { return NGX_ERROR; @@ -709,7 +724,7 @@ ngx_http_perl_call_handler(pTHX_ ngx_htt } if (n != 1) { - ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, + ngx_log_error(NGX_LOG_ALERT, c->log, 0, "call_sv(\"%V\") returned %d results", handler, n); status = NGX_OK; } diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c --- a/src/http/ngx_http.c +++ b/src/http/ngx_http.c @@ -101,9 +101,6 @@ ngx_http_block(ngx_conf_t *cf, ngx_comma #if (NGX_PCRE) ngx_uint_t regex; #endif -#if (NGX_WIN32) - ngx_iocp_conf_t *iocpcf; -#endif /* the main http context */ @@ -821,10 +818,14 @@ ngx_http_block(ngx_conf_t *cf, ngx_comma ls->log.handler = ngx_accept_log_error; #if (NGX_WIN32) + { + ngx_iocp_conf_t *iocpcf; + iocpcf = ngx_event_get_conf(cf->cycle->conf_ctx, ngx_iocp_module); if (iocpcf->acceptex_read) { ls->post_accept_buffer_size = cscf->client_header_buffer_size; } + } #endif ls->backlog = in_addr[a].listen_conf->backlog; 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 @@ -1803,10 +1803,6 @@ ngx_http_core_location(ngx_conf_t *cf, n ngx_http_conf_ctx_t *ctx, *pctx; ngx_http_core_srv_conf_t *cscf; ngx_http_core_loc_conf_t *clcf, *pclcf, **clcfp; -#if (NGX_PCRE) - ngx_str_t err; - u_char errstr[NGX_MAX_CONF_ERRSTR]; -#endif ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)); if (ctx == NULL) { @@ -1861,6 +1857,9 @@ ngx_http_core_location(ngx_conf_t *cf, n && value[1].data[1] == '*')) { #if (NGX_PCRE) + ngx_str_t err; + u_char errstr[NGX_MAX_CONF_ERRSTR]; + err.len = NGX_MAX_CONF_ERRSTR; err.data = errstr; @@ -2803,10 +2802,6 @@ ngx_http_core_server_name(ngx_conf_t *cf ngx_str_t *value, name; ngx_uint_t i; ngx_http_server_name_t *sn; -#if (NGX_PCRE) - ngx_str_t err; - u_char errstr[NGX_MAX_CONF_ERRSTR]; -#endif value = cf->args->elts; @@ -2882,6 +2877,10 @@ ngx_http_core_server_name(ngx_conf_t *cf } #if (NGX_PCRE) + { + ngx_str_t err; + u_char errstr[NGX_MAX_CONF_ERRSTR]; + err.len = NGX_MAX_CONF_ERRSTR; err.data = errstr; @@ -2898,7 +2897,7 @@ ngx_http_core_server_name(ngx_conf_t *cf sn->name.len = value[i].len; sn->name.data = value[i].data; - + } #else ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "the using of the regex \"%V\" " diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c --- a/src/http/ngx_http_parse.c +++ b/src/http/ngx_http_parse.c @@ -1039,7 +1039,7 @@ ngx_http_parse_complex_uri(ngx_http_requ break; #endif case '/': - if (merge_slashes) { + if (!merge_slashes) { *u++ = ch; } break; 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 @@ -232,9 +232,6 @@ ngx_http_init_request(ngx_event_t *rev) ngx_http_core_srv_conf_t *cscf; ngx_http_core_loc_conf_t *clcf; ngx_http_core_main_conf_t *cmcf; -#if (NGX_HTTP_SSL) - ngx_http_ssl_srv_conf_t *sscf; -#endif #if (NGX_STAT_STUB) ngx_atomic_fetch_add(ngx_stat_reading, -1); @@ -354,6 +351,9 @@ ngx_http_init_request(ngx_event_t *rev) #if (NGX_HTTP_SSL) + { + ngx_http_ssl_srv_conf_t *sscf; + sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); if (sscf->enable) { @@ -370,6 +370,7 @@ ngx_http_init_request(ngx_event_t *rev) r->main_filter_need_in_memory = 1; } + } #endif @@ -1398,11 +1399,7 @@ ngx_http_process_request_header(ngx_http static void ngx_http_process_request(ngx_http_request_t *r) { - ngx_connection_t *c; -#if (NGX_HTTP_SSL) - long rc; - ngx_http_ssl_srv_conf_t *sscf; -#endif + ngx_connection_t *c; c = r->connection; @@ -1416,6 +1413,9 @@ ngx_http_process_request(ngx_http_reques #if (NGX_HTTP_SSL) if (c->ssl) { + long rc; + ngx_http_ssl_srv_conf_t *sscf; + sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); if (sscf->verify) { @@ -1469,12 +1469,6 @@ ngx_http_find_virtual_server(ngx_http_re { ngx_http_core_loc_conf_t *clcf; ngx_http_core_srv_conf_t *cscf; -#if (NGX_PCRE) - ngx_int_t n; - ngx_uint_t i; - ngx_str_t name; - ngx_http_server_name_t *sn; -#endif cscf = ngx_hash_find_combined(&r->virtual_names->names, hash, host, len); @@ -1485,6 +1479,10 @@ ngx_http_find_virtual_server(ngx_http_re #if (NGX_PCRE) if (r->virtual_names->nregex) { + ngx_int_t n; + ngx_uint_t i; + ngx_str_t name; + ngx_http_server_name_t *sn; name.len = len; name.data = host; @@ -2095,7 +2093,7 @@ ngx_http_set_keepalive(ngx_http_request_ if (hc->free) { for (i = 0; i < hc->nfree; i++) { - ngx_pfree(c->pool, hc->free[i]); + ngx_pfree(c->pool, hc->free[i]->start); hc->free[i] = NULL; } @@ -2107,7 +2105,7 @@ ngx_http_set_keepalive(ngx_http_request_ if (hc->busy) { for (i = 0; i < hc->nbusy; i++) { - ngx_pfree(c->pool, hc->busy[i]); + ngx_pfree(c->pool, hc->busy[i]->start); hc->busy[i] = NULL; } 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 @@ -381,7 +381,7 @@ ngx_http_upstream_init(ngx_http_request_ } else { - host = &r->upstream->resolved->host; + host = &u->resolved->host; umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); @@ -665,7 +665,6 @@ ngx_http_upstream_connect(ngx_http_reque tp = ngx_timeofday(); u->state->response_sec = tp->sec; u->state->response_msec = tp->msec; - u->state->peer = u->peer.name; rc = ngx_event_connect_peer(&u->peer); @@ -678,6 +677,8 @@ ngx_http_upstream_connect(ngx_http_reque return; } + u->state->peer = u->peer.name; + if (rc == NGX_BUSY) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no live upstreams"); ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_NOLIVE); @@ -840,10 +841,9 @@ ngx_http_upstream_reinit(ngx_http_reques return NGX_ERROR; } - ngx_memzero(&r->upstream->headers_in, - sizeof(ngx_http_upstream_headers_in_t)); - - if (ngx_list_init(&r->upstream->headers_in.headers, r->pool, 8, + ngx_memzero(&u->headers_in, sizeof(ngx_http_upstream_headers_in_t)); + + if (ngx_list_init(&u->headers_in.headers, r->pool, 8, sizeof(ngx_table_elt_t)) != NGX_OK) { @@ -1078,7 +1078,7 @@ ngx_http_upstream_process_header(ngx_eve u->buffer.tag = u->output.tag; - if (ngx_list_init(&r->upstream->headers_in.headers, r->pool, 8, + if (ngx_list_init(&u->headers_in.headers, r->pool, 8, sizeof(ngx_table_elt_t)) != NGX_OK) { @@ -1158,7 +1158,7 @@ ngx_http_upstream_process_header(ngx_eve return; } - if (rc == NGX_ERROR || rc == NGX_HTTP_INTERNAL_SERVER_ERROR) { + if (rc == NGX_ERROR) { ngx_http_upstream_finalize_request(r, u, NGX_HTTP_INTERNAL_SERVER_ERROR); return; @@ -1247,11 +1247,11 @@ ngx_http_upstream_process_header(ngx_eve umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); - if (r->upstream->headers_in.x_accel_redirect) { + if (u->headers_in.x_accel_redirect) { ngx_http_upstream_finalize_request(r, u, NGX_DECLINED); - part = &r->upstream->headers_in.headers.part; + part = &u->headers_in.headers.part; h = part->elts; for (i = 0; /* void */; i++) { @@ -1278,7 +1278,7 @@ ngx_http_upstream_process_header(ngx_eve } } - uri = &r->upstream->headers_in.x_accel_redirect->value; + uri = &u->headers_in.x_accel_redirect->value; args.len = 0; args.data = NULL; flags = 0; @@ -1300,7 +1300,7 @@ ngx_http_upstream_process_header(ngx_eve return; } - part = &r->upstream->headers_in.headers.part; + part = &u->headers_in.headers.part; h = part->elts; for (i = 0; /* void */; i++) { @@ -2164,9 +2164,9 @@ ngx_http_upstream_store(ngx_http_request #endif - if (r->upstream->headers_in.last_modified) { - - last_modified = &r->upstream->headers_in.last_modified->value; + if (u->headers_in.last_modified) { + + last_modified = &u->headers_in.last_modified->value; lm = ngx_http_parse_time(last_modified->data, last_modified->len); @@ -2224,7 +2224,7 @@ ngx_http_upstream_store(ngx_http_request #if (NGX_WIN32) if (err == NGX_EEXIST) { - if (ngx_win32_rename_file(temp, &path, r->pool) != NGX_ERROR) { + if (ngx_win32_rename_file(temp, &path, r->connection->log) == NGX_OK) { if (ngx_rename_file(temp->data, path.data) != NGX_FILE_ERROR) { return; @@ -2372,14 +2372,18 @@ ngx_http_upstream_cleanup(void *data) { ngx_http_request_t *r = data; + ngx_http_upstream_t *u; + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "cleanup http upstream request: \"%V\"", &r->uri); - if (r->upstream->resolved && r->upstream->resolved->ctx) { - ngx_resolve_name_done(r->upstream->resolved->ctx); + u = r->upstream; + + if (u->resolved && u->resolved->ctx) { + ngx_resolve_name_done(u->resolved->ctx); } - ngx_http_upstream_finalize_request(r, r->upstream, NGX_DONE); + ngx_http_upstream_finalize_request(r, u, NGX_DONE); } @@ -3408,6 +3412,113 @@ ngx_http_upstream_add(ngx_conf_t *cf, ng } +ngx_int_t +ngx_http_upstream_hide_headers_hash(ngx_conf_t *cf, + ngx_http_upstream_conf_t *conf, ngx_http_upstream_conf_t *prev, + ngx_str_t *default_hide_headers, ngx_hash_init_t *hash) +{ + ngx_str_t *h; + ngx_uint_t i, j; + ngx_array_t hide_headers; + ngx_hash_key_t *hk; + + if (conf->hide_headers == NGX_CONF_UNSET_PTR + && conf->pass_headers == NGX_CONF_UNSET_PTR) + { + conf->hide_headers_hash = prev->hide_headers_hash; + + if (conf->hide_headers_hash.buckets) { + return NGX_OK; + } + + conf->hide_headers = prev->hide_headers; + conf->pass_headers = prev->pass_headers; + + } else { + if (conf->hide_headers == NGX_CONF_UNSET_PTR) { + conf->hide_headers = prev->hide_headers; + } + + if (conf->pass_headers == NGX_CONF_UNSET_PTR) { + conf->pass_headers = prev->pass_headers; + } + } + + if (ngx_array_init(&hide_headers, cf->temp_pool, 4, sizeof(ngx_hash_key_t)) + != NGX_OK) + { + return NGX_ERROR; + } + + for (h = default_hide_headers; h->len; h++) { + hk = ngx_array_push(&hide_headers); + if (hk == NULL) { + return NGX_ERROR; + } + + hk->key = *h; + hk->key_hash = ngx_hash_key_lc(h->data, h->len); + hk->value = (void *) 1; + } + + if (conf->hide_headers != NGX_CONF_UNSET_PTR) { + + h = conf->hide_headers->elts; + + for (i = 0; i < conf->hide_headers->nelts; i++) { + + hk = hide_headers.elts; + + for (j = 0; j < hide_headers.nelts; j++) { + if (ngx_strcasecmp(h[i].data, hk[j].key.data) == 0) { + goto exist; + } + } + + hk = ngx_array_push(&hide_headers); + if (hk == NULL) { + return NGX_ERROR; + } + + hk->key = h[i]; + hk->key_hash = ngx_hash_key_lc(h[i].data, h[i].len); + hk->value = (void *) 1; + + exist: + + continue; + } + } + + if (conf->pass_headers != NGX_CONF_UNSET_PTR) { + + h = conf->pass_headers->elts; + hk = hide_headers.elts; + + for (i = 0; i < conf->pass_headers->nelts; i++) { + for (j = 0; j < hide_headers.nelts; j++) { + + if (hk[j].key.data == NULL) { + continue; + } + + if (ngx_strcasecmp(h[i].data, hk[j].key.data) == 0) { + hk[j].key.data = NULL; + break; + } + } + } + } + + hash->hash = &conf->hide_headers_hash; + hash->key = ngx_hash_key_lc; + hash->pool = cf->pool; + hash->temp_pool = NULL; + + return ngx_hash_init(hash, hide_headers.elts, hide_headers.nelts); +} + + static void * ngx_http_upstream_create_main_conf(ngx_conf_t *cf) { 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 @@ -269,6 +269,9 @@ ngx_int_t ngx_http_upstream_header_varia void ngx_http_upstream_init(ngx_http_request_t *r); ngx_http_upstream_srv_conf_t *ngx_http_upstream_add(ngx_conf_t *cf, ngx_url_t *u, ngx_uint_t flags); +ngx_int_t ngx_http_upstream_hide_headers_hash(ngx_conf_t *cf, + ngx_http_upstream_conf_t *conf, ngx_http_upstream_conf_t *prev, + ngx_str_t *default_hide_headers, ngx_hash_init_t *hash); #define ngx_http_conf_upstream_srv_conf(uscf, module) \ diff --git a/src/mail/ngx_mail_handler.c b/src/mail/ngx_mail_handler.c --- a/src/mail/ngx_mail_handler.c +++ b/src/mail/ngx_mail_handler.c @@ -29,10 +29,6 @@ ngx_mail_init_connection(ngx_connection_ ngx_mail_in_port_t *imip; ngx_mail_in_addr_t *imia; ngx_mail_session_t *s; -#if (NGX_MAIL_SSL) - ngx_mail_ssl_conf_t *sslcf; -#endif - /* find the server configuration for the address:port */ @@ -116,6 +112,8 @@ ngx_mail_init_connection(ngx_connection_ c->log_error = NGX_ERROR_INFO; #if (NGX_MAIL_SSL) + { + ngx_mail_ssl_conf_t *sslcf; sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module); @@ -123,7 +121,7 @@ ngx_mail_init_connection(ngx_connection_ ngx_mail_ssl_init_connection(&sslcf->ssl, c); return; } - + } #endif ngx_mail_init_session(c); diff --git a/src/mail/ngx_mail_imap_handler.c b/src/mail/ngx_mail_imap_handler.c --- a/src/mail/ngx_mail_imap_handler.c +++ b/src/mail/ngx_mail_imap_handler.c @@ -302,7 +302,7 @@ ngx_mail_imap_auth_state(ngx_event_t *re static ngx_int_t ngx_mail_imap_login(ngx_mail_session_t *s, ngx_connection_t *c) { - ngx_str_t *arg; + ngx_str_t *arg; #if (NGX_MAIL_SSL) if (ngx_mail_starttls_only(s, c)) { @@ -410,15 +410,14 @@ static ngx_int_t ngx_mail_imap_capability(ngx_mail_session_t *s, ngx_connection_t *c) { ngx_mail_imap_srv_conf_t *iscf; -#if (NGX_MAIL_SSL) - ngx_mail_ssl_conf_t *sslcf; -#endif iscf = ngx_mail_get_module_srv_conf(s, ngx_mail_imap_module); #if (NGX_MAIL_SSL) if (c->ssl == NULL) { + ngx_mail_ssl_conf_t *sslcf; + sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module); if (sslcf->starttls == NGX_MAIL_STARTTLS_ON) { 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 @@ -283,7 +283,7 @@ ngx_mail_pop3_auth_state(ngx_event_t *re static ngx_int_t ngx_mail_pop3_user(ngx_mail_session_t *s, ngx_connection_t *c) { - ngx_str_t *arg; + ngx_str_t *arg; #if (NGX_MAIL_SSL) if (ngx_mail_starttls_only(s, c)) { @@ -344,15 +344,14 @@ static ngx_int_t ngx_mail_pop3_capa(ngx_mail_session_t *s, ngx_connection_t *c, ngx_int_t stls) { ngx_mail_pop3_srv_conf_t *pscf; -#if (NGX_MAIL_SSL) - ngx_mail_ssl_conf_t *sslcf; -#endif pscf = ngx_mail_get_module_srv_conf(s, ngx_mail_pop3_module); #if (NGX_MAIL_SSL) if (stls && c->ssl == NULL) { + ngx_mail_ssl_conf_t *sslcf; + sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module); if (sslcf->starttls == NGX_MAIL_STARTTLS_ON) { diff --git a/src/mail/ngx_mail_smtp_handler.c b/src/mail/ngx_mail_smtp_handler.c --- a/src/mail/ngx_mail_smtp_handler.c +++ b/src/mail/ngx_mail_smtp_handler.c @@ -319,9 +319,6 @@ ngx_mail_smtp_helo(ngx_mail_session_t *s { ngx_str_t *arg; ngx_mail_smtp_srv_conf_t *sscf; -#if (NGX_MAIL_SSL) - ngx_mail_ssl_conf_t *sslcf; -#endif if (s->args.nelts != 1) { s->out.len = sizeof(smtp_invalid_argument) - 1; @@ -352,6 +349,8 @@ ngx_mail_smtp_helo(ngx_mail_session_t *s #if (NGX_MAIL_SSL) if (c->ssl == NULL) { + ngx_mail_ssl_conf_t *sslcf; + sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module); if (sslcf->starttls == NGX_MAIL_STARTTLS_ON) { diff --git a/src/os/unix/ngx_process_cycle.c b/src/os/unix/ngx_process_cycle.c --- a/src/os/unix/ngx_process_cycle.c +++ b/src/os/unix/ngx_process_cycle.c @@ -687,17 +687,16 @@ ngx_worker_process_cycle(ngx_cycle_t *cy { ngx_uint_t i; ngx_connection_t *c; -#if (NGX_THREADS) - ngx_int_t n; - ngx_err_t err; - ngx_core_conf_t *ccf; -#endif ngx_worker_process_init(cycle, 1); ngx_setproctitle("worker process"); #if (NGX_THREADS) + { + ngx_int_t n; + ngx_err_t err; + ngx_core_conf_t *ccf; ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); @@ -736,7 +735,7 @@ ngx_worker_process_cycle(ngx_cycle_t *cy } } } - + } #endif for ( ;; ) {