=== modified file '.pc/applied-patches' --- .pc/applied-patches 2010-03-03 23:50:36 +0000 +++ .pc/applied-patches 2010-07-21 11:15:58 +0000 @@ -1,2 +1,3 @@ nginx-upstream-fair.diff dlopen.diff +fix_reloading_ipv6.diff === added directory '.pc/fix_reloading_ipv6.diff' === added directory '.pc/fix_reloading_ipv6.diff/src' === added directory '.pc/fix_reloading_ipv6.diff/src/core' === added file '.pc/fix_reloading_ipv6.diff/src/core/ngx_cycle.c' --- .pc/fix_reloading_ipv6.diff/src/core/ngx_cycle.c 1970-01-01 00:00:00 +0000 +++ .pc/fix_reloading_ipv6.diff/src/core/ngx_cycle.c 2010-07-21 11:15:58 +0000 @@ -0,0 +1,1343 @@ + +/* + * Copyright (C) Igor Sysoev + */ + + +#include +#include +#include + + +static void ngx_destroy_cycle_pools(ngx_conf_t *conf); +static ngx_int_t ngx_cmp_sockaddr(struct sockaddr *sa1, struct sockaddr *sa2); +static ngx_int_t ngx_init_zone_pool(ngx_cycle_t *cycle, + ngx_shm_zone_t *shm_zone); +static ngx_int_t ngx_test_lockfile(u_char *file, ngx_log_t *log); +static void ngx_clean_old_cycles(ngx_event_t *ev); + + +volatile ngx_cycle_t *ngx_cycle; +ngx_array_t ngx_old_cycles; + +static ngx_pool_t *ngx_temp_pool; +static ngx_event_t ngx_cleaner_event; + +ngx_uint_t ngx_test_config; + +#if (NGX_THREADS) +ngx_tls_key_t ngx_core_tls_key; +#endif + + +/* STUB NAME */ +static ngx_connection_t dumb; +/* STUB */ + +static ngx_str_t error_log = ngx_string(NGX_ERROR_LOG_PATH); + + +ngx_cycle_t * +ngx_init_cycle(ngx_cycle_t *old_cycle) +{ + void *rv; + char **senv, **env; + ngx_uint_t i, n; + ngx_log_t *log; + ngx_time_t *tp; + ngx_conf_t conf; + ngx_pool_t *pool; + ngx_cycle_t *cycle, **old; + ngx_shm_zone_t *shm_zone, *oshm_zone; + 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; + char hostname[NGX_MAXHOSTNAMELEN]; + + ngx_timezone_update(); + + /* force localtime update with a new timezone */ + + tp = ngx_timeofday(); + tp->sec = 0; + + ngx_time_update(); + + + log = old_cycle->log; + + pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log); + if (pool == NULL) { + return NULL; + } + pool->log = log; + + cycle = ngx_pcalloc(pool, sizeof(ngx_cycle_t)); + if (cycle == NULL) { + ngx_destroy_pool(pool); + return NULL; + } + + cycle->pool = pool; + cycle->log = log; + cycle->new_log.log_level = NGX_LOG_ERR; + cycle->old_cycle = old_cycle; + + cycle->conf_prefix.len = old_cycle->conf_prefix.len; + cycle->conf_prefix.data = ngx_pstrdup(pool, &old_cycle->conf_prefix); + if (cycle->conf_prefix.data == NULL) { + ngx_destroy_pool(pool); + return NULL; + } + + cycle->prefix.len = old_cycle->prefix.len; + cycle->prefix.data = ngx_pstrdup(pool, &old_cycle->prefix); + if (cycle->prefix.data == NULL) { + ngx_destroy_pool(pool); + return NULL; + } + + cycle->conf_file.len = old_cycle->conf_file.len; + cycle->conf_file.data = ngx_pnalloc(pool, old_cycle->conf_file.len + 1); + if (cycle->conf_file.data == NULL) { + ngx_destroy_pool(pool); + return NULL; + } + ngx_cpystrn(cycle->conf_file.data, old_cycle->conf_file.data, + old_cycle->conf_file.len + 1); + + cycle->conf_param.len = old_cycle->conf_param.len; + cycle->conf_param.data = ngx_pstrdup(pool, &old_cycle->conf_param); + if (cycle->conf_param.data == NULL) { + ngx_destroy_pool(pool); + return NULL; + } + + + n = old_cycle->pathes.nelts ? old_cycle->pathes.nelts : 10; + + cycle->pathes.elts = ngx_pcalloc(pool, n * sizeof(ngx_path_t *)); + if (cycle->pathes.elts == NULL) { + ngx_destroy_pool(pool); + return NULL; + } + + cycle->pathes.nelts = 0; + cycle->pathes.size = sizeof(ngx_path_t *); + cycle->pathes.nalloc = n; + cycle->pathes.pool = pool; + + + if (old_cycle->open_files.part.nelts) { + n = old_cycle->open_files.part.nelts; + for (part = old_cycle->open_files.part.next; part; part = part->next) { + n += part->nelts; + } + + } else { + n = 20; + } + + if (ngx_list_init(&cycle->open_files, pool, n, sizeof(ngx_open_file_t)) + != NGX_OK) + { + ngx_destroy_pool(pool); + return NULL; + } + + + if (old_cycle->shared_memory.part.nelts) { + n = old_cycle->shared_memory.part.nelts; + for (part = old_cycle->shared_memory.part.next; part; part = part->next) + { + n += part->nelts; + } + + } else { + n = 1; + } + + if (ngx_list_init(&cycle->shared_memory, pool, n, sizeof(ngx_shm_zone_t)) + != NGX_OK) + { + ngx_destroy_pool(pool); + return NULL; + } + + n = old_cycle->listening.nelts ? old_cycle->listening.nelts : 10; + + cycle->listening.elts = ngx_pcalloc(pool, n * sizeof(ngx_listening_t)); + if (cycle->listening.elts == NULL) { + ngx_destroy_pool(pool); + return NULL; + } + + cycle->listening.nelts = 0; + cycle->listening.size = sizeof(ngx_listening_t); + cycle->listening.nalloc = n; + cycle->listening.pool = pool; + + + cycle->conf_ctx = ngx_pcalloc(pool, ngx_max_module * sizeof(void *)); + if (cycle->conf_ctx == NULL) { + ngx_destroy_pool(pool); + return NULL; + } + + + if (gethostname(hostname, NGX_MAXHOSTNAMELEN) == -1) { + ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, "gethostname() failed"); + ngx_destroy_pool(pool); + return NULL; + } + + /* on Linux gethostname() silently truncates name that does not fit */ + + hostname[NGX_MAXHOSTNAMELEN - 1] = '\0'; + cycle->hostname.len = ngx_strlen(hostname); + + cycle->hostname.data = ngx_pnalloc(pool, cycle->hostname.len); + if (cycle->hostname.data == NULL) { + ngx_destroy_pool(pool); + return NULL; + } + + ngx_memcpy(cycle->hostname.data, hostname, cycle->hostname.len); + + + for (i = 0; ngx_modules[i]; i++) { + if (ngx_modules[i]->type != NGX_CORE_MODULE) { + continue; + } + + module = ngx_modules[i]->ctx; + + if (module->create_conf) { + rv = module->create_conf(cycle); + if (rv == NULL) { + ngx_destroy_pool(pool); + return NULL; + } + cycle->conf_ctx[ngx_modules[i]->index] = rv; + } + } + + + senv = environ; + + + ngx_memzero(&conf, sizeof(ngx_conf_t)); + /* STUB: init array ? */ + conf.args = ngx_array_create(pool, 10, sizeof(ngx_str_t)); + if (conf.args == NULL) { + ngx_destroy_pool(pool); + return NULL; + } + + conf.temp_pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log); + if (conf.temp_pool == NULL) { + ngx_destroy_pool(pool); + return NULL; + } + + + conf.ctx = cycle->conf_ctx; + conf.cycle = cycle; + conf.pool = pool; + conf.log = log; + conf.module_type = NGX_CORE_MODULE; + conf.cmd_type = NGX_MAIN_CONF; + +#if 0 + log->log_level = NGX_LOG_DEBUG_ALL; +#endif + + if (ngx_conf_param(&conf) != NGX_CONF_OK) { + environ = senv; + ngx_destroy_cycle_pools(&conf); + return NULL; + } + + if (ngx_conf_parse(&conf, &cycle->conf_file) != NGX_CONF_OK) { + environ = senv; + ngx_destroy_cycle_pools(&conf); + return NULL; + } + + if (ngx_test_config) { + ngx_log_stderr(0, "the configuration file %s syntax is ok", + cycle->conf_file.data); + } + + for (i = 0; ngx_modules[i]; i++) { + if (ngx_modules[i]->type != NGX_CORE_MODULE) { + continue; + } + + module = ngx_modules[i]->ctx; + + if (module->init_conf) { + if (module->init_conf(cycle, cycle->conf_ctx[ngx_modules[i]->index]) + == NGX_CONF_ERROR) + { + environ = senv; + ngx_destroy_cycle_pools(&conf); + return NULL; + } + } + } + + if (ngx_process == NGX_PROCESS_SIGNALLER) { + return cycle; + } + + ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); + + if (ngx_test_config) { + + if (ngx_create_pidfile(&ccf->pid, log) != NGX_OK) { + goto failed; + } + + } else if (!ngx_is_init_cycle(old_cycle)) { + + /* + * we do not create the pid file in the first ngx_init_cycle() call + * because we need to write the demonized process pid + */ + + old_ccf = (ngx_core_conf_t *) ngx_get_conf(old_cycle->conf_ctx, + ngx_core_module); + if (ccf->pid.len != old_ccf->pid.len + || ngx_strcmp(ccf->pid.data, old_ccf->pid.data) != 0) + { + /* new pid file name */ + + if (ngx_create_pidfile(&ccf->pid, log) != NGX_OK) { + goto failed; + } + + ngx_delete_pidfile(old_cycle); + } + } + + + if (ngx_test_lockfile(cycle->lock_file.data, log) != NGX_OK) { + goto failed; + } + + + if (ngx_create_pathes(cycle, ccf->user) != NGX_OK) { + goto failed; + } + + + if (cycle->new_log.file == NULL) { + cycle->new_log.file = ngx_conf_open_file(cycle, &error_log); + if (cycle->new_log.file == NULL) { + goto failed; + } + } + + /* open the new files */ + + part = &cycle->open_files.part; + file = part->elts; + + for (i = 0; /* void */ ; i++) { + + if (i >= part->nelts) { + if (part->next == NULL) { + break; + } + part = part->next; + file = part->elts; + i = 0; + } + + if (file[i].name.len == 0) { + continue; + } + + file[i].fd = ngx_open_file(file[i].name.data, + NGX_FILE_APPEND, + NGX_FILE_CREATE_OR_OPEN, + NGX_FILE_DEFAULT_ACCESS); + + ngx_log_debug3(NGX_LOG_DEBUG_CORE, log, 0, + "log: %p %d \"%s\"", + &file[i], file[i].fd, file[i].name.data); + + if (file[i].fd == NGX_INVALID_FILE) { + ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, + ngx_open_file_n " \"%s\" failed", + file[i].name.data); + goto failed; + } + +#if !(NGX_WIN32) + if (fcntl(file[i].fd, F_SETFD, FD_CLOEXEC) == -1) { + ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, + "fcntl(FD_CLOEXEC) \"%s\" failed", + file[i].name.data); + goto failed; + } +#endif + } + + cycle->log = &cycle->new_log; + pool->log = &cycle->new_log; + + + /* create shared memory */ + + part = &cycle->shared_memory.part; + shm_zone = part->elts; + + for (i = 0; /* void */ ; i++) { + + if (i >= part->nelts) { + if (part->next == NULL) { + break; + } + part = part->next; + shm_zone = part->elts; + i = 0; + } + + if (shm_zone[i].shm.size == 0) { + ngx_log_error(NGX_LOG_EMERG, log, 0, + "zero size shared memory zone \"%V\"", + &shm_zone[i].shm.name); + goto failed; + } + + if (shm_zone[i].init == NULL) { + /* unused shared zone */ + continue; + } + + shm_zone[i].shm.log = cycle->log; + + opart = &old_cycle->shared_memory.part; + oshm_zone = opart->elts; + + for (n = 0; /* void */ ; n++) { + + if (n >= opart->nelts) { + if (opart->next == NULL) { + break; + } + opart = opart->next; + oshm_zone = opart->elts; + n = 0; + } + + if (shm_zone[i].shm.name.len != oshm_zone[n].shm.name.len) { + continue; + } + + if (ngx_strncmp(shm_zone[i].shm.name.data, + oshm_zone[n].shm.name.data, + shm_zone[i].shm.name.len) + != 0) + { + continue; + } + + if (shm_zone[i].shm.size == oshm_zone[n].shm.size) { + shm_zone[i].shm.addr = oshm_zone[n].shm.addr; + + if (shm_zone[i].init(&shm_zone[i], oshm_zone[n].data) + != NGX_OK) + { + goto failed; + } + + goto shm_zone_found; + } + + ngx_shm_free(&oshm_zone[n].shm); + + break; + } + + if (ngx_shm_alloc(&shm_zone[i].shm) != NGX_OK) { + goto failed; + } + + if (ngx_init_zone_pool(cycle, &shm_zone[i]) != NGX_OK) { + goto failed; + } + + if (shm_zone[i].init(&shm_zone[i], NULL) != NGX_OK) { + goto failed; + } + + shm_zone_found: + + continue; + } + + + /* handle the listening sockets */ + + if (old_cycle->listening.nelts) { + ls = old_cycle->listening.elts; + for (i = 0; i < old_cycle->listening.nelts; i++) { + ls[i].remain = 0; + } + + nls = cycle->listening.elts; + for (n = 0; n < cycle->listening.nelts; n++) { + + for (i = 0; i < old_cycle->listening.nelts; i++) { + if (ls[i].ignore) { + continue; + } + + if (ngx_cmp_sockaddr(nls[n].sockaddr, ls[i].sockaddr) == NGX_OK) + { + nls[n].fd = ls[i].fd; + nls[n].previous = &ls[i]; + ls[i].remain = 1; + + if (ls[n].backlog != nls[i].backlog) { + nls[n].listen = 1; + } + +#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) + + /* + * FreeBSD, except the most recent versions, + * could not remove accept filter + */ + nls[n].deferred_accept = ls[i].deferred_accept; + + if (ls[i].accept_filter && nls[n].accept_filter) { + if (ngx_strcmp(ls[i].accept_filter, + nls[n].accept_filter) + != 0) + { + nls[n].delete_deferred = 1; + nls[n].add_deferred = 1; + } + + } else if (ls[i].accept_filter) { + nls[n].delete_deferred = 1; + + } else if (nls[n].accept_filter) { + nls[n].add_deferred = 1; + } +#endif + +#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT) + + if (ls[n].deferred_accept && !nls[n].deferred_accept) { + nls[n].delete_deferred = 1; + + } else if (ls[i].deferred_accept != nls[n].deferred_accept) + { + nls[n].add_deferred = 1; + } +#endif + break; + } + } + + if (nls[n].fd == -1) { + nls[n].open = 1; + } + } + + } else { + ls = cycle->listening.elts; + for (i = 0; i < cycle->listening.nelts; i++) { + ls[i].open = 1; +#if (NGX_HAVE_DEFERRED_ACCEPT && defined SO_ACCEPTFILTER) + if (ls[i].accept_filter) { + ls[i].add_deferred = 1; + } +#endif +#if (NGX_HAVE_DEFERRED_ACCEPT && defined TCP_DEFER_ACCEPT) + if (ls[i].deferred_accept) { + ls[i].add_deferred = 1; + } +#endif + } + } + + if (ngx_open_listening_sockets(cycle) != NGX_OK) { + goto failed; + } + + if (!ngx_test_config) { + ngx_configure_listening_sockets(cycle); + } + + + /* commit the new cycle configuration */ + + if (!ngx_use_stderr && cycle->log->file->fd != ngx_stderr) { + + if (ngx_set_stderr(cycle->log->file->fd) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + ngx_set_stderr_n " failed"); + } + } + + pool->log = cycle->log; + + for (i = 0; ngx_modules[i]; i++) { + if (ngx_modules[i]->init_module) { + if (ngx_modules[i]->init_module(cycle) != NGX_OK) { + /* fatal */ + exit(1); + } + } + } + + + /* close and delete stuff that lefts from an old cycle */ + + /* free the unnecessary shared memory */ + + opart = &old_cycle->shared_memory.part; + oshm_zone = opart->elts; + + for (i = 0; /* void */ ; i++) { + + if (i >= opart->nelts) { + if (opart->next == NULL) { + goto old_shm_zone_done; + } + opart = opart->next; + oshm_zone = opart->elts; + i = 0; + } + + part = &cycle->shared_memory.part; + shm_zone = part->elts; + + for (n = 0; /* void */ ; n++) { + + if (n >= part->nelts) { + if (part->next == NULL) { + break; + } + part = part->next; + shm_zone = part->elts; + n = 0; + } + + if (oshm_zone[i].shm.name.len == shm_zone[n].shm.name.len + && ngx_strncmp(oshm_zone[i].shm.name.data, + shm_zone[n].shm.name.data, + oshm_zone[i].shm.name.len) + == 0) + { + goto live_shm_zone; + } + } + + ngx_shm_free(&oshm_zone[i].shm); + + live_shm_zone: + + continue; + } + +old_shm_zone_done: + + + /* close the unnecessary listening sockets */ + + ls = old_cycle->listening.elts; + for (i = 0; i < old_cycle->listening.nelts; i++) { + + if (ls[i].remain || ls[i].fd == -1) { + continue; + } + + if (ngx_close_socket(ls[i].fd) == -1) { + ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, + ngx_close_socket_n " listening socket on %V failed", + &ls[i].addr_text); + } + } + + + /* close the unnecessary open files */ + + part = &old_cycle->open_files.part; + file = part->elts; + + for (i = 0; /* void */ ; i++) { + + if (i >= part->nelts) { + if (part->next == NULL) { + break; + } + part = part->next; + file = part->elts; + i = 0; + } + + if (file[i].fd == NGX_INVALID_FILE || file[i].fd == ngx_stderr) { + continue; + } + + if (ngx_close_file(file[i].fd) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, + ngx_close_file_n " \"%s\" failed", + file[i].name.data); + } + } + + ngx_destroy_pool(conf.temp_pool); + + 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, therefore we save the 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; + } + + + if (ngx_temp_pool == NULL) { + ngx_temp_pool = ngx_create_pool(128, cycle->log); + if (ngx_temp_pool == NULL) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, + "can not create ngx_temp_pool"); + exit(1); + } + + n = 10; + ngx_old_cycles.elts = ngx_pcalloc(ngx_temp_pool, + n * sizeof(ngx_cycle_t *)); + if (ngx_old_cycles.elts == NULL) { + exit(1); + } + ngx_old_cycles.nelts = 0; + ngx_old_cycles.size = sizeof(ngx_cycle_t *); + ngx_old_cycles.nalloc = n; + ngx_old_cycles.pool = ngx_temp_pool; + + ngx_cleaner_event.handler = ngx_clean_old_cycles; + ngx_cleaner_event.log = cycle->log; + ngx_cleaner_event.data = &dumb; + dumb.fd = (ngx_socket_t) -1; + } + + ngx_temp_pool->log = cycle->log; + + old = ngx_array_push(&ngx_old_cycles); + if (old == NULL) { + exit(1); + } + *old = old_cycle; + + if (!ngx_cleaner_event.timer_set) { + ngx_add_timer(&ngx_cleaner_event, 30000); + ngx_cleaner_event.timer_set = 1; + } + + return cycle; + + +failed: + + if (!ngx_is_init_cycle(old_cycle)) { + old_ccf = (ngx_core_conf_t *) ngx_get_conf(old_cycle->conf_ctx, + ngx_core_module); + if (old_ccf->environment) { + environ = old_ccf->environment; + } + } + + /* rollback the new cycle configuration */ + + part = &cycle->open_files.part; + file = part->elts; + + for (i = 0; /* void */ ; i++) { + + if (i >= part->nelts) { + if (part->next == NULL) { + break; + } + part = part->next; + file = part->elts; + i = 0; + } + + if (file[i].fd == NGX_INVALID_FILE || file[i].fd == ngx_stderr) { + continue; + } + + if (ngx_close_file(file[i].fd) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, + ngx_close_file_n " \"%s\" failed", + file[i].name.data); + } + } + + if (ngx_test_config) { + ngx_destroy_cycle_pools(&conf); + return NULL; + } + + ls = cycle->listening.elts; + for (i = 0; i < cycle->listening.nelts; i++) { + if (ls[i].fd == -1 || !ls[i].open) { + continue; + } + + if (ngx_close_socket(ls[i].fd) == -1) { + ngx_log_error(NGX_LOG_EMERG, log, ngx_socket_errno, + ngx_close_socket_n " %V failed", + &ls[i].addr_text); + } + } + + ngx_destroy_cycle_pools(&conf); + + return NULL; +} + + +static void +ngx_destroy_cycle_pools(ngx_conf_t *conf) +{ + ngx_destroy_pool(conf->temp_pool); + ngx_destroy_pool(conf->pool); +} + + +static ngx_int_t +ngx_cmp_sockaddr(struct sockaddr *sa1, struct sockaddr *sa2) +{ + struct sockaddr_in *sin1, *sin2; +#if (NGX_HAVE_INET6) + struct sockaddr_in6 *sin61, *sin62; +#endif + + if (sa1->sa_family != sa2->sa_family) { + return NGX_DECLINED; + } + + switch (sa1->sa_family) { + +#if (NGX_HAVE_INET6) + case AF_INET6: + sin61 = (struct sockaddr_in6 *) sa1; + sin62 = (struct sockaddr_in6 *) sa2; + + if (sin61->sin6_port != sin61->sin6_port) { + return NGX_DECLINED; + } + + if (ngx_memcmp(&sin61->sin6_addr, &sin62->sin6_addr, 16) != 0) { + return NGX_DECLINED; + } + + break; +#endif + + default: /* AF_INET */ + + sin1 = (struct sockaddr_in *) sa1; + sin2 = (struct sockaddr_in *) sa2; + + if (sin1->sin_port != sin2->sin_port) { + return NGX_DECLINED; + } + + if (sin1->sin_addr.s_addr != sin2->sin_addr.s_addr) { + return NGX_DECLINED; + } + + break; + } + + return NGX_OK; +} + + +static ngx_int_t +ngx_init_zone_pool(ngx_cycle_t *cycle, ngx_shm_zone_t *zn) +{ + u_char *file; + ngx_slab_pool_t *sp; + + sp = (ngx_slab_pool_t *) zn->shm.addr; + + if (zn->shm.exists) { + + if (sp == sp->addr) { + return NGX_OK; + } + + ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, + "shared zone \"%V\" has no equal addresses: %p vs %p", + &zn->shm.name, sp->addr, sp); + return NGX_ERROR; + } + + sp->end = zn->shm.addr + zn->shm.size; + sp->min_shift = 3; + sp->addr = zn->shm.addr; + +#if (NGX_HAVE_ATOMIC_OPS) + + file = NULL; + +#else + + file = ngx_pnalloc(cycle->pool, cycle->lock_file.len + zn->shm.name.len); + if (file == NULL) { + return NGX_ERROR; + } + + (void) ngx_sprintf(file, "%V%V%Z", &cycle->lock_file, &zn->shm.name); + +#endif + + if (ngx_shmtx_create(&sp->mutex, (void *) &sp->lock, file) != NGX_OK) { + return NGX_ERROR; + } + + ngx_slab_init(sp); + + return NGX_OK; +} + + +ngx_int_t +ngx_create_pidfile(ngx_str_t *name, ngx_log_t *log) +{ + size_t len; + ngx_uint_t create; + ngx_file_t file; + u_char pid[NGX_INT64_LEN + 2]; + + if (ngx_process > NGX_PROCESS_MASTER) { + return NGX_OK; + } + + ngx_memzero(&file, sizeof(ngx_file_t)); + + file.name = *name; + file.log = log; + + create = ngx_test_config ? NGX_FILE_CREATE_OR_OPEN : NGX_FILE_TRUNCATE; + + file.fd = ngx_open_file(file.name.data, NGX_FILE_RDWR, + create, NGX_FILE_DEFAULT_ACCESS); + + if (file.fd == NGX_INVALID_FILE) { + ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, + ngx_open_file_n " \"%s\" failed", file.name.data); + return NGX_ERROR; + } + + if (!ngx_test_config) { + len = ngx_snprintf(pid, NGX_INT64_LEN + 2, "%P%N", ngx_pid) - pid; + + if (ngx_write_file(&file, pid, len, 0) == NGX_ERROR) { + return NGX_ERROR; + } + } + + if (ngx_close_file(file.fd) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, + ngx_close_file_n " \"%s\" failed", file.name.data); + } + + return NGX_OK; +} + + +void +ngx_delete_pidfile(ngx_cycle_t *cycle) +{ + u_char *name; + ngx_core_conf_t *ccf; + + ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); + + name = ngx_new_binary ? ccf->oldpid.data : ccf->pid.data; + + if (ngx_delete_file(name) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + ngx_delete_file_n " \"%s\" failed", name); + } +} + + +ngx_int_t +ngx_signal_process(ngx_cycle_t *cycle, char *sig) +{ + ssize_t n; + ngx_int_t pid; + ngx_file_t file; + ngx_core_conf_t *ccf; + u_char buf[NGX_INT64_LEN + 2]; + + ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "signal process started"); + + ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); + + file.name = ccf->pid; + file.log = cycle->log; + + file.fd = ngx_open_file(file.name.data, NGX_FILE_RDONLY, + NGX_FILE_OPEN, NGX_FILE_DEFAULT_ACCESS); + + if (file.fd == NGX_INVALID_FILE) { + ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno, + ngx_open_file_n " \"%s\" failed", file.name.data); + return 1; + } + + n = ngx_read_file(&file, buf, NGX_INT64_LEN + 2, 0); + + if (ngx_close_file(file.fd) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + ngx_close_file_n " \"%s\" failed", file.name.data); + } + + if (n == NGX_ERROR) { + return 1; + } + + while (n-- && (buf[n] == CR || buf[n] == LF)) { /* void */ } + + pid = ngx_atoi(buf, ++n); + + if (pid == NGX_ERROR) { + ngx_log_error(NGX_LOG_ERR, cycle->log, 0, + "invalid PID number \"%*s\" in \"%s\"", + n, buf, file.name.data); + return 1; + } + + return ngx_os_signal_process(cycle, sig, pid); + +} + + +static ngx_int_t +ngx_test_lockfile(u_char *file, ngx_log_t *log) +{ +#if !(NGX_HAVE_ATOMIC_OPS) + ngx_fd_t fd; + + fd = ngx_open_file(file, NGX_FILE_RDWR, NGX_FILE_CREATE_OR_OPEN, + NGX_FILE_DEFAULT_ACCESS); + + if (fd == NGX_INVALID_FILE) { + ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, + ngx_open_file_n " \"%s\" failed", file); + return NGX_ERROR; + } + + if (ngx_close_file(fd) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, + ngx_close_file_n " \"%s\" failed", file); + } + + if (ngx_delete_file(file) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, + ngx_delete_file_n " \"%s\" failed", file); + } + +#endif + + return NGX_OK; +} + + +void +ngx_reopen_files(ngx_cycle_t *cycle, ngx_uid_t user) +{ + ssize_t n, len; + ngx_fd_t fd; + ngx_uint_t i; + ngx_list_part_t *part; + ngx_open_file_t *file; + + part = &cycle->open_files.part; + file = part->elts; + + for (i = 0; /* void */ ; i++) { + + if (i >= part->nelts) { + if (part->next == NULL) { + break; + } + part = part->next; + file = part->elts; + i = 0; + } + + if (file[i].name.len == 0) { + continue; + } + + len = file[i].pos - file[i].buffer; + + if (file[i].buffer && len != 0) { + + n = ngx_write_fd(file[i].fd, file[i].buffer, len); + + if (n == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, + ngx_write_fd_n " to \"%s\" failed", + file[i].name.data); + + } else if (n != len) { + ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, + ngx_write_fd_n " to \"%s\" was incomplete: %z of %uz", + file[i].name.data, n, len); + } + + file[i].pos = file[i].buffer; + } + + fd = ngx_open_file(file[i].name.data, NGX_FILE_APPEND, + NGX_FILE_CREATE_OR_OPEN, NGX_FILE_DEFAULT_ACCESS); + + ngx_log_debug3(NGX_LOG_DEBUG_EVENT, cycle->log, 0, + "reopen file \"%s\", old:%d new:%d", + file[i].name.data, file[i].fd, fd); + + if (fd == NGX_INVALID_FILE) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, + ngx_open_file_n " \"%s\" failed", file[i].name.data); + continue; + } + +#if !(NGX_WIN32) + 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) + == NGX_FILE_ERROR) + { + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, + ngx_file_info_n " \"%s\" failed", + file[i].name.data); + + if (ngx_close_file(fd) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, + ngx_close_file_n " \"%s\" failed", + file[i].name.data); + } + } + + if (fi.st_uid != user) { + if (chown((const char *) file[i].name.data, user, -1) == -1) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, + "chown(\"%s\", %d) failed", + file[i].name.data, user); + + if (ngx_close_file(fd) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, + ngx_close_file_n " \"%s\" failed", + file[i].name.data); + } + } + } + + if ((fi.st_mode & (S_IRUSR|S_IWUSR)) != (S_IRUSR|S_IWUSR)) { + + fi.st_mode |= (S_IRUSR|S_IWUSR); + + if (chmod((const char *) file[i].name.data, fi.st_mode) == -1) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, + "chmod() \"%s\" failed", file[i].name.data); + + if (ngx_close_file(fd) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, + ngx_close_file_n " \"%s\" failed", + file[i].name.data); + } + } + } + } + + if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, + "fcntl(FD_CLOEXEC) \"%s\" failed", + file[i].name.data); + + if (ngx_close_file(fd) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, + ngx_close_file_n " \"%s\" failed", + file[i].name.data); + } + + continue; + } +#endif + + if (ngx_close_file(file[i].fd) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, + ngx_close_file_n " \"%s\" failed", + file[i].name.data); + } + + file[i].fd = fd; + } + +#if !(NGX_WIN32) + + if (cycle->log->file->fd != STDERR_FILENO) { + if (dup2(cycle->log->file->fd, STDERR_FILENO) == -1) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno, + "dup2(STDERR) failed"); + } + } + +#endif +} + + +ngx_shm_zone_t * +ngx_shared_memory_add(ngx_conf_t *cf, ngx_str_t *name, size_t size, void *tag) +{ + ngx_uint_t i; + ngx_shm_zone_t *shm_zone; + ngx_list_part_t *part; + + part = &cf->cycle->shared_memory.part; + shm_zone = part->elts; + + for (i = 0; /* void */ ; i++) { + + if (i >= part->nelts) { + if (part->next == NULL) { + break; + } + part = part->next; + shm_zone = part->elts; + i = 0; + } + + if (name->len != shm_zone[i].shm.name.len) { + continue; + } + + if (ngx_strncmp(name->data, shm_zone[i].shm.name.data, name->len) + != 0) + { + continue; + } + + if (size && size != shm_zone[i].shm.size) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "the size %uz of shared memory zone \"%V\" " + "conflicts with already declared size %uz", + size, &shm_zone[i].shm.name, shm_zone[i].shm.size); + return NULL; + } + + if (tag != shm_zone[i].tag) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "the shared memory zone \"%V\" is " + "already declared for a different use", + &shm_zone[i].shm.name); + return NULL; + } + + return &shm_zone[i]; + } + + shm_zone = ngx_list_push(&cf->cycle->shared_memory); + + if (shm_zone == NULL) { + return NULL; + } + + shm_zone->data = NULL; + shm_zone->shm.log = cf->cycle->log; + shm_zone->shm.size = size; + shm_zone->shm.name = *name; + shm_zone->shm.exists = 0; + shm_zone->init = NULL; + shm_zone->tag = tag; + + return shm_zone; +} + + +static void +ngx_clean_old_cycles(ngx_event_t *ev) +{ + ngx_uint_t i, n, found, live; + ngx_log_t *log; + ngx_cycle_t **cycle; + + log = ngx_cycle->log; + ngx_temp_pool->log = log; + + ngx_log_debug0(NGX_LOG_DEBUG_CORE, log, 0, "clean old cycles"); + + live = 0; + + cycle = ngx_old_cycles.elts; + for (i = 0; i < ngx_old_cycles.nelts; i++) { + + if (cycle[i] == NULL) { + continue; + } + + found = 0; + + for (n = 0; n < cycle[i]->connection_n; n++) { + if (cycle[i]->connections[n].fd != (ngx_socket_t) -1) { + found = 1; + + ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, "live fd:%d", n); + + break; + } + } + + if (found) { + live = 1; + continue; + } + + ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, "clean old cycle: %d", i); + + ngx_destroy_pool(cycle[i]->pool); + cycle[i] = NULL; + } + + ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, "old cycles status: %d", live); + + if (live) { + ngx_add_timer(ev, 30000); + + } else { + ngx_destroy_pool(ngx_temp_pool); + ngx_temp_pool = NULL; + ngx_old_cycles.nelts = 0; + } +} === modified file 'CHANGES' --- CHANGES 2010-03-03 23:50:36 +0000 +++ CHANGES 2010-07-21 11:15:58 +0000 @@ -1,4 +1,125 @@ +Changes with nginx 0.7.67 15 Jun 2010 + + *) Security: nginx/Windows worker might be terminated abnormally if a + requested file name has invalid UTF-8 encoding. + + +Changes with nginx 0.7.66 07 Jun 2010 + + *) Security: now nginx/Windows ignores default file stream name. + Thanks to Jose Antonio Vazquez Gonzalez. + + *) Change: now the charset filter runs before the SSI filter. + + *) Change: now no message is written in an error log if a variable is + not found by $r->variable() method. + + *) Change: now keepalive connections after POST requests are not + disabled for MSIE 7.0+. + Thanks to Adam Lounds. + + *) Feature: the "proxy_no_cache" and "fastcgi_no_cache" directives. + + *) Feature: now the "rewrite" directive does a redirect automatically + if the $scheme variable is used. + Thanks to Piotr Sikora. + + *) Feature: the "chunked_transfer_encoding" directive. + + *) Feature: the $geoip_city_continent_code, $geoip_latitude, and + $geoip_longitude variables. + Thanks to Arvind Sundararajan. + + *) Feature: now the ngx_http_image_filter_module deletes always EXIF + and other application specific data if the data consume more than 5% + of a JPEG file. + + *) Feature: now the "msie_padding" directive works for Chrome too. + + *) Workaround: now keepalive connections are disabled for Safari. + Thanks to Joshua Sierles. + + *) Bugfix: nginx ignored the "private" and "no-store" values in the + "Cache-Control" backend response header line. + + *) Bugfix: an "&" character was not escaped when it was copied in + arguments part in a rewrite rule. + + *) Bugfix: nginx might be terminated abnormally while a signal + processing or if the directive "timer_resolution" was used on + platforms which do not support kqueue or eventport notification + methods. + Thanks to George Xie and Maxim Dounin. + + *) Bugfix: if temporary files and permanent storage area resided at + different file systems, then permanent file modification times were + incorrect. + Thanks to Maxim Dounin. + + *) Bugfix: ngx_http_memcached_module might issue the error message + "memcached sent invalid trailer". + Thanks to Maxim Dounin. + + *) Bugfix: nginx could not built zlib-1.2.4 library using the library + sources. + Thanks to Maxim Dounin. + + *) Bugfix: values of the $query_string, $arg_..., etc. variables cached + in main request were used by the SSI module in subrequests. + + *) Bugfix: nginx did not support HTTPS referrers. + + *) Bugfix: nginx/Windows might not find file if path in configuration + was given in other character case; the bug had appeared in 0.7.65. + + *) Bugfix: the $date_local variable has an incorrect value, if the "%s" + format was used. + Thanks to Maxim Dounin. + + *) Bugfix: nginx did not support all ciphers and digests used in client + certificates. + Thanks to Innocenty Enikeew. + + *) Bugfix: if ssl_session_cache was not set or was set to "none", then + during client certificate verify the error "session id context + uninitialized" might occur; the bug had appeared in 0.7.1. + + *) Bugfix: OpenSSL-1.0.0 compatibility on 64-bit Linux. + Thanks to Maxim Dounin. + + *) Bugfix: a geo range returned default value if the range included two + or more /16 networks and did not begin at /16 network boundary. + + *) Bugfix: the $uid_got variable might not be used in the SSI and perl + modules. + + *) Bugfix: a worker process hung if a FIFO file was requested. + Thanks to Vicente Aguilar and Maxim Dounin. + + *) Bugfix: a variable value was repeatedly encoded after each an "echo" + SSI-command output; the bug had appeared in 0.6.14. + + *) Bugfix: a "stub" parameter of an "include" SSI directive was not + used, if empty response has 200 status code. + + *) Bugfix: a block used in a "stub" parameter of an "include" SSI + directive was output with "text/plain" MIME type. + + *) Bugfix: if a proxied or FastCGI request was internally redirected to + another proxied or FastCGI location, then a segmentation fault might + occur in a worker process; the bug had appeared in 0.7.65. + Thanks to Yichun Zhang. + + *) Bugfix: IMAP connections may hang until they timed out while talking + to Zimbra server. + Thanks to Alan Batie. + + *) Bugfix: nginx did not support chunked transfer encoding for 201 + responses. + Thanks to Julian Reich. + + Changes with nginx 0.7.65 01 Feb 2010 *) Security: now nginx/Windows ignores trailing spaces in URI. === modified file 'CHANGES.ru' --- CHANGES.ru 2010-03-03 23:50:36 +0000 +++ CHANGES.ru 2010-07-21 11:15:58 +0000 @@ -1,4 +1,128 @@ +Изменения в nginx 0.7.67 15.06.2010 + + *) Безопасность: рабочий процесс nginx/Windows мог завершаться аварийно + при запросе файла с неверной кодировкой UTF-8. + + +Изменения в nginx 0.7.66 07.06.2010 + + *) Безопасность: теперь nginx/Windows игнорирует имя потока файла по + умолчанию. + Спасибо Jose Antonio Vazquez Gonzalez. + + *) Изменение: теперь charset-фильтр работает до SSI-фильтра. + + *) Изменение: теперь в лог ошибок не пишется сообщение, если переменная + не найдена с помощью метода $r->variable(). + + *) Изменение: теперь keepalive соединения после запросов POST не + запрещаются для MSIE 7.0+. + Спасибо Adam Lounds. + + *) Добавление: директивы proxy_no_cache и fastcgi_no_cache. + + *) Добавление: теперь при использовании переменной $scheme в директиве + rewrite автоматически делается редирект. + Спасибо Piotr Sikora. + + *) Добавление: директива chunked_transfer_encoding. + + *) Добавление: переменные $geoip_city_continent_code, $geoip_latitude и + $geoip_longitude. + Спасибо Arvind Sundararajan. + + *) Добавление: модуль ngx_http_image_filter_module теперь всегда + удаляет EXIF и другие данные, если они занимают больше 5% в + JPEG-файле. + + *) Добавление: теперь директива msie_padding работает и для Chrome. + + *) Изменение: теперь keepalive соединения запрещены для Safari. + Спасибо Joshua Sierles. + + *) Исправление: nginx игнорировал значения "private" и "no-store" в + строке "Cache-Control" в заголовке ответа бэкенда. + + *) Исправление: символ "&" при копировании в аргументы в правилах + rewrite не экранировался. + + *) Исправление: nginx мог завершаться аварийно во время обработки + сигнала или при использовании директивы timer_resolution на + платформах, не поддерживающих методы kqueue или eventport. + Спасибо George Xie и Максиму Дунину. + + *) Исправление: если временные файлы и постоянное место хранения + располагались на разных файловых системах, то у постоянных файлов + время изменения было неверным. + Спасибо Максиму Дунину. + + *) Исправление: модуль ngx_http_memcached_module мог выдавать ошибку + "memcached sent invalid trailer". + Спасибо Максиму Дунину. + + *) Исправление: nginx не мог собрать библиотеку zlib-1.2.4 из исходных + текстов. + Спасибо Максиму Дунину. + + *) Исправление: модуль SSI в подзапросах использовал закэшированные в + основном запросе значения переменных $query_string, $arg_... и им + подобных. + + *) Исправление: nginx не поддерживал HTTPS-рефереры. + + *) Исправление: nginx/Windows мог не находить файлы, если путь в + конфигурации был задан в другом регистре; ошибка появилась в 0.7.65. + + *) Исправление: переменная $date_local выдавала неверное время, если + использовался формат "%s". + Спасибо Максиму Дунину. + + *) Исправление: nginx не поддерживал все шифры, используемые в + клиентских сертификатах. + Спасибо Иннокентию Еникееву. + + *) Исправление: если ssl_session_cache не был установлен или установлен + в none, то при проверке клиентского сертификаты могла происходить + ошибка "session id context uninitialized"; ошибка появилась в 0.7.1. + + *) Исправление: совместимость с OpenSSL-1.0.0 на 64-битном Linux. + Спасибо Максиму Дунину. + + *) Исправление: geo-диапазон возвращал значение по умолчанию, если + диапазон включал в себя одну и более сетей размером /16 и не + начинался на границе сети размером /16. + + *) Исправление: переменную $uid_got нельзя было использовать в SSI и + перловом модулях. + + *) Исправление: рабочий процесс зависал при запросе файла FIFO. + Спасибо Vicente Aguilar и Максиму Дунину. + + *) Исправление: значение переменной повторно экранировалось после + каждого вывода SSI-команды echo; ошибка появилась в 0.6.14. + + *) Исправление: параметр stub в SSI-директиве include не использовался, + если пустой ответ имел код 200. + + *) Исправление: блок, используемый в параметре stub в SSI-директиве + include, выводился с MIME-типом "text/plain". + + *) Исправление: если проксированный или FastCGI запрос внутренне + перенаправлялся в другой проксированный или FastCGI location, то в + рабочем процессе мог произойти segmentation fault; ошибка появилась + в 0.7.65. + Спасибо Yichun Zhang. + + *) Исправление: соединения IMAP к серверу Zimbra могло зависнуть до + таймаута. + Спасибо Alan Batie. + + *) Исправление: nginx не поддерживал передачу chunk'ами для 201-ых + ответов. + Спасибо Julian Reich. + + Изменения в nginx 0.7.65 01.02.2010 *) Безопасность: теперь nginx/Windows игнорирует пробелы в конце URI. @@ -178,7 +302,7 @@ *) Добавление: директивы limit_req_log_level и limit_conn_log_level. - *) Исправление: Теперь директива limit_req соответствует алгоритму + *) Исправление: теперь директива limit_req соответствует алгоритму leaky bucket. Спасибо Максиму Дунину. @@ -1648,7 +1772,7 @@ Спасибо Андрею Нигматулину. *) Исправление: ngx_http_memcached_module не устанавливал - upstream_response_time. + $upstream_response_time. Спасибо Максиму Дунину. *) Исправление: рабочий процесс мог зациклиться при использовании === modified file 'auto/cc/conf' --- auto/cc/conf 2007-02-19 10:30:07 +0000 +++ auto/cc/conf 2010-07-21 11:15:58 +0000 @@ -104,6 +104,7 @@ fi CFLAGS="$CFLAGS $NGX_CC_OPT" +NGX_TEST_LD_OPT="$NGX_LD_OPT" if [ "$NGX_PLATFORM" != win32 ]; then === modified file 'auto/cc/gcc' --- auto/cc/gcc 2009-10-19 23:22:06 +0000 +++ auto/cc/gcc 2010-07-21 11:15:58 +0000 @@ -51,8 +51,6 @@ #NGX_GCC_OPT="-Os" NGX_GCC_OPT="-O" -CFLAGS="$CFLAGS $NGX_GCC_OPT" - #CFLAGS="$CFLAGS -fomit-frame-pointer" case $CPU in === modified file 'auto/feature' --- auto/feature 2008-09-02 20:48:58 +0000 +++ auto/feature 2010-07-21 11:15:58 +0000 @@ -39,7 +39,7 @@ ngx_test="$CC $CC_TEST_FLAGS $CC_AUX_FLAGS $ngx_feature_inc_path \ - -o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_LD_OPT $ngx_feature_libs" + -o $NGX_AUTOTEST $NGX_AUTOTEST.c $NGX_TEST_LD_OPT $ngx_feature_libs" ngx_feature_inc_path= === modified file 'auto/lib/openssl/conf' --- auto/lib/openssl/conf 2010-03-03 23:50:36 +0000 +++ auto/lib/openssl/conf 2010-07-21 11:15:58 +0000 @@ -19,6 +19,8 @@ # libeay32.lib requires gdi32.lib CORE_LIBS="$CORE_LIBS gdi32.lib" + # OpenSSL 1.0.0 requires crypt32.lib + CORE_LIBS="$CORE_LIBS crypt32.lib" ;; *) === modified file 'auto/lib/openssl/make' --- auto/lib/openssl/make 2010-03-03 23:50:36 +0000 +++ auto/lib/openssl/make 2010-07-21 11:15:58 +0000 @@ -57,7 +57,7 @@ && \$(MAKE) clean \\ && ./config --prefix=$ngx_prefix no-shared $OPENSSL_OPT \\ && \$(MAKE) \\ - && \$(MAKE) install + && \$(MAKE) install LIBDIR=lib END === modified file 'auto/lib/openssl/makefile.bcc' --- auto/lib/openssl/makefile.bcc 2009-10-19 23:22:06 +0000 +++ auto/lib/openssl/makefile.bcc 2010-07-21 11:15:58 +0000 @@ -5,8 +5,7 @@ all: cd $(OPENSSL) - perl Configure BC-32 no-shared --prefix=openssl -DNO_SYS_TYPES_H \ - $(OPENSSL_OPT) + perl Configure BC-32 no-shared --prefix=openssl $(OPENSSL_OPT) ms\do_nasm === modified file 'auto/lib/openssl/makefile.msvc' --- auto/lib/openssl/makefile.msvc 2009-10-19 23:22:06 +0000 +++ auto/lib/openssl/makefile.msvc 2010-07-21 11:15:58 +0000 @@ -5,8 +5,7 @@ all: cd $(OPENSSL) - perl Configure VC-WIN32 no-shared --prefix=openssl -DNO_SYS_TYPES_H \ - $(OPENSSL_OPT) + perl Configure VC-WIN32 no-shared --prefix=openssl $(OPENSSL_OPT) ms\do_ms === modified file 'auto/lib/zlib/make' --- auto/lib/zlib/make 2009-10-19 23:22:06 +0000 +++ auto/lib/zlib/make 2010-07-21 11:15:58 +0000 @@ -53,7 +53,7 @@ $ZLIB/libz.a: $NGX_MAKEFILE cd $ZLIB \\ - && \$(MAKE) clean \\ + && \$(MAKE) distclean \\ && cp contrib/asm586/match.S . \\ && CFLAGS="$ZLIB_OPT -DASMV" CC="\$(CC)" \\ ./configure \\ @@ -70,7 +70,7 @@ $ZLIB/libz.a: $NGX_MAKEFILE cd $ZLIB \\ - && \$(MAKE) clean \\ + && \$(MAKE) distclean \\ && cp contrib/asm686/match.S . \\ && CFLAGS="$ZLIB_OPT -DASMV" CC="\$(CC)" \\ ./configure \\ @@ -103,7 +103,7 @@ $ZLIB/libz.a: $NGX_MAKEFILE cd $ZLIB \\ - && \$(MAKE) clean \\ + && \$(MAKE) distclean \\ && CFLAGS="$ZLIB_OPT" CC="\$(CC)" \\ ./configure \\ && \$(MAKE) libz.a === modified file 'auto/modules' --- auto/modules 2009-11-30 13:34:00 +0000 +++ auto/modules 2010-07-21 11:15:58 +0000 @@ -101,8 +101,8 @@ # ngx_http_range_header_filter # ngx_http_gzip_filter # ngx_http_postpone_filter +# ngx_http_ssi_filter # ngx_http_charset_filter -# ngx_http_ssi_filter # ngx_http_xslt_filter # ngx_http_image_filter_filter # ngx_http_sub_filter @@ -130,19 +130,19 @@ HTTP_SRCS="$HTTP_SRCS $HTTP_POSTPONE_FILTER_SRCS" fi +if [ $HTTP_SSI = YES ]; then + have=NGX_HTTP_SSI . auto/have + HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_SSI_FILTER_MODULE" + HTTP_DEPS="$HTTP_DEPS $HTTP_SSI_DEPS" + HTTP_SRCS="$HTTP_SRCS $HTTP_SSI_SRCS" +fi + if [ $HTTP_CHARSET = YES ]; then have=NGX_HTTP_CHARSET . auto/have HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_CHARSET_FILTER_MODULE" HTTP_SRCS="$HTTP_SRCS $HTTP_CHARSET_SRCS" fi -if [ $HTTP_SSI = YES ]; then - have=NGX_HTTP_SSI . auto/have - HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_SSI_FILTER_MODULE" - HTTP_DEPS="$HTTP_DEPS $HTTP_SSI_DEPS" - HTTP_SRCS="$HTTP_SRCS $HTTP_SSI_SRCS" -fi - if [ $HTTP_XSLT = YES ]; then USE_LIBXSLT=YES HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES $HTTP_XSLT_FILTER_MODULE" === modified file 'auto/unix' --- auto/unix 2009-10-19 23:22:06 +0000 +++ auto/unix 2010-07-21 11:15:58 +0000 @@ -133,6 +133,16 @@ . auto/feature +ngx_feature="sys_errlist[]" +ngx_feature_name="NGX_HAVE_SYS_ERRLIST" +ngx_feature_run=yes +ngx_feature_incs="#include " +ngx_feature_path= +ngx_feature_libs= +ngx_feature_test="int n = sys_nerr; const char *p = sys_errlist[1];" +. auto/feature + + ngx_feature="localtime_r()" ngx_feature_name="NGX_HAVE_LOCALTIME_R" ngx_feature_run=no === added file 'debian/README.Debian' --- debian/README.Debian 1970-01-01 00:00:00 +0000 +++ debian/README.Debian 2010-07-21 11:15:58 +0000 @@ -0,0 +1,9 @@ +README for Debian +----------------- + + Files under /var/www/ are not supported as per Debian Policy. + Please see: http://lintian.debian.org/tags/dir-or-file-in-var-www.html and, + http://www.pathname.com/fhs/pub/fhs-2.3.html#THEVARHIERARCHY for more + details and explanations. + + -- Kartik Mistry Fri, 05 Mar 2010 13:31:15 +0530 === modified file 'debian/changelog' --- debian/changelog 2010-03-05 01:36:05 +0000 +++ debian/changelog 2010-07-21 11:15:58 +0000 @@ -1,3 +1,104 @@ +nginx (0.7.67-2ubuntu1) maverick; urgency=low + + * Merge from Debian unstable (LP: #608172) Remaining changes: + + debian/rules: + with-http_dav_module + with-http_geoip_module + with-http_gzip_static_module + with-http_realip_module + with-http_sub_module + + .pc/applied-patches + fix_reloading_ipv6.diff + + -- Mikhail Turov Wed, 21 Jul 2010 11:57:53 +0100 + +nginx (0.7.67-2) unstable; urgency=low + + * debian/conf/sites-available/default: + + Removed reference to SSLv2 protocol (Closes: #589139) + * debian/control: + + Updated Standards-Version to 3.9.0 + * debian/copyright: + + Don't point to BSD license file, included exact upstream version of + license text + + Added missing copyright owner for contrib/ scripts + + debian/* license is same as upstream now as discussed with co-maintainers + + -- Kartik Mistry Mon, 19 Jul 2010 10:36:32 +0530 + +nginx (0.7.67-1) unstable; urgency=low + + * New upstream release + + -- Kartik Mistry Wed, 16 Jun 2010 01:26:51 +0530 + +nginx (0.7.65-7) unstable; urgency=low + + [Kartik Mistry] + * debian/rules: + + Enabled HTTPSubModule module in configure (Closes: #584828) + + Arranged configure options in better manner + + -- Kartik Mistry Mon, 07 Jun 2010 14:33:24 +0530 + +nginx (0.7.65-6) unstable; urgency=low + + [Kartik Mistry] + * debian/README.Debian: + + Fixed typo and somewhat better wordings + * debian/conf/mime.types: + + Added entry to support 7zip files (Closes: #580423) + * debian/init.d: + + Do not print config testing info until an error found, Thanks to Ubuntu + bug 568293 + * debian/copyright: + + Updated as per DEP-5 specification + + -- Kartik Mistry Sat, 22 May 2010 01:41:33 +0530 + +nginx (0.7.65-5) unstable; urgency=low + + [Kartik Mistry] + * debian/patches/fix_reloading_ipv6.diff: + + Added patch to fix reloading with IPv6 addresses, Thanks to + Matthias-Christian Ott for patch (Closes: #577456) + + -- Kartik Mistry Wed, 14 Apr 2010 11:36:48 +0530 + +nginx (0.7.65-4) unstable; urgency=low + + [Kartik Mistry] + * debian/conf/sites-available/default: + + Really listen for both IPv4 and IPv6 addresses. Thanks to Nikolaus + Schulz for notice (Closes: #574983) + * debian/control, debian/rules: + + Added GeoIP support, Thanks to Caetano Carezzato + (Closes: #575280) + * debian/conf/mime.types: + + Added svg entry to mime.types, Jeremy Lal + (Closes: #575155) + + -- Kartik Mistry Thu, 25 Mar 2010 00:21:50 +0530 + +nginx (0.7.65-3) unstable; urgency=medium + + [Kartik Mistry] + * Urgency set to medium due to Release Goal + * debian/conf/sites-available/default: + + Listen for both IPv4 and IPv6 addresses by default (Closes: #574983) + + -- Kartik Mistry Tue, 23 Mar 2010 10:30:18 +0530 + +nginx (0.7.65-2) unstable; urgency=low + + * debian/README.Debian: + + Added explanation about not installing files in /var/www/ + (Closes: #572513) + * debian/rules: + + Readded realip module support (Closes: #507419) + + -- Kartik Mistry Sat, 06 Mar 2010 13:14:48 +0530 + nginx (0.7.65-1ubuntu2) lucid; urgency=low * Re-enable http_realip_module (debian/rules). === modified file 'debian/conf/mime.types' --- debian/conf/mime.types 2007-12-08 11:27:54 +0000 +++ debian/conf/mime.types 2010-07-21 11:15:58 +0000 @@ -20,6 +20,7 @@ image/x-icon ico; image/x-jng jng; image/x-ms-bmp bmp; + image/svg+xml svg svgz; application/java-archive jar war ear; application/mac-binhex40 hqx; @@ -31,6 +32,7 @@ application/vnd.ms-powerpoint ppt; application/vnd.wap.wmlc wmlc; application/vnd.wap.xhtml+xml xhtml; + application/x-7z-compressed 7z; application/x-cocoa cco; application/x-java-archive-diff jardiff; application/x-java-jnlp-file jnlp; === modified file 'debian/conf/sites-available/default' --- debian/conf/sites-available/default 2010-02-01 23:44:21 +0000 +++ debian/conf/sites-available/default 2010-07-21 11:15:58 +0000 @@ -5,13 +5,16 @@ # statements for each of your virtual hosts server { - listen 80 default; + + listen 80; ## listen for ipv4 + listen [::]:80 default ipv6only=on; ## listen for ipv6 + server_name localhost; access_log /var/log/nginx/localhost.access.log; location / { - root /var/www/nginx-default; + root /var/www; index index.html index.htm; } @@ -86,8 +89,8 @@ #ssl_session_timeout 5m; -#ssl_protocols SSLv2 SSLv3 TLSv1; -#ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP; +#ssl_protocols SSLv3 TLSv1; +#ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP; #ssl_prefer_server_ciphers on; #location / { === modified file 'debian/control' --- debian/control 2010-03-03 23:50:36 +0000 +++ debian/control 2010-07-21 11:15:58 +0000 @@ -7,10 +7,11 @@ Kartik Mistry Build-Depends: debhelper (>= 7), autotools-dev, + libgeoip-dev, libssl-dev, libpcre3-dev, zlib1g-dev -Standards-Version: 3.8.4 +Standards-Version: 3.9.0 Homepage: http://nginx.net Vcs-Svn: svn://svn.debian.org/svn/collab-maint/deb-maint/nginx/trunk Vcs-Browser: http://svn.debian.org/wsvn/collab-maint/deb-maint/nginx/trunk === modified file 'debian/copyright' --- debian/copyright 2010-02-05 11:20:28 +0000 +++ debian/copyright 2010-07-21 11:15:58 +0000 @@ -1,39 +1,40 @@ -This package was debianized by Jose Parrella on -Tue, 5 Sep 2006 11:33:34 -0400. - -It was downloaded from http://nginx.net/ - +Format-Specification: http://svn.debian.org/wsvn/dep/web/deps/dep5.mdwn?op=file&rev=135 +Name: nginx +Maintainer: Jose Parrella +Source: http://nginx.net/ Upstream Author: Igor Sysoev -Copyright б╘ 2002-2010 Igor Sysoev - +Files: * +Copyright: б╘ 2002-2010, Igor Sysoev License: BSD - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - SUCH DAMAGE. - -On Debian systems, the complete text of the BSD License can be found in -`/usr/share/common-licenses/BSD'. - -The Debian packaging is б╘ 2006-2010, Jose Parrella , -Fabio Tranchitella and б╘ 2009-2010, Kartik Mistry - and is licensed under the GPL-2 or later, see -`/usr/share/common-licenses/GPL-2' and `/usr/share/common-licenses/GPL-3'. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + . + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + . + THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Files: contrib/geo2nginx.pl +Copyright: б╘ 2005, Andrei Nigmatulin + +Files: modules/nginx-upstream-fair/ngx_http_upstream_fair_module.c +Copyright: б╘ 2007, Igor Sysoev, Grzegorz Nosek + +Files: debian/* +Copyright: б╘ 2006-2010, Jose Parrella , + Fabio Tranchitella + б╘ 2009-2010, Kartik Mistry +License: Same as upstream license. === modified file 'debian/init.d' --- debian/init.d 2010-03-03 23:50:36 +0000 +++ debian/init.d 2010-07-21 11:15:58 +0000 @@ -27,10 +27,11 @@ . /lib/lsb/init-functions test_nginx_config() { - if nginx -t $DAEMON_OPTS + if $DAEMON -t $DAEMON_OPTS >/dev/null 2>&1 then return 0 else + $DAEMON -t $DAEMON_OPTS return $? fi } === added file 'debian/patches/fix_reloading_ipv6.diff' --- debian/patches/fix_reloading_ipv6.diff 1970-01-01 00:00:00 +0000 +++ debian/patches/fix_reloading_ipv6.diff 2010-07-21 11:15:58 +0000 @@ -0,0 +1,15 @@ +Description: Patch to fix reloading IPv6 addresses +Debian Bug: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=577456 +Author: Matthias-Christian Ott + +--- nginx-0.7.65.orig/src/core/ngx_cycle.c 2010-04-13 10:07:14.000000000 +0530 ++++ nginx-0.7.65/src/core/ngx_cycle.c 2010-04-13 10:09:59.000000000 +0530 +@@ -847,7 +847,7 @@ + sin61 = (struct sockaddr_in6 *) sa1; + sin62 = (struct sockaddr_in6 *) sa2; + +- if (sin61->sin6_port != sin61->sin6_port) { ++ if (sin61->sin6_port != sin62->sin6_port) { + return NGX_DECLINED; + } + === modified file 'debian/patches/nginx-upstream-fair.diff' (properties changed: +x to -x) === modified file 'debian/patches/series' --- debian/patches/series 2010-02-01 23:44:21 +0000 +++ debian/patches/series 2010-07-21 11:15:58 +0000 @@ -1,2 +1,3 @@ nginx-upstream-fair.diff dlopen.diff +fix_reloading_ipv6.diff === modified file 'debian/rules' --- debian/rules 2010-03-05 01:36:05 +0000 +++ debian/rules 2010-07-21 11:15:58 +0000 @@ -23,19 +23,24 @@ endif ./configure --conf-path=/etc/nginx/nginx.conf \ --error-log-path=/var/log/nginx/error.log \ - --pid-path=/var/run/nginx.pid \ - --lock-path=/var/lock/nginx.lock \ + --http-client-body-temp-path=/var/lib/nginx/body \ + --http-fastcgi-temp-path=/var/lib/nginx/fastcgi \ --http-log-path=/var/log/nginx/access.log \ - --http-client-body-temp-path=/var/lib/nginx/body \ --http-proxy-temp-path=/var/lib/nginx/proxy \ - --http-fastcgi-temp-path=/var/lib/nginx/fastcgi \ + --lock-path=/var/lock/nginx.lock \ + --pid-path=/var/run/nginx.pid \ --with-debug \ + --with-http_dav_module \ + --with-http_flv_module \ + --with-http_geoip_module \ + --with-http_gzip_static_module \ + --with-http_realip_module \ --with-http_stub_status_module \ - --with-http_flv_module \ --with-http_ssl_module \ --with-http_dav_module \ --with-http_gzip_static_module \ --with-http_realip_module \ + --with-http_sub_module \ --with-mail \ --with-mail_ssl_module \ --with-ipv6 \ === modified file 'src/core/nginx.h' --- src/core/nginx.h 2010-03-03 23:50:36 +0000 +++ src/core/nginx.h 2010-07-21 11:15:58 +0000 @@ -8,8 +8,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 7065 -#define NGINX_VERSION "0.7.65" +#define nginx_version 7067 +#define NGINX_VERSION "0.7.67" #define NGINX_VER "nginx/" NGINX_VERSION #define NGINX_VAR "NGINX" === modified file 'src/core/ngx_cycle.c' --- src/core/ngx_cycle.c 2009-11-30 13:34:00 +0000 +++ src/core/ngx_cycle.c 2010-07-21 11:15:58 +0000 @@ -63,7 +63,7 @@ tp = ngx_timeofday(); tp->sec = 0; - ngx_time_update(0, 0); + ngx_time_update(); log = old_cycle->log; @@ -847,7 +847,7 @@ sin61 = (struct sockaddr_in6 *) sa1; sin62 = (struct sockaddr_in6 *) sa2; - if (sin61->sin6_port != sin61->sin6_port) { + if (sin61->sin6_port != sin62->sin6_port) { return NGX_DECLINED; } === modified file 'src/core/ngx_file.c' --- src/core/ngx_file.c 2010-03-03 23:50:36 +0000 +++ src/core/ngx_file.c 2010-07-21 11:15:58 +0000 @@ -762,10 +762,12 @@ size -= n; } - if (ngx_set_file_time(to, nfd, cf->time) != NGX_OK) { - ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno, - ngx_set_file_time_n " \"%s\" failed", to); - goto failed; + if (cf->time != -1) { + if (ngx_set_file_time(to, nfd, cf->time) != NGX_OK) { + ngx_log_error(NGX_LOG_ALERT, cf->log, ngx_errno, + ngx_set_file_time_n " \"%s\" failed", to); + goto failed; + } } rc = NGX_OK; === modified file 'src/core/ngx_open_file_cache.c' --- src/core/ngx_open_file_cache.c 2010-03-03 23:50:36 +0000 +++ src/core/ngx_open_file_cache.c 2010-07-21 11:15:58 +0000 @@ -487,7 +487,14 @@ } if (!of->log) { - fd = ngx_open_file(name, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0); + + /* + * Use non-blocking open() not to hang on FIFO files, etc. + * This flag has no effect on a regular files. + */ + + fd = ngx_open_file(name, NGX_FILE_RDONLY|NGX_FILE_NONBLOCK, + NGX_FILE_OPEN, 0); } else { fd = ngx_open_file(name, NGX_FILE_APPEND, NGX_FILE_CREATE_OR_OPEN, === modified file 'src/core/ngx_string.c' --- src/core/ngx_string.c 2010-03-03 23:50:36 +0000 +++ src/core/ngx_string.c 2010-07-21 11:15:58 +0000 @@ -1277,13 +1277,13 @@ 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */ }; - /* " ", "#", "%", "+", "?", %00-%1F, %7F-%FF */ + /* " ", "#", "%", "&", "+", "?", %00-%1F, %7F-%FF */ static uint32_t args[] = { 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */ /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */ - 0x80000829, /* 1000 0000 0000 0000 0000 1000 0010 1001 */ + 0x80000869, /* 1000 0000 0000 0000 0000 1000 0110 1001 */ /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */ 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */ === modified file 'src/core/ngx_times.c' --- src/core/ngx_times.c 2009-10-19 23:22:06 +0000 +++ src/core/ngx_times.c 2010-07-21 11:15:58 +0000 @@ -28,6 +28,17 @@ volatile ngx_str_t ngx_cached_http_time; volatile ngx_str_t ngx_cached_http_log_time; +#if !(NGX_WIN32) + +/* + * locatime() and localtime_r() are not Async-Signal-Safe functions, therefore, + * they must not be called by a signal handler, so we use the cached + * GMT offset value. Fortunately the value is changed only two times a year. + */ + +static ngx_int_t cached_gmtoff; +#endif + static ngx_time_t cached_time[NGX_TIME_SLOTS]; static u_char cached_err_log_time[NGX_TIME_SLOTS] [sizeof("1970/09/28 12:00:00")]; @@ -50,15 +61,17 @@ ngx_cached_time = &cached_time[0]; - ngx_time_update(0, 0); + ngx_time_update(); } void -ngx_time_update(time_t sec, ngx_uint_t msec) +ngx_time_update(void) { u_char *p0, *p1, *p2; ngx_tm_t tm, gmt; + time_t sec; + ngx_uint_t msec; ngx_time_t *tp; struct timeval tv; @@ -66,12 +79,10 @@ return; } - if (sec == 0) { - ngx_gettimeofday(&tv); + ngx_gettimeofday(&tv); - sec = tv.tv_sec; - msec = tv.tv_usec / 1000; - } + sec = tv.tv_sec; + msec = tv.tv_usec / 1000; ngx_current_msec = (ngx_msec_t) sec * 1000 + msec; @@ -112,12 +123,14 @@ #elif (NGX_HAVE_GMTOFF) ngx_localtime(sec, &tm); - tp->gmtoff = (ngx_int_t) (tm.ngx_tm_gmtoff / 60); + cached_gmtoff = (ngx_int_t) (tm.ngx_tm_gmtoff / 60); + tp->gmtoff = cached_gmtoff; #else ngx_localtime(sec, &tm); - tp->gmtoff = ngx_timezone(tm.ngx_tm_isdst); + cached_gmtoff = ngx_timezone(tm.ngx_tm_isdst); + tp->gmtoff = cached_gmtoff; #endif @@ -151,6 +164,57 @@ } +#if !(NGX_WIN32) + +void +ngx_time_sigsafe_update(void) +{ + u_char *p; + ngx_tm_t tm; + time_t sec; + ngx_time_t *tp; + struct timeval tv; + + if (!ngx_trylock(&ngx_time_lock)) { + return; + } + + ngx_gettimeofday(&tv); + + sec = tv.tv_sec; + + tp = &cached_time[slot]; + + if (tp->sec == sec) { + ngx_unlock(&ngx_time_lock); + return; + } + + if (slot == NGX_TIME_SLOTS - 1) { + slot = 0; + } else { + slot++; + } + + ngx_gmtime(sec + cached_gmtoff * 60, &tm); + + p = &cached_err_log_time[slot][0]; + + (void) ngx_sprintf(p, "%4d/%02d/%02d %02d:%02d:%02d", + tm.ngx_tm_year, tm.ngx_tm_mon, + tm.ngx_tm_mday, tm.ngx_tm_hour, + tm.ngx_tm_min, tm.ngx_tm_sec); + + ngx_memory_barrier(); + + ngx_cached_err_log_time.data = p; + + ngx_unlock(&ngx_time_lock); +} + +#endif + + u_char * ngx_http_time(u_char *buf, time_t t) { === modified file 'src/core/ngx_times.h' --- src/core/ngx_times.h 2009-10-19 23:22:06 +0000 +++ src/core/ngx_times.h 2010-07-21 11:15:58 +0000 @@ -20,7 +20,8 @@ void ngx_time_init(void); -void ngx_time_update(time_t sec, ngx_uint_t msec); +void ngx_time_update(void); +void ngx_time_sigsafe_update(void); u_char *ngx_http_time(u_char *buf, time_t t); u_char *ngx_http_cookie_time(u_char *buf, time_t t); void ngx_gmtime(time_t t, ngx_tm_t *tp); === modified file 'src/event/modules/ngx_devpoll_module.c' --- src/event/modules/ngx_devpoll_module.c 2009-11-08 09:53:46 +0000 +++ src/event/modules/ngx_devpoll_module.c 2010-07-21 11:15:58 +0000 @@ -375,8 +375,8 @@ err = 0; } - if (flags & NGX_UPDATE_TIME) { - ngx_time_update(0, 0); + if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) { + ngx_time_update(); } if (err) { === modified file 'src/event/modules/ngx_epoll_module.c' --- src/event/modules/ngx_epoll_module.c 2009-11-08 09:53:46 +0000 +++ src/event/modules/ngx_epoll_module.c 2010-07-21 11:15:58 +0000 @@ -407,8 +407,8 @@ err = 0; } - if (flags & NGX_UPDATE_TIME) { - ngx_time_update(0, 0); + if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) { + ngx_time_update(); } if (err) { === modified file 'src/event/modules/ngx_eventport_module.c' --- src/event/modules/ngx_eventport_module.c 2009-11-08 09:53:46 +0000 +++ src/event/modules/ngx_eventport_module.c 2010-07-21 11:15:58 +0000 @@ -405,7 +405,7 @@ err = ngx_errno; if (flags & NGX_UPDATE_TIME) { - ngx_time_update(0, 0); + ngx_time_update(); } if (n == -1) { @@ -439,7 +439,7 @@ for (i = 0; i < events; i++) { if (event_list[i].portev_source == PORT_SOURCE_TIMER) { - ngx_time_update(0, 0); + ngx_time_update(); continue; } === modified file 'src/event/modules/ngx_kqueue_module.c' --- src/event/modules/ngx_kqueue_module.c 2009-11-30 13:34:00 +0000 +++ src/event/modules/ngx_kqueue_module.c 2010-07-21 11:15:58 +0000 @@ -543,8 +543,8 @@ err = 0; } - if (flags & NGX_UPDATE_TIME) { - ngx_time_update(0, 0); + if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) { + ngx_time_update(); } ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, @@ -595,7 +595,7 @@ #if (NGX_HAVE_TIMER_EVENT) if (event_list[i].filter == EVFILT_TIMER) { - ngx_time_update(0, 0); + ngx_time_update(); continue; } === modified file 'src/event/modules/ngx_poll_module.c' --- src/event/modules/ngx_poll_module.c 2007-12-08 11:27:54 +0000 +++ src/event/modules/ngx_poll_module.c 2010-07-21 11:15:58 +0000 @@ -266,8 +266,8 @@ err = 0; } - if (flags & NGX_UPDATE_TIME) { - ngx_time_update(0, 0); + if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) { + ngx_time_update(); } ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, === modified file 'src/event/modules/ngx_rtsig_module.c' --- src/event/modules/ngx_rtsig_module.c 2009-11-08 09:53:46 +0000 +++ src/event/modules/ngx_rtsig_module.c 2010-07-21 11:15:58 +0000 @@ -323,7 +323,7 @@ "rtsig signo:%d", signo); if (flags & NGX_UPDATE_TIME) { - ngx_time_update(0, 0); + ngx_time_update(); } if (err == NGX_EAGAIN) { @@ -349,7 +349,7 @@ signo, si.si_fd, si.si_band); if (flags & NGX_UPDATE_TIME) { - ngx_time_update(0, 0); + ngx_time_update(); } rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module); @@ -419,7 +419,7 @@ } else if (signo == SIGALRM) { - ngx_time_update(0, 0); + ngx_time_update(); return NGX_OK; @@ -671,7 +671,7 @@ } if (flags & NGX_UPDATE_TIME) { - ngx_time_update(0, 0); + ngx_time_update(); } ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, === modified file 'src/event/modules/ngx_select_module.c' --- src/event/modules/ngx_select_module.c 2009-10-19 23:22:06 +0000 +++ src/event/modules/ngx_select_module.c 2010-07-21 11:15:58 +0000 @@ -266,8 +266,8 @@ err = 0; } - if (flags & NGX_UPDATE_TIME) { - ngx_time_update(0, 0); + if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) { + ngx_time_update(); } ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, === modified file 'src/event/modules/ngx_win32_select_module.c' --- src/event/modules/ngx_win32_select_module.c 2009-10-19 23:22:06 +0000 +++ src/event/modules/ngx_win32_select_module.c 2010-07-21 11:15:58 +0000 @@ -273,7 +273,7 @@ } if (flags & NGX_UPDATE_TIME) { - ngx_time_update(0, 0); + ngx_time_update(); } ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, === modified file 'src/event/ngx_event.c' --- src/event/ngx_event.c 2009-11-30 13:34:00 +0000 +++ src/event/ngx_event.c 2010-07-21 11:15:58 +0000 @@ -562,8 +562,6 @@ { ngx_event_timer_alarm = 1; - ngx_time_update(0, 0); - #if 1 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, "timer signal"); #endif === modified file 'src/event/ngx_event_openssl.c' --- src/event/ngx_event_openssl.c 2010-03-03 23:50:36 +0000 +++ src/event/ngx_event_openssl.c 2010-07-21 11:15:58 +0000 @@ -106,6 +106,8 @@ ENGINE_load_builtin_engines(); + OpenSSL_add_all_algorithms(); + ngx_ssl_connection_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL); if (ngx_ssl_connection_index == -1) { @@ -559,6 +561,9 @@ #if (NGX_DEBUG) { char buf[129], *s, *d; +#if OPENSSL_VERSION_NUMBER >= 0x1000000fL + const +#endif SSL_CIPHER *cipher; cipher = SSL_get_current_cipher(c->ssl->connection); @@ -1308,10 +1313,14 @@ /* handshake failures */ if (n == SSL_R_DIGEST_CHECK_FAILED /* 149 */ + || n == SSL_R_LENGTH_MISMATCH /* 159 */ || n == SSL_R_NO_CIPHERS_PASSED /* 182 */ + || n == SSL_R_NO_CIPHERS_SPECIFIED /* 183 */ || n == SSL_R_NO_SHARED_CIPHER /* 193 */ + || n == SSL_R_RECORD_LENGTH_MISMATCH /* 213 */ || n == SSL_R_UNEXPECTED_MESSAGE /* 244 */ || n == SSL_R_UNEXPECTED_RECORD /* 245 */ + || n == SSL_R_UNKNOWN_ALERT_TYPE /* 246 */ || n == SSL_R_UNKNOWN_PROTOCOL /* 252 */ || n == SSL_R_WRONG_VERSION_NUMBER /* 267 */ || n == SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC /* 281 */ @@ -1424,6 +1433,8 @@ return NGX_OK; } + SSL_CTX_set_session_id_context(ssl->ctx, sess_ctx->data, sess_ctx->len); + if (builtin_session_cache == NGX_SSL_NONE_SCACHE) { /* @@ -1455,8 +1466,6 @@ SSL_CTX_set_session_cache_mode(ssl->ctx, cache_mode); - SSL_CTX_set_session_id_context(ssl->ctx, sess_ctx->data, sess_ctx->len); - if (builtin_session_cache != NGX_SSL_NO_BUILTIN_SCACHE) { if (builtin_session_cache != NGX_SSL_DFLT_BUILTIN_SCACHE) { @@ -2311,5 +2320,6 @@ static void ngx_openssl_exit(ngx_cycle_t *cycle) { + EVP_cleanup(); ENGINE_cleanup(); } === modified file 'src/event/ngx_event_openssl.h' --- src/event/ngx_event_openssl.h 2010-03-03 23:50:36 +0000 +++ src/event/ngx_event_openssl.h 2010-07-21 11:15:58 +0000 @@ -15,6 +15,7 @@ #include #include #include +#include #define NGX_SSL_NAME "OpenSSL" === modified file 'src/http/modules/ngx_http_autoindex_module.c' --- src/http/modules/ngx_http_autoindex_module.c 2009-11-30 13:34:00 +0000 +++ src/http/modules/ngx_http_autoindex_module.c 2010-07-21 11:15:58 +0000 @@ -160,10 +160,6 @@ return NGX_DECLINED; } - if (r->zero_in_uri) { - return NGX_DECLINED; - } - if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) { return NGX_DECLINED; } === modified file 'src/http/modules/ngx_http_chunked_filter_module.c' --- src/http/modules/ngx_http_chunked_filter_module.c 2009-10-19 23:22:06 +0000 +++ src/http/modules/ngx_http_chunked_filter_module.c 2010-07-21 11:15:58 +0000 @@ -50,9 +50,10 @@ static ngx_int_t ngx_http_chunked_header_filter(ngx_http_request_t *r) { + ngx_http_core_loc_conf_t *clcf; + if (r->headers_out.status == NGX_HTTP_NOT_MODIFIED || r->headers_out.status == NGX_HTTP_NO_CONTENT - || r->headers_out.status == NGX_HTTP_CREATED || r != r->main || (r->method & NGX_HTTP_HEAD)) { @@ -64,7 +65,14 @@ r->keepalive = 0; } else { - r->chunked = 1; + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + + if (clcf->chunked_transfer_encoding) { + r->chunked = 1; + + } else { + r->keepalive = 0; + } } } === modified file 'src/http/modules/ngx_http_dav_module.c' --- src/http/modules/ngx_http_dav_module.c 2009-11-30 13:34:00 +0000 +++ src/http/modules/ngx_http_dav_module.c 2010-07-21 11:15:58 +0000 @@ -146,10 +146,6 @@ ngx_int_t rc; ngx_http_dav_loc_conf_t *dlcf; - if (r->zero_in_uri) { - return NGX_DECLINED; - } - dlcf = ngx_http_get_module_loc_conf(r, ngx_http_dav_module); if (!(r->method & dlcf->methods)) { @@ -325,13 +321,13 @@ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http delete filename: \"%s\"", path.data); - if (ngx_file_info(path.data, &fi) == NGX_FILE_ERROR) { + if (ngx_link_info(path.data, &fi) == NGX_FILE_ERROR) { err = ngx_errno; rc = (err == NGX_ENOTDIR) ? NGX_HTTP_CONFLICT : NGX_HTTP_NOT_FOUND; return ngx_http_dav_error(r->connection->log, err, - rc, ngx_file_info_n, path.data); + rc, ngx_link_info_n, path.data); } if (ngx_is_dir(&fi)) { @@ -358,7 +354,7 @@ /* * we do not need to test (r->uri.data[r->uri.len - 1] == '/') - * because ngx_file_info("/file/") returned NGX_ENOTDIR above + * because ngx_link_info("/file/") returned NGX_ENOTDIR above */ depth = ngx_http_dav_depth(r, 0); @@ -685,12 +681,12 @@ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http copy to: \"%s\"", copy.path.data); - if (ngx_file_info(copy.path.data, &fi) == NGX_FILE_ERROR) { + if (ngx_link_info(copy.path.data, &fi) == NGX_FILE_ERROR) { err = ngx_errno; if (err != NGX_ENOENT) { return ngx_http_dav_error(r->connection->log, err, - NGX_HTTP_NOT_FOUND, ngx_file_info_n, + NGX_HTTP_NOT_FOUND, ngx_link_info_n, copy.path.data); } @@ -719,9 +715,9 @@ dir = ngx_is_dir(&fi); } - if (ngx_file_info(path.data, &fi) == NGX_FILE_ERROR) { + if (ngx_link_info(path.data, &fi) == NGX_FILE_ERROR) { return ngx_http_dav_error(r->connection->log, ngx_errno, - NGX_HTTP_NOT_FOUND, ngx_file_info_n, + NGX_HTTP_NOT_FOUND, ngx_link_info_n, path.data); } === modified file 'src/http/modules/ngx_http_fastcgi_module.c' --- src/http/modules/ngx_http_fastcgi_module.c 2010-03-03 23:50:36 +0000 +++ src/http/modules/ngx_http_fastcgi_module.c 2010-07-21 11:15:58 +0000 @@ -333,6 +333,13 @@ 0, &ngx_http_fastcgi_module }, + { ngx_string("fastcgi_no_cache"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, + ngx_http_no_cache_set_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_fastcgi_loc_conf_t, upstream.no_cache), + NULL }, + { ngx_string("fastcgi_cache_valid"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, ngx_http_file_cache_valid_set_slot, @@ -1890,6 +1897,7 @@ #if (NGX_HTTP_CACHE) conf->upstream.cache = NGX_CONF_UNSET_PTR; conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT; + conf->upstream.no_cache = NGX_CONF_UNSET_PTR; conf->upstream.cache_valid = NGX_CONF_UNSET_PTR; #endif @@ -2111,6 +2119,9 @@ conf->upstream.cache_methods |= NGX_HTTP_GET|NGX_HTTP_HEAD; + ngx_conf_merge_ptr_value(conf->upstream.no_cache, + prev->upstream.no_cache, NULL); + ngx_conf_merge_ptr_value(conf->upstream.cache_valid, prev->upstream.cache_valid, NULL); === modified file 'src/http/modules/ngx_http_flv_module.c' --- src/http/modules/ngx_http_flv_module.c 2009-10-19 23:22:06 +0000 +++ src/http/modules/ngx_http_flv_module.c 2010-07-21 11:15:58 +0000 @@ -80,10 +80,6 @@ return NGX_DECLINED; } - if (r->zero_in_uri) { - return NGX_DECLINED; - } - rc = ngx_http_discard_request_body(r); if (rc != NGX_OK) { === modified file 'src/http/modules/ngx_http_geo_module.c' --- src/http/modules/ngx_http_geo_module.c 2009-11-30 13:34:00 +0000 +++ src/http/modules/ngx_http_geo_module.c 2010-07-21 11:15:58 +0000 @@ -589,7 +589,7 @@ ngx_array_t *a; ngx_http_geo_range_t *range; - for (n = start; n <= end; n += 0x10000) { + for (n = start; n <= end; n = (n + 0x10000) & 0xffff0000) { h = n >> 16; === modified file 'src/http/modules/ngx_http_geoip_module.c' --- src/http/modules/ngx_http_geoip_module.c 2009-11-08 09:53:46 +0000 +++ src/http/modules/ngx_http_geoip_module.c 2010-07-21 11:15:58 +0000 @@ -30,6 +30,9 @@ ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_geoip_city_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); +static ngx_int_t ngx_http_geoip_city_float_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data); +static GeoIPRecord *ngx_http_geoip_get_city_record(ngx_http_request_t *r); static ngx_int_t ngx_http_geoip_add_variables(ngx_conf_t *cf); static void *ngx_http_geoip_create_conf(ngx_conf_t *cf); @@ -93,23 +96,32 @@ static ngx_http_variable_t ngx_http_geoip_vars[] = { - { ngx_string("geoip_country_code"), NULL, ngx_http_geoip_country_variable, + { ngx_string("geoip_country_code"), NULL, + ngx_http_geoip_country_variable, (uintptr_t) GeoIP_country_code_by_ipnum, 0, 0 }, - { ngx_string("geoip_country_code3"), NULL, ngx_http_geoip_country_variable, + { ngx_string("geoip_country_code3"), NULL, + ngx_http_geoip_country_variable, (uintptr_t) GeoIP_country_code3_by_ipnum, 0, 0 }, - { ngx_string("geoip_country_name"), NULL, ngx_http_geoip_country_variable, + { ngx_string("geoip_country_name"), NULL, + ngx_http_geoip_country_variable, (uintptr_t) GeoIP_country_name_by_ipnum, 0, 0 }, - { ngx_string("geoip_city_country_code"), NULL, ngx_http_geoip_city_variable, + { ngx_string("geoip_city_continent_code"), NULL, + ngx_http_geoip_city_variable, + offsetof(GeoIPRecord, continent_code), 0, 0 }, + + { ngx_string("geoip_city_country_code"), NULL, + ngx_http_geoip_city_variable, offsetof(GeoIPRecord, country_code), 0, 0 }, { ngx_string("geoip_city_country_code3"), NULL, ngx_http_geoip_city_variable, offsetof(GeoIPRecord, country_code3), 0, 0 }, - { ngx_string("geoip_city_country_name"), NULL, ngx_http_geoip_city_variable, + { ngx_string("geoip_city_country_name"), NULL, + ngx_http_geoip_city_variable, offsetof(GeoIPRecord, country_name), 0, 0 }, { ngx_string("geoip_region"), NULL, @@ -124,6 +136,14 @@ ngx_http_geoip_city_variable, offsetof(GeoIPRecord, postal_code), 0, 0 }, + { ngx_string("geoip_latitude"), NULL, + ngx_http_geoip_city_float_variable, + offsetof(GeoIPRecord, latitude), 0, 0 }, + + { ngx_string("geoip_longitude"), NULL, + ngx_http_geoip_city_float_variable, + offsetof(GeoIPRecord, longitude), 0, 0 }, + { ngx_null_string, NULL, NULL, 0, 0, 0 } }; @@ -179,34 +199,16 @@ ngx_http_geoip_city_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { - u_long addr; - char *val; - size_t len; - GeoIPRecord *gr; - struct sockaddr_in *sin; - ngx_http_geoip_conf_t *gcf; - - gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module); - - if (gcf->city == NULL) { - goto not_found; - } - - if (r->connection->sockaddr->sa_family != AF_INET) { - goto not_found; - } - - sin = (struct sockaddr_in *) r->connection->sockaddr; - addr = ntohl(sin->sin_addr.s_addr); - - gr = GeoIP_record_by_ipnum(gcf->city, addr); - + char *val; + size_t len; + GeoIPRecord *gr; + + gr = ngx_http_geoip_get_city_record(r); if (gr == NULL) { goto not_found; } val = *(char **) ((char *) gr + data); - if (val == NULL) { goto no_value; } @@ -243,6 +245,56 @@ static ngx_int_t +ngx_http_geoip_city_float_variable(ngx_http_request_t *r, + ngx_http_variable_value_t *v, uintptr_t data) +{ + float val; + GeoIPRecord *gr; + + gr = ngx_http_geoip_get_city_record(r); + if (gr == NULL) { + v->not_found = 1; + return NGX_OK; + } + + v->data = ngx_pnalloc(r->pool, NGX_INT64_LEN + 5); + if (v->data == NULL) { + GeoIPRecord_delete(gr); + return NGX_ERROR; + } + + val = *(float *) ((char *) gr + data); + + v->len = ngx_sprintf(v->data, "%.4f", val) - v->data; + + GeoIPRecord_delete(gr); + + return NGX_OK; +} + + +static GeoIPRecord * +ngx_http_geoip_get_city_record(ngx_http_request_t *r) +{ + u_long addr; + struct sockaddr_in *sin; + ngx_http_geoip_conf_t *gcf; + + gcf = ngx_http_get_module_main_conf(r, ngx_http_geoip_module); + + if (gcf->city && r->connection->sockaddr->sa_family == AF_INET) { + + sin = (struct sockaddr_in *) r->connection->sockaddr; + addr = ntohl(sin->sin_addr.s_addr); + + return GeoIP_record_by_ipnum(gcf->city, addr); + } + + return NULL; +} + + +static ngx_int_t ngx_http_geoip_add_variables(ngx_conf_t *cf) { ngx_http_variable_t *var, *v; === modified file 'src/http/modules/ngx_http_gzip_static_module.c' --- src/http/modules/ngx_http_gzip_static_module.c 2010-03-03 23:50:36 +0000 +++ src/http/modules/ngx_http_gzip_static_module.c 2010-07-21 11:15:58 +0000 @@ -89,10 +89,6 @@ return NGX_DECLINED; } - if (r->zero_in_uri) { - return NGX_DECLINED; - } - gzcf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_static_module); if (!gzcf->enable) { @@ -179,7 +175,7 @@ #if !(NGX_WIN32) /* the not regular files are probably Unix specific */ if (!of.is_file) { - ngx_log_error(NGX_LOG_CRIT, log, ngx_errno, + ngx_log_error(NGX_LOG_CRIT, log, 0, "\"%s\" is not a regular file", path.data); return NGX_HTTP_NOT_FOUND; === modified file 'src/http/modules/ngx_http_image_filter_module.c' --- src/http/modules/ngx_http_image_filter_module.c 2009-11-30 13:34:00 +0000 +++ src/http/modules/ngx_http_image_filter_module.c 2010-07-21 11:15:58 +0000 @@ -63,6 +63,7 @@ ngx_uint_t phase; ngx_uint_t type; + ngx_uint_t force; } ngx_http_image_filter_ctx_t; @@ -501,7 +502,8 @@ if (rc == NGX_OK && ctx->width <= ctx->max_width - && ctx->height <= ctx->max_height) + && ctx->height <= ctx->max_height + && !ctx->force) { return ngx_http_image_asis(r, ctx); } @@ -601,6 +603,7 @@ ngx_http_image_size(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx) { u_char *p, *last; + size_t len, app; ngx_uint_t width, height; p = ctx->image; @@ -611,26 +614,38 @@ p += 2; last = ctx->image + ctx->length - 10; + width = 0; + height = 0; + app = 0; while (p < last) { if (p[0] == 0xff && p[1] != 0xff) { ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "JPEG: %02xd %02xd", *p, *(p + 1)); + "JPEG: %02xd %02xd", p[0], p[1]); p++; - if (*p == 0xc0 || *p == 0xc1 || *p == 0xc2 || *p == 0xc3 - || *p == 0xc9 || *p == 0xca || *p == 0xcb) + if ((*p == 0xc0 || *p == 0xc1 || *p == 0xc2 || *p == 0xc3 + || *p == 0xc9 || *p == 0xca || *p == 0xcb) + && (width == 0 || height == 0)) { - goto found; + width = p[6] * 256 + p[7]; + height = p[4] * 256 + p[5]; } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "JPEG: %02xd %02xd", p[1], p[2]); - p += p[1] * 256 + p[2]; + len = p[1] * 256 + p[2]; + + if (*p >= 0xe1 && *p <= 0xef) { + /* application data, e.g., EXIF, Adobe XMP, etc. */ + app += len; + } + + p += len; continue; } @@ -638,12 +653,16 @@ p++; } - return NGX_DECLINED; - - found: - - width = p[6] * 256 + p[7]; - height = p[4] * 256 + p[5]; + if (width == 0 || height == 0) { + return NGX_DECLINED; + } + + if (ctx->length / 20 < app) { + /* force conversion if application data consume more than 5% */ + ctx->force = 1; + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "app data size: %uz", app); + } break; @@ -708,7 +727,8 @@ conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module); - if ((ngx_uint_t) sx <= ctx->max_width + if (!ctx->force + && (ngx_uint_t) sx <= ctx->max_width && (ngx_uint_t) sy <= ctx->max_height) { gdImageDestroy(src); === modified file 'src/http/modules/ngx_http_index_module.c' --- src/http/modules/ngx_http_index_module.c 2010-03-03 23:50:36 +0000 +++ src/http/modules/ngx_http_index_module.c 2010-07-21 11:15:58 +0000 @@ -116,10 +116,6 @@ return NGX_DECLINED; } - if (r->zero_in_uri) { - return NGX_DECLINED; - } - ilcf = ngx_http_get_module_loc_conf(r, ngx_http_index_module); clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); === modified file 'src/http/modules/ngx_http_memcached_module.c' --- src/http/modules/ngx_http_memcached_module.c 2009-11-30 13:34:00 +0000 +++ src/http/modules/ngx_http_memcached_module.c 2010-07-21 11:15:58 +0000 @@ -423,15 +423,20 @@ if (ngx_strncmp(b->last, ngx_http_memcached_end + NGX_HTTP_MEMCACHED_END - ctx->rest, - ctx->rest) + bytes) != 0) { ngx_log_error(NGX_LOG_ERR, ctx->request->connection->log, 0, "memcached sent invalid trailer"); + + u->length = 0; + ctx->rest = 0; + + return NGX_OK; } - u->length = 0; - ctx->rest = 0; + u->length -= bytes; + ctx->rest -= bytes; return NGX_OK; } === modified file 'src/http/modules/ngx_http_proxy_module.c' --- src/http/modules/ngx_http_proxy_module.c 2010-03-03 23:50:36 +0000 +++ src/http/modules/ngx_http_proxy_module.c 2010-07-21 11:15:58 +0000 @@ -357,6 +357,13 @@ 0, &ngx_http_proxy_module }, + { ngx_string("proxy_no_cache"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, + ngx_http_no_cache_set_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_proxy_loc_conf_t, upstream.no_cache), + NULL }, + { ngx_string("proxy_cache_valid"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, ngx_http_file_cache_valid_set_slot, @@ -630,6 +637,7 @@ u->process_header = ngx_http_proxy_process_status_line; u->abort_request = ngx_http_proxy_abort_request; u->finalize_request = ngx_http_proxy_finalize_request; + r->state = 0; if (plcf->redirects) { u->rewrite_redirect = ngx_http_proxy_rewrite_redirect; @@ -1191,6 +1199,7 @@ ctx->status_end = NULL; r->upstream->process_header = ngx_http_proxy_process_status_line; + r->state = 0; return NGX_OK; } @@ -1906,7 +1915,7 @@ * conf->body_set_len = NULL; * conf->body_set = NULL; * conf->body_source = { 0, NULL }; - * conf->rewrite_locations = NULL; + * conf->redirects = NULL; */ conf->upstream.store = NGX_CONF_UNSET; @@ -1931,6 +1940,7 @@ #if (NGX_HTTP_CACHE) conf->upstream.cache = NGX_CONF_UNSET_PTR; conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT; + conf->upstream.no_cache = NGX_CONF_UNSET_PTR; conf->upstream.cache_valid = NGX_CONF_UNSET_PTR; #endif @@ -2155,6 +2165,9 @@ |NGX_HTTP_UPSTREAM_FT_OFF; } + ngx_conf_merge_ptr_value(conf->upstream.no_cache, + prev->upstream.no_cache, NULL); + ngx_conf_merge_ptr_value(conf->upstream.cache_valid, prev->upstream.cache_valid, NULL); @@ -2747,9 +2760,16 @@ } if (ngx_strcmp(value[1].data, "default") == 0) { + if (plcf->proxy_lengths) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "\"proxy_redirect default\" may not be used " + "with \"proxy_pass\" directive with variables"); + return NGX_CONF_ERROR; + } + if (plcf->url.data == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, - "\"proxy_rewrite_location default\" must go " + "\"proxy_redirect default\" must go " "after the \"proxy_pass\" directive"); return NGX_CONF_ERROR; } === modified file 'src/http/modules/ngx_http_random_index_module.c' --- src/http/modules/ngx_http_random_index_module.c 2010-03-03 23:50:36 +0000 +++ src/http/modules/ngx_http_random_index_module.c 2010-07-21 11:15:58 +0000 @@ -86,10 +86,6 @@ return NGX_DECLINED; } - if (r->zero_in_uri) { - return NGX_DECLINED; - } - if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD|NGX_HTTP_POST))) { return NGX_DECLINED; } === modified file 'src/http/modules/ngx_http_referer_module.c' --- src/http/modules/ngx_http_referer_module.c 2009-11-27 11:10:18 +0000 +++ src/http/modules/ngx_http_referer_module.c 2010-07-21 11:15:58 +0000 @@ -124,18 +124,27 @@ len = r->headers_in.referer->value.len; ref = r->headers_in.referer->value.data; - if (len < sizeof("http://i.ru") - 1 - || (ngx_strncasecmp(ref, (u_char *) "http://", 7) != 0)) - { - if (rlcf->blocked_referer) { - goto valid; + if (len >= sizeof("http://i.ru") - 1) { + last = ref + len; + + if (ngx_strncasecmp(ref, (u_char *) "http://", 7) == 0) { + ref += 7; + goto valid_scheme; + + } else if (ngx_strncasecmp(ref, (u_char *) "https://", 8) == 0) { + ref += 8; + goto valid_scheme; } - - goto invalid; - } - - last = ref + len; - ref += 7; + } + + if (rlcf->blocked_referer) { + goto valid; + } + + goto invalid; + +valid_scheme: + i = 0; key = 0; === modified file 'src/http/modules/ngx_http_rewrite_module.c' --- src/http/modules/ngx_http_rewrite_module.c 2009-11-30 13:34:00 +0000 +++ src/http/modules/ngx_http_rewrite_module.c 2010-07-21 11:15:58 +0000 @@ -340,13 +340,10 @@ last = 0; - if (ngx_strncmp(value[2].data, "http://", sizeof("http://") - 1) == 0) { - regex->status = NGX_HTTP_MOVED_TEMPORARILY; - regex->redirect = 1; - last = 1; - } - - if (ngx_strncmp(value[2].data, "https://", sizeof("https://") - 1) == 0) { + if (ngx_strncmp(value[2].data, "http://", sizeof("http://") - 1) == 0 + || ngx_strncmp(value[2].data, "https://", sizeof("https://") - 1) == 0 + || ngx_strncmp(value[2].data, "$scheme", sizeof("$scheme") - 1) == 0) + { regex->status = NGX_HTTP_MOVED_TEMPORARILY; regex->redirect = 1; last = 1; === modified file 'src/http/modules/ngx_http_ssi_filter_module.c' --- src/http/modules/ngx_http_ssi_filter_module.c 2009-11-30 13:34:00 +0000 +++ src/http/modules/ngx_http_ssi_filter_module.c 2010-07-21 11:15:58 +0000 @@ -14,7 +14,6 @@ #define NGX_HTTP_SSI_ADD_PREFIX 1 #define NGX_HTTP_SSI_ADD_ZERO 2 -#define NGX_HTTP_SSI_EXPR_TEST 4 typedef struct { @@ -1701,8 +1700,7 @@ val = ngx_http_ssi_get_variable(r, &var, key); if (val == NULL) { - vv = ngx_http_get_variable(r, &var, key, - flags & NGX_HTTP_SSI_EXPR_TEST); + vv = ngx_http_get_variable(r, &var, key); if (vv == NULL) { return NGX_ERROR; } @@ -2061,9 +2059,9 @@ out = data; if (!r->header_sent) { - if (ngx_http_set_content_type(r) != NGX_OK) { - return NGX_ERROR; - } + r->headers_out.content_type_len = + r->parent->headers_out.content_type_len; + r->headers_out.content_type = r->parent->headers_out.content_type; if (ngx_http_send_header(r) == NGX_ERROR) { return NGX_ERROR; @@ -2110,7 +2108,7 @@ value = ngx_http_ssi_get_variable(r, var, key); if (value == NULL) { - vv = ngx_http_get_variable(r, var, key, 1); + vv = ngx_http_get_variable(r, var, key); if (vv == NULL) { return NGX_HTTP_SSI_ERROR; @@ -2161,11 +2159,10 @@ } } + p = value->data; + switch (ctx->encoding) { - case NGX_HTTP_SSI_NO_ENCODING: - break; - case NGX_HTTP_SSI_URL_ENCODING: len = 2 * ngx_escape_uri(NULL, value->data, value->len, NGX_ESCAPE_HTML); @@ -2177,11 +2174,9 @@ } (void) ngx_escape_uri(p, value->data, value->len, NGX_ESCAPE_HTML); - - value->len += len; - value->data = p; } + len += value->len; break; case NGX_HTTP_SSI_ENTITY_ENCODING: @@ -2194,11 +2189,13 @@ } (void) ngx_escape_html(p, value->data, value->len); - - value->len += len; - value->data = p; } + len += value->len; + break; + + default: /* NGX_HTTP_SSI_NO_ENCODING */ + len = value->len; break; } @@ -2213,8 +2210,8 @@ } b->memory = 1; - b->pos = value->data; - b->last = value->data + value->len; + b->pos = p; + b->last = p + len; cl->buf = b; cl->next = NULL; @@ -2362,7 +2359,7 @@ p++; } - flags = (p == last) ? NGX_HTTP_SSI_EXPR_TEST : 0; + flags = 0; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "left: \"%V\"", &left); @@ -2614,8 +2611,7 @@ return NGX_ERROR; } - v->len = ngx_sprintf(v->data, "%T", tp->sec + (gmt ? 0 : tp->gmtoff)) - - v->data; + v->len = ngx_sprintf(v->data, "%T", tp->sec) - v->data; return NGX_OK; } === modified file 'src/http/modules/ngx_http_static_module.c' --- src/http/modules/ngx_http_static_module.c 2009-10-19 23:22:06 +0000 +++ src/http/modules/ngx_http_static_module.c 2010-07-21 11:15:58 +0000 @@ -66,10 +66,6 @@ return NGX_DECLINED; } - if (r->zero_in_uri) { - return NGX_DECLINED; - } - log = r->connection->log; /* @@ -188,7 +184,7 @@ #if !(NGX_WIN32) /* the not regular files are probably Unix specific */ if (!of.is_file) { - ngx_log_error(NGX_LOG_CRIT, log, ngx_errno, + ngx_log_error(NGX_LOG_CRIT, log, 0, "\"%s\" is not a regular file", path.data); return NGX_HTTP_NOT_FOUND; === modified file 'src/http/modules/ngx_http_userid_filter_module.c' --- src/http/modules/ngx_http_userid_filter_module.c 2009-11-30 13:34:00 +0000 +++ src/http/modules/ngx_http_userid_filter_module.c 2010-07-21 11:15:58 +0000 @@ -545,7 +545,7 @@ { ngx_http_variable_t *var; - var = ngx_http_add_variable(cf, &ngx_http_userid_got, NGX_HTTP_VAR_NOHASH); + var = ngx_http_add_variable(cf, &ngx_http_userid_got, 0); if (var == NULL) { return NGX_ERROR; } === modified file 'src/http/modules/perl/nginx.pm' --- src/http/modules/perl/nginx.pm 2010-03-03 23:50:36 +0000 +++ src/http/modules/perl/nginx.pm 2010-07-21 11:15:58 +0000 @@ -47,7 +47,7 @@ HTTP_INSUFFICIENT_STORAGE ); -our $VERSION = '0.7.65'; +our $VERSION = '0.7.67'; require XSLoader; XSLoader::load('nginx', $VERSION); === modified file 'src/http/modules/perl/nginx.xs' --- src/http/modules/perl/nginx.xs 2009-10-19 23:22:06 +0000 +++ src/http/modules/perl/nginx.xs 2010-07-21 11:15:58 +0000 @@ -847,7 +847,7 @@ #endif - vv = ngx_http_get_variable(r, &var, hash, 1); + vv = ngx_http_get_variable(r, &var, hash); if (vv == NULL) { XSRETURN_UNDEF; } @@ -901,9 +901,6 @@ XSRETURN_UNDEF; } - ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, - "variable \"%V\" not found", &var); - XSRETURN_UNDEF; } === modified file 'src/http/modules/perl/ngx_http_perl_module.c' --- src/http/modules/perl/ngx_http_perl_module.c 2010-03-03 23:50:36 +0000 +++ src/http/modules/perl/ngx_http_perl_module.c 2010-07-21 11:15:58 +0000 @@ -30,12 +30,6 @@ } ngx_http_perl_variable_t; -typedef struct { - SV *sv; - PerlInterpreter *perl; -} ngx_http_perl_cleanup_t; - - #if (NGX_HTTP_SSI) static ngx_int_t ngx_http_perl_ssi(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ssi_ctx, ngx_str_t **params); @@ -174,10 +168,6 @@ static ngx_int_t ngx_http_perl_handler(ngx_http_request_t *r) { - if (r->zero_in_uri) { - return NGX_HTTP_NOT_FOUND; - } - ngx_http_perl_handle_request(r); return NGX_DONE; === modified file 'src/http/ngx_http_cache.h' --- src/http/ngx_http_cache.h 2009-11-30 13:34:00 +0000 +++ src/http/ngx_http_cache.h 2010-07-21 11:15:58 +0000 @@ -133,6 +133,11 @@ char *ngx_http_file_cache_valid_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +ngx_int_t ngx_http_cache(ngx_http_request_t *r, ngx_array_t *no_cache); +char *ngx_http_no_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); + + extern ngx_str_t ngx_http_cache_status[]; === modified file 'src/http/ngx_http_copy_filter_module.c' --- src/http/ngx_http_copy_filter_module.c 2009-10-19 23:22:06 +0000 +++ src/http/ngx_http_copy_filter_module.c 2010-07-21 11:15:58 +0000 @@ -104,7 +104,9 @@ ctx->output_filter = (ngx_output_chain_filter_pt) ngx_http_next_filter; ctx->filter_ctx = r; - r->request_output = 1; + if (in && in->buf && ngx_buf_size(in->buf)) { + r->request_output = 1; + } } rc = ngx_output_chain(ctx, in); === modified file 'src/http/ngx_http_core_module.c' --- src/http/ngx_http_core_module.c 2010-03-03 23:50:36 +0000 +++ src/http/ngx_http_core_module.c 2010-07-21 11:15:58 +0000 @@ -560,6 +560,13 @@ offsetof(ngx_http_core_loc_conf_t, if_modified_since), &ngx_http_core_if_modified_since }, + { ngx_string("chunked_transfer_encoding"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, + ngx_conf_set_flag_slot, + NGX_HTTP_LOC_CONF_OFFSET, + offsetof(ngx_http_core_loc_conf_t, chunked_transfer_encoding), + NULL }, + { ngx_string("error_page"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF |NGX_CONF_2MORE, @@ -744,14 +751,24 @@ break; } - if (r->keepalive && r->headers_in.msie && r->method == NGX_HTTP_POST) { - - /* - * MSIE may wait for some time if an response for - * a POST request was sent over a keepalive connection - */ - - r->keepalive = 0; + if (r->keepalive) { + + if (r->headers_in.msie6) { + if (r->method == NGX_HTTP_POST) { + /* + * MSIE may wait for some time if an response for + * a POST request was sent over a keepalive connection + */ + r->keepalive = 0; + } + + } else if (r->headers_in.safari) { + /* + * Safari may send a POST request to a closed keepalive + * connection and stalls for some time + */ + r->keepalive = 0; + } } if (r->headers_in.content_length_n > 0) { @@ -1288,7 +1305,7 @@ /* no content handler was found */ - if (r->uri.data[r->uri.len - 1] == '/' && !r->zero_in_uri) { + if (r->uri.data[r->uri.len - 1] == '/') { if (ngx_http_map_uri_to_path(r, &path, &root, 0) != NULL) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, @@ -2076,7 +2093,6 @@ ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, "http subrequest \"%V?%V\"", uri, &sr->args); - sr->zero_in_uri = (flags & NGX_HTTP_ZERO_IN_URI) != 0; sr->subrequest_in_memory = (flags & NGX_HTTP_SUBREQUEST_IN_MEMORY) != 0; sr->waited = (flags & NGX_HTTP_SUBREQUEST_WAITED) != 0; @@ -2944,6 +2960,7 @@ lcf->log_subrequest = NGX_CONF_UNSET; lcf->recursive_error_pages = NGX_CONF_UNSET; lcf->server_tokens = NGX_CONF_UNSET; + lcf->chunked_transfer_encoding = NGX_CONF_UNSET; lcf->types_hash_max_size = NGX_CONF_UNSET_UINT; lcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT; @@ -3181,6 +3198,8 @@ ngx_conf_merge_value(conf->recursive_error_pages, prev->recursive_error_pages, 0); ngx_conf_merge_value(conf->server_tokens, prev->server_tokens, 1); + ngx_conf_merge_value(conf->chunked_transfer_encoding, + prev->chunked_transfer_encoding, 1); ngx_conf_merge_ptr_value(conf->open_file_cache, prev->open_file_cache, NULL); === modified file 'src/http/ngx_http_core_module.h' --- src/http/ngx_http_core_module.h 2009-11-30 13:34:00 +0000 +++ src/http/ngx_http_core_module.h 2010-07-21 11:15:58 +0000 @@ -358,6 +358,7 @@ ngx_flag_t log_subrequest; /* log_subrequest */ ngx_flag_t recursive_error_pages; /* recursive_error_pages */ ngx_flag_t server_tokens; /* server_tokens */ + ngx_flag_t chunked_transfer_encoding; /* chunked_transfer_encoding */ #if (NGX_HTTP_GZIP) ngx_flag_t gzip_vary; /* gzip_vary */ === modified file 'src/http/ngx_http_file_cache.c' --- src/http/ngx_http_file_cache.c 2010-03-03 23:50:36 +0000 +++ src/http/ngx_http_file_cache.c 2010-07-21 11:15:58 +0000 @@ -1128,7 +1128,7 @@ if (cache->files++ > 100) { - ngx_time_update(0, 0); + ngx_time_update(); elapsed = ngx_abs((ngx_msec_int_t) (ngx_current_msec - cache->last)); @@ -1145,7 +1145,7 @@ ngx_msleep(200); - ngx_time_update(0, 0); + ngx_time_update(); } cache->last = ngx_current_msec; @@ -1604,3 +1604,69 @@ return NGX_CONF_OK; } + + +ngx_int_t +ngx_http_cache(ngx_http_request_t *r, ngx_array_t *no_cache) +{ + ngx_str_t val; + ngx_uint_t i; + ngx_http_complex_value_t *cv; + + cv = no_cache->elts; + + for (i = 0; i < no_cache->nelts; i++) { + if (ngx_http_complex_value(r, &cv[i], &val) != NGX_OK) { + return NGX_ERROR; + } + + if (val.len && val.data[0] != '0') { + return NGX_DECLINED; + } + } + + return NGX_OK; +} + + +char * +ngx_http_no_cache_set_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + char *p = conf; + + ngx_str_t *value; + ngx_uint_t i; + ngx_array_t **a; + ngx_http_complex_value_t *cv; + ngx_http_compile_complex_value_t ccv; + + a = (ngx_array_t **) (p + cmd->offset); + + if (*a == NGX_CONF_UNSET_PTR) { + *a = ngx_array_create(cf->pool, 1, sizeof(ngx_http_complex_value_t)); + if (*a == NULL) { + return NGX_CONF_ERROR; + } + } + + value = cf->args->elts; + + for (i = 1; i < cf->args->nelts; i++) { + cv = ngx_array_push(*a); + if (cv == NULL) { + return NGX_CONF_ERROR; + } + + ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); + + ccv.cf = cf; + ccv.value = &value[i]; + ccv.complex_value = cv; + + if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { + return NGX_CONF_ERROR; + } + } + + return NGX_CONF_OK; +} === modified file 'src/http/ngx_http_header_filter_module.c' --- src/http/ngx_http_header_filter_module.c 2010-03-03 23:50:36 +0000 +++ src/http/ngx_http_header_filter_module.c 2010-07-21 11:15:58 +0000 @@ -538,8 +538,8 @@ r->headers_out.location->value.len = b->last - p; r->headers_out.location->value.data = p; - r->headers_out.location->key.len = sizeof("Location: ") - 1; - r->headers_out.location->key.data = (u_char *) "Location: "; + r->headers_out.location->key.len = sizeof("Location") - 1; + r->headers_out.location->key.data = (u_char *) "Location"; *b->last++ = CR; *b->last++ = LF; } === modified file 'src/http/ngx_http_parse.c' --- src/http/ngx_http_parse.c 2009-11-30 13:34:00 +0000 +++ src/http/ngx_http_parse.c 2010-07-21 11:15:58 +0000 @@ -438,8 +438,7 @@ r->plus_in_uri = 1; break; case '\0': - r->zero_in_uri = 1; - break; + return NGX_HTTP_PARSE_INVALID_REQUEST; default: state = sw_check_uri; break; @@ -496,8 +495,7 @@ r->plus_in_uri = 1; break; case '\0': - r->zero_in_uri = 1; - break; + return NGX_HTTP_PARSE_INVALID_REQUEST; } break; @@ -526,8 +524,7 @@ r->complex_uri = 1; break; case '\0': - r->zero_in_uri = 1; - break; + return NGX_HTTP_PARSE_INVALID_REQUEST; } break; @@ -1202,7 +1199,7 @@ ch = *p++; } else if (ch == '\0') { - r->zero_in_uri = 1; + return NGX_HTTP_PARSE_INVALID_REQUEST; } state = quoted_state; @@ -1304,8 +1301,7 @@ } if (ch == '\0') { - *flags |= NGX_HTTP_ZERO_IN_URI; - continue; + goto unsafe; } if (ngx_path_separator(ch) && len > 2) { @@ -1449,34 +1445,19 @@ void ngx_http_split_args(ngx_http_request_t *r, ngx_str_t *uri, ngx_str_t *args) { - u_char ch, *p, *last; - - p = uri->data; - - last = p + uri->len; - - args->len = 0; - - while (p < last) { - - ch = *p++; - - if (ch == '?') { - args->len = last - p; - args->data = p; - - uri->len = p - 1 - uri->data; - - if (ngx_strlchr(p, last, '\0') != NULL) { - r->zero_in_uri = 1; - } - - return; - } - - if (ch == '\0') { - r->zero_in_uri = 1; - continue; - } + u_char *p, *last; + + last = uri->data + uri->len; + + p = ngx_strlchr(uri->data, last, '?'); + + if (p) { + uri->len = p - uri->data; + p++; + args->len = last - p; + args->data = p; + + } else { + args->len = 0; } } === modified file 'src/http/ngx_http_request.c' --- src/http/ngx_http_request.c 2010-03-03 23:50:36 +0000 +++ src/http/ngx_http_request.c 2010-07-21 11:15:58 +0000 @@ -784,16 +784,31 @@ p = r->uri.data + r->uri.len - 1; - if (*p == '.' || *p == ' ') { - - while (--p > r->uri.data && (*p == '.' || *p == ' ')) { - /* void */ - } - + while (p > r->uri.data) { + + if (*p == ' ') { + p--; + continue; + } + + if (*p == '.') { + p--; + continue; + } + + if (ngx_strncasecmp(p - 6, (u_char *) "::$data", 7) == 0) { + p -= 7; + continue; + } + + break; + } + + if (p != r->uri.data + r->uri.len - 1) { r->uri.len = p + 1 - r->uri.data; - ngx_http_set_exten(r); } + } #endif @@ -1443,6 +1458,12 @@ if (ngx_strstrn(user_agent, "Gecko/", 6 - 1)) { r->headers_in.gecko = 1; + } else if (ngx_strstrn(user_agent, "Chrome/", 7 - 1)) { + r->headers_in.chrome = 1; + + } else if (ngx_strstrn(user_agent, "Safari/", 7 - 1)) { + r->headers_in.safari = 1; + } else if (ngx_strstrn(user_agent, "Konqueror", 9 - 1)) { r->headers_in.konqueror = 1; } === modified file 'src/http/ngx_http_request.h' --- src/http/ngx_http_request.h 2010-03-03 23:50:36 +0000 +++ src/http/ngx_http_request.h 2010-07-21 11:15:58 +0000 @@ -57,7 +57,7 @@ #define NGX_HTTP_PARSE_INVALID_HEADER 13 -#define NGX_HTTP_ZERO_IN_URI 1 +/* unused 1 */ #define NGX_HTTP_SUBREQUEST_IN_MEMORY 2 #define NGX_HTTP_SUBREQUEST_WAITED 4 #define NGX_HTTP_LOG_UNSAFE 8 @@ -220,6 +220,8 @@ unsigned msie6:1; unsigned opera:1; unsigned gecko:1; + unsigned chrome:1; + unsigned safari:1; unsigned konqueror:1; } ngx_http_headers_in_t; @@ -428,9 +430,6 @@ /* URI with "+" */ unsigned plus_in_uri:1; - /* URI with "\0" or "%00" */ - unsigned zero_in_uri:1; - unsigned invalid_header:1; unsigned valid_location:1; === modified file 'src/http/ngx_http_special_response.c' --- src/http/ngx_http_special_response.c 2009-10-19 23:22:06 +0000 +++ src/http/ngx_http_special_response.c 2010-07-21 11:15:58 +0000 @@ -31,13 +31,13 @@ ; -static u_char ngx_http_msie_stub[] = -"" CRLF -"" CRLF -"" CRLF -"" CRLF -"" CRLF -"" CRLF +static u_char ngx_http_msie_padding[] = +"" CRLF +"" CRLF +"" CRLF +"" CRLF +"" CRLF +"" CRLF ; @@ -517,8 +517,6 @@ r->err_status = overwrite; - r->zero_in_uri = 0; - if (ngx_http_complex_value(r, &err_page->value, &uri) != NGX_OK) { return NGX_ERROR; } @@ -598,12 +596,12 @@ r->headers_out.content_length_n = ngx_http_error_pages[err].len + len; if (clcf->msie_padding - && r->headers_in.msie + && (r->headers_in.msie || r->headers_in.chrome) && r->http_version >= NGX_HTTP_VERSION_10 && err >= NGX_HTTP_LEVEL_300) { r->headers_out.content_length_n += - sizeof(ngx_http_msie_stub) - 1; + sizeof(ngx_http_msie_padding) - 1; msie_padding = 1; } @@ -671,8 +669,8 @@ } b->memory = 1; - b->pos = ngx_http_msie_stub; - b->last = ngx_http_msie_stub + sizeof(ngx_http_msie_stub) - 1; + b->pos = ngx_http_msie_padding; + b->last = ngx_http_msie_padding + sizeof(ngx_http_msie_padding) - 1; out[1].next = &out[2]; out[2].buf = b; === modified file 'src/http/ngx_http_upstream.c' --- src/http/ngx_http_upstream.c 2010-03-03 23:50:36 +0000 +++ src/http/ngx_http_upstream.c 2010-07-21 11:15:58 +0000 @@ -363,8 +363,6 @@ if (u && u->cleanup) { ngx_http_upstream_cleanup(r); - *u->cleanup = NULL; - u->cleanup = NULL; } u = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_t)); @@ -587,6 +585,13 @@ ngx_int_t rc; ngx_http_cache_t *c; + if (u->conf->no_cache) { + rc = ngx_http_cache(r, u->conf->no_cache); + if (rc != NGX_OK) { + return rc; + } + } + if (!(r->method & u->conf->cache_methods)) { return NGX_DECLINED; } @@ -1775,10 +1780,6 @@ return NGX_DONE; } - if (flags & NGX_HTTP_ZERO_IN_URI) { - r->zero_in_uri = 1; - } - if (r->method != NGX_HTTP_HEAD) { r->method = NGX_HTTP_GET; } @@ -3004,16 +3005,18 @@ return NGX_OK; } - last = h->value.data + h->value.len; + p = h->value.data; + last = p + h->value.len; - if (ngx_strlcasestrn(h->value.data, last, (u_char *) "no-cache", 8 - 1) - != NULL) + if (ngx_strlcasestrn(p, last, (u_char *) "no-cache", 8 - 1) != NULL + || ngx_strlcasestrn(p, last, (u_char *) "no-store", 8 - 1) != NULL + || ngx_strlcasestrn(p, last, (u_char *) "private", 7 - 1) != NULL) { u->cacheable = 0; return NGX_OK; } - p = ngx_strlcasestrn(h->value.data, last, (u_char *) "max-age=", 8 - 1); + p = ngx_strlcasestrn(p, last, (u_char *) "max-age=", 8 - 1); if (p == NULL) { return NGX_OK; === modified file 'src/http/ngx_http_upstream.h' --- src/http/ngx_http_upstream.h 2009-11-30 13:34:00 +0000 +++ src/http/ngx_http_upstream.h 2010-07-21 11:15:58 +0000 @@ -160,6 +160,7 @@ ngx_uint_t cache_methods; ngx_array_t *cache_valid; + ngx_array_t *no_cache; /* ngx_http_complex_value_t */ #endif ngx_array_t *store_lengths; === modified file 'src/http/ngx_http_variables.c' --- src/http/ngx_http_variables.c 2010-03-03 23:50:36 +0000 +++ src/http/ngx_http_variables.c 2010-07-21 11:15:58 +0000 @@ -196,7 +196,8 @@ { ngx_string("server_name"), NULL, ngx_http_variable_server_name, 0, 0, 0 }, { ngx_string("request_method"), NULL, - ngx_http_variable_request_method, 0, 0, 0 }, + ngx_http_variable_request_method, 0, + NGX_HTTP_VAR_NOCACHEABLE, 0 }, { ngx_string("remote_user"), NULL, ngx_http_variable_remote_user, 0, 0, 0 }, @@ -440,8 +441,7 @@ ngx_http_variable_value_t * -ngx_http_get_variable(ngx_http_request_t *r, ngx_str_t *name, ngx_uint_t key, - ngx_uint_t nowarn) +ngx_http_get_variable(ngx_http_request_t *r, ngx_str_t *name, ngx_uint_t key) { ngx_http_variable_t *v; ngx_http_variable_value_t *vv; @@ -453,7 +453,7 @@ if (v) { if (v->flags & NGX_HTTP_VAR_INDEXED) { - return ngx_http_get_indexed_variable(r, v->index); + return ngx_http_get_flushed_variable(r, v->index); } else { @@ -494,7 +494,7 @@ return NULL; } - if (ngx_strncmp(name->data, "upstream_http_", 10) == 0) { + if (ngx_strncmp(name->data, "upstream_http_", 14) == 0) { if (ngx_http_upstream_header_variable(r, vv, (uintptr_t) name) == NGX_OK) @@ -525,11 +525,6 @@ vv->not_found = 1; - if (nowarn == 0) { - ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, - "unknown \"%V\" variable", name); - } - return vv; } @@ -1781,6 +1776,7 @@ if (ngx_strncmp(v[i].name.data, "arg_", 4) == 0) { v[i].get_handler = ngx_http_variable_argument; v[i].data = (uintptr_t) &v[i].name; + v[i].flags = NGX_HTTP_VAR_NOCACHEABLE; continue; } === modified file 'src/http/ngx_http_variables.h' --- src/http/ngx_http_variables.h 2009-10-19 23:22:06 +0000 +++ src/http/ngx_http_variables.h 2010-07-21 11:15:58 +0000 @@ -50,7 +50,7 @@ ngx_uint_t index); ngx_http_variable_value_t *ngx_http_get_variable(ngx_http_request_t *r, - ngx_str_t *name, ngx_uint_t key, ngx_uint_t nowarn); + ngx_str_t *name, ngx_uint_t key); ngx_int_t ngx_http_variable_unknown_header(ngx_http_variable_value_t *v, ngx_str_t *var, ngx_list_part_t *part, size_t prefix); === modified file 'src/mail/ngx_mail_pop3_handler.c' --- src/mail/ngx_mail_pop3_handler.c 2009-10-19 23:22:06 +0000 +++ src/mail/ngx_mail_pop3_handler.c 2010-07-21 11:15:58 +0000 @@ -188,7 +188,6 @@ default: rc = NGX_MAIL_PARSE_INVALID_COMMAND; - s->mail_state = ngx_pop3_start; break; } @@ -215,7 +214,6 @@ default: rc = NGX_MAIL_PARSE_INVALID_COMMAND; - s->mail_state = ngx_pop3_start; break; } === modified file 'src/mail/ngx_mail_proxy_module.c' --- src/mail/ngx_mail_proxy_module.c 2009-11-30 13:34:00 +0000 +++ src/mail/ngx_mail_proxy_module.c 2010-07-21 11:15:58 +0000 @@ -726,7 +726,7 @@ b->last += n; - if (b->last - b->pos < 5) { + if (b->last - b->pos < 4) { return NGX_AGAIN; } === modified file 'src/os/unix/ngx_errno.h' --- src/os/unix/ngx_errno.h 2009-11-30 13:34:00 +0000 +++ src/os/unix/ngx_errno.h 2010-07-21 11:15:58 +0000 @@ -64,10 +64,22 @@ /* Solaris and Tru64 UNIX have thread-safe strerror() */ -#define ngx_strerror_r(err, errstr, size) \ +#define ngx_strerror_r(err, errstr, size) \ ngx_cpystrn(errstr, (u_char *) strerror(err), size) #endif +#if (NGX_HAVE_SYS_ERRLIST) + +#define ngx_sigsafe_strerror(err) \ + (err > 0 && err < sys_nerr) ? sys_errlist[err] : "Unknown error" + +#else + +#define ngx_sigsafe_strerror(err) "" + +#endif + + #endif /* _NGX_ERRNO_H_INCLUDED_ */ === modified file 'src/os/unix/ngx_files.h' --- src/os/unix/ngx_files.h 2010-03-03 23:50:36 +0000 +++ src/os/unix/ngx_files.h 2010-07-21 11:15:58 +0000 @@ -64,6 +64,7 @@ #define NGX_FILE_OPEN 0 #define NGX_FILE_TRUNCATE O_CREAT|O_TRUNC #define NGX_FILE_APPEND O_WRONLY|O_APPEND +#define NGX_FILE_NONBLOCK O_NONBLOCK #define NGX_FILE_DEFAULT_ACCESS 0644 #define NGX_FILE_OWNER_ACCESS 0600 @@ -138,6 +139,9 @@ #define ngx_fd_info(fd, sb) fstat(fd, sb) #define ngx_fd_info_n "fstat()" +#define ngx_link_info(file, sb) lstat((const char *) file, sb) +#define ngx_link_info_n "lstat()" + #define ngx_is_dir(sb) (S_ISDIR((sb)->st_mode)) #define ngx_is_file(sb) (S_ISREG((sb)->st_mode)) #define ngx_is_link(sb) (S_ISLNK((sb)->st_mode)) === modified file 'src/os/unix/ngx_process.c' --- src/os/unix/ngx_process.c 2009-11-30 13:34:00 +0000 +++ src/os/unix/ngx_process.c 2010-07-21 11:15:58 +0000 @@ -315,7 +315,7 @@ } } - ngx_time_update(0, 0); + ngx_time_sigsafe_update(); action = ""; @@ -476,16 +476,17 @@ */ if (err == NGX_ECHILD) { - ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, errno, - "waitpid() failed"); + ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, 0, + "waitpid() failed (%d: %s)", + err, ngx_sigsafe_strerror(err)); return; } #endif - ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, errno, - "waitpid() failed"); - + ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, + "waitpid() failed (%d: %s)", + err, ngx_sigsafe_strerror(err)); return; } === modified file 'src/os/unix/ngx_process_cycle.c' --- src/os/unix/ngx_process_cycle.c 2010-03-03 23:50:36 +0000 +++ src/os/unix/ngx_process_cycle.c 2010-07-21 11:15:58 +0000 @@ -168,7 +168,7 @@ sigsuspend(&set); - ngx_time_update(0, 0); + ngx_time_update(); ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "wake up, sigio %i", sigio); @@ -1337,7 +1337,7 @@ next = (n <= next) ? n : next; - ngx_time_update(0, 0); + ngx_time_update(); } } @@ -1367,7 +1367,7 @@ if (path[i]->loader) { path[i]->loader(path[i]->data); - ngx_time_update(0, 0); + ngx_time_update(); } }