# HG changeset patch # User Igor Sysoev # Date 1156881600 -14400 # Node ID 38e7b94d63acdc707dfa5e44d262f9b08a441097 # Parent 1965c8e23be74d0a72f48f9652e82351bbe4f742 nginx 0.4.0 *) Change in internal API: the HTTP modules initialization was moved from the init module phase to the HTTP postconfiguration phase. *) Change: now the request body is not read beforehand for the ngx_http_perl_module: it's required to start the reading using the $r->has_request_body method. *) Feature: the ngx_http_perl_module supports the DECLINED return code. *) Feature: the ngx_http_dav_module supports the incoming "Date" header line for the PUT method. *) Feature: the "ssi" directive is available inside the "if" block. *) Bugfix: a segmentation fault occurred if there was an "index" directive with variables and the first index name was without variables; bug appeared in 0.1.29. diff --git a/CHANGES b/CHANGES --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,29 @@ +Changes with nginx 0.4.0 30 Aug 2006 + + *) Change in internal API: the HTTP modules initialization was moved + from the init module phase to the HTTP postconfiguration phase. + + *) Change: now the request body is not read beforehand for the + ngx_http_perl_module: it's required to start the reading using the + $r->has_request_body method. + + *) Feature: the ngx_http_perl_module supports the DECLINED return code. + + *) Feature: the ngx_http_dav_module supports the incoming "Date" header + line for the PUT method. + + *) Feature: the "ssi" directive is available inside the "if" block. + + *) Bugfix: a segmentation fault occurred if there was an "index" + directive with variables and the first index name was without + variables; bug appeared in 0.1.29. + + Changes with nginx 0.3.61 28 Aug 2006 + *) Change: now the "tcp_nodelay" directive is turned on by default. + *) Feature: the "msie_refresh" directive. *) Feature: the "recursive_error_pages" directive. diff --git a/CHANGES.ru b/CHANGES.ru --- a/CHANGES.ru +++ b/CHANGES.ru @@ -1,6 +1,30 @@ +Изменения в nginx 0.4.0 30.08.2006 + + *) Изменение во внутреннем API: инициализация модулей HTTP перенесена + из фазы init module в фазу HTTP postconfiguration. + + *) Изменение: теперь тело запроса в модуле ngx_http_perl_module не + считывается заранее: нужно явно инициировать чтение с помощью метода + $r->has_request_body. + + *) Добавление: модуль ngx_http_perl_module поддерживает код возврата + DECLINED. + + *) Добавление: модуль ngx_http_dav_module поддерживает входящую строку + заголовка "Date" для метода PUT. + + *) Добавление: директива ssi работает внутри блока if. + + *) Исправление: происходил segmentation fault, если в директиве index + использовалась переменные и при этом первое имя индексного файла + было без переменных; ошибка появилась в 0.1.29. + + Изменения в nginx 0.3.61 28.08.2006 + *) Изменение: директива tcp_nodelay теперь по умолчанию включена. + *) Добавление: директива msie_refresh. *) Добавление: директива recursive_error_pages. diff --git a/auto/cc/gcc b/auto/cc/gcc --- a/auto/cc/gcc +++ b/auto/cc/gcc @@ -182,5 +182,3 @@ CFLAGS="$CFLAGS -g" if [ ".$CPP" = "." ]; then CPP="$CC -E" fi - -NGX_PERL_CFLAGS="$CFLAGS" diff --git a/auto/cc/icc b/auto/cc/icc --- a/auto/cc/icc +++ b/auto/cc/icc @@ -91,6 +91,8 @@ CFLAGS="$CFLAGS -wd269" CFLAGS="$CFLAGS -wd810" # parameter was never referenced CFLAGS="$CFLAGS -wd869" +# attribute "unused" is only allowed in a function definition, warning on pTHX_ +CFLAGS="$CFLAGS -wd1301" # STUB # enumerated type mixed with another type diff --git a/auto/lib/perl/conf b/auto/lib/perl/conf --- a/auto/lib/perl/conf +++ b/auto/lib/perl/conf @@ -19,9 +19,16 @@ if test -n "$NGX_PERL_VER"; then exit 1; fi - CFLAGS="$CFLAGS `$NGX_PERL -MExtUtils::Embed -e ccopts`" - # gcc 4.1/4.2 - CFLAGS=`echo $CFLAGS | sed -e 's/-Wunused-value/-Wno-unused-value/'` + NGX_PERL_CFLAGS="$CFLAGS `$NGX_PERL -MExtUtils::Embed -e ccopts`" + NGX_PM_CFLAGS=`$NGX_PERL -MExtUtils::Embed -e ccopts` + + # gcc 4.1/4.2 warn about unused values in pTHX_ + NGX_PERL_CFLAGS=`echo $NGX_PERL_CFLAGS \ + | sed -e 's/-Wunused-value/-Wno-unused-value/'` + # icc8 warns 'declaration hides parameter "my_perl"' in ENTER and LEAVE + NGX_PERL_CFLAGS=`echo $NGX_PERL_CFLAGS \ + | sed -e 's/-wd171/-wd171 -wd1599/'` + ngx_perl_ldopts=`$NGX_PERL -MExtUtils::Embed -e ldopts` if $NGX_PERL -V:usemultiplicity | grep define > /dev/null; then diff --git a/auto/lib/perl/make b/auto/lib/perl/make --- a/auto/lib/perl/make +++ b/auto/lib/perl/make @@ -24,9 +24,8 @@ cat << END cp -p src/http/modules/perl/Makefile.PL $NGX_OBJS/src/http/modules/perl/ cd $NGX_OBJS/src/http/modules/perl \ - && NGX_PERL_CFLAGS="$NGX_PERL_CFLAGS $NGX_CC_OPT" \ + && NGX_PM_CFLAGS="\$(NGX_PM_CFLAGS) -g $NGX_CC_OPT" \ NGX_PCRE=$PCRE \ - NGX_ZLIB=$ZLIB \ NGX_OBJS=$NGX_OBJS \ $NGX_PERL Makefile.PL \ LIB=$NGX_PERL_MODULES diff --git a/auto/make b/auto/make --- a/auto/make +++ b/auto/make @@ -22,6 +22,11 @@ LINK = $LINK END +if test -n "$NGX_PERL_CFLAGS"; then + echo NGX_PERL_CFLAGS = $NGX_PERL_CFLAGS >> $NGX_MAKEFILE + echo NGX_PM_CFLAGS = $NGX_PM_CFLAGS >> $NGX_MAKEFILE +fi + if [ "$BMAKE" = wmake ]; then echo MAKE = wmake >> $NGX_MAKEFILE @@ -238,23 +243,37 @@ if [ $HTTP = YES ]; then ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) $ngx_use_pch \$(ALL_INCS)" else ngx_cc="\$(CC) $ngx_compile_opt \$(CFLAGS) \$(CORE_INCS) \$(HTTP_INCS)" + ngx_perl_cc="\$(CC) $ngx_compile_opt \$(NGX_PERL_CFLAGS) " + ngx_perl_cc="$ngx_perl_cc \$(CORE_INCS) \$(HTTP_INCS)" fi - for ngx_src in $HTTP_SRCS + for ngx_source in $HTTP_SRCS do - ngx_src=`echo $ngx_src | sed -e "s/\//$ngx_regex_dirsep/g"` + ngx_src=`echo $ngx_source | sed -e "s/\//$ngx_regex_dirsep/g"` ngx_obj=`echo $ngx_src \ | sed -e "s#^\(.*\.\)cpp\\$#$ngx_objs_dir\1$ngx_objext#g" \ -e "s#^\(.*\.\)cc\\$#$ngx_objs_dir\1$ngx_objext#g" \ -e "s#^\(.*\.\)c\\$#$ngx_objs_dir\1$ngx_objext#g" \ -e "s#^\(.*\.\)S\\$#$ngx_objs_dir\1$ngx_objext#g"` - cat << END >> $NGX_MAKEFILE + if [ $ngx_source = src/http/modules/perl/ngx_http_perl_module.c ]; then + + cat << END >> $NGX_MAKEFILE + +$ngx_obj: \$(CORE_DEPS) \$(HTTP_DEPS)$ngx_cont$ngx_src + $ngx_perl_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX + +END + else + + cat << END >> $NGX_MAKEFILE $ngx_obj: \$(CORE_DEPS) \$(HTTP_DEPS)$ngx_cont$ngx_src $ngx_cc$ngx_tab$ngx_objout$ngx_obj$ngx_tab$ngx_src$NGX_AUX END + + fi done fi diff --git a/src/core/nginx.h b/src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -8,7 +8,7 @@ #define _NGINX_H_INCLUDED_ -#define NGINX_VER "nginx/0.3.61" +#define NGINX_VER "nginx/0.4.0" #define NGINX_VAR "NGINX" #define NGX_OLDPID_EXT ".oldbin" diff --git a/src/http/modules/ngx_http_access_module.c b/src/http/modules/ngx_http_access_module.c --- a/src/http/modules/ngx_http_access_module.c +++ b/src/http/modules/ngx_http_access_module.c @@ -29,7 +29,7 @@ static char *ngx_http_access_rule(ngx_co static void *ngx_http_access_create_loc_conf(ngx_conf_t *cf); static char *ngx_http_access_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child); -static ngx_int_t ngx_http_access_init(ngx_cycle_t *cycle); +static ngx_int_t ngx_http_access_init(ngx_conf_t *cf); static ngx_command_t ngx_http_access_commands[] = { @@ -57,7 +57,7 @@ static ngx_command_t ngx_http_access_co static ngx_http_module_t ngx_http_access_module_ctx = { NULL, /* preconfiguration */ - NULL, /* postconfiguration */ + ngx_http_access_init, /* postconfiguration */ NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -76,7 +76,7 @@ ngx_module_t ngx_http_access_module = { ngx_http_access_commands, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ - ngx_http_access_init, /* init module */ + NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ @@ -215,12 +215,12 @@ ngx_http_access_merge_loc_conf(ngx_conf_ static ngx_int_t -ngx_http_access_init(ngx_cycle_t *cycle) +ngx_http_access_init(ngx_conf_t *cf) { ngx_http_handler_pt *h; ngx_http_core_main_conf_t *cmcf; - cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module); + cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); h = ngx_array_push(&cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers); if (h == NULL) { diff --git a/src/http/modules/ngx_http_addition_filter_module.c b/src/http/modules/ngx_http_addition_filter_module.c --- a/src/http/modules/ngx_http_addition_filter_module.c +++ b/src/http/modules/ngx_http_addition_filter_module.c @@ -20,10 +20,10 @@ typedef struct { } ngx_http_addition_ctx_t; -static ngx_int_t ngx_http_addition_filter_init(ngx_cycle_t *cycle); static void *ngx_http_addition_create_conf(ngx_conf_t *cf); static char *ngx_http_addition_merge_conf(ngx_conf_t *cf, void *parent, void *child); +static ngx_int_t ngx_http_addition_filter_init(ngx_conf_t *cf); static ngx_command_t ngx_http_addition_commands[] = { @@ -48,7 +48,7 @@ static ngx_command_t ngx_http_addition_ static ngx_http_module_t ngx_http_addition_filter_module_ctx = { NULL, /* preconfiguration */ - NULL, /* postconfiguration */ + ngx_http_addition_filter_init, /* postconfiguration */ NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -67,7 +67,7 @@ ngx_module_t ngx_http_addition_filter_m ngx_http_addition_commands, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ - ngx_http_addition_filter_init, /* init module */ + NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ @@ -178,7 +178,7 @@ ngx_http_addition_body_filter(ngx_http_r static ngx_int_t -ngx_http_addition_filter_init(ngx_cycle_t *cycle) +ngx_http_addition_filter_init(ngx_conf_t *cf) { ngx_http_next_header_filter = ngx_http_top_header_filter; ngx_http_top_header_filter = ngx_http_addition_header_filter; diff --git a/src/http/modules/ngx_http_auth_basic_module.c b/src/http/modules/ngx_http_auth_basic_module.c --- a/src/http/modules/ngx_http_auth_basic_module.c +++ b/src/http/modules/ngx_http_auth_basic_module.c @@ -32,7 +32,7 @@ static void ngx_http_auth_basic_close(ng static void *ngx_http_auth_basic_create_loc_conf(ngx_conf_t *cf); static char *ngx_http_auth_basic_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child); -static ngx_int_t ngx_http_auth_basic_init(ngx_cycle_t *cycle); +static ngx_int_t ngx_http_auth_basic_init(ngx_conf_t *cf); static char *ngx_http_auth_basic(ngx_conf_t *cf, void *post, void *data); @@ -62,7 +62,7 @@ static ngx_command_t ngx_http_auth_basi static ngx_http_module_t ngx_http_auth_basic_module_ctx = { NULL, /* preconfiguration */ - NULL, /* postconfiguration */ + ngx_http_auth_basic_init, /* postconfiguration */ NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -81,7 +81,7 @@ ngx_module_t ngx_http_auth_basic_module ngx_http_auth_basic_commands, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ - ngx_http_auth_basic_init, /* init module */ + NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ @@ -351,12 +351,12 @@ ngx_http_auth_basic_merge_loc_conf(ngx_c static ngx_int_t -ngx_http_auth_basic_init(ngx_cycle_t *cycle) +ngx_http_auth_basic_init(ngx_conf_t *cf) { ngx_http_handler_pt *h; ngx_http_core_main_conf_t *cmcf; - cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module); + cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); h = ngx_array_push(&cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers); if (h == NULL) { 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 @@ -48,7 +48,7 @@ static int ngx_libc_cdecl ngx_http_autoi const void *two); static ngx_int_t ngx_http_autoindex_error(ngx_http_request_t *r, ngx_dir_t *dir, ngx_str_t *name); -static ngx_int_t ngx_http_autoindex_init(ngx_cycle_t *cycle); +static ngx_int_t ngx_http_autoindex_init(ngx_conf_t *cf); static void *ngx_http_autoindex_create_loc_conf(ngx_conf_t *cf); static char *ngx_http_autoindex_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child); @@ -83,7 +83,7 @@ static ngx_command_t ngx_http_autoindex static ngx_http_module_t ngx_http_autoindex_module_ctx = { NULL, /* preconfiguration */ - NULL, /* postconfiguration */ + ngx_http_autoindex_init, /* postconfiguration */ NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -102,7 +102,7 @@ ngx_module_t ngx_http_autoindex_module ngx_http_autoindex_commands, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ - ngx_http_autoindex_init, /* init module */ + NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ @@ -590,25 +590,6 @@ ngx_http_autoindex_error(ngx_http_reques } -static ngx_int_t -ngx_http_autoindex_init(ngx_cycle_t *cycle) -{ - ngx_http_handler_pt *h; - ngx_http_core_main_conf_t *cmcf; - - cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module); - - h = ngx_array_push(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers); - if (h == NULL) { - return NGX_ERROR; - } - - *h = ngx_http_autoindex_handler; - - return NGX_OK; -} - - static void * ngx_http_autoindex_create_loc_conf(ngx_conf_t *cf) { @@ -639,3 +620,22 @@ ngx_http_autoindex_merge_loc_conf(ngx_co return NGX_CONF_OK; } + + +static ngx_int_t +ngx_http_autoindex_init(ngx_conf_t *cf) +{ + ngx_http_handler_pt *h; + ngx_http_core_main_conf_t *cmcf; + + cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); + + h = ngx_array_push(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers); + if (h == NULL) { + return NGX_ERROR; + } + + *h = ngx_http_autoindex_handler; + + return NGX_OK; +} diff --git a/src/http/modules/ngx_http_charset_filter_module.c b/src/http/modules/ngx_http_charset_filter_module.c --- a/src/http/modules/ngx_http_charset_filter_module.c +++ b/src/http/modules/ngx_http_charset_filter_module.c @@ -102,8 +102,6 @@ static char *ngx_http_set_charset_slot(n void *conf); static ngx_int_t ngx_http_add_charset(ngx_array_t *charsets, ngx_str_t *name); -static ngx_int_t ngx_http_charset_filter_init(ngx_cycle_t *cycle); - static void *ngx_http_charset_create_main_conf(ngx_conf_t *cf); static void *ngx_http_charset_create_loc_conf(ngx_conf_t *cf); static char *ngx_http_charset_merge_loc_conf(ngx_conf_t *cf, @@ -169,7 +167,7 @@ ngx_module_t ngx_http_charset_filter_mo ngx_http_charset_filter_commands, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ - ngx_http_charset_filter_init, /* init module */ + NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ @@ -1334,19 +1332,6 @@ ngx_http_add_charset(ngx_array_t *charse } -static ngx_int_t -ngx_http_charset_filter_init(ngx_cycle_t *cycle) -{ - ngx_http_next_header_filter = ngx_http_top_header_filter; - ngx_http_top_header_filter = ngx_http_charset_header_filter; - - ngx_http_next_body_filter = ngx_http_top_body_filter; - ngx_http_top_body_filter = ngx_http_charset_body_filter; - - return NGX_OK; -} - - static void * ngx_http_charset_create_main_conf(ngx_conf_t *cf) { @@ -1516,5 +1501,11 @@ ngx_http_charset_postconfiguration(ngx_c dst[tables[t].src] = tables[t].dst2src; } + ngx_http_next_header_filter = ngx_http_top_header_filter; + ngx_http_top_header_filter = ngx_http_charset_header_filter; + + ngx_http_next_body_filter = ngx_http_top_body_filter; + ngx_http_top_body_filter = ngx_http_charset_body_filter; + return NGX_OK; } diff --git a/src/http/modules/ngx_http_chunked_filter_module.c b/src/http/modules/ngx_http_chunked_filter_module.c --- a/src/http/modules/ngx_http_chunked_filter_module.c +++ b/src/http/modules/ngx_http_chunked_filter_module.c @@ -9,12 +9,12 @@ #include -static ngx_int_t ngx_http_chunked_filter_init(ngx_cycle_t *cycle); +static ngx_int_t ngx_http_chunked_filter_init(ngx_conf_t *cf); static ngx_http_module_t ngx_http_chunked_filter_module_ctx = { NULL, /* preconfiguration */ - NULL, /* postconfiguration */ + ngx_http_chunked_filter_init, /* postconfiguration */ NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -33,7 +33,7 @@ ngx_module_t ngx_http_chunked_filter_mo NULL, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ - ngx_http_chunked_filter_init, /* init module */ + NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ @@ -183,7 +183,7 @@ ngx_http_chunked_body_filter(ngx_http_re static ngx_int_t -ngx_http_chunked_filter_init(ngx_cycle_t *cycle) +ngx_http_chunked_filter_init(ngx_conf_t *cf) { ngx_http_next_header_filter = ngx_http_top_header_filter; ngx_http_top_header_filter = ngx_http_chunked_header_filter; 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 @@ -28,7 +28,7 @@ static char *ngx_http_dav_access(ngx_con static void *ngx_http_dav_create_loc_conf(ngx_conf_t *cf); static char *ngx_http_dav_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child); -static ngx_int_t ngx_http_dav_init(ngx_cycle_t *cycle); +static ngx_int_t ngx_http_dav_init(ngx_conf_t *cf); static ngx_conf_bitmask_t ngx_http_dav_methods_mask[] = { @@ -69,7 +69,7 @@ static ngx_command_t ngx_http_dav_comma static ngx_http_module_t ngx_http_dav_module_ctx = { NULL, /* preconfiguration */ - NULL, /* postconfiguration */ + ngx_http_dav_init, /* postconfiguration */ NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -88,7 +88,7 @@ ngx_module_t ngx_http_dav_module = { ngx_http_dav_commands, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ - ngx_http_dav_init, /* init module */ + NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ @@ -245,6 +245,7 @@ ngx_http_dav_put_handler(ngx_http_reques { char *failed; u_char *name; + time_t date; ngx_err_t err; ngx_str_t *temp, path; ngx_uint_t status; @@ -295,6 +296,24 @@ ngx_http_dav_put_handler(ngx_http_reques #endif + if (r->headers_in.date) { + date = ngx_http_parse_time(r->headers_in.date->value.data, + r->headers_in.date->value.len); + + if (date != NGX_ERROR) { + if (ngx_set_file_time(temp->data, + r->request_body->temp_file->file.fd, date) + != NGX_OK) + { + err = ngx_errno; + failed = ngx_set_file_time_n; + name = temp->data; + + goto failed; + } + } + } + failed = ngx_rename_file_n; name = path.data; @@ -332,13 +351,10 @@ ngx_http_dav_put_handler(ngx_http_reques err = ngx_errno; } - -#else +#endif failed: -#endif - if (ngx_delete_file(temp->data) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, ngx_delete_file_n " \"%s\" failed", @@ -543,12 +559,12 @@ ngx_http_dav_merge_loc_conf(ngx_conf_t * static ngx_int_t -ngx_http_dav_init(ngx_cycle_t *cycle) +ngx_http_dav_init(ngx_conf_t *cf) { ngx_http_handler_pt *h; ngx_http_core_main_conf_t *cmcf; - cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module); + cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); h = ngx_array_push(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers); if (h == NULL) { diff --git a/src/http/modules/ngx_http_gzip_filter_module.c b/src/http/modules/ngx_http_gzip_filter_module.c --- a/src/http/modules/ngx_http_gzip_filter_module.c +++ b/src/http/modules/ngx_http_gzip_filter_module.c @@ -83,7 +83,7 @@ static ngx_int_t ngx_http_gzip_add_varia static ngx_int_t ngx_http_gzip_ratio_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); -static ngx_int_t ngx_http_gzip_filter_init(ngx_cycle_t *cycle); +static ngx_int_t ngx_http_gzip_filter_init(ngx_conf_t *cf); static void *ngx_http_gzip_create_conf(ngx_conf_t *cf); static char *ngx_http_gzip_merge_conf(ngx_conf_t *cf, void *parent, void *child); @@ -201,7 +201,7 @@ static ngx_command_t ngx_http_gzip_filt static ngx_http_module_t ngx_http_gzip_filter_module_ctx = { ngx_http_gzip_add_variables, /* preconfiguration */ - NULL, /* postconfiguration */ + ngx_http_gzip_filter_init, /* postconfiguration */ NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -220,7 +220,7 @@ ngx_module_t ngx_http_gzip_filter_modul ngx_http_gzip_filter_commands, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ - ngx_http_gzip_filter_init, /* init module */ + NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ @@ -1030,19 +1030,6 @@ ngx_http_gzip_ratio_variable(ngx_http_re } -static ngx_int_t -ngx_http_gzip_filter_init(ngx_cycle_t *cycle) -{ - ngx_http_next_header_filter = ngx_http_top_header_filter; - ngx_http_top_header_filter = ngx_http_gzip_header_filter; - - ngx_http_next_body_filter = ngx_http_top_body_filter; - ngx_http_top_body_filter = ngx_http_gzip_body_filter; - - return NGX_OK; -} - - static void * ngx_http_gzip_create_conf(ngx_conf_t *cf) { @@ -1123,6 +1110,19 @@ ngx_http_gzip_merge_conf(ngx_conf_t *cf, } +static ngx_int_t +ngx_http_gzip_filter_init(ngx_conf_t *cf) +{ + ngx_http_next_header_filter = ngx_http_top_header_filter; + ngx_http_top_header_filter = ngx_http_gzip_header_filter; + + ngx_http_next_body_filter = ngx_http_top_body_filter; + ngx_http_top_body_filter = ngx_http_gzip_body_filter; + + return NGX_OK; +} + + static char * ngx_http_gzip_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { diff --git a/src/http/modules/ngx_http_headers_filter_module.c b/src/http/modules/ngx_http_headers_filter_module.c --- a/src/http/modules/ngx_http_headers_filter_module.c +++ b/src/http/modules/ngx_http_headers_filter_module.c @@ -28,10 +28,10 @@ typedef struct { #define NGX_HTTP_EXPIRES_EPOCH -2147483645 -static ngx_int_t ngx_http_headers_filter_init(ngx_cycle_t *cycle); static void *ngx_http_headers_create_conf(ngx_conf_t *cf); static char *ngx_http_headers_merge_conf(ngx_conf_t *cf, void *parent, void *child); +static ngx_int_t ngx_http_headers_filter_init(ngx_conf_t *cf); static char *ngx_http_headers_expires(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static char *ngx_http_headers_add(ngx_conf_t *cf, ngx_command_t *cmd, @@ -62,7 +62,7 @@ static ngx_command_t ngx_http_headers_f static ngx_http_module_t ngx_http_headers_filter_module_ctx = { NULL, /* preconfiguration */ - NULL, /* postconfiguration */ + ngx_http_headers_filter_init, /* postconfiguration */ NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -81,7 +81,7 @@ ngx_module_t ngx_http_headers_filter_mo ngx_http_headers_filter_commands, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ - ngx_http_headers_filter_init, /* init module */ + NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ @@ -274,16 +274,6 @@ ngx_http_headers_filter(ngx_http_request } -static ngx_int_t -ngx_http_headers_filter_init(ngx_cycle_t *cycle) -{ - ngx_http_next_header_filter = ngx_http_top_header_filter; - ngx_http_top_header_filter = ngx_http_headers_filter; - - return NGX_OK; -} - - static void * ngx_http_headers_create_conf(ngx_conf_t *cf) { @@ -331,6 +321,16 @@ ngx_http_headers_merge_conf(ngx_conf_t * } +static ngx_int_t +ngx_http_headers_filter_init(ngx_conf_t *cf) +{ + ngx_http_next_header_filter = ngx_http_top_header_filter; + ngx_http_top_header_filter = ngx_http_headers_filter; + + return NGX_OK; +} + + static char * ngx_http_headers_expires(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { 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 @@ -40,7 +40,7 @@ static ngx_int_t ngx_http_index_test_dir static ngx_int_t ngx_http_index_error(ngx_http_request_t *r, ngx_http_index_ctx_t *ctx, ngx_err_t err); -static ngx_int_t ngx_http_index_init(ngx_cycle_t *cycle); +static ngx_int_t ngx_http_index_init(ngx_conf_t *cf); static void *ngx_http_index_create_loc_conf(ngx_conf_t *cf); static char *ngx_http_index_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child); @@ -74,7 +74,7 @@ static ngx_command_t ngx_http_index_com static ngx_http_module_t ngx_http_index_module_ctx = { NULL, /* preconfiguration */ - NULL, /* postconfiguration */ + ngx_http_index_init, /* postconfiguration */ NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -93,7 +93,7 @@ ngx_module_t ngx_http_index_module = { ngx_http_index_commands, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ - ngx_http_index_init, /* init module */ + NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ @@ -198,7 +198,7 @@ ngx_http_index_handler(ngx_http_request_ len += 16; } - if (len > ctx->path.len) { + if (len > (size_t) (ctx->path.data + ctx->path.len - ctx->index.data)) { last = ngx_http_map_uri_to_path(r, &ctx->path, len); if (last == NULL) { @@ -378,7 +378,7 @@ ngx_http_index_create_loc_conf(ngx_conf_ } conf->indices = NULL; - conf->max_index_len = 1; + conf->max_index_len = 0; return conf; } @@ -422,6 +422,25 @@ ngx_http_index_merge_loc_conf(ngx_conf_t } +static ngx_int_t +ngx_http_index_init(ngx_conf_t *cf) +{ + ngx_http_handler_pt *h; + ngx_http_core_main_conf_t *cmcf; + + cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); + + h = ngx_array_push(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers); + if (h == NULL) { + return NGX_ERROR; + } + + *h = ngx_http_index_handler; + + return NGX_OK; +} + + /* TODO: warn about duplicate indices */ static char * @@ -429,8 +448,8 @@ ngx_http_index_set_index(ngx_conf_t *cf, { ngx_http_index_loc_conf_t *ilcf = conf; + ngx_str_t *value; ngx_uint_t i, n; - ngx_str_t *value; ngx_http_index_t *index; ngx_http_script_compile_t sc; @@ -471,9 +490,7 @@ ngx_http_index_set_index(ngx_conf_t *cf, n = ngx_http_script_variables_count(&value[i]); if (n == 0) { - if (ilcf->max_index_len != 0 - && ilcf->max_index_len < index->name.len) - { + if (ilcf->max_index_len < index->name.len) { ilcf->max_index_len = index->name.len; } @@ -496,28 +513,7 @@ ngx_http_index_set_index(ngx_conf_t *cf, if (ngx_http_script_compile(&sc) != NGX_OK) { return NGX_CONF_ERROR; } - - ilcf->max_index_len = 0; } return NGX_CONF_OK; } - - -static ngx_int_t -ngx_http_index_init(ngx_cycle_t *cycle) -{ - ngx_http_handler_pt *h; - ngx_http_core_main_conf_t *cmcf; - - cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module); - - h = ngx_array_push(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers); - if (h == NULL) { - return NGX_ERROR; - } - - *h = ngx_http_index_handler; - - 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 @@ -10,12 +10,12 @@ -static ngx_int_t ngx_http_not_modified_filter_init(ngx_cycle_t *cycle); +static ngx_int_t ngx_http_not_modified_filter_init(ngx_conf_t *cf); static ngx_http_module_t ngx_http_not_modified_filter_module_ctx = { NULL, /* preconfiguration */ - NULL, /* postconfiguration */ + ngx_http_not_modified_filter_init, /* postconfiguration */ NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -34,7 +34,7 @@ ngx_module_t ngx_http_not_modified_filt NULL, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ - ngx_http_not_modified_filter_init, /* init module */ + NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ @@ -47,7 +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; @@ -80,7 +81,8 @@ static ngx_int_t ngx_http_not_modified_h } -static ngx_int_t ngx_http_not_modified_filter_init(ngx_cycle_t *cycle) +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_range_filter_module.c b/src/http/modules/ngx_http_range_filter_module.c --- a/src/http/modules/ngx_http_range_filter_module.c +++ b/src/http/modules/ngx_http_range_filter_module.c @@ -49,13 +49,13 @@ typedef struct { } ngx_http_range_filter_ctx_t; -static ngx_int_t ngx_http_range_header_filter_init(ngx_cycle_t *cycle); -static ngx_int_t ngx_http_range_body_filter_init(ngx_cycle_t *cycle); +static ngx_int_t ngx_http_range_header_filter_init(ngx_conf_t *cf); +static ngx_int_t ngx_http_range_body_filter_init(ngx_conf_t *cf); static ngx_http_module_t ngx_http_range_header_filter_module_ctx = { NULL, /* preconfiguration */ - NULL, /* postconfiguration */ + ngx_http_range_header_filter_init, /* postconfiguration */ NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -74,7 +74,7 @@ ngx_module_t ngx_http_range_header_filt NULL, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ - ngx_http_range_header_filter_init, /* init module */ + NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ @@ -86,7 +86,7 @@ ngx_module_t ngx_http_range_header_filt static ngx_http_module_t ngx_http_range_body_filter_module_ctx = { NULL, /* preconfiguration */ - NULL, /* postconfiguration */ + ngx_http_range_body_filter_init, /* postconfiguration */ NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -105,7 +105,7 @@ ngx_module_t ngx_http_range_body_filter NULL, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ - ngx_http_range_body_filter_init, /* init module */ + NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ @@ -588,7 +588,7 @@ ngx_http_range_body_filter(ngx_http_requ static ngx_int_t -ngx_http_range_header_filter_init(ngx_cycle_t *cycle) +ngx_http_range_header_filter_init(ngx_conf_t *cf) { ngx_http_next_header_filter = ngx_http_top_header_filter; ngx_http_top_header_filter = ngx_http_range_header_filter; @@ -598,7 +598,7 @@ ngx_http_range_header_filter_init(ngx_cy static ngx_int_t -ngx_http_range_body_filter_init(ngx_cycle_t *cycle) +ngx_http_range_body_filter_init(ngx_conf_t *cf) { ngx_http_next_body_filter = ngx_http_top_body_filter; ngx_http_top_body_filter = ngx_http_range_body_filter; diff --git a/src/http/modules/ngx_http_realip_module.c b/src/http/modules/ngx_http_realip_module.c --- a/src/http/modules/ngx_http_realip_module.c +++ b/src/http/modules/ngx_http_realip_module.c @@ -30,7 +30,7 @@ static char *ngx_http_realip_from(ngx_co static void *ngx_http_realip_create_loc_conf(ngx_conf_t *cf); static char *ngx_http_realip_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child); -static ngx_int_t ngx_http_realip_init(ngx_cycle_t *cycle); +static ngx_int_t ngx_http_realip_init(ngx_conf_t *cf); static ngx_conf_enum_t ngx_http_realip_header[] = { @@ -63,7 +63,7 @@ static ngx_command_t ngx_http_realip_co static ngx_http_module_t ngx_http_realip_module_ctx = { NULL, /* preconfiguration */ - NULL, /* postconfiguration */ + ngx_http_realip_init, /* postconfiguration */ NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -82,7 +82,7 @@ ngx_module_t ngx_http_realip_module = { ngx_http_realip_commands, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ - ngx_http_realip_init, /* init module */ + NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ @@ -250,12 +250,12 @@ ngx_http_realip_merge_loc_conf(ngx_conf_ static ngx_int_t -ngx_http_realip_init(ngx_cycle_t *cycle) +ngx_http_realip_init(ngx_conf_t *cf) { ngx_http_handler_pt *h; ngx_http_core_main_conf_t *cmcf; - cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module); + cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); h = ngx_array_push(&cmcf->phases[NGX_HTTP_POST_READ_PHASE].handlers); if (h == NULL) { diff --git a/src/http/modules/ngx_http_rewrite_module.c b/src/http/modules/ngx_http_rewrite_module.c --- a/src/http/modules/ngx_http_rewrite_module.c +++ b/src/http/modules/ngx_http_rewrite_module.c @@ -23,7 +23,7 @@ typedef struct { static void *ngx_http_rewrite_create_loc_conf(ngx_conf_t *cf); static char *ngx_http_rewrite_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child); -static ngx_int_t ngx_http_rewrite_init(ngx_cycle_t *cycle); +static ngx_int_t ngx_http_rewrite_init(ngx_conf_t *cf); static char *ngx_http_rewrite(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static char *ngx_http_rewrite_return(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); @@ -104,7 +104,7 @@ static ngx_command_t ngx_http_rewrite_c static ngx_http_module_t ngx_http_rewrite_module_ctx = { NULL, /* preconfiguration */ - NULL, /* postconfiguration */ + ngx_http_rewrite_init, /* postconfiguration */ NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -123,7 +123,7 @@ ngx_module_t ngx_http_rewrite_module = ngx_http_rewrite_commands, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ - ngx_http_rewrite_init, /* init module */ + NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ @@ -267,12 +267,12 @@ ngx_http_rewrite_merge_loc_conf(ngx_conf static ngx_int_t -ngx_http_rewrite_init(ngx_cycle_t *cycle) +ngx_http_rewrite_init(ngx_conf_t *cf) { ngx_http_handler_pt *h; ngx_http_core_main_conf_t *cmcf; - cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module); + cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); h = ngx_array_push(&cmcf->phases[NGX_HTTP_SERVER_REWRITE_PHASE].handlers); if (h == NULL) { diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c --- a/src/http/modules/ngx_http_ssi_filter_module.c +++ b/src/http/modules/ngx_http_ssi_filter_module.c @@ -106,13 +106,14 @@ static char *ngx_http_ssi_init_main_conf static void *ngx_http_ssi_create_conf(ngx_conf_t *cf); static char *ngx_http_ssi_merge_conf(ngx_conf_t *cf, void *parent, void *child); -static ngx_int_t ngx_http_ssi_filter_init(ngx_cycle_t *cycle); +static ngx_int_t ngx_http_ssi_filter_init(ngx_conf_t *cf); static ngx_command_t ngx_http_ssi_filter_commands[] = { { ngx_string("ssi"), - NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF + |NGX_CONF_FLAG, ngx_conf_set_flag_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_ssi_loc_conf_t, enable), @@ -160,7 +161,7 @@ static ngx_command_t ngx_http_ssi_filte static ngx_http_module_t ngx_http_ssi_filter_module_ctx = { ngx_http_ssi_preconfiguration, /* preconfiguration */ - NULL, /* postconfiguration */ + ngx_http_ssi_filter_init, /* postconfiguration */ ngx_http_ssi_create_main_conf, /* create main configuration */ ngx_http_ssi_init_main_conf, /* init main configuration */ @@ -179,7 +180,7 @@ ngx_module_t ngx_http_ssi_filter_module ngx_http_ssi_filter_commands, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ - ngx_http_ssi_filter_init, /* init module */ + NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ @@ -2654,7 +2655,7 @@ ngx_http_ssi_merge_conf(ngx_conf_t *cf, static ngx_int_t -ngx_http_ssi_filter_init(ngx_cycle_t *cycle) +ngx_http_ssi_filter_init(ngx_conf_t *cf) { ngx_http_next_header_filter = ngx_http_top_header_filter; ngx_http_top_header_filter = ngx_http_ssi_header_filter; 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 @@ -18,7 +18,7 @@ static ngx_int_t ngx_http_static_handler static void *ngx_http_static_create_loc_conf(ngx_conf_t *cf); static char *ngx_http_static_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child); -static ngx_int_t ngx_http_static_init(ngx_cycle_t *cycle); +static ngx_int_t ngx_http_static_init(ngx_conf_t *cf); static ngx_command_t ngx_http_static_commands[] = { @@ -40,7 +40,7 @@ static ngx_command_t ngx_http_static_co ngx_http_module_t ngx_http_static_module_ctx = { NULL, /* preconfiguration */ - NULL, /* postconfiguration */ + ngx_http_static_init, /* postconfiguration */ NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -59,7 +59,7 @@ ngx_module_t ngx_http_static_module = { ngx_http_static_commands, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ - ngx_http_static_init, /* init module */ + NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ @@ -317,12 +317,12 @@ ngx_http_static_merge_loc_conf(ngx_conf_ static ngx_int_t -ngx_http_static_init(ngx_cycle_t *cycle) +ngx_http_static_init(ngx_conf_t *cf) { ngx_http_handler_pt *h; ngx_http_core_main_conf_t *cmcf; - cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module); + cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); h = ngx_array_push(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers); if (h == NULL) { diff --git a/src/http/modules/ngx_http_userid_filter_module.c b/src/http/modules/ngx_http_userid_filter_module.c --- a/src/http/modules/ngx_http_userid_filter_module.c +++ b/src/http/modules/ngx_http_userid_filter_module.c @@ -59,7 +59,7 @@ static ngx_int_t ngx_http_userid_add_var static ngx_int_t ngx_http_userid_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); -static ngx_int_t ngx_http_userid_init(ngx_cycle_t *cycle); +static ngx_int_t ngx_http_userid_init(ngx_conf_t *cf); static void *ngx_http_userid_create_conf(ngx_conf_t *cf); static char *ngx_http_userid_merge_conf(ngx_conf_t *cf, void *parent, void *child); @@ -162,7 +162,7 @@ static ngx_command_t ngx_http_userid_co static ngx_http_module_t ngx_http_userid_filter_module_ctx = { ngx_http_userid_add_variables, /* preconfiguration */ - NULL, /* postconfiguration */ + ngx_http_userid_init, /* postconfiguration */ NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -181,7 +181,7 @@ ngx_module_t ngx_http_userid_filter_mod ngx_http_userid_commands, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ - ngx_http_userid_init, /* init module */ + NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ @@ -622,16 +622,6 @@ ngx_http_userid_variable(ngx_http_reques } -static ngx_int_t -ngx_http_userid_init(ngx_cycle_t *cycle) -{ - ngx_http_next_header_filter = ngx_http_top_header_filter; - ngx_http_top_header_filter = ngx_http_userid_filter; - - return NGX_OK; -} - - static void * ngx_http_userid_create_conf(ngx_conf_t *cf) { @@ -693,6 +683,16 @@ ngx_http_userid_merge_conf(ngx_conf_t *c } +static ngx_int_t +ngx_http_userid_init(ngx_conf_t *cf) +{ + ngx_http_next_header_filter = ngx_http_top_header_filter; + ngx_http_top_header_filter = ngx_http_userid_filter; + + return NGX_OK; +} + + static char * ngx_http_userid_domain(ngx_conf_t *cf, void *post, void *data) { diff --git a/src/http/modules/perl/Makefile.PL b/src/http/modules/perl/Makefile.PL --- a/src/http/modules/perl/Makefile.PL +++ b/src/http/modules/perl/Makefile.PL @@ -12,7 +12,7 @@ WriteMakefile( ABSTRACT_FROM => 'nginx.pm', # retrieve abstract from module AUTHOR => 'Igor Sysoev', - CCFLAGS => "$ENV{NGX_PERL_CFLAGS}", + CCFLAGS => "$ENV{NGX_PM_CFLAGS}", OPTIMIZE => '-O', INC => "-I ../../../../../src/core " . @@ -22,8 +22,9 @@ WriteMakefile( "-I ../../../../../src/http/modules " . "-I ../../../../../src/http/modules/perl " . "-I ../../../../../$ENV{NGX_OBJS} " . - "-I ../../../../../$ENV{NGX_PCRE} " . - "-I ../../../../../$ENV{NGX_ZLIB} ", + ($ENV{NGX_PCRE} =~ /^(YES|NO)/ ? "" : + ($ENV{NGX_PCRE} =~ m#^/# ? "-I $ENV{NGX_PCRE} " : + "-I ../../../../../$ENV{NGX_PCRE} ")), depend => { 'nginx.c' => diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm --- a/src/http/modules/perl/nginx.pm +++ b/src/http/modules/perl/nginx.pm @@ -17,7 +17,7 @@ our @EXPORT = qw( HTTP_SERVER_ERROR ); -our $VERSION = '0.3.43'; +our $VERSION = '0.4.0'; require XSLoader; XSLoader::load('nginx', $VERSION); diff --git a/src/http/modules/perl/nginx.xs b/src/http/modules/perl/nginx.xs --- a/src/http/modules/perl/nginx.xs +++ b/src/http/modules/perl/nginx.xs @@ -329,6 +329,42 @@ header_in(r, key) void +has_request_body(r, next) + CODE: + + dXSTARG; + ngx_http_request_t *r; + SV *next; + ngx_http_perl_ctx_t *ctx; + + ngx_http_perl_set_request(r); + + if (r->headers_in.content_length_n <= 0) { + XSRETURN_UNDEF; + } + + next = ST(1); + + ctx = ngx_http_get_module_ctx(r, ngx_http_perl_module); + ctx->next = next; + + r->request_body_in_single_buf = 1; + r->request_body_in_persistent_file = 1; + r->request_body_delete_incomplete_file = 1; + + if (r->request_body_in_file_only) { + r->request_body_file_log_level = 0; + } + + ngx_http_read_client_request_body(r, ngx_http_perl_handle_request); + + sv_upgrade(TARG, SVt_IV); + sv_setiv(TARG, 1); + + ST(0) = TARG; + + +void request_body(r) CODE: 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 @@ -45,7 +45,6 @@ static ngx_int_t ngx_http_perl_ssi(ngx_h ngx_http_ssi_ctx_t *ssi_ctx, ngx_str_t **params); #endif -static void ngx_http_perl_handle_request(ngx_http_request_t *r); static ngx_int_t ngx_http_perl_get_interpreter(ngx_http_perl_main_conf_t *pmcf, PerlInterpreter **perl, ngx_log_t *log); @@ -176,6 +175,9 @@ static ngx_http_ssi_command_t ngx_http_ #endif +static ngx_str_t ngx_null_name = ngx_null_string; + + static HV *nginx_stash; static void @@ -190,13 +192,16 @@ ngx_http_perl_xs_init(pTHX) static ngx_int_t ngx_http_perl_handler(ngx_http_request_t *r) { - ngx_int_t rc; - /* TODO: Win32 */ if (r->zero_in_uri) { return NGX_HTTP_NOT_FOUND; } + ngx_http_perl_handle_request(r); + + return NGX_DONE; + +#if 0 r->request_body_in_single_buf = 1; r->request_body_in_persistent_file = 1; r->request_body_delete_incomplete_file = 1; @@ -212,14 +217,16 @@ ngx_http_perl_handler(ngx_http_request_t } return NGX_DONE; +#endif } -static void +void ngx_http_perl_handle_request(ngx_http_request_t *r) { + SV *sub; ngx_int_t rc; - ngx_str_t uri, args; + ngx_str_t uri, args, *handler; ngx_http_perl_ctx_t *ctx; ngx_http_perl_loc_conf_t *plcf; ngx_http_perl_main_conf_t *pmcf; @@ -231,7 +238,7 @@ ngx_http_perl_handle_request(ngx_http_re if (ctx == NULL) { ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_perl_ctx_t)); if (ctx == NULL) { - ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); + ngx_http_finalize_request(r, NGX_ERROR); return; } @@ -251,10 +258,18 @@ ngx_http_perl_handle_request(ngx_http_re dTHXa(ctx->perl); - plcf = ngx_http_get_module_loc_conf(r, ngx_http_perl_module); + if (ctx->next == NULL) { + plcf = ngx_http_get_module_loc_conf(r, ngx_http_perl_module); + sub = plcf->sub; + handler = &plcf->handler; - rc = ngx_http_perl_call_handler(aTHX_ r, plcf->sub, NULL, - &plcf->handler, NULL); + } else { + sub = ctx->next; + handler = &ngx_null_name; + ctx->next = NULL; + } + + rc = ngx_http_perl_call_handler(aTHX_ r, sub, NULL, handler, NULL); } @@ -278,6 +293,10 @@ ngx_http_perl_handle_request(ngx_http_re ctx->filename.data = NULL; ctx->redirect_uri.len = 0; + if (ctx->done || ctx->next) { + return; + } + if (uri.len) { ngx_http_internal_redirect(r, &uri, &args); return; @@ -285,6 +304,7 @@ ngx_http_perl_handle_request(ngx_http_re if (rc == NGX_OK || rc == NGX_HTTP_OK) { ngx_http_send_special(r, NGX_HTTP_LAST); + ctx->done = 1; } ngx_http_finalize_request(r, rc); @@ -666,14 +686,6 @@ ngx_http_perl_run_requires(pTHX_ ngx_arr } -#if (__INTEL_COMPILER) -/* - * disable 'declaration hides parameter "my_perl"' warning for ENTER and LEAVE - */ -#pragma warning(disable:1599) -#endif - - static ngx_int_t ngx_http_perl_call_handler(pTHX_ ngx_http_request_t *r, SV *sub, ngx_str_t **args, ngx_str_t *handler, ngx_str_t *rv) @@ -773,11 +785,6 @@ ngx_http_perl_call_handler(pTHX_ ngx_htt } -#if (__INTEL_COMPILER) -#pragma warning(default:1599) -#endif - - static void ngx_http_perl_eval_anon_sub(pTHX_ ngx_str_t *handler, SV **sv) { diff --git a/src/http/modules/perl/ngx_http_perl_module.h b/src/http/modules/perl/ngx_http_perl_module.h --- a/src/http/modules/perl/ngx_http_perl_module.h +++ b/src/http/modules/perl/ngx_http_perl_module.h @@ -24,6 +24,9 @@ typedef struct { ngx_str_t filename; ngx_str_t redirect_uri; ngx_str_t redirect_args; + SV *next; + + ngx_uint_t done; /* unsigned done:1; */ #if (NGX_HTTP_SSI) ngx_http_ssi_ctx_t *ssi; @@ -47,4 +50,7 @@ extern ngx_module_t ngx_http_perl_modul extern void boot_DynaLoader(pTHX_ CV* cv); +void ngx_http_perl_handle_request(ngx_http_request_t *r); + + #endif /* _NGX_HTTP_PERL_MODULE_H_INCLUDED_ */ diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c --- a/src/http/ngx_http.c +++ b/src/http/ngx_http.c @@ -75,8 +75,9 @@ ngx_http_block(ngx_conf_t *cf, ngx_comma { char *rv; u_char ch; - ngx_int_t rc; - ngx_uint_t mi, m, s, l, p, a, i; + ngx_int_t rc, j; + ngx_uint_t mi, m, s, l, p, a, i, n; + ngx_uint_t find_config_index, use_rewrite, use_access; ngx_uint_t last, bind_all, done; ngx_conf_t pcf; ngx_array_t headers_in, in_ports; @@ -93,9 +94,11 @@ ngx_http_block(ngx_conf_t *cf, ngx_comma ngx_http_conf_in_addr_t *in_addr; ngx_hash_keys_arrays_t ha; ngx_http_server_name_t *name; + ngx_http_phase_handler_t *ph; ngx_http_virtual_names_t *vn; ngx_http_core_srv_conf_t **cscfp, *cscf; ngx_http_core_loc_conf_t *clcf; + ngx_http_phase_handler_pt checker; ngx_http_core_main_conf_t *cmcf; #if (NGX_WIN32) ngx_iocp_conf_t *iocpcf; @@ -293,8 +296,6 @@ ngx_http_block(ngx_conf_t *cf, ngx_comma return NGX_CONF_ERROR; } - cmcf->phases[NGX_HTTP_POST_READ_PHASE].type = NGX_OK; - if (ngx_array_init(&cmcf->phases[NGX_HTTP_SERVER_REWRITE_PHASE].handlers, cf->pool, 1, sizeof(ngx_http_handler_pt)) @@ -303,27 +304,6 @@ ngx_http_block(ngx_conf_t *cf, ngx_comma return NGX_CONF_ERROR; } - cmcf->phases[NGX_HTTP_SERVER_REWRITE_PHASE].type = NGX_OK; - - - /* the special find config phase for a single handler */ - - if (ngx_array_init(&cmcf->phases[NGX_HTTP_FIND_CONFIG_PHASE].handlers, - cf->pool, 1, sizeof(ngx_http_handler_pt)) - != NGX_OK) - { - return NGX_CONF_ERROR; - } - - cmcf->phases[NGX_HTTP_FIND_CONFIG_PHASE].type = NGX_OK; - - h = ngx_array_push(&cmcf->phases[NGX_HTTP_FIND_CONFIG_PHASE].handlers); - if (h == NULL) { - return NGX_CONF_ERROR; - } - - *h = ngx_http_find_location_config; - if (ngx_array_init(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers, cf->pool, 1, sizeof(ngx_http_handler_pt)) @@ -332,8 +312,6 @@ ngx_http_block(ngx_conf_t *cf, ngx_comma return NGX_CONF_ERROR; } - cmcf->phases[NGX_HTTP_REWRITE_PHASE].type = NGX_OK; - if (ngx_array_init(&cmcf->phases[NGX_HTTP_PREACCESS_PHASE].handlers, cf->pool, 1, sizeof(ngx_http_handler_pt)) @@ -342,8 +320,6 @@ ngx_http_block(ngx_conf_t *cf, ngx_comma return NGX_CONF_ERROR; } - cmcf->phases[NGX_HTTP_PREACCESS_PHASE].type = NGX_OK; - if (ngx_array_init(&cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers, cf->pool, 2, sizeof(ngx_http_handler_pt)) @@ -352,8 +328,6 @@ ngx_http_block(ngx_conf_t *cf, ngx_comma return NGX_CONF_ERROR; } - cmcf->phases[NGX_HTTP_ACCESS_PHASE].type = NGX_DECLINED; - if (ngx_array_init(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers, cf->pool, 4, sizeof(ngx_http_handler_pt)) @@ -362,8 +336,6 @@ ngx_http_block(ngx_conf_t *cf, ngx_comma return NGX_CONF_ERROR; } - cmcf->phases[NGX_HTTP_CONTENT_PHASE].type = NGX_OK; - if (ngx_array_init(&cmcf->phases[NGX_HTTP_LOG_PHASE].handlers, cf->pool, 1, sizeof(ngx_http_handler_pt)) @@ -372,8 +344,6 @@ ngx_http_block(ngx_conf_t *cf, ngx_comma return NGX_CONF_ERROR; } - cmcf->phases[NGX_HTTP_LOG_PHASE].type = NGX_OK; - if (ngx_array_init(&headers_in, cf->temp_pool, 32, sizeof(ngx_hash_key_t)) != NGX_OK) @@ -432,6 +402,91 @@ ngx_http_block(ngx_conf_t *cf, ngx_comma *cf = pcf; + cmcf->phase_engine.server_rewrite_index = (ngx_uint_t) -1; + find_config_index = 0; + use_rewrite = cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers.nelts ? 1 : 0; + use_access = cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers.nelts ? 1 : 0; + + n = use_rewrite + use_access + 1; /* find config phase */ + + for (i = 0; i < NGX_HTTP_LOG_PHASE; i++) { + n += cmcf->phases[i].handlers.nelts; + } + + ph = ngx_pcalloc(cf->pool, + n * sizeof(ngx_http_phase_handler_t) + sizeof(void *)); + if (ph == NULL) { + return NGX_CONF_ERROR; + } + + cmcf->phase_engine.handlers = ph; + n = 0; + + for (i = 0; i < NGX_HTTP_LOG_PHASE; i++) { + h = cmcf->phases[i].handlers.elts; + + switch (i) { + + case NGX_HTTP_SERVER_REWRITE_PHASE: + if (cmcf->phase_engine.server_rewrite_index == (ngx_uint_t) -1) { + cmcf->phase_engine.server_rewrite_index = n; + } + checker = ngx_http_core_generic_phase; + + break; + + case NGX_HTTP_FIND_CONFIG_PHASE: + find_config_index = n; + + ph->checker = ngx_http_core_find_config_phase; + n++; + ph++; + + continue; + + case NGX_HTTP_POST_REWRITE_PHASE: + if (use_rewrite) { + ph->checker = ngx_http_core_post_rewrite_phase; + ph->next = find_config_index; + n++; + ph++; + } + + continue; + + case NGX_HTTP_ACCESS_PHASE: + checker = ngx_http_core_access_phase; + n++; + break; + + case NGX_HTTP_POST_ACCESS_PHASE: + if (use_access) { + ph->checker = ngx_http_core_post_access_phase; + ph->next = n; + ph++; + } + + continue; + + case NGX_HTTP_CONTENT_PHASE: + checker = ngx_http_core_content_phase; + break; + + default: + checker = ngx_http_core_generic_phase; + } + + n += cmcf->phases[i].handlers.nelts; + + for (j = cmcf->phases[i].handlers.nelts - 1; j >=0; j--) { + ph->checker = checker; + ph->handler = h[j]; + ph->next = n; + ph++; + } + } + + /* * create the lists of ports, addresses and server names * to quickly find the server core module configuration at run-time @@ -936,7 +991,6 @@ ngx_http_add_names(ngx_conf_t *cf, ngx_h if (name == NULL) { return NGX_ERROR; } - server_names = cscf->server_names.elts; *name = server_names[i]; } diff --git a/src/http/ngx_http_copy_filter_module.c b/src/http/ngx_http_copy_filter_module.c --- a/src/http/ngx_http_copy_filter_module.c +++ b/src/http/ngx_http_copy_filter_module.c @@ -17,7 +17,7 @@ typedef struct { static void *ngx_http_copy_filter_create_conf(ngx_conf_t *cf); static char *ngx_http_copy_filter_merge_conf(ngx_conf_t *cf, void *parent, void *child); -static ngx_int_t ngx_http_copy_filter_init(ngx_cycle_t *cycle); +static ngx_int_t ngx_http_copy_filter_init(ngx_conf_t *cf); static ngx_command_t ngx_http_copy_filter_commands[] = { @@ -35,7 +35,7 @@ static ngx_command_t ngx_http_copy_filt static ngx_http_module_t ngx_http_copy_filter_module_ctx = { NULL, /* preconfiguration */ - NULL, /* postconfiguration */ + ngx_http_copy_filter_init, /* postconfiguration */ NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -54,7 +54,7 @@ ngx_module_t ngx_http_copy_filter_modul ngx_http_copy_filter_commands, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ - ngx_http_copy_filter_init, /* init module */ + NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ @@ -149,7 +149,7 @@ ngx_http_copy_filter_merge_conf(ngx_conf static ngx_int_t -ngx_http_copy_filter_init(ngx_cycle_t *cycle) +ngx_http_copy_filter_init(ngx_conf_t *cf) { ngx_http_next_filter = ngx_http_top_body_filter; ngx_http_top_body_filter = ngx_http_copy_filter; 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 @@ -23,7 +23,6 @@ typedef struct { #define NGX_HTTP_LOCATION_REGEX 4 -static void ngx_http_core_run_phases(ngx_http_request_t *r); static ngx_int_t ngx_http_core_find_location(ngx_http_request_t *r, ngx_array_t *locations, size_t len); @@ -474,6 +473,8 @@ ngx_module_t ngx_http_core_module = { void ngx_http_handler(ngx_http_request_t *r) { + ngx_http_core_main_conf_t *cmcf; + r->connection->log->action = NULL; r->connection->unexpected_eof = 0; @@ -500,8 +501,8 @@ ngx_http_handler(ngx_http_request_t *r) if (r->keepalive && r->headers_in.msie && r->method == NGX_HTTP_POST) { /* - * MSIE may wait for some time if the response for - * the POST request is sent over the keepalive connection + * MSIE may wait for some time if an response for + * a POST request was sent over a keepalive connection */ r->keepalive = 0; @@ -515,172 +516,84 @@ ngx_http_handler(ngx_http_request_t *r) } } - r->write_event_handler = ngx_http_core_run_phases; - r->valid_unparsed_uri = 1; r->valid_location = 1; - r->uri_changed = 1; - - r->phase = (!r->internal) ? NGX_HTTP_POST_READ_PHASE: - NGX_HTTP_SERVER_REWRITE_PHASE; - r->phase_handler = 0; - + + if (!r->internal) { + r->phase_handler = 0; + + } else { + cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); + r->phase_handler = cmcf->phase_engine.server_rewrite_index; + } + + r->write_event_handler = ngx_http_core_run_phases; ngx_http_core_run_phases(r); } -static void +void ngx_http_core_run_phases(ngx_http_request_t *r) { ngx_int_t rc; - ngx_str_t path; - ngx_http_handler_pt *h; - ngx_http_core_loc_conf_t *clcf; + ngx_http_phase_handler_t *ph; ngx_http_core_main_conf_t *cmcf; - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http phase handler"); - cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); - for (/* void */; r->phase < NGX_HTTP_LOG_PHASE; r->phase++) { - - if (r->phase == NGX_HTTP_REWRITE_PHASE + 1 && r->uri_changed) { - - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "uri changes: %d", r->uri_changes); - - /* - * gcc before 3.3 compiles the broken code for - * if (r->uri_changes-- == 0) - * if the r->uri_changes is defined as - * unsigned uri_changes:4 - */ - - r->uri_changes--; - - if (r->uri_changes == 0) { - ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, - "rewrite or internal redirection cycle " - "while processing \"%V\"", &r->uri); - ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); - return; - } - - r->phase = NGX_HTTP_FIND_CONFIG_PHASE; - } - - if (r->phase == NGX_HTTP_ACCESS_PHASE && r != r->main) { - continue; - } - - if (r->phase == NGX_HTTP_CONTENT_PHASE && r->content_handler) { - r->write_event_handler = ngx_http_request_empty_handler; - ngx_http_finalize_request(r, r->content_handler(r)); - return; - } - - h = cmcf->phases[r->phase].handlers.elts; - for (r->phase_handler = cmcf->phases[r->phase].handlers.nelts - 1; - r->phase_handler >= 0; - r->phase_handler--) - { - rc = h[r->phase_handler](r); - - if (rc == NGX_DONE) { - - /* - * we should never use r here because - * it may point to already freed data - */ - - return; - } - - if (rc == NGX_DECLINED) { - continue; - } - - if (r->phase == NGX_HTTP_ACCESS_PHASE) { - clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - - if (clcf->satisfy_any) { - - if (rc == NGX_OK) { - r->access_code = 0; - - if (r->headers_out.www_authenticate) { - r->headers_out.www_authenticate->hash = 0; - } - - break; - } - - if (rc == NGX_HTTP_FORBIDDEN || rc == NGX_HTTP_UNAUTHORIZED) - { - r->access_code = rc; - - continue; - } - } - } - - if (rc >= NGX_HTTP_SPECIAL_RESPONSE - || rc == NGX_HTTP_NO_CONTENT - || rc == NGX_ERROR) - { - ngx_http_finalize_request(r, rc); - return; - } - - if (r->phase == NGX_HTTP_CONTENT_PHASE) { - ngx_http_finalize_request(r, rc); - return; - } - - if (rc == NGX_AGAIN) { - return; - } - - if (rc == NGX_OK && cmcf->phases[r->phase].type == NGX_OK) { - break; - } - - } - - if (r->phase == NGX_HTTP_ACCESS_PHASE && r->access_code) { - - if (r->access_code == NGX_HTTP_FORBIDDEN) { - ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, - "access forbidden by rule"); - } - - ngx_http_finalize_request(r, r->access_code); + ph = cmcf->phase_engine.handlers; + + while (ph[r->phase_handler].checker) { + + rc = ph[r->phase_handler].checker(r, &ph[r->phase_handler]); + + if (rc == NGX_OK) { return; } } - - /* no content handler was found */ - - if (r->uri.data[r->uri.len - 1] == '/' && !r->zero_in_uri) { - - if (ngx_http_map_uri_to_path(r, &path, 0) != NULL) { - ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, - "directory index of \"%V\" is forbidden", &path); - } - - ngx_http_finalize_request(r, NGX_HTTP_FORBIDDEN); - return; - } - - ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no handler found"); - - ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND); } ngx_int_t -ngx_http_find_location_config(ngx_http_request_t *r) +ngx_http_core_generic_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph) +{ + ngx_int_t rc; + + /* + * generic phase checker, + * used by the post read, server rewrite, rewrite, and pre-access phases + */ + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "generic phase: %ui", r->phase_handler); + + rc = ph->handler(r); + + if (rc == NGX_OK) { + r->phase_handler = ph->next; + return NGX_AGAIN; + } + + if (rc == NGX_DECLINED) { + r->phase_handler++; + return NGX_AGAIN; + } + + if (rc == NGX_AGAIN || rc == NGX_DONE) { + return NGX_OK; + } + + /* rc == NGX_ERROR || rc == NGX_HTTP_... */ + + ngx_http_finalize_request(r, rc); + + return NGX_OK; +} + + +ngx_int_t +ngx_http_core_find_config_phase(ngx_http_request_t *r, + ngx_http_phase_handler_t *ph) { ngx_int_t rc; ngx_http_core_loc_conf_t *clcf; @@ -694,13 +607,15 @@ ngx_http_find_location_config(ngx_http_r rc = ngx_http_core_find_location(r, &cscf->locations, 0); if (rc == NGX_HTTP_INTERNAL_SERVER_ERROR) { - return rc; + ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); + return NGX_OK; } clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); if (!r->internal && clcf->internal) { - return NGX_HTTP_NOT_FOUND; + ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND); + return NGX_OK; } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, @@ -723,14 +638,16 @@ ngx_http_find_location_config(ngx_http_r "client intented to send too large body: %O bytes", r->headers_in.content_length_n); - return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE; + ngx_http_finalize_request(r, NGX_HTTP_REQUEST_ENTITY_TOO_LARGE); + return NGX_OK; } if (rc == NGX_HTTP_LOCATION_AUTO_REDIRECT) { r->headers_out.location = ngx_list_push(&r->headers_out.headers); if (r->headers_out.location == NULL) { - return NGX_HTTP_INTERNAL_SERVER_ERROR; + ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); + return NGX_OK; } /* @@ -740,9 +657,190 @@ ngx_http_find_location_config(ngx_http_r r->headers_out.location->value = clcf->name; - return NGX_HTTP_MOVED_PERMANENTLY; + ngx_http_finalize_request(r, NGX_HTTP_MOVED_PERMANENTLY); + return NGX_OK; + } + + r->phase_handler++; + return NGX_AGAIN; +} + + +ngx_int_t +ngx_http_core_post_rewrite_phase(ngx_http_request_t *r, + ngx_http_phase_handler_t *ph) +{ + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "post rewrite phase: %ui", r->phase_handler); + + if (!r->uri_changed) { + r->phase_handler++; + return NGX_AGAIN; + } + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "uri changes: %d", r->uri_changes); + + /* + * gcc before 3.3 compiles the broken code for + * if (r->uri_changes-- == 0) + * if the r->uri_changes is defined as + * unsigned uri_changes:4 + */ + + r->uri_changes--; + + if (r->uri_changes == 0) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "rewrite or internal redirection cycle " + "while processing \"%V\"", &r->uri); + + ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); + return NGX_OK; + } + + r->phase_handler = ph->next; + + return NGX_AGAIN; +} + + +ngx_int_t +ngx_http_core_access_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph) +{ + ngx_int_t rc; + ngx_http_core_loc_conf_t *clcf; + + if (r != r->main) { + r->phase_handler = ph->next; + return NGX_AGAIN; + } + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "access phase: %ui", r->phase_handler); + + rc = ph->handler(r); + + if (rc == NGX_DECLINED) { + r->phase_handler++; + return NGX_AGAIN; + } + + if (rc == NGX_AGAIN || rc == NGX_DONE) { + return NGX_OK; } + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + + if (clcf->satisfy_any == 0) { + + if (rc == NGX_OK) { + r->phase_handler++; + return NGX_AGAIN; + } + + } else { + if (rc == NGX_OK) { + r->access_code = 0; + + if (r->headers_out.www_authenticate) { + r->headers_out.www_authenticate->hash = 0; + } + + r->phase_handler = ph->next; + return NGX_AGAIN; + } + + if (rc == NGX_HTTP_FORBIDDEN || rc == NGX_HTTP_UNAUTHORIZED) { + r->access_code = rc; + + r->phase_handler++; + return NGX_AGAIN; + } + } + + /* rc == NGX_ERROR || rc == NGX_HTTP_... */ + + ngx_http_finalize_request(r, rc); + return NGX_OK; +} + + +ngx_int_t +ngx_http_core_post_access_phase(ngx_http_request_t *r, + ngx_http_phase_handler_t *ph) +{ + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "post access phase: %ui", r->phase_handler); + + if (r->access_code) { + + if (r->access_code == NGX_HTTP_FORBIDDEN) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "access forbidden by rule"); + } + + ngx_http_finalize_request(r, r->access_code); + return NGX_OK; + } + + r->phase_handler++; + return NGX_AGAIN; +} + + +ngx_int_t +ngx_http_core_content_phase(ngx_http_request_t *r, + ngx_http_phase_handler_t *ph) +{ + ngx_int_t rc; + ngx_str_t path; + + if (r->content_handler) { + r->write_event_handler = ngx_http_request_empty_handler; + ngx_http_finalize_request(r, r->content_handler(r)); + return NGX_OK; + } + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "content phase: %ui", r->phase_handler); + + rc = ph->handler(r); + + if (rc == NGX_DONE) { + return NGX_OK; + } + + if (rc != NGX_DECLINED) { + ngx_http_finalize_request(r, rc); + return NGX_OK; + } + + /* rc == NGX_DECLINED */ + + ph++; + + if (ph->checker) { + r->phase_handler++; + return NGX_AGAIN; + } + + /* no content handler was found */ + + if (r->uri.data[r->uri.len - 1] == '/' && !r->zero_in_uri) { + + if (ngx_http_map_uri_to_path(r, &path, 0) != NULL) { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "directory index of \"%V\" is forbidden", &path); + } + + ngx_http_finalize_request(r, NGX_HTTP_FORBIDDEN); + return NGX_OK; + } + + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "no handler found"); + + ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND); return NGX_OK; } @@ -1916,7 +2014,7 @@ ngx_http_core_create_srv_conf(ngx_conf_t return NGX_CONF_ERROR; } - if (ngx_array_init(&cscf->server_names, cf->pool, 4, + if (ngx_array_init(&cscf->server_names, cf->temp_pool, 4, sizeof(ngx_http_server_name_t)) == NGX_ERROR) { 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 @@ -49,28 +49,48 @@ typedef enum { NGX_HTTP_POST_READ_PHASE = 0, NGX_HTTP_SERVER_REWRITE_PHASE, + NGX_HTTP_FIND_CONFIG_PHASE, NGX_HTTP_REWRITE_PHASE, + NGX_HTTP_POST_REWRITE_PHASE, NGX_HTTP_PREACCESS_PHASE, NGX_HTTP_ACCESS_PHASE, + NGX_HTTP_POST_ACCESS_PHASE, + NGX_HTTP_CONTENT_PHASE, NGX_HTTP_LOG_PHASE } ngx_http_phases; +typedef struct ngx_http_phase_handler_s ngx_http_phase_handler_t; + +typedef ngx_int_t (*ngx_http_phase_handler_pt)(ngx_http_request_t *r, + ngx_http_phase_handler_t *ph); + +struct ngx_http_phase_handler_s { + ngx_http_phase_handler_pt checker; + ngx_http_handler_pt handler; + ngx_uint_t next; +}; + + +typedef struct { + ngx_http_phase_handler_t *handlers; + ngx_uint_t server_rewrite_index; +} ngx_http_phase_engine_t; + typedef struct { ngx_array_t handlers; - ngx_int_t type; /* NGX_OK, NGX_DECLINED */ } ngx_http_phase_t; typedef struct { ngx_array_t servers; /* ngx_http_core_srv_conf_t */ - ngx_http_phase_t phases[NGX_HTTP_LOG_PHASE + 1]; + ngx_http_phase_engine_t phase_engine; ngx_hash_t headers_in_hash; @@ -85,6 +105,8 @@ typedef struct { ngx_uint_t variables_hash_bucket_size; ngx_hash_keys_arrays_t *variables_keys; + + ngx_http_phase_t phases[NGX_HTTP_LOG_PHASE + 1]; } ngx_http_core_main_conf_t; @@ -262,7 +284,19 @@ struct ngx_http_core_loc_conf_s { }; -ngx_int_t ngx_http_find_location_config(ngx_http_request_t *r); +void ngx_http_core_run_phases(ngx_http_request_t *r); +ngx_int_t ngx_http_core_generic_phase(ngx_http_request_t *r, + ngx_http_phase_handler_t *ph); +ngx_int_t ngx_http_core_find_config_phase(ngx_http_request_t *r, + ngx_http_phase_handler_t *ph); +ngx_int_t ngx_http_core_post_rewrite_phase(ngx_http_request_t *r, + ngx_http_phase_handler_t *ph); +ngx_int_t ngx_http_core_access_phase(ngx_http_request_t *r, + ngx_http_phase_handler_t *ph); +ngx_int_t ngx_http_core_post_access_phase(ngx_http_request_t *r, + ngx_http_phase_handler_t *ph); +ngx_int_t ngx_http_core_content_phase(ngx_http_request_t *r, + ngx_http_phase_handler_t *ph); ngx_int_t ngx_http_set_content_type(ngx_http_request_t *r); ngx_int_t ngx_http_set_exten(ngx_http_request_t *r); 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 @@ -10,13 +10,13 @@ #include -static ngx_int_t ngx_http_header_filter_init(ngx_cycle_t *cycle); +static ngx_int_t ngx_http_header_filter_init(ngx_conf_t *cf); static ngx_int_t ngx_http_header_filter(ngx_http_request_t *r); static ngx_http_module_t ngx_http_header_filter_module_ctx = { NULL, /* preconfiguration */ - NULL, /* postconfiguration */ + ngx_http_header_filter_init, /* postconfiguration */ NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -35,7 +35,7 @@ ngx_module_t ngx_http_header_filter_mod NULL, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ - ngx_http_header_filter_init, /* init module */ + NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ @@ -152,8 +152,8 @@ ngx_http_header_filter(ngx_http_request_ { u_char *p; size_t len; + ngx_buf_t *b; ngx_uint_t status, i; - ngx_buf_t *b; ngx_chain_t out; ngx_list_part_t *part; ngx_table_elt_t *header; @@ -533,7 +533,7 @@ ngx_http_header_filter(ngx_http_request_ static ngx_int_t -ngx_http_header_filter_init(ngx_cycle_t *cycle) +ngx_http_header_filter_init(ngx_conf_t *cf) { ngx_http_top_header_filter = ngx_http_header_filter; diff --git a/src/http/ngx_http_postpone_filter_module.c b/src/http/ngx_http_postpone_filter_module.c --- a/src/http/ngx_http_postpone_filter_module.c +++ b/src/http/ngx_http_postpone_filter_module.c @@ -11,12 +11,12 @@ static ngx_int_t ngx_http_postpone_filter_output_postponed_request(ngx_http_request_t *r); -static ngx_int_t ngx_http_postpone_filter_init(ngx_cycle_t *cycle); +static ngx_int_t ngx_http_postpone_filter_init(ngx_conf_t *cf); static ngx_http_module_t ngx_http_postpone_filter_module_ctx = { NULL, /* preconfiguration */ - NULL, /* postconfiguration */ + ngx_http_postpone_filter_init, /* postconfiguration */ NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -35,7 +35,7 @@ ngx_module_t ngx_http_postpone_filter_m NULL, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ - ngx_http_postpone_filter_init, /* init module */ + NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ @@ -219,7 +219,7 @@ ngx_http_postpone_filter_output_postpone static ngx_int_t -ngx_http_postpone_filter_init(ngx_cycle_t *cycle) +ngx_http_postpone_filter_init(ngx_conf_t *cf) { ngx_http_next_filter = ngx_http_top_body_filter; ngx_http_top_body_filter = ngx_http_postpone_filter; diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -140,6 +140,9 @@ ngx_http_header_t ngx_http_headers_in[] { ngx_string("Destination"), offsetof(ngx_http_headers_in_t, destination), ngx_http_process_header_line }, + + { ngx_string("Date"), offsetof(ngx_http_headers_in_t, date), + ngx_http_process_header_line }, #endif { ngx_string("Cookie"), 0, ngx_http_process_cookie }, @@ -933,9 +936,11 @@ ngx_http_read_request_header(ngx_http_re { ssize_t n; ngx_event_t *rev; + ngx_connection_t *c; ngx_http_core_srv_conf_t *cscf; - rev = r->connection->read; + c = r->connection; + rev = c->read; n = r->header_in->last - r->header_in->pos; @@ -944,8 +949,8 @@ ngx_http_read_request_header(ngx_http_re } if (rev->ready) { - n = r->connection->recv(r->connection, r->header_in->last, - r->header_in->end - r->header_in->last); + n = c->recv(c, r->header_in->last, + r->header_in->end - r->header_in->last); } else { n = NGX_AGAIN; } @@ -966,11 +971,14 @@ ngx_http_read_request_header(ngx_http_re } if (n == 0) { - ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, + ngx_log_error(NGX_LOG_INFO, c->log, 0, "client closed prematurely connection"); } if (n == 0 || n == NGX_ERROR) { + c->error = rev->error; + c->log->action = "sending response to client"; + ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); return NGX_ERROR; } @@ -1155,8 +1163,9 @@ ngx_http_process_unique_header_line(ngx_ } ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, - "client sent duplicate header line: \"%V: %V\"", - &h->key, &h->value); + "client sent duplicate header line: \"%V: %V\", " + "previous value: \"%V: %V\"", + &h->key, &h->value, &(*ph)->key, &(*ph)->value); ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); @@ -1460,6 +1469,13 @@ ngx_http_finalize_request(ngx_http_reque "http finalize request: %d, \"%V?%V\"", rc, &r->uri, &r->args); + if (rc == NGX_DECLINED) { + r->content_handler = NULL; + r->write_event_handler = ngx_http_core_run_phases; + ngx_http_core_run_phases(r); + return; + } + if (r != r->main && rc != NGX_ERROR && !r->connection->error diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -184,6 +184,7 @@ typedef struct { #if (NGX_HTTP_DAV) ngx_table_elt_t *depth; ngx_table_elt_t *destination; + ngx_table_elt_t *date; #endif ngx_str_t user; @@ -352,7 +353,6 @@ struct ngx_http_request_s { ngx_str_t server_name; ngx_http_virtual_names_t *virtual_names; - ngx_uint_t phase; ngx_int_t phase_handler; ngx_http_handler_pt content_handler; ngx_uint_t access_code; diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c --- a/src/http/ngx_http_request_body.c +++ b/src/http/ngx_http_request_body.c @@ -417,12 +417,12 @@ ngx_http_discard_body(ngx_http_request_t ngx_del_timer(rev); } + r->discard_body = 1; + if (r->headers_in.content_length_n <= 0) { return NGX_OK; } - r->discard_body = 1; - size = r->header_in->last - r->header_in->pos; if (size) { diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c --- a/src/http/ngx_http_special_response.c +++ b/src/http/ngx_http_special_response.c @@ -307,7 +307,7 @@ ngx_http_special_response_handler(ngx_ht ngx_int_t rc; ngx_buf_t *b; ngx_str_t *uri, *location; - ngx_uint_t i, err, msie_padding; + ngx_uint_t i, n, err, msie_padding; ngx_chain_t *out, *cl; ngx_http_err_page_t *err_page; ngx_http_core_loc_conf_t *clcf; @@ -375,8 +375,23 @@ ngx_http_special_response_handler(ngx_ht { return NGX_ERROR; } + + if (r->zero_in_uri) { + for (n = 0; n < uri->len; n++) { + if (uri->data[n] == '\0') { + goto zero; + } + } + + r->zero_in_uri = 0; + } + + } else { + r->zero_in_uri = 0; } + zero: + if (uri->data[0] == '/') { return ngx_http_internal_redirect(r, uri, NULL); } diff --git a/src/http/ngx_http_special_response.c-C b/src/http/ngx_http_special_response.c-C new file mode 100644 --- /dev/null +++ b/src/http/ngx_http_special_response.c-C @@ -0,0 +1,548 @@ + +/* + * Copyright (C) Igor Sysoev + */ + + +#include +#include +#include +#include + + +static u_char error_tail[] = +"
" NGINX_VER "
" CRLF +"" CRLF +"" CRLF +; + + +static u_char ngx_http_msie_stub[] = +"" CRLF +"" CRLF +"" CRLF +"" CRLF +"" CRLF +"" CRLF +; + + +static char error_301_page[] = +"" CRLF +"301 Moved Permanently" CRLF +"" CRLF +"

301 Moved Permanently

" CRLF +; + + +static char error_302_page[] = +"" CRLF +"302 Found" CRLF +"" CRLF +"

302 Found

" CRLF +; + + +static char error_400_page[] = +"" CRLF +"400 Bad Request" CRLF +"" CRLF +"

400 Bad Request

" CRLF +; + + +static char error_401_page[] = +"" CRLF +"401 Authorization Required" CRLF +"" CRLF +"

401 Authorization Required

" CRLF +; + + +static char error_402_page[] = +"" CRLF +"402 Payment Required" CRLF +"" CRLF +"

402 Payment Required

" CRLF +; + + +static char error_403_page[] = +"" CRLF +"403 Forbidden" CRLF +"" CRLF +"

403 Forbidden

" CRLF +; + + +static char error_404_page[] = +"" CRLF +"404 Not Found" CRLF +"" CRLF +"

404 Not Found

" CRLF +; + + +static char error_405_page[] = +"" CRLF +"405 Not Allowed" CRLF +"" CRLF +"

405 Not Allowed

" CRLF +; + + +static char error_406_page[] = +"" CRLF +"406 Not Acceptable" CRLF +"" CRLF +"

406 Not Acceptable

" CRLF +; + + +static char error_408_page[] = +"" CRLF +"408 Request Time-out" CRLF +"" CRLF +"

408 Request Time-out

" CRLF +; + + +static char error_409_page[] = +"" CRLF +"409 Conflict" CRLF +"" CRLF +"

409 Conflict

" CRLF +; + + +static char error_410_page[] = +"" CRLF +"410 Gone" CRLF +"" CRLF +"

410 Gone

" CRLF +; + + +static char error_411_page[] = +"" CRLF +"411 Length Required" CRLF +"" CRLF +"

411 Length Required

" CRLF +; + + +static char error_413_page[] = +"" CRLF +"413 Request Entity Too Large" CRLF +"" CRLF +"

413 Request Entity Too Large

" CRLF +; + + +static char error_414_page[] = +"" CRLF +"414 Request-URI Too Large" CRLF +"" CRLF +"

414 Request-URI Too Large

" CRLF +; + + +static char error_415_page[] = +"" CRLF +"415 Unsupported Media Type" CRLF +"" CRLF +"

415 Unsupported Media Type

" CRLF +; + + +static char error_416_page[] = +"" CRLF +"416 Requested Range Not Satisfiable" CRLF +"" CRLF +"

416 Requested Range Not Satisfiable

" CRLF +; + + +static char error_495_page[] = +"" CRLF +"400 The SSL certificate error" +CRLF +"" CRLF +"

400 Bad Request

" CRLF +"
The SSL certificate error
" CRLF +; + + +static char error_496_page[] = +"" CRLF +"400 No required SSL certificate was sent" +CRLF +"" CRLF +"

400 Bad Request

" CRLF +"
No required SSL certificate was sent
" CRLF +; + + +static char error_497_page[] = +"" CRLF +"400 The plain HTTP request was sent to HTTPS port" +CRLF +"" CRLF +"

400 Bad Request

" CRLF +"
The plain HTTP request was sent to HTTPS port
" CRLF +; + + +static char error_500_page[] = +"" CRLF +"500 Internal Server Error" CRLF +"" CRLF +"

500 Internal Server Error

" CRLF +; + + +static char error_501_page[] = +"" CRLF +"501 Method Not Implemented" CRLF +"" CRLF +"

501 Method Not Implemented

" CRLF +; + + +static char error_502_page[] = +"" CRLF +"502 Bad Gateway" CRLF +"" CRLF +"

502 Bad Gateway

" CRLF +; + + +static char error_503_page[] = +"" CRLF +"503 Service Temporarily Unavailable" CRLF +"" CRLF +"

503 Service Temporarily Unavailable

" CRLF +; + + +static char error_504_page[] = +"" CRLF +"504 Gateway Time-out" CRLF +"" CRLF +"

504 Gateway Time-out

" CRLF +; + + +static char error_507_page[] = +"" CRLF +"507 Insufficient Storage" CRLF +"" CRLF +"

507 Insufficient Storage

" CRLF +; + + +static ngx_str_t error_pages[] = { + + ngx_null_string, /* 201, 204 */ + +#define NGX_HTTP_LEVEL_200 1 + + /* ngx_null_string, */ /* 300 */ + ngx_string(error_301_page), + ngx_string(error_302_page), + ngx_null_string, /* 303 */ + +#define NGX_HTTP_LEVEL_300 3 + + ngx_string(error_400_page), + ngx_string(error_401_page), + ngx_string(error_402_page), + ngx_string(error_403_page), + ngx_string(error_404_page), + ngx_string(error_405_page), + ngx_string(error_406_page), + ngx_null_string, /* 407 */ + ngx_string(error_408_page), + ngx_string(error_409_page), + ngx_string(error_410_page), + ngx_string(error_411_page), + ngx_null_string, /* 412 */ + ngx_string(error_413_page), + ngx_string(error_414_page), + ngx_string(error_415_page), + ngx_string(error_416_page), + +#define NGX_HTTP_LEVEL_400 17 + + ngx_string(error_495_page), /* 495, https certificate error */ + ngx_string(error_496_page), /* 496, https no certificate */ + ngx_string(error_497_page), /* 497, http to https */ + ngx_string(error_404_page), /* 498, invalid host name */ + ngx_null_string, /* 499, client had closed connection */ + + ngx_string(error_500_page), + ngx_string(error_501_page), + ngx_string(error_502_page), + ngx_string(error_503_page), + ngx_string(error_504_page), + ngx_null_string, /* 505 */ + ngx_null_string, /* 506 */ + ngx_string(error_507_page) +}; + + +ngx_int_t +ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error) +{ + ngx_int_t rc; + ngx_buf_t *b; + ngx_str_t *uri; + ngx_uint_t i, n, err, msie_padding; + ngx_chain_t *out, *cl; + ngx_http_err_page_t *err_page; + ngx_http_core_loc_conf_t *clcf; + + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "http special response: %d, \"%V\"", error, &r->uri); + + rc = ngx_http_discard_body(r); + + if (rc == NGX_HTTP_INTERNAL_SERVER_ERROR) { + error = NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + r->headers_out.status = error; + r->err_status = error; + + if (r->keepalive != 0) { + switch (error) { + case NGX_HTTP_BAD_REQUEST: + case NGX_HTTP_REQUEST_ENTITY_TOO_LARGE: + case NGX_HTTP_REQUEST_URI_TOO_LARGE: + case NGX_HTTP_TO_HTTPS: + case NGX_HTTPS_CERT_ERROR: + case NGX_HTTPS_NO_CERT: + case NGX_HTTP_INTERNAL_SERVER_ERROR: + r->keepalive = 0; + } + } + + if (r->lingering_close == 1) { + switch (error) { + case NGX_HTTP_BAD_REQUEST: + case NGX_HTTP_TO_HTTPS: + case NGX_HTTPS_CERT_ERROR: + case NGX_HTTPS_NO_CERT: + r->lingering_close = 0; + } + } + + r->headers_out.content_type.len = 0; + + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + + if (!r->error_page && clcf->error_pages) { + + if (clcf->recursive_error_pages == 0) { + r->error_page = 1; + } + + err_page = clcf->error_pages->elts; + + for (i = 0; i < clcf->error_pages->nelts; i++) { + + if (err_page[i].status == error) { + r->err_status = err_page[i].overwrite; + + r->method = NGX_HTTP_GET; + + uri = &err_page[i].uri; + + if (err_page[i].uri_lengths) { + if (ngx_http_script_run(r, uri, + err_page[i].uri_lengths->elts, 0, + err_page[i].uri_values->elts) + == NULL) + { + return NGX_ERROR; + } + + if (r->zero_in_uri) { + for (n = 0; n < uri->len; n++) { + if (uri->data[n] == '\0') { + goto zero; + } + } + + r->zero_in_uri = 0; + } + + } else { + r->zero_in_uri = 0; + } + + zero: + + if (uri->data[0] == '/') { + return ngx_http_internal_redirect(r, uri, NULL); + } + + r->headers_out.location = + ngx_list_push(&r->headers_out.headers); + + if (r->headers_out.location) { + error = NGX_HTTP_MOVED_TEMPORARILY; + + r->err_status = NGX_HTTP_MOVED_TEMPORARILY; + + r->headers_out.location->hash = 1; + r->headers_out.location->key.len = sizeof("Location") - 1; + r->headers_out.location->key.data = (u_char *) "Location"; + r->headers_out.location->value = *uri; + + } else { + return NGX_ERROR; + } + } + } + } + + if (error == NGX_HTTP_CREATED) { + /* 201 */ + err = 0; + r->header_only = 1; + + } else if (error == NGX_HTTP_NO_CONTENT) { + /* 204 */ + err = 0; + + } else if (error < NGX_HTTP_BAD_REQUEST) { + /* 3XX */ + err = error - NGX_HTTP_MOVED_PERMANENTLY + NGX_HTTP_LEVEL_200; + + } else if (error < NGX_HTTP_OWN_CODES) { + /* 4XX */ + err = error - NGX_HTTP_BAD_REQUEST + NGX_HTTP_LEVEL_200 + + NGX_HTTP_LEVEL_300; + + } else { + /* 49X, 5XX */ + err = error - NGX_HTTP_OWN_CODES + NGX_HTTP_LEVEL_200 + + NGX_HTTP_LEVEL_300 + + NGX_HTTP_LEVEL_400; + switch (error) { + case NGX_HTTP_TO_HTTPS: + case NGX_HTTPS_CERT_ERROR: + case NGX_HTTPS_NO_CERT: + r->headers_out.status = NGX_HTTP_BAD_REQUEST; + error = NGX_HTTP_BAD_REQUEST; + break; + } + } + + msie_padding = 0; + + if (error_pages[err].len) { + r->headers_out.content_length_n = error_pages[err].len + + sizeof(error_tail) - 1; + + if (clcf->msie_padding + && r->headers_in.msie + && r->http_version >= NGX_HTTP_VERSION_10 + && error >= NGX_HTTP_BAD_REQUEST + && error != NGX_HTTP_REQUEST_URI_TOO_LARGE) + { + r->headers_out.content_length_n += sizeof(ngx_http_msie_stub) - 1; + msie_padding = 1; + } + + r->headers_out.content_type.len = sizeof("text/html") - 1; + r->headers_out.content_type.data = (u_char *) "text/html"; + + } else { + r->headers_out.content_length_n = -1; + } + + if (r->headers_out.content_length) { + r->headers_out.content_length->hash = 0; + r->headers_out.content_length = NULL; + } + + ngx_http_clear_accept_ranges(r); + ngx_http_clear_last_modified(r); + + rc = ngx_http_send_header(r); + + if (rc == NGX_ERROR || r->header_only) { + return rc; + } + + if (error_pages[err].len == 0) { + return NGX_OK; + } + + + b = ngx_calloc_buf(r->pool); + if (b == NULL) { + return NGX_ERROR; + } + + b->memory = 1; + b->pos = error_pages[err].data; + b->last = error_pages[err].data + error_pages[err].len; + + cl = ngx_alloc_chain_link(r->pool); + if (cl == NULL) { + return NGX_ERROR; + } + + cl->buf = b; + out = cl; + + + b = ngx_calloc_buf(r->pool); + if (b == NULL) { + return NGX_ERROR; + } + + b->memory = 1; + b->pos = error_tail; + b->last = error_tail + sizeof(error_tail) - 1; + + cl->next = ngx_alloc_chain_link(r->pool); + if (cl->next == NULL) { + return NGX_ERROR; + } + + cl = cl->next; + cl->buf = b; + + if (msie_padding) { + b = ngx_calloc_buf(r->pool); + if (b == NULL) { + return NGX_ERROR; + } + + b->memory = 1; + b->pos = ngx_http_msie_stub; + b->last = ngx_http_msie_stub + sizeof(ngx_http_msie_stub) - 1; + + cl->next = ngx_alloc_chain_link(r->pool); + if (cl->next == NULL) { + return NGX_ERROR; + } + + cl = cl->next; + cl->buf = b; + } + + if (r == r->main) { + b->last_buf = 1; + } + + b->last_in_chain = 1; + + cl->next = NULL; + + return ngx_http_output_filter(r, out); +} diff --git a/src/http/ngx_http_special_response.c.rej b/src/http/ngx_http_special_response.c.rej new file mode 100644 --- /dev/null +++ b/src/http/ngx_http_special_response.c.rej @@ -0,0 +1,23 @@ +*************** +*** 294,302 **** + ngx_int_t + ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error) + { + ngx_int_t rc; + ngx_buf_t *b; +- ngx_str_t *uri; + ngx_uint_t i, err, msie_padding; + ngx_chain_t *out, *cl; + ngx_http_err_page_t *err_page; +--- 302,312 ---- + ngx_int_t + ngx_http_special_response_handler(ngx_http_request_t *r, ngx_int_t error) + { ++ u_char *p; ++ size_t msie_refresh; + ngx_int_t rc; + ngx_buf_t *b; ++ ngx_str_t *uri, *location; + ngx_uint_t i, err, msie_padding; + ngx_chain_t *out, *cl; + ngx_http_err_page_t *err_page; 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 @@ -1134,11 +1134,11 @@ ngx_http_upstream_process_header(ngx_eve } } + umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); + if (r->upstream->headers_in.x_accel_redirect) { ngx_http_upstream_finalize_request(r, u, NGX_DECLINED); - umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); - part = &r->upstream->headers_in.headers.part; h = part->elts; @@ -1188,29 +1188,6 @@ ngx_http_upstream_process_header(ngx_eve return; } - ngx_http_upstream_send_response(r, u); -} - - -static void -ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) -{ - int tcp_nodelay; - ssize_t size; - ngx_int_t rc; - ngx_uint_t i; - ngx_list_part_t *part; - ngx_table_elt_t *h; - ngx_event_pipe_t *p; - ngx_connection_t *c; - ngx_pool_cleanup_t *cl; - ngx_pool_cleanup_file_t *clf; - ngx_http_core_loc_conf_t *clcf; - ngx_http_upstream_header_t *hh; - ngx_http_upstream_main_conf_t *umcf; - - umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); - part = &r->upstream->headers_in.headers.part; h = part->elts; @@ -1270,6 +1247,22 @@ ngx_http_upstream_send_response(ngx_http u->length = NGX_MAX_SIZE_T_VALUE; } + ngx_http_upstream_send_response(r, u); +} + + +static void +ngx_http_upstream_send_response(ngx_http_request_t *r, ngx_http_upstream_t *u) +{ + int tcp_nodelay; + ssize_t size; + ngx_int_t rc; + ngx_event_pipe_t *p; + ngx_connection_t *c; + ngx_pool_cleanup_t *cl; + ngx_pool_cleanup_file_t *clf; + ngx_http_core_loc_conf_t *clcf; + rc = ngx_http_send_header(r); if (rc == NGX_ERROR || rc > NGX_OK || r->post_action) { diff --git a/src/http/ngx_http_write_filter_module.c b/src/http/ngx_http_write_filter_module.c --- a/src/http/ngx_http_write_filter_module.c +++ b/src/http/ngx_http_write_filter_module.c @@ -10,12 +10,12 @@ #include -static ngx_int_t ngx_http_write_filter_init(ngx_cycle_t *cycle); +static ngx_int_t ngx_http_write_filter_init(ngx_conf_t *cf); static ngx_http_module_t ngx_http_write_filter_module_ctx = { NULL, /* preconfiguration */ - NULL, /* postconfiguration */ + ngx_http_write_filter_init, /* postconfiguration */ NULL, /* create main configuration */ NULL, /* init main configuration */ @@ -34,7 +34,7 @@ ngx_module_t ngx_http_write_filter_modu NULL, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init master */ - ngx_http_write_filter_init, /* init module */ + NULL, /* init module */ NULL, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ @@ -271,7 +271,7 @@ ngx_http_write_filter(ngx_http_request_t static ngx_int_t -ngx_http_write_filter_init(ngx_cycle_t *cycle) +ngx_http_write_filter_init(ngx_conf_t *cf) { ngx_http_top_body_filter = ngx_http_write_filter; diff --git a/src/os/unix/ngx_files.c b/src/os/unix/ngx_files.c --- a/src/os/unix/ngx_files.c +++ b/src/os/unix/ngx_files.c @@ -221,6 +221,24 @@ ngx_write_chain_to_file(ngx_file_t *file ngx_int_t +ngx_set_file_time(u_char *name, ngx_fd_t fd, time_t s) +{ + struct timeval tv[2]; + + tv[0].tv_sec = s; + tv[0].tv_usec = 0; + tv[1].tv_sec = s; + tv[1].tv_usec = 0; + + if (utimes((char *) name, tv) != -1) { + return NGX_OK; + } + + return NGX_ERROR; +} + + +ngx_int_t ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir) { dir->dir = opendir((const char *) name->data); diff --git a/src/os/unix/ngx_files.h b/src/os/unix/ngx_files.h --- a/src/os/unix/ngx_files.h +++ b/src/os/unix/ngx_files.h @@ -58,11 +58,15 @@ ssize_t ngx_write_chain_to_file(ngx_file #define ngx_rename_file(o, n) rename((const char *) o, (const char *) n) -#define ngx_rename_file_n "rename" +#define ngx_rename_file_n "rename()" #define ngx_change_file_access(n, a) chmod((const char *) n, a) -#define ngx_change_file_access_n "chmod" +#define ngx_change_file_access_n "chmod()" + + +ngx_int_t ngx_set_file_time(u_char *name, ngx_fd_t fd, time_t s); +#define ngx_set_file_time_n "utimes()" #define ngx_file_info(file, sb) stat((const char *) file, sb)