Mercurial > hg > nginx-vendor-0-5
diff src/http/ngx_http_core_module.c @ 230:38e7b94d63ac NGINX_0_4_0
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.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Wed, 30 Aug 2006 00:00:00 +0400 |
parents | 9eebc1b2cdbb |
children | c982febb7588 |
line wrap: on
line diff
--- 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) {