# HG changeset patch # User Igor Sysoev # Date 1240171200 -14400 # Node ID 549994537f15f7212b5f09f1f4d6e00f2dc562f9 # Parent eb4fdebda67325ad8c7b431b04b4b73ba0b40752 nginx 0.7.52 *) Feature: the first native Windows binary release. *) Bugfix: in processing HEAD method while caching. *) Bugfix: in processing the "If-Modified-Since", "If-Range", etc. client request header lines while caching. *) Bugfix: now the "Set-Cookie" and "P3P" header lines are hidden in cacheable responses. *) Bugfix: if nginx was built with the ngx_http_perl_module and with a perl which supports threads, then during a master process exit the message "panic: MUTEX_LOCK" might be issued. *) Bugfix: nginx could not be built --without-http-cache; the bug had appeared in 0.7.48. *) Bugfix: nginx could not be built on platforms different from i386, amd64, sparc, and ppc; the bug had appeared in 0.7.42. diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,27 @@ +Changes with nginx 0.7.52 20 Apr 2009 + + *) Feature: the first native Windows binary release. + + *) Bugfix: in processing HEAD method while caching. + + *) Bugfix: in processing the "If-Modified-Since", "If-Range", etc. + client request header lines while caching. + + *) Bugfix: now the "Set-Cookie" and "P3P" header lines are hidden in + cacheable responses. + + *) Bugfix: if nginx was built with the ngx_http_perl_module and with a + perl which supports threads, then during a master process exit the + message "panic: MUTEX_LOCK" might be issued. + + *) Bugfix: nginx could not be built --without-http-cache; the bug had + appeared in 0.7.48. + + *) Bugfix: nginx could not be built on platforms different from i386, + amd64, sparc, and ppc; the bug had appeared in 0.7.42. + + Changes with nginx 0.7.51 12 Apr 2009 *) Feature: the "try_files" directive supports a response code in the diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,4 +1,27 @@ +Изменения в nginx 0.7.52 20.04.2009 + + *) Добавление: первая бинарная версия под Windows. + + *) Исправление: корректная обработка метода HEAD при кэшировании. + + *) Исправление: корректная обработка строк "If-Modified-Since", + "If-Range" и им подобных в заголовке запроса клиента при кэшировании. + + *) Исправление: теперь строки "Set-Cookie" и "P3P" скрываются в + заголовке ответа для закэшированных ответов. + + *) Исправление: если nginx был собран с модулем ngx_http_perl_module и + perl поддерживал потоки, то при выходе основного процесса могла + выдаваться ошибка "panic: MUTEX_LOCK". + + *) Исправление: nginx не собирался с параметром --without-http-cache; + ошибка появилась в 0.7.48. + + *) Исправление: nginx не собирался на платформах, отличных от i386, + amd64, sparc и ppc; ошибка появилась в 0.7.42. + + Изменения в nginx 0.7.51 12.04.2009 *) Добавление: директива try_files поддерживает код ответа в последнем diff --git a/auto/cc/bcc b/auto/cc/bcc --- a/auto/cc/bcc +++ b/auto/cc/bcc @@ -24,7 +24,7 @@ esac # __stdcall #CPU_OPT="$CPU_OPT -ps" # __fastcall -CPU_OPT="$CPU_OPT -pr" +#CPU_OPT="$CPU_OPT -pr" CFLAGS="$CFLAGS $CPU_OPT" @@ -46,7 +46,7 @@ NGX_USE_PCH="-Hu -H=$NGX_OBJS/ngx_config # Win32 GUI mode application -LINK="\$(CC) -laa" +#LINK="\$(CC) -laa" # the resource file diff --git a/auto/cc/msvc b/auto/cc/msvc --- a/auto/cc/msvc +++ b/auto/cc/msvc @@ -51,12 +51,12 @@ case $CPU in ;; esac -# __cdecl, use with OpenSSL, md5 asm, and sha1 asm +# __cdecl, default, must be used with OpenSSL, md5 asm, and sha1 asm #CPU_OPT="$CPU_OPT -Gd" # __stdcall #CPU_OPT="$CPU_OPT -Gz" # __fastcall -CPU_OPT="$CPU_OPT -Gr" +#CPU_OPT="$CPU_OPT -Gr" CFLAGS="$CFLAGS $CPU_OPT" @@ -86,17 +86,26 @@ LIBC="-MT" CFLAGS="$CFLAGS $LIBC" +CORE_LIBS="$CORE_LIBS kernel32.lib user32.lib" + # Win32 GUI mode application -CORE_LIBS="$CORE_LIBS kernel32.lib user32.lib" -CORE_LINK="$CORE_LINK -subsystem:windows -entry:mainCRTStartup" +#CORE_LINK="$CORE_LINK -subsystem:windows -entry:mainCRTStartup" # debug +# msvc8 under Wine issues +# Program database manager mismatch; please check your installation if [ $NGX_CC_NAME != msvc8 ]; then CFLAGS="$CFLAGS -Zi" CORE_LINK="$CORE_LINK -debug" fi +# MSVC 2005 supports C99 variadic macros +if [ $NGX_CC_NAME = msvc8 ]; then + have=NGX_HAVE_C99_VARIADIC_MACROS . auto/have +fi + + # precompiled headers CORE_DEPS="$CORE_DEPS $NGX_OBJS/ngx_config.pch" NGX_PCH="$NGX_OBJS/ngx_config.pch" diff --git a/auto/cc/owc b/auto/cc/owc --- a/auto/cc/owc +++ b/auto/cc/owc @@ -71,7 +71,7 @@ NGX_USE_PCH="-fh=$NGX_OBJS/ngx_config.pc # the link flags, built target is NT GUI mode application -CORE_LINK="$CORE_LINK -l=nt_win" +#CORE_LINK="$CORE_LINK -l=nt_win" # the resource file diff --git a/auto/lib/md5/conf b/auto/lib/md5/conf --- a/auto/lib/md5/conf +++ b/auto/lib/md5/conf @@ -4,7 +4,7 @@ if [ $MD5 != NONE ]; then - if grep MD5_Init $MD5/md5.h >/dev/null; then + if grep MD5_Init $MD5/md5.h 2>&1 >/dev/null; then # OpenSSL md5 OPENSSL_MD5=YES have=NGX_HAVE_OPENSSL_MD5 . auto/have diff --git a/auto/lib/openssl/conf b/auto/lib/openssl/conf --- a/auto/lib/openssl/conf +++ b/auto/lib/openssl/conf @@ -6,6 +6,21 @@ if [ $OPENSSL != NONE ]; then CORE_INCS="$CORE_INCS $OPENSSL/include" case "$CC" in + + cl|bcc32) + have=NGX_OPENSSL . auto/have + have=NGX_SSL . auto/have + + LINK_DEPS="$LINK_DEPS $OPENSSL/out32/ssleay32.lib" + CORE_LIBS="$CORE_LIBS $OPENSSL/out32/ssleay32.lib" + + LINK_DEPS="$LINK_DEPS $OPENSSL/out32/libeay32.lib" + CORE_LIBS="$CORE_LIBS $OPENSSL/out32/libeay32.lib" + + # libeay32.lib requires gdi32.lib and advapi32.lib + CORE_LIBS="$CORE_LIBS gdi32.lib advapi32.lib" + ;; + *) have=NGX_OPENSSL . auto/have have=NGX_SSL . auto/have @@ -34,10 +49,8 @@ else CORE_LIBS="$CORE_LIBS c:/openssl/ssleay32.lib" CORE_LIBS="$CORE_LIBS c:/openssl/libeay32.lib" - # libeay32.lib requires gdi32.lib - CORE_LIBS="$CORE_LIBS gdi32.lib" - # OpenSSL 0.8's libeay32.lib requires advapi32.lib - CORE_LIBS="$CORE_LIBS advapi32.lib" + # libeay32.lib requires gdi32.lib and advapi32.lib + CORE_LIBS="$CORE_LIBS gdi32.lib advapi32.lib" ;; *) diff --git a/auto/lib/openssl/make b/auto/lib/openssl/make --- a/auto/lib/openssl/make +++ b/auto/lib/openssl/make @@ -13,7 +13,38 @@ case $USE_THREADS in *) NGX_OPENSSL_CONFIG="$NGX_OPENSSL_CONFIG threads" ;; esac -case "$NGX_PLATFORM" in +case "$CC" in + cl) + cat << END >> $NGX_MAKEFILE + +$OPENSSL/out32/ssleay32.lib: + cd $OPENSSL + perl Configure VC-WIN32 no-shared + ms\\do_ms + \$(MAKE) -f ms\\nt.mak + cd ..\\..\\.. + +END + + ;; + + bcc32) + cat << END >> $NGX_MAKEFILE + +`echo "$OPENSSL\\out32\\libeay32.lib: $OPENSSL\\out32\\ssleay32.lib" \ + | sed -e "s/\//$ngx_regex_dirsep/g"` + +`echo "$OPENSSL\\out32\\ssleay32.lib:" | sed -e "s/\//$ngx_regex_dirsep/g"` + cd `echo "$OPENSSL" | sed -e "s/\//$ngx_regex_dirsep/g"` + perl Configure BC-32 no-shared + ms\\do_nasm + \$(MAKE) -f ms\\bcb.mak + cd ..\\..\\.. + +END + + ;; + *) cat << END >> $NGX_MAKEFILE diff --git a/auto/sources b/auto/sources --- a/auto/sources +++ b/auto/sources @@ -215,8 +215,6 @@ WIN32_DEPS="$CORE_DEPS $EVENT_DEPS \ src/os/win32/ngx_socket.h \ src/os/win32/ngx_os.h \ src/os/win32/ngx_user.h \ - src/os/win32/ngx_gui.h \ - src/os/win32/ngx_gui_resources.h \ src/os/win32/ngx_process_cycle.h" WIN32_CONFIG=src/os/win32/ngx_win32_config.h @@ -233,14 +231,15 @@ WIN32_SRCS="$CORE_SRCS $EVENT_SRCS \ src/os/win32/ngx_wsarecv.c \ src/os/win32/ngx_wsarecv_chain.c \ src/os/win32/ngx_udp_wsarecv.c \ + src/os/win32/ngx_wsasend.c \ src/os/win32/ngx_wsasend_chain.c \ src/os/win32/ngx_win32_init.c \ src/os/win32/ngx_user.c \ - src/os/win32/ngx_gui.c \ + src/os/win32/ngx_event_log.c \ src/os/win32/ngx_process_cycle.c \ src/event/ngx_event_acceptex.c" -NGX_WIN32_ICONS="src/os/win32/nginx.ico src/os/win32/nginx_tray.ico" +NGX_WIN32_ICONS="src/os/win32/nginx.ico" NGX_WIN32_RC="src/os/win32/nginx.rc" diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -180,10 +180,14 @@ ngx_module_t ngx_core_module = { }; -ngx_uint_t ngx_max_module; +ngx_uint_t ngx_max_module; -static ngx_uint_t ngx_show_version; -static ngx_uint_t ngx_show_configure; +static ngx_uint_t ngx_show_version; +static ngx_uint_t ngx_show_configure; +#if (NGX_WIN32) +static char *ngx_signal; +#endif + static char **ngx_os_environ; @@ -191,8 +195,6 @@ static char **ngx_os_environ; int ngx_cdecl main(int argc, char *const *argv) { - char *p; - ssize_t n; ngx_int_t i; ngx_log_t *log; ngx_cycle_t *cycle, init_cycle; @@ -243,29 +245,14 @@ main(int argc, char *const *argv) if (ngx_show_version) { - p = "nginx version: " NGINX_VER CRLF; - n = sizeof("nginx version: " NGINX_VER CRLF) - 1; - - if (ngx_write_fd(ngx_stderr_fileno, p, n) != n) { - return 1; - } + ngx_log_stderr("nginx version: " NGINX_VER); if (ngx_show_configure) { #ifdef NGX_COMPILER - p = "built by " NGX_COMPILER CRLF; - n = sizeof("built by " NGX_COMPILER CRLF) - 1; - - if (ngx_write_fd(ngx_stderr_fileno, p, n) != n) { - return 1; - } + ngx_log_stderr("built by " NGX_COMPILER); #endif - p = "configure arguments: " NGX_CONFIGURE CRLF; - n = sizeof("configure arguments :" NGX_CONFIGURE CRLF) - 1; - - if (ngx_write_fd(ngx_stderr_fileno, p, n) != n) { - return 1; - } + ngx_log_stderr("configure arguments: " NGX_CONFIGURE); } if (!ngx_test_config) { @@ -301,18 +288,16 @@ main(int argc, char *const *argv) cycle = ngx_init_cycle(&init_cycle); if (cycle == NULL) { if (ngx_test_config) { - ngx_log_error(NGX_LOG_EMERG, log, 0, - "the configuration file %s test failed", - init_cycle.conf_file.data); + ngx_log_stderr("the configuration file %s test failed", + init_cycle.conf_file.data); } return 1; } if (ngx_test_config) { - ngx_log_error(NGX_LOG_INFO, log, 0, - "the configuration file %s was tested successfully", - cycle->conf_file.data); + ngx_log_stderr("the configuration file %s was tested successfully", + cycle->conf_file.data); return 0; } @@ -322,22 +307,15 @@ main(int argc, char *const *argv) ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); - ngx_process = ccf->master ? NGX_PROCESS_MASTER : NGX_PROCESS_SINGLE; + if (ccf->master && ngx_process == NGX_PROCESS_SINGLE) { + ngx_process = NGX_PROCESS_MASTER; + } #if (NGX_WIN32) -#if 0 - - TODO: - - if (ccf->run_as_service) { - if (ngx_service(cycle->log) != NGX_OK) { - return 1; - } - - return 0; + if (ngx_signal) { + return ngx_signal_process(cycle, ngx_signal); } -#endif #else @@ -353,17 +331,17 @@ main(int argc, char *const *argv) ngx_daemonized = 1; } +#endif + if (ngx_create_pidfile(&ccf->pid, cycle->log) != NGX_OK) { return 1; } -#endif - - if (ngx_process == NGX_PROCESS_MASTER) { - ngx_master_process_cycle(cycle); + if (ngx_process == NGX_PROCESS_SINGLE) { + ngx_single_process_cycle(cycle); } else { - ngx_single_process_cycle(cycle); + ngx_master_process_cycle(cycle); } return 0; @@ -664,6 +642,29 @@ ngx_getopt(ngx_cycle_t *cycle, int argc, cycle->conf_param.len = ngx_strlen(cycle->conf_param.data); break; +#if (NGX_WIN32) + case 's': + if (argv[++i] == NULL) { + ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, + "the option \"-s\" requires parameter"); + return NGX_ERROR; + } + + if (ngx_strcmp(argv[i], "stop") == 0 + || ngx_strcmp(argv[i], "quit") == 0 + || ngx_strcmp(argv[i], "reopen") == 0 + || ngx_strcmp(argv[i], "reload") == 0) + { + ngx_process = NGX_PROCESS_SIGNALLER; + ngx_signal = argv[i]; + break; + } + + ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, + "invalid option: \"-s %s\"", argv[i]); + return NGX_ERROR; +#endif + default: ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, "invalid option: \"%s\"", argv[i]); @@ -805,6 +806,27 @@ ngx_core_module_init_conf(ngx_cycle_t *c #endif + + if (ccf->pid.len == 0) { + ccf->pid.len = sizeof(NGX_PID_PATH) - 1; + ccf->pid.data = (u_char *) NGX_PID_PATH; + } + + if (ngx_conf_full_name(cycle, &ccf->pid, 0) != NGX_OK) { + return NGX_CONF_ERROR; + } + + ccf->oldpid.len = ccf->pid.len + sizeof(NGX_OLDPID_EXT); + + ccf->oldpid.data = ngx_pnalloc(cycle->pool, ccf->oldpid.len); + if (ccf->oldpid.data == NULL) { + return NGX_CONF_ERROR; + } + + ngx_memcpy(ngx_cpymem(ccf->oldpid.data, ccf->pid.data, ccf->pid.len), + NGX_OLDPID_EXT, sizeof(NGX_OLDPID_EXT)); + + #if !(NGX_WIN32) if (ccf->user == (uid_t) NGX_CONF_UNSET_UINT && geteuid() == 0) { @@ -833,25 +855,6 @@ ngx_core_module_init_conf(ngx_cycle_t *c ccf->group = grp->gr_gid; } - if (ccf->pid.len == 0) { - ccf->pid.len = sizeof(NGX_PID_PATH) - 1; - ccf->pid.data = (u_char *) NGX_PID_PATH; - } - - if (ngx_conf_full_name(cycle, &ccf->pid, 0) != NGX_OK) { - return NGX_CONF_ERROR; - } - - ccf->oldpid.len = ccf->pid.len + sizeof(NGX_OLDPID_EXT); - - ccf->oldpid.data = ngx_pnalloc(cycle->pool, ccf->oldpid.len); - if (ccf->oldpid.data == NULL) { - return NGX_CONF_ERROR; - } - - ngx_memcpy(ngx_cpymem(ccf->oldpid.data, ccf->pid.data, ccf->pid.len), - NGX_OLDPID_EXT, sizeof(NGX_OLDPID_EXT)); - if (ccf->lock_file.len == 0) { ccf->lock_file.len = sizeof(NGX_LOCK_PATH) - 1; diff --git a/src/core/nginx.h b/src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -8,8 +8,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 007051 -#define NGINX_VERSION "0.7.51" +#define nginx_version 7052 +#define NGINX_VERSION "0.7.52" #define NGINX_VER "nginx/" NGINX_VERSION #define NGINX_VAR "NGINX" diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c --- a/src/core/ngx_connection.c +++ b/src/core/ngx_connection.c @@ -557,29 +557,31 @@ ngx_close_listening_sockets(ngx_cycle_t c = ls[i].connection; - if (c->read->active) { - if (ngx_event_flags & NGX_USE_RTSIG_EVENT) { - ngx_del_conn(c, NGX_CLOSE_EVENT); + if (c) { + if (c->read->active) { + if (ngx_event_flags & NGX_USE_RTSIG_EVENT) { + ngx_del_conn(c, NGX_CLOSE_EVENT); - } else if (ngx_event_flags & NGX_USE_EPOLL_EVENT) { + } else if (ngx_event_flags & NGX_USE_EPOLL_EVENT) { - /* - * it seems that Linux-2.6.x OpenVZ sends events - * for closed shared listening sockets unless - * the events was explicity deleted - */ + /* + * it seems that Linux-2.6.x OpenVZ sends events + * for closed shared listening sockets unless + * the events was explicity deleted + */ - ngx_del_event(c->read, NGX_READ_EVENT, 0); + ngx_del_event(c->read, NGX_READ_EVENT, 0); - } else { - ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT); + } else { + ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT); + } } + + ngx_free_connection(c); + + c->fd = (ngx_socket_t) -1; } - ngx_free_connection(c); - - c->fd = (ngx_socket_t) -1; - ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0, "close listening %V #%d ", &ls[i].addr_text, ls[i].fd); diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c --- a/src/core/ngx_cycle.c +++ b/src/core/ngx_cycle.c @@ -9,9 +9,11 @@ #include -static ngx_int_t ngx_test_lockfile(u_char *file, ngx_log_t *log); 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); @@ -44,7 +46,6 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) { void *rv; char **senv, **env; - u_char *lock_file; ngx_uint_t i, n; ngx_log_t *log; ngx_time_t *tp; @@ -52,7 +53,6 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) ngx_pool_t *pool; ngx_cycle_t *cycle, **old; ngx_shm_zone_t *shm_zone, *oshm_zone; - ngx_slab_pool_t *shpool; ngx_list_part_t *part, *opart; ngx_open_file_t *file; ngx_listening_t *ls, *nls; @@ -270,9 +270,8 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) } if (ngx_test_config) { - ngx_log_error(NGX_LOG_INFO, log, 0, - "the configuration file %s syntax is ok", - cycle->conf_file.data); + ngx_log_stderr("the configuration file %s syntax is ok", + cycle->conf_file.data); } @@ -296,8 +295,6 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); -#if !(NGX_WIN32) - if (ngx_test_config) { if (ngx_create_pidfile(&ccf->pid, log) != NGX_OK) { @@ -326,8 +323,6 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) } } -#endif - if (ngx_test_lockfile(cycle->lock_file.data, log) != NGX_OK) { goto failed; @@ -412,7 +407,7 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) if (shm_zone[i].shm.size == 0) { ngx_log_error(NGX_LOG_EMERG, log, 0, "zero size shared memory zone \"%V\"", - &shm_zone[i].name); + &shm_zone[i].shm.name); goto failed; } @@ -437,12 +432,13 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) n = 0; } - if (shm_zone[i].name.len != oshm_zone[n].name.len) { + if (shm_zone[i].shm.name.len != oshm_zone[n].shm.name.len) { continue; } - if (ngx_strncmp(shm_zone[i].name.data, oshm_zone[n].name.data, - shm_zone[i].name.len) + if (ngx_strncmp(shm_zone[i].shm.name.data, + oshm_zone[n].shm.name.data, + shm_zone[i].shm.name.len) != 0) { continue; @@ -469,38 +465,13 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) goto failed; } - shpool = (ngx_slab_pool_t *) shm_zone[i].shm.addr; - - shpool->end = shm_zone[i].shm.addr + shm_zone[i].shm.size; - shpool->min_shift = 3; - -#if (NGX_HAVE_ATOMIC_OPS) - - lock_file = NULL; - -#else - - lock_file = ngx_pnalloc(cycle->pool, - cycle->lock_file.len + shm_zone[i].name.len); + if (!shm_zone[i].shm.exists) { - if (lock_file == NULL) { - goto failed; + if (ngx_init_zone_pool(cycle, &shm_zone[i]) != NGX_OK) { + goto failed; + } } - (void) ngx_cpystrn(ngx_cpymem(lock_file, cycle->lock_file.data, - cycle->lock_file.len), - shm_zone[i].name.data, shm_zone[i].name.len + 1); - -#endif - - if (ngx_shmtx_create(&shpool->mutex, (void *) &shpool->lock, lock_file) - != NGX_OK) - { - goto failed; - } - - ngx_slab_init(shpool); - if (shm_zone[i].init(&shm_zone[i], NULL) != NGX_OK) { goto failed; } @@ -672,10 +643,10 @@ ngx_init_cycle(ngx_cycle_t *old_cycle) n = 0; } - if (oshm_zone[i].name.len == shm_zone[n].name.len - && ngx_strncmp(oshm_zone[i].name.data, - shm_zone[n].name.data, - oshm_zone[i].name.len) + 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; @@ -917,7 +888,41 @@ ngx_cmp_sockaddr(struct sockaddr *sa1, s } -#if !(NGX_WIN32) +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; + + sp->end = zn->shm.addr + zn->shm.size; + sp->min_shift = 3; + +#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) @@ -927,6 +932,10 @@ ngx_create_pidfile(ngx_str_t *name, ngx_ 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; @@ -976,8 +985,6 @@ ngx_delete_pidfile(ngx_cycle_t *cycle) } } -#endif - static ngx_int_t ngx_test_lockfile(u_char *file, ngx_log_t *log) @@ -1175,27 +1182,29 @@ ngx_shared_memory_add(ngx_conf_t *cf, ng i = 0; } - if (name->len != shm_zone[i].name.len) { + if (name->len != shm_zone[i].shm.name.len) { continue; } - if (ngx_strncmp(name->data, shm_zone[i].name.data, name->len) != 0) { + 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].name, shm_zone[i].shm.size); + "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].name); + "the shared memory zone \"%V\" is " + "already declared for a different use", + &shm_zone[i].shm.name); return NULL; } @@ -1211,8 +1220,9 @@ ngx_shared_memory_add(ngx_conf_t *cf, ng 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->name = *name; shm_zone->tag = tag; return shm_zone; diff --git a/src/core/ngx_cycle.h b/src/core/ngx_cycle.h --- a/src/core/ngx_cycle.h +++ b/src/core/ngx_cycle.h @@ -29,7 +29,6 @@ struct ngx_shm_zone_s { void *data; ngx_shm_t shm; ngx_shm_zone_init_pt init; - ngx_str_t name; void *tag; }; diff --git a/src/core/ngx_log.c b/src/core/ngx_log.c --- a/src/core/ngx_log.c +++ b/src/core/ngx_log.c @@ -184,9 +184,30 @@ ngx_log_debug_core(ngx_log_t *log, ngx_e void -ngx_log_abort(ngx_err_t err, const char *text) +ngx_log_abort(ngx_err_t err, const char *text, void *param) +{ + ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, err, text, param); +} + + +void ngx_cdecl +ngx_log_stderr(const char *fmt, ...) { - ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, err, text); + u_char *p; + va_list args; + u_char errstr[NGX_MAX_ERROR_STR]; + + va_start(args, fmt); + p = ngx_vsnprintf(errstr, NGX_MAX_ERROR_STR, fmt, args); + va_end(args); + + if (p > errstr + NGX_MAX_ERROR_STR - NGX_LINEFEED_SIZE) { + p = errstr + NGX_MAX_ERROR_STR - NGX_LINEFEED_SIZE; + } + + ngx_linefeed(p); + + (void) ngx_write_fd(ngx_stderr_fileno, errstr, p - errstr); } @@ -206,9 +227,9 @@ ngx_log_init(void) NGX_FILE_DEFAULT_ACCESS); if (ngx_stderr.fd == NGX_INVALID_FILE) { - ngx_message_box("nginx", MB_OK, ngx_errno, - "Could not open error log file: " - ngx_open_file_n " \"" NGX_ERROR_LOG_PATH "\" failed"); + ngx_event_log(ngx_errno, + "Could not open error log file: " + ngx_open_file_n " \"" NGX_ERROR_LOG_PATH "\" failed"); return NULL; } diff --git a/src/core/ngx_log.h b/src/core/ngx_log.h --- a/src/core/ngx_log.h +++ b/src/core/ngx_log.h @@ -198,7 +198,8 @@ void ngx_cdecl ngx_log_debug_core(ngx_lo ngx_log_t *ngx_log_init(void); ngx_log_t *ngx_log_create_errlog(ngx_cycle_t *cycle, ngx_array_t *args); char *ngx_set_error_log_levels(ngx_conf_t *cf, ngx_log_t *log); -void ngx_log_abort(ngx_err_t err, const char *text); +void ngx_log_abort(ngx_err_t err, const char *text, void *param); +void ngx_cdecl ngx_log_stderr(const char *fmt, ...); extern ngx_module_t ngx_errlog_module; diff --git a/src/core/ngx_slab.c b/src/core/ngx_slab.c --- a/src/core/ngx_slab.c +++ b/src/core/ngx_slab.c @@ -584,9 +584,9 @@ ngx_slab_free_locked(ngx_slab_pool_t *po ngx_slab_free_pages(pool, &pool->pages[n], size); - size <<= ngx_pagesize_shift; + ngx_slab_junk(p, size << ngx_pagesize_shift); - goto done; + return; } /* not reached */ diff --git a/src/core/ngx_slab.h b/src/core/ngx_slab.h --- a/src/core/ngx_slab.h +++ b/src/core/ngx_slab.h @@ -37,6 +37,8 @@ typedef struct { u_char *log_ctx; u_char zero; + + void *data; } ngx_slab_pool_t; diff --git a/src/event/ngx_event.c b/src/event/ngx_event.c --- a/src/event/ngx_event.c +++ b/src/event/ngx_event.c @@ -442,7 +442,7 @@ ngx_event_module_init(ngx_cycle_t *cycle ecf = (*cf)[ngx_event_core_module.ctx_index]; - if (!ngx_test_config) { + if (!ngx_test_config && ngx_process <= NGX_PROCESS_MASTER) { ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "using the \"%s\" event method", ecf->name); } @@ -506,6 +506,8 @@ ngx_event_module_init(ngx_cycle_t *cycle #endif shm.size = size; + shm.name.len = sizeof("nginx_shared_zone"); + shm.name.data = (u_char *) "nginx_shared_zone"; shm.log = cycle->log; if (ngx_shm_alloc(&shm) != NGX_OK) { @@ -535,7 +537,7 @@ ngx_event_module_init(ngx_cycle_t *cycle #endif - *ngx_connection_counter = 1; + (void) ngx_atomic_cmp_set(ngx_connection_counter, 0, 1); ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "counter: %p, %d", diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c --- a/src/event/ngx_event_accept.c +++ b/src/event/ngx_event_accept.c @@ -57,8 +57,8 @@ ngx_event_accept(ngx_event_t *ev) return; } - ngx_log_error((err == NGX_ECONNABORTED) ? NGX_LOG_ERR: - NGX_LOG_ALERT, + ngx_log_error((ngx_uint_t) ((err == NGX_ECONNABORTED) ? + NGX_LOG_ERR : NGX_LOG_ALERT), ev->log, err, "accept() failed"); if (err == NGX_ECONNABORTED) { diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -1387,7 +1387,7 @@ ngx_ssl_session_cache(ngx_ssl_t *ssl, ng } } - SSL_CTX_set_timeout(ssl->ctx, timeout); + SSL_CTX_set_timeout(ssl->ctx, (long) timeout); if (shm_zone) { shm_zone->init = ngx_ssl_session_cache_init; @@ -1421,6 +1421,11 @@ ngx_ssl_session_cache_init(ngx_shm_zone_ return NGX_OK; } + if (shm_zone->shm.exists) { + shm_zone->data = data; + return NGX_OK; + } + shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; cache = ngx_slab_alloc(shpool, sizeof(ngx_ssl_session_cache_t)); @@ -1428,12 +1433,15 @@ ngx_ssl_session_cache_init(ngx_shm_zone_ return NGX_ERROR; } + shpool->data = cache; + shm_zone->data = cache; + ngx_rbtree_init(&cache->session_rbtree, &cache->sentinel, ngx_ssl_session_rbtree_insert_value); ngx_queue_init(&cache->expire_queue); - len = sizeof(" in SSL session shared cache \"\"") + shm_zone->name.len; + len = sizeof(" in SSL session shared cache \"\"") + shm_zone->shm.name.len; shpool->log_ctx = ngx_slab_alloc(shpool, len); if (shpool->log_ctx == NULL) { @@ -1441,9 +1449,7 @@ ngx_ssl_session_cache_init(ngx_shm_zone_ } ngx_sprintf(shpool->log_ctx, " in SSL session shared cache \"%V\"%Z", - &shm_zone->name); - - shm_zone->data = cache; + &shm_zone->shm.name); return NGX_OK; } diff --git a/src/http/modules/ngx_http_autoindex_module.c b/src/http/modules/ngx_http_autoindex_module.c --- a/src/http/modules/ngx_http_autoindex_module.c +++ b/src/http/modules/ngx_http_autoindex_module.c @@ -157,7 +157,6 @@ ngx_http_autoindex_handler(ngx_http_requ return NGX_DECLINED; } - /* TODO: Win32 */ if (r->zero_in_uri) { return NGX_DECLINED; } diff --git a/src/http/modules/ngx_http_dav_module.c b/src/http/modules/ngx_http_dav_module.c --- a/src/http/modules/ngx_http_dav_module.c +++ b/src/http/modules/ngx_http_dav_module.c @@ -148,7 +148,6 @@ ngx_http_dav_handler(ngx_http_request_t ngx_int_t rc; ngx_http_dav_loc_conf_t *dlcf; - /* TODO: Win32 */ if (r->zero_in_uri) { return NGX_DECLINED; } diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c --- a/src/http/modules/ngx_http_fastcgi_module.c +++ b/src/http/modules/ngx_http_fastcgi_module.c @@ -2043,7 +2043,7 @@ ngx_http_fastcgi_merge_loc_conf(ngx_conf ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"fastcgi_cache\" zone \"%V\" is unknown", - &shm_zone->name); + &shm_zone->shm.name); return NGX_CONF_ERROR; } diff --git a/src/http/modules/ngx_http_flv_module.c b/src/http/modules/ngx_http_flv_module.c --- a/src/http/modules/ngx_http_flv_module.c +++ b/src/http/modules/ngx_http_flv_module.c @@ -80,7 +80,6 @@ ngx_http_flv_handler(ngx_http_request_t return NGX_DECLINED; } - /* TODO: Win32 */ if (r->zero_in_uri) { return NGX_DECLINED; } diff --git a/src/http/modules/ngx_http_gzip_static_module.c b/src/http/modules/ngx_http_gzip_static_module.c --- a/src/http/modules/ngx_http_gzip_static_module.c +++ b/src/http/modules/ngx_http_gzip_static_module.c @@ -89,7 +89,6 @@ ngx_http_gzip_static_handler(ngx_http_re return NGX_DECLINED; } - /* TODO: Win32 */ if (r->zero_in_uri) { return NGX_DECLINED; } diff --git a/src/http/modules/ngx_http_index_module.c b/src/http/modules/ngx_http_index_module.c --- a/src/http/modules/ngx_http_index_module.c +++ b/src/http/modules/ngx_http_index_module.c @@ -116,7 +116,6 @@ ngx_http_index_handler(ngx_http_request_ return NGX_DECLINED; } - /* TODO: Win32 */ if (r->zero_in_uri) { return NGX_DECLINED; } diff --git a/src/http/modules/ngx_http_limit_req_module.c b/src/http/modules/ngx_http_limit_req_module.c --- a/src/http/modules/ngx_http_limit_req_module.c +++ b/src/http/modules/ngx_http_limit_req_module.c @@ -10,30 +10,39 @@ typedef struct { - u_char color; - u_char dummy; - u_short len; - ngx_queue_t queue; - ngx_msec_t last; - ngx_uint_t excess; /* integer value, 1 corresponds to 0.001 r/s */ - u_char data[1]; + u_char color; + u_char dummy; + u_short len; + ngx_queue_t queue; + ngx_msec_t last; + /* integer value, 1 corresponds to 0.001 r/s */ + ngx_uint_t excess; + u_char data[1]; } ngx_http_limit_req_node_t; typedef struct { - ngx_rbtree_t *rbtree; - ngx_queue_t *queue; - ngx_slab_pool_t *shpool; - ngx_uint_t rate; /* integer value, 1 corresponds to 0.001 r/s */ - ngx_int_t index; - ngx_str_t var; + ngx_rbtree_t rbtree; + ngx_rbtree_node_t sentinel; + ngx_queue_t queue; +} ngx_http_limit_req_shctx_t; + + +typedef struct { + ngx_http_limit_req_shctx_t *sh; + ngx_slab_pool_t *shpool; + /* integer value, 1 corresponds to 0.001 r/s */ + ngx_uint_t rate; + ngx_int_t index; + ngx_str_t var; } ngx_http_limit_req_ctx_t; typedef struct { - ngx_shm_zone_t *shm_zone; - ngx_uint_t burst; /* integer value, 1 corresponds to 0.001 r/s */ - ngx_uint_t nodelay;/* unsigned nodelay:1 */ + ngx_shm_zone_t *shm_zone; + /* integer value, 1 corresponds to 0.001 r/s */ + ngx_uint_t burst; + ngx_uint_t nodelay;/* unsigned nodelay:1 */ } ngx_http_limit_req_conf_t; @@ -163,7 +172,7 @@ ngx_http_limit_req_handler(ngx_http_requ if (lr) { ngx_queue_remove(&lr->queue); - ngx_queue_insert_head(ctx->queue, &lr->queue); + ngx_queue_insert_head(&ctx->sh->queue, &lr->queue); excess = lr->excess; @@ -179,7 +188,7 @@ ngx_http_limit_req_handler(ngx_http_requ ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "limiting requests, excess: %ui.%03ui by zone \"%V\"", - excess / 1000, excess % 1000, &lrcf->shm_zone->name); + excess / 1000, excess % 1000, &lrcf->shm_zone->shm.name); return NGX_HTTP_SERVICE_UNAVAILABLE; } @@ -193,7 +202,7 @@ ngx_http_limit_req_handler(ngx_http_requ ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, "delaying request, excess: %ui.%03ui, by zone \"%V\"", - excess / 1000, excess % 1000, &lrcf->shm_zone->name); + excess / 1000, excess % 1000, &lrcf->shm_zone->shm.name); if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) { return NGX_HTTP_INTERNAL_SERVER_ERROR; @@ -239,9 +248,9 @@ ngx_http_limit_req_handler(ngx_http_requ lr->excess = 0; ngx_memcpy(lr->data, vv->data, len); - ngx_rbtree_insert(ctx->rbtree, node); + ngx_rbtree_insert(&ctx->sh->rbtree, node); - ngx_queue_insert_head(ctx->queue, &lr->queue); + ngx_queue_insert_head(&ctx->sh->queue, &lr->queue); done: @@ -324,8 +333,8 @@ ngx_http_limit_req_lookup(ngx_http_limit ctx = lrcf->shm_zone->data; - node = ctx->rbtree->root; - sentinel = ctx->rbtree->sentinel; + node = ctx->sh->rbtree.root; + sentinel = ctx->sh->rbtree.sentinel; while (node != sentinel) { @@ -411,11 +420,11 @@ ngx_http_limit_req_expire(ngx_http_limit while (n < 3) { - if (ngx_queue_empty(ctx->queue)) { + if (ngx_queue_empty(&ctx->sh->queue)) { return; } - q = ngx_queue_last(ctx->queue); + q = ngx_queue_last(&ctx->sh->queue); lr = ngx_queue_data(q, ngx_http_limit_req_node_t, queue); @@ -440,7 +449,7 @@ ngx_http_limit_req_expire(ngx_http_limit node = (ngx_rbtree_node_t *) ((u_char *) lr - offsetof(ngx_rbtree_node_t, color)); - ngx_rbtree_delete(ctx->rbtree, node); + ngx_rbtree_delete(&ctx->sh->rbtree, node); ngx_slab_free_locked(ctx->shpool, node); } @@ -453,7 +462,6 @@ ngx_http_limit_req_init_zone(ngx_shm_zon ngx_http_limit_req_ctx_t *octx = data; size_t len; - ngx_rbtree_node_t *sentinel; ngx_http_limit_req_ctx_t *ctx; ctx = shm_zone->data; @@ -463,12 +471,11 @@ ngx_http_limit_req_init_zone(ngx_shm_zon ngx_log_error(NGX_LOG_EMERG, shm_zone->shm.log, 0, "limit_req \"%V\" uses the \"%V\" variable " "while previously it used the \"%V\" variable", - &shm_zone->name, &ctx->var, &octx->var); + &shm_zone->shm.name, &ctx->var, &octx->var); return NGX_ERROR; } - ctx->rbtree = octx->rbtree; - ctx->queue = octx->queue; + ctx->sh = octx->sh; ctx->shpool = octx->shpool; return NGX_OK; @@ -476,27 +483,25 @@ ngx_http_limit_req_init_zone(ngx_shm_zon ctx->shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; - ctx->rbtree = ngx_slab_alloc(ctx->shpool, sizeof(ngx_rbtree_t)); - if (ctx->rbtree == NULL) { - return NGX_ERROR; + if (shm_zone->shm.exists) { + ctx->sh = ctx->shpool->data; + + return NGX_OK; } - sentinel = ngx_slab_alloc(ctx->shpool, sizeof(ngx_rbtree_node_t)); - if (sentinel == NULL) { + ctx->sh = ngx_slab_alloc(ctx->shpool, sizeof(ngx_http_limit_req_shctx_t)); + if (ctx->sh == NULL) { return NGX_ERROR; } - ngx_rbtree_init(ctx->rbtree, sentinel, + ctx->shpool->data = ctx->sh; + + ngx_rbtree_init(&ctx->sh->rbtree, &ctx->sh->sentinel, ngx_http_limit_req_rbtree_insert_value); - ctx->queue = ngx_slab_alloc(ctx->shpool, sizeof(ngx_queue_t)); - if (ctx->queue == NULL) { - return NGX_ERROR; - } + ngx_queue_init(&ctx->sh->queue); - ngx_queue_init(ctx->queue); - - len = sizeof(" in limit_req zone \"\"") + shm_zone->name.len; + len = sizeof(" in limit_req zone \"\"") + shm_zone->shm.name.len; ctx->shpool->log_ctx = ngx_slab_alloc(ctx->shpool, len); if (ctx->shpool->log_ctx == NULL) { @@ -504,7 +509,7 @@ ngx_http_limit_req_init_zone(ngx_shm_zon } ngx_sprintf(ctx->shpool->log_ctx, " in limit_req zone \"%V\"%Z", - &shm_zone->name); + &shm_zone->shm.name); return NGX_OK; } @@ -574,6 +579,8 @@ ngx_http_limit_req_zone(ngx_conf_t *cf, p = (u_char *) ngx_strchr(name.data, ':'); if (p) { + *p = '\0'; + name.len = p - name.data; p++; @@ -744,7 +751,7 @@ ngx_http_limit_req(ngx_conf_t *cf, ngx_c if (lrcf->shm_zone->data == NULL) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "unknown limit_req_zone \"%V\"", - &lrcf->shm_zone->name); + &lrcf->shm_zone->shm.name); return NGX_CONF_ERROR; } diff --git a/src/http/modules/ngx_http_limit_zone_module.c b/src/http/modules/ngx_http_limit_zone_module.c --- a/src/http/modules/ngx_http_limit_zone_module.c +++ b/src/http/modules/ngx_http_limit_zone_module.c @@ -191,7 +191,7 @@ ngx_http_limit_zone_handler(ngx_http_req ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "limiting connections by zone \"%V\"", - &lzcf->shm_zone->name); + &lzcf->shm_zone->shm.name); return NGX_HTTP_SERVICE_UNAVAILABLE; } @@ -328,7 +328,7 @@ ngx_http_limit_zone_init_zone(ngx_shm_zo ngx_log_error(NGX_LOG_EMERG, shm_zone->shm.log, 0, "limit_zone \"%V\" uses the \"%V\" variable " "while previously it used the \"%V\" variable", - &shm_zone->name, &ctx->var, &octx->var); + &shm_zone->shm.name, &ctx->var, &octx->var); return NGX_ERROR; } @@ -339,11 +339,19 @@ ngx_http_limit_zone_init_zone(ngx_shm_zo shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; + if (shm_zone->shm.exists) { + ctx->rbtree = shpool->data; + + return NGX_OK; + } + ctx->rbtree = ngx_slab_alloc(shpool, sizeof(ngx_rbtree_t)); if (ctx->rbtree == NULL) { return NGX_ERROR; } + shpool->data = ctx->rbtree; + sentinel = ngx_slab_alloc(shpool, sizeof(ngx_rbtree_node_t)); if (sentinel == NULL) { return NGX_ERROR; @@ -352,14 +360,15 @@ ngx_http_limit_zone_init_zone(ngx_shm_zo ngx_rbtree_init(ctx->rbtree, sentinel, ngx_http_limit_zone_rbtree_insert_value); - len = sizeof(" in limit_zone \"\"") + shm_zone->name.len; + len = sizeof(" in limit_zone \"\"") + shm_zone->shm.name.len; shpool->log_ctx = ngx_slab_alloc(shpool, len); if (shpool->log_ctx == NULL) { return NGX_ERROR; } - ngx_sprintf(shpool->log_ctx, " in limit_zone \"%V\"%Z", &shm_zone->name); + ngx_sprintf(shpool->log_ctx, " in limit_zone \"%V\"%Z", + &shm_zone->shm.name); return NGX_OK; } diff --git a/src/http/modules/ngx_http_not_modified_filter_module.c b/src/http/modules/ngx_http_not_modified_filter_module.c --- a/src/http/modules/ngx_http_not_modified_filter_module.c +++ b/src/http/modules/ngx_http_not_modified_filter_module.c @@ -47,8 +47,8 @@ ngx_module_t ngx_http_not_modified_filt static ngx_http_output_header_filter_pt ngx_http_next_header_filter; -static -ngx_int_t ngx_http_not_modified_header_filter(ngx_http_request_t *r) +static ngx_int_t +ngx_http_not_modified_header_filter(ngx_http_request_t *r) { time_t ims; ngx_http_core_loc_conf_t *clcf; @@ -92,8 +92,8 @@ ngx_int_t ngx_http_not_modified_header_f } -static -ngx_int_t ngx_http_not_modified_filter_init(ngx_conf_t *cf) +static ngx_int_t +ngx_http_not_modified_filter_init(ngx_conf_t *cf) { ngx_http_next_header_filter = ngx_http_top_header_filter; ngx_http_top_header_filter = ngx_http_not_modified_header_filter; diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -497,6 +497,40 @@ static ngx_str_t ngx_http_proxy_hide_he }; +#if (NGX_HTTP_CACHE) + +static ngx_keyval_t ngx_http_proxy_cache_headers[] = { + { ngx_string("Host"), ngx_string("$proxy_host") }, + { ngx_string("Connection"), ngx_string("close") }, + { ngx_string("Keep-Alive"), ngx_string("") }, + { ngx_string("Expect"), ngx_string("") }, + { ngx_string("If-Modified-Since"), ngx_string("") }, + { ngx_string("If-Unmodified-Since"), ngx_string("") }, + { ngx_string("If-Match-None"), ngx_string("") }, + { ngx_string("If-Match"), ngx_string("") }, + { ngx_string("Range"), ngx_string("") }, + { ngx_string("If-Range"), ngx_string("") }, + { ngx_null_string, ngx_null_string } +}; + + +static ngx_str_t ngx_http_proxy_hide_cache_headers[] = { + ngx_string("Date"), + ngx_string("Server"), + ngx_string("X-Pad"), + ngx_string("X-Accel-Expires"), + ngx_string("X-Accel-Redirect"), + ngx_string("X-Accel-Limit-Rate"), + ngx_string("X-Accel-Buffering"), + ngx_string("X-Accel-Charset"), + ngx_string("Set-Cookie"), + ngx_string("P3P"), + ngx_null_string +}; + +#endif + + static ngx_http_variable_t ngx_http_proxy_vars[] = { { ngx_string("proxy_host"), NULL, ngx_http_proxy_host_variable, 0, @@ -1906,6 +1940,7 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t ngx_http_proxy_loc_conf_t *conf = child; size_t size; + ngx_str_t *h; ngx_keyval_t *s; ngx_hash_init_t hash; ngx_http_proxy_redirect_t *pr; @@ -2069,7 +2104,7 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "\"proxy_cache\" zone \"%V\" is unknown", - &shm_zone->name); + &shm_zone->shm.name); return NGX_CONF_ERROR; } @@ -2170,9 +2205,18 @@ ngx_http_proxy_merge_loc_conf(ngx_conf_t hash.bucket_size = conf->headers_hash_bucket_size; hash.name = "proxy_headers_hash"; +#if (NGX_HTTP_CACHE) + + h = conf->upstream.cache ? ngx_http_proxy_hide_cache_headers: + ngx_http_proxy_hide_headers; +#else + + h = ngx_http_proxy_hide_headers; + +#endif + if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream, - &prev->upstream, - ngx_http_proxy_hide_headers, &hash) + &prev->upstream, h, &hash) != NGX_OK) { return NGX_CONF_ERROR; @@ -2286,7 +2330,17 @@ ngx_http_proxy_merge_headers(ngx_conf_t src = conf->headers_source->elts; - for (h = ngx_http_proxy_headers; h->key.len; h++) { +#if (NGX_HTTP_CACHE) + + h = conf->upstream.cache ? ngx_http_proxy_cache_headers: + ngx_http_proxy_headers; +#else + + h = ngx_http_proxy_headers; + +#endif + + while (h->key.len) { for (i = 0; i < conf->headers_source->nelts; i++) { if (ngx_strcasecmp(h->key.data, src[i].key.data) == 0) { @@ -2305,7 +2359,7 @@ ngx_http_proxy_merge_headers(ngx_conf_t next: - continue; + h++; } diff --git a/src/http/modules/ngx_http_random_index_module.c b/src/http/modules/ngx_http_random_index_module.c --- a/src/http/modules/ngx_http_random_index_module.c +++ b/src/http/modules/ngx_http_random_index_module.c @@ -86,7 +86,6 @@ ngx_http_random_index_handler(ngx_http_r return NGX_DECLINED; } - /* TODO: Win32 */ if (r->zero_in_uri) { return NGX_DECLINED; } diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c --- a/src/http/modules/ngx_http_ssl_module.c +++ b/src/http/modules/ngx_http_ssl_module.c @@ -320,8 +320,8 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t sscf->enable = NGX_CONF_UNSET; sscf->prefer_server_ciphers = NGX_CONF_UNSET; - sscf->verify = NGX_CONF_UNSET; - sscf->verify_depth = NGX_CONF_UNSET; + sscf->verify = NGX_CONF_UNSET_UINT; + sscf->verify_depth = NGX_CONF_UNSET_UINT; sscf->builtin_session_cache = NGX_CONF_UNSET; sscf->session_timeout = NGX_CONF_UNSET; @@ -564,6 +564,7 @@ ngx_http_ssl_session_cache(ngx_conf_t *c for (j = sizeof("shared:") - 1; j < value[i].len; j++) { if (value[i].data[j] == ':') { + value[i].data[j] = '\0'; break; } diff --git a/src/http/modules/ngx_http_static_module.c b/src/http/modules/ngx_http_static_module.c --- a/src/http/modules/ngx_http_static_module.c +++ b/src/http/modules/ngx_http_static_module.c @@ -66,7 +66,6 @@ ngx_http_static_handler(ngx_http_request return NGX_DECLINED; } - /* TODO: Win32 */ if (r->zero_in_uri) { return NGX_DECLINED; } diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm --- a/src/http/modules/perl/nginx.pm +++ b/src/http/modules/perl/nginx.pm @@ -47,7 +47,7 @@ our @EXPORT = qw( HTTP_INSUFFICIENT_STORAGE ); -our $VERSION = '0.7.51'; +our $VERSION = '0.7.52'; require XSLoader; XSLoader::load('nginx', $VERSION); diff --git a/src/http/modules/perl/ngx_http_perl_module.c b/src/http/modules/perl/ngx_http_perl_module.c --- a/src/http/modules/perl/ngx_http_perl_module.c +++ b/src/http/modules/perl/ngx_http_perl_module.c @@ -154,10 +154,14 @@ static ngx_http_ssi_command_t ngx_http_ #endif -static ngx_str_t ngx_null_name = ngx_null_string; +static ngx_str_t ngx_null_name = ngx_null_string; + +static HV *nginx_stash; +#if (NGX_HAVE_PERL_MULTIPLICITY) +static ngx_uint_t ngx_perl_term; +#endif -static HV *nginx_stash; static void ngx_http_perl_xs_init(pTHX) @@ -171,7 +175,6 @@ ngx_http_perl_xs_init(pTHX) static ngx_int_t ngx_http_perl_handler(ngx_http_request_t *r) { - /* TODO: Win32 */ if (r->zero_in_uri) { return NGX_HTTP_NOT_FOUND; } @@ -821,6 +824,12 @@ ngx_http_perl_cleanup_perl(void *data) (void) perl_destruct(perl); perl_free(perl); + + if (ngx_perl_term) { + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, "perl term"); + + PERL_SYS_TERM(); + } } #endif @@ -1041,15 +1050,13 @@ ngx_http_perl_init_worker(ngx_cycle_t *c pmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_perl_module); - { - - dTHXa(pmcf->perl); - PERL_SET_CONTEXT(pmcf->perl); + if (pmcf) { + dTHXa(pmcf->perl); + PERL_SET_CONTEXT(pmcf->perl); - /* set worker's $$ */ + /* set worker's $$ */ - sv_setiv(GvSV(gv_fetchpv("$", TRUE, SVt_PV)), (I32) ngx_pid); - + sv_setiv(GvSV(gv_fetchpv("$", TRUE, SVt_PV)), (I32) ngx_pid); } return NGX_OK; @@ -1059,16 +1066,24 @@ ngx_http_perl_init_worker(ngx_cycle_t *c static void ngx_http_perl_exit(ngx_cycle_t *cycle) { +#if (NGX_HAVE_PERL_MULTIPLICITY) + + ngx_perl_term = 1; + +#else ngx_http_perl_main_conf_t *pmcf; pmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_perl_module); - { + if (pmcf && nginx_stash) { + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, cycle->log, 0, "perl term"); - dTHXa(pmcf->perl); - PERL_SET_CONTEXT(pmcf->perl); + (void) perl_destruct(pmcf->perl); - PERL_SYS_TERM(); + perl_free(pmcf->perl); + PERL_SYS_TERM(); } + +#endif } diff --git a/src/http/ngx_http_cache.h b/src/http/ngx_http_cache.h --- a/src/http/ngx_http_cache.h +++ b/src/http/ngx_http_cache.h @@ -94,16 +94,21 @@ typedef struct { } ngx_http_file_cache_header_t; +typedef struct { + ngx_rbtree_t rbtree; + ngx_rbtree_node_t sentinel; + ngx_queue_t queue; + ngx_atomic_t cold; + off_t size; +} ngx_http_file_cache_sh_t; + + struct ngx_http_file_cache_s { - ngx_rbtree_t *rbtree; - ngx_queue_t *queue; + ngx_http_file_cache_sh_t *sh; ngx_slab_pool_t *shpool; ngx_path_t *path; - ngx_atomic_t *cold; - off_t *size; - off_t max_size; size_t bsize; diff --git a/src/http/ngx_http_config.h b/src/http/ngx_http_config.h --- a/src/http/ngx_http_config.h +++ b/src/http/ngx_http_config.h @@ -69,8 +69,10 @@ typedef struct { ((ngx_http_conf_ctx_t *) cf->ctx)->loc_conf[module.ctx_index] #define ngx_http_cycle_get_module_main_conf(cycle, module) \ - ((ngx_http_conf_ctx_t *) \ - cycle->conf_ctx[ngx_http_module.index])->main_conf[module.ctx_index] + (cycle->conf_ctx[ngx_http_module.index] ? \ + ((ngx_http_conf_ctx_t *) cycle->conf_ctx[ngx_http_module.index]) \ + ->main_conf[module.ctx_index]: \ + NULL) #endif /* _NGX_HTTP_CONFIG_H_INCLUDED_ */ diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -691,7 +691,7 @@ ngx_module_t ngx_http_core_module = { }; -static ngx_str_t ngx_http_core_get_method = { 3, (u_char *) "GET " }; +ngx_str_t ngx_http_core_get_method = { 3, (u_char *) "GET " }; void diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -468,6 +468,8 @@ extern ngx_module_t ngx_http_core_modul extern ngx_uint_t ngx_http_max_module; +extern ngx_str_t ngx_http_core_get_method; + #define ngx_http_clear_content_length(r) \ \ diff --git a/src/http/ngx_http_file_cache.c b/src/http/ngx_http_file_cache.c --- a/src/http/ngx_http_file_cache.c +++ b/src/http/ngx_http_file_cache.c @@ -44,7 +44,6 @@ ngx_http_file_cache_init(ngx_shm_zone_t ngx_http_file_cache_t *ocache = data; size_t len; - ngx_rbtree_node_t *sentinel; ngx_http_file_cache_t *cache; cache = shm_zone->data; @@ -54,17 +53,15 @@ ngx_http_file_cache_init(ngx_shm_zone_t ngx_log_error(NGX_LOG_EMERG, shm_zone->shm.log, 0, "cache \"%V\" uses the \"%V\" cache path " "while previously it used the \"%V\" cache path", - &shm_zone->name, &cache->path->name, + &shm_zone->shm.name, &cache->path->name, &ocache->path->name); return NGX_ERROR; } - cache->rbtree = ocache->rbtree; - cache->queue = ocache->queue; + cache->sh = ocache->sh; + cache->shpool = ocache->shpool; - cache->cold = ocache->cold; - cache->size = ocache->size; cache->bsize = ocache->bsize; cache->max_size /= cache->bsize; @@ -74,45 +71,33 @@ ngx_http_file_cache_init(ngx_shm_zone_t cache->shpool = (ngx_slab_pool_t *) shm_zone->shm.addr; - cache->rbtree = ngx_slab_alloc(cache->shpool, sizeof(ngx_rbtree_t)); - if (cache->rbtree == NULL) { - return NGX_ERROR; + if (shm_zone->shm.exists) { + cache->sh = cache->shpool->data; + cache->bsize = ngx_fs_bsize(cache->path->name.data); + + return NGX_OK; } - sentinel = ngx_slab_alloc(cache->shpool, sizeof(ngx_rbtree_node_t)); - if (sentinel == NULL) { + cache->sh = ngx_slab_alloc(cache->shpool, sizeof(ngx_http_file_cache_sh_t)); + if (cache->sh == NULL) { return NGX_ERROR; } - ngx_rbtree_init(cache->rbtree, sentinel, + cache->shpool->data = cache->sh; + + ngx_rbtree_init(&cache->sh->rbtree, &cache->sh->sentinel, ngx_http_file_cache_rbtree_insert_value); - cache->queue = ngx_slab_alloc(cache->shpool, sizeof(ngx_queue_t)); - if (cache->queue == NULL) { - return NGX_ERROR; - } - - ngx_queue_init(cache->queue); + ngx_queue_init(&cache->sh->queue); - cache->cold = ngx_slab_alloc(cache->shpool, sizeof(ngx_atomic_t)); - if (cache->cold == NULL) { - return NGX_ERROR; - } - - *cache->cold = 1; - - cache->size = ngx_slab_alloc(cache->shpool, sizeof(off_t)); - if (cache->size == NULL) { - return NGX_ERROR; - } - - *cache->size = 0; + cache->sh->cold = 1; + cache->sh->size = 0; cache->bsize = ngx_fs_bsize(cache->path->name.data); cache->max_size /= cache->bsize; - len = sizeof(" in cache keys zone \"\"") + shm_zone->name.len; + len = sizeof(" in cache keys zone \"\"") + shm_zone->shm.name.len; cache->shpool->log_ctx = ngx_slab_alloc(cache->shpool, len); if (cache->shpool->log_ctx == NULL) { @@ -120,7 +105,7 @@ ngx_http_file_cache_init(ngx_shm_zone_t } ngx_sprintf(cache->shpool->log_ctx, " in cache keys zone \"%V\"%Z", - &shm_zone->name); + &shm_zone->shm.name); return NGX_OK; } @@ -202,7 +187,7 @@ ngx_http_file_cache_open(ngx_http_reques return rc; } - cold = *cache->cold; + cold = cache->sh->cold; if (rc == NGX_OK) { @@ -337,7 +322,7 @@ ngx_http_file_cache_open(ngx_http_reques c->node->body_start = c->body_start; c->node->exists = 1; - *cache->size += (c->length + cache->bsize - 1) / cache->bsize; + cache->sh->size += (c->length + cache->bsize - 1) / cache->bsize; } ngx_shmtx_unlock(&cache->shpool->mutex); @@ -434,7 +419,7 @@ ngx_http_file_cache_exists(ngx_http_file ngx_memcpy(fcn->key, &c->key[sizeof(ngx_rbtree_key_t)], NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t)); - ngx_rbtree_insert(cache->rbtree, &fcn->node); + ngx_rbtree_insert(&cache->sh->rbtree, &fcn->node); renew: @@ -454,7 +439,7 @@ done: fcn->expire = ngx_time() + cache->inactive; - ngx_queue_insert_head(cache->queue, &fcn->queue); + ngx_queue_insert_head(&cache->sh->queue, &fcn->queue); c->uniq = fcn->uniq; c->uses = fcn->uses; @@ -479,8 +464,8 @@ ngx_http_file_cache_lookup(ngx_http_file ngx_memcpy((u_char *) &node_key, key, sizeof(ngx_rbtree_key_t)); - node = cache->rbtree->root; - sentinel = cache->rbtree->sentinel; + node = cache->sh->rbtree.root; + sentinel = cache->sh->rbtree.sentinel; while (node != sentinel) { @@ -663,7 +648,7 @@ ngx_http_file_cache_update(ngx_http_requ c->node->length = c->length; - *cache->size += size; + cache->sh->size += size; if (rc == NGX_OK) { c->node->exists = 1; @@ -828,8 +813,8 @@ ngx_http_file_cache_forced_expire(ngx_ht ngx_shmtx_lock(&cache->shpool->mutex); - for (q = ngx_queue_last(cache->queue); - q != ngx_queue_sentinel(cache->queue); + for (q = ngx_queue_last(&cache->sh->queue); + q != ngx_queue_sentinel(&cache->sh->queue); q = ngx_queue_prev(q)) { fcn = ngx_queue_data(q, ngx_http_file_cache_node_t, queue); @@ -853,7 +838,7 @@ ngx_http_file_cache_forced_expire(ngx_ht if (!fcn->exists) { ngx_queue_remove(q); - ngx_rbtree_delete(cache->rbtree, &fcn->node); + ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node); ngx_slab_free_locked(cache->shpool, fcn); break; @@ -902,12 +887,12 @@ ngx_http_file_cache_expire(ngx_http_file for ( ;; ) { - if (ngx_queue_empty(cache->queue)) { + if (ngx_queue_empty(&cache->sh->queue)) { wait = 10; break; } - q = ngx_queue_last(cache->queue); + q = ngx_queue_last(&cache->sh->queue); fcn = ngx_queue_data(q, ngx_http_file_cache_node_t, queue); @@ -939,7 +924,7 @@ ngx_http_file_cache_expire(ngx_http_file */ ngx_queue_remove(q); - ngx_rbtree_delete(cache->rbtree, &fcn->node); + ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node); ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "ignore long locked inactive cache entry %*s, count:%d", @@ -951,7 +936,7 @@ ngx_http_file_cache_expire(ngx_http_file if (!fcn->exists) { ngx_queue_remove(q); - ngx_rbtree_delete(cache->rbtree, &fcn->node); + ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node); ngx_slab_free_locked(cache->shpool, fcn); continue; @@ -979,7 +964,7 @@ ngx_http_file_cache_delete(ngx_http_file fcn = ngx_queue_data(q, ngx_http_file_cache_node_t, queue); - *cache->size -= (fcn->length + cache->bsize - 1) / cache->bsize; + cache->sh->size -= (fcn->length + cache->bsize - 1) / cache->bsize; path = cache->path; @@ -993,7 +978,7 @@ ngx_http_file_cache_delete(ngx_http_file ngx_queue_remove(q); - ngx_rbtree_delete(cache->rbtree, &fcn->node); + ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node); ngx_slab_free_locked(cache->shpool, fcn); @@ -1024,7 +1009,7 @@ ngx_http_file_cache_manager(void *data) time_t next; ngx_tree_ctx_t tree; - if (*cache->cold) { + if (cache->sh->cold) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, "http file cache manager update"); @@ -1045,12 +1030,12 @@ ngx_http_file_cache_manager(void *data) return 10; } - *cache->cold = 0; + cache->sh->cold = 0; ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0, "http file cache: %V %.3fM, bsize: %uz", &cache->path->name, - ((double) *cache->size * cache->bsize) / (1024 * 1024), + ((double) cache->sh->size * cache->bsize) / (1024 * 1024), cache->bsize); } @@ -1062,7 +1047,7 @@ ngx_http_file_cache_manager(void *data) for ( ;; ) { ngx_shmtx_lock(&cache->shpool->mutex); - size = *cache->size; + size = cache->sh->size; ngx_shmtx_unlock(&cache->shpool->mutex); @@ -1245,7 +1230,7 @@ ngx_http_file_cache_add(ngx_http_file_ca ngx_memcpy(fcn->key, &c->key[sizeof(ngx_rbtree_key_t)], NGX_HTTP_CACHE_KEY_LEN - sizeof(ngx_rbtree_key_t)); - ngx_rbtree_insert(cache->rbtree, &fcn->node); + ngx_rbtree_insert(&cache->sh->rbtree, &fcn->node); fcn->uses = 1; fcn->count = 0; @@ -1257,7 +1242,7 @@ ngx_http_file_cache_add(ngx_http_file_ca fcn->body_start = c->body_start; fcn->length = c->length; - *cache->size += (c->length + cache->bsize - 1) / cache->bsize; + cache->sh->size += (c->length + cache->bsize - 1) / cache->bsize; } else { ngx_queue_remove(&fcn->queue); @@ -1265,7 +1250,7 @@ ngx_http_file_cache_add(ngx_http_file_ca fcn->expire = ngx_time() + cache->inactive; - ngx_queue_insert_head(cache->queue, &fcn->queue); + ngx_queue_insert_head(&cache->sh->queue, &fcn->queue); ngx_shmtx_unlock(&cache->shpool->mutex); @@ -1399,6 +1384,8 @@ ngx_http_file_cache_set_slot(ngx_conf_t p = (u_char *) ngx_strchr(name.data, ':'); if (p) { + *p = '\0'; + name.len = p - name.data; p++; diff --git a/src/http/ngx_http_header_filter_module.c b/src/http/ngx_http_header_filter_module.c --- a/src/http/ngx_http_header_filter_module.c +++ b/src/http/ngx_http_header_filter_module.c @@ -247,7 +247,7 @@ ngx_http_header_filter(ngx_http_request_ len += ngx_http_status_lines[status].len; } else if (status >= NGX_HTTP_BAD_REQUEST - && status < NGX_HTTP_LAST_LEVEL_400) + && status < NGX_HTTP_LAST_LEVEL_400) { /* 4XX */ status = status - NGX_HTTP_BAD_REQUEST @@ -586,7 +586,7 @@ ngx_http_header_filter(ngx_http_request_ } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "%*s\n", (size_t) (b->last - b->pos), b->pos); + "%*s", (size_t) (b->last - b->pos), b->pos); /* the end of HTTP header */ *b->last++ = CR; *b->last++ = LF; diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c +++ b/src/http/ngx_http_upstream.c @@ -532,10 +532,14 @@ ngx_http_upstream_cache(ngx_http_request ngx_int_t rc; ngx_http_cache_t *c; - if (!(r->method & NGX_HTTP_GET)) { + if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) { return NGX_DECLINED; } + if (r->method & NGX_HTTP_HEAD) { + u->method = ngx_http_core_get_method; + } + c = ngx_pcalloc(r->pool, sizeof(ngx_http_cache_t)); if (c == NULL) { return NGX_ERROR; @@ -1821,11 +1825,32 @@ ngx_http_upstream_send_response(ngx_http rc = ngx_http_send_header(r); - if (rc == NGX_ERROR || rc > NGX_OK || r->post_action || r->header_only) { + if (rc == NGX_ERROR || rc > NGX_OK || r->post_action) { ngx_http_upstream_finalize_request(r, u, rc); return; } + c = r->connection; + + if (r->header_only) { + + if (u->cacheable || u->store) { + + if (ngx_shutdown_socket(c->fd, NGX_WRITE_SHUTDOWN) == -1) { + ngx_connection_error(c, ngx_socket_errno, + ngx_shutdown_socket_n " failed"); + } + + r->read_event_handler = ngx_http_request_empty_handler; + r->write_event_handler = ngx_http_request_empty_handler; + c->error = 1; + + } else { + ngx_http_upstream_finalize_request(r, u, rc); + return; + } + } + u->header_sent = 1; if (r->request_body && r->request_body->temp_file) { @@ -1833,8 +1858,6 @@ ngx_http_upstream_send_response(ngx_http r->request_body->temp_file->file.fd = NGX_INVALID_FILE; } - c = r->connection; - clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); if (!u->buffering) { @@ -1942,6 +1965,7 @@ ngx_http_upstream_send_response(ngx_http } else { u->cacheable = 0; + r->headers_out.last_modified_time = -1; } } @@ -2819,8 +2843,6 @@ static ngx_int_t ngx_http_upstream_process_cache_control(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset) { - u_char *p, *last; - ngx_int_t n; ngx_array_t *pa; ngx_table_elt_t **ph; @@ -2840,6 +2862,11 @@ ngx_http_upstream_process_cache_control( *ph = h; +#if (NGX_HTTP_CACHE) + { + u_char *p, *last; + ngx_int_t n; + if (r->cache == NULL) { return NGX_OK; } @@ -2885,6 +2912,9 @@ ngx_http_upstream_process_cache_control( } r->cache->valid_sec = ngx_time() + n; + } +#endif + return NGX_OK; } @@ -2893,10 +2923,12 @@ static ngx_int_t ngx_http_upstream_process_expires(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset) { + r->upstream->headers_in.expires = h; + +#if (NGX_HTTP_CACHE) + { time_t expires; - r->upstream->headers_in.expires = h; - if (r->cache == NULL) { return NGX_OK; } @@ -2913,6 +2945,8 @@ ngx_http_upstream_process_expires(ngx_ht } r->cache->valid_sec = expires; + } +#endif return NGX_OK; } @@ -2922,12 +2956,14 @@ static ngx_int_t ngx_http_upstream_process_accel_expires(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset) { + r->upstream->headers_in.x_accel_expires = h; + +#if (NGX_HTTP_CACHE) + { u_char *p; size_t len; ngx_int_t n; - r->upstream->headers_in.x_accel_expires = h; - if (r->cache == NULL) { return NGX_OK; } @@ -2958,6 +2994,8 @@ ngx_http_upstream_process_accel_expires( if (n != NGX_ERROR) { r->cache->valid_sec = n; } + } +#endif return NGX_OK; } @@ -3163,7 +3201,7 @@ ngx_http_upstream_copy_last_modified(ngx #if (NGX_HTTP_CACHE) - if (r->cached) { + if (r->cached || r->upstream->cacheable) { r->headers_out.last_modified = ho; r->headers_out.last_modified_time = ngx_http_parse_time(h->value.data, h->value.len); diff --git a/src/os/unix/ngx_send.c b/src/os/unix/ngx_send.c --- a/src/os/unix/ngx_send.c +++ b/src/os/unix/ngx_send.c @@ -40,6 +40,8 @@ ngx_unix_send(ngx_connection_t *c, u_cha wev->ready = 0; } + c->sent += n; + return n; } diff --git a/src/os/unix/ngx_shmem.h b/src/os/unix/ngx_shmem.h --- a/src/os/unix/ngx_shmem.h +++ b/src/os/unix/ngx_shmem.h @@ -15,7 +15,9 @@ typedef struct { u_char *addr; size_t size; + ngx_str_t name; ngx_log_t *log; + ngx_uint_t exists; /* unsigned exists:1; */ } ngx_shm_t;