diff options
author | Igor Sysoev <igor@sysoev.ru> | 2004-07-18 23:11:20 +0400 |
---|---|---|
committer | Igor Sysoev <igor@sysoev.ru> | 2004-07-18 23:11:20 +0400 |
commit | 74a5ddb47aef86bb07336713bb1ace0007c2d452 (patch) | |
tree | 449c6ceb229b7646ef40417135c66843a677746b /src/http | |
parent | f38e046a0a2e7437f8232ef2a99cead69c4b9ebb (diff) |
nginx-0.0.7-2004-07-18-23:11:20 import
Diffstat (limited to 'src/http')
-rw-r--r-- | src/http/modules/ngx_http_access_handler.c | 5 | ||||
-rw-r--r-- | src/http/modules/ngx_http_charset_filter.c | 6 | ||||
-rw-r--r-- | src/http/modules/ngx_http_index_handler.c | 51 | ||||
-rw-r--r-- | src/http/modules/ngx_http_rewrite_handler.c | 4 | ||||
-rw-r--r-- | src/http/modules/ngx_http_ssl_module.c | 6 | ||||
-rw-r--r-- | src/http/modules/ngx_http_static_handler.c | 6 | ||||
-rw-r--r-- | src/http/modules/ngx_http_status_handler.c | 4 | ||||
-rw-r--r-- | src/http/modules/proxy/ngx_http_proxy_handler.c | 6 | ||||
-rw-r--r-- | src/http/ngx_http.c | 48 | ||||
-rw-r--r-- | src/http/ngx_http_config.h | 12 | ||||
-rw-r--r-- | src/http/ngx_http_core_module.c | 324 | ||||
-rw-r--r-- | src/http/ngx_http_core_module.h | 31 | ||||
-rw-r--r-- | src/http/ngx_http_request.c | 72 | ||||
-rw-r--r-- | src/http/ngx_http_request.h | 3 | ||||
-rw-r--r-- | src/http/ngx_http_request_body.c | 2 | ||||
-rw-r--r-- | src/http/ngx_http_special_response.c | 8 | ||||
-rw-r--r-- | src/http/ngx_http_write_filter.c | 17 |
17 files changed, 401 insertions, 204 deletions
diff --git a/src/http/modules/ngx_http_access_handler.c b/src/http/modules/ngx_http_access_handler.c index a57526ef2..b6fdeab09 100644 --- a/src/http/modules/ngx_http_access_handler.c +++ b/src/http/modules/ngx_http_access_handler.c @@ -190,13 +190,8 @@ static char *ngx_http_access_merge_loc_conf(ngx_conf_t *cf, static ngx_int_t ngx_http_access_init(ngx_cycle_t *cycle) { ngx_http_handler_pt *h; - ngx_http_conf_ctx_t *ctx; ngx_http_core_main_conf_t *cmcf; -#if 0 - ctx = (ngx_http_conf_ctx_t *) cycle->conf_ctx[ngx_http_module.index]; - cmcf = ctx->main_conf[ngx_http_core_module.ctx_index]; -#endif cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module); h = ngx_push_array(&cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers); diff --git a/src/http/modules/ngx_http_charset_filter.c b/src/http/modules/ngx_http_charset_filter.c index d7ce88e10..662f0b28a 100644 --- a/src/http/modules/ngx_http_charset_filter.c +++ b/src/http/modules/ngx_http_charset_filter.c @@ -363,7 +363,6 @@ static char *ngx_http_set_charset_slot(ngx_conf_t *cf, ngx_command_t *cmd, ngx_int_t *cp; ngx_str_t *value; ngx_http_charset_t *charset; - ngx_http_conf_ctx_t *ctx; ngx_http_charset_main_conf_t *mcf; cp = (ngx_int_t *) (p + cmd->offset); @@ -372,8 +371,9 @@ static char *ngx_http_set_charset_slot(ngx_conf_t *cf, ngx_command_t *cmd, return "is duplicate"; } - ctx = cf->ctx; - mcf = ctx->main_conf[ngx_http_charset_filter_module.ctx_index]; + mcf = ngx_http_conf_get_module_main_conf(cf, + ngx_http_charset_filter_module); + value = cf->args->elts; *cp = ngx_http_add_charset(&mcf->charsets, &value[1]); diff --git a/src/http/modules/ngx_http_index_handler.c b/src/http/modules/ngx_http_index_handler.c index 80e4d19d9..ddd889404 100644 --- a/src/http/modules/ngx_http_index_handler.c +++ b/src/http/modules/ngx_http_index_handler.c @@ -98,6 +98,7 @@ ngx_module_t ngx_http_index_module = { ngx_int_t ngx_http_index_handler(ngx_http_request_t *r) { u_char *name; + size_t len; ngx_fd_t fd; ngx_int_t rc; ngx_str_t *index; @@ -160,6 +161,7 @@ ngx_int_t ngx_http_index_handler(ngx_http_request_t *r) #endif +#if 0 ctx->path.data = ngx_palloc(r->pool, clcf->root.len + r->uri.len + ilcf->max_index_len - clcf->alias * clcf->name.len); @@ -169,9 +171,35 @@ ngx_int_t ngx_http_index_handler(ngx_http_request_t *r) ctx->redirect.data = ngx_cpymem(ctx->path.data, clcf->root.data, clcf->root.len); +#endif if (clcf->alias) { - ctx->last = ngx_cpystrn(ctx->redirect.data, + if (clcf->root.len > clcf->name.len) { + ctx->path.data = ngx_palloc(r->pool, clcf->root.len + + r->uri.len + - clcf->name.len + + ilcf->max_index_len); + if (ctx->path.data == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + ctx->redirect.data = ctx->path.data + clcf->root.len + 1 + - clcf->name.len; + + } else { + ctx->redirect.data = ngx_palloc(r->pool, r->uri.len + + ilcf->max_index_len); + if (ctx->redirect.data == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + ctx->path.data = ctx->redirect.data + clcf->name.len + - clcf->root.len; + } + + ngx_memcpy(ctx->path.data, clcf->root.data, clcf->root.len); + + ctx->last = ngx_cpystrn(ctx->path.data + clcf->root.len, r->uri.data + clcf->name.len, r->uri.len + 1 - clcf->name.len); @@ -185,6 +213,15 @@ ngx_int_t ngx_http_index_handler(ngx_http_request_t *r) } } else { + ctx->path.data = ngx_palloc(r->pool, clcf->root.len + r->uri.len + + ilcf->max_index_len); + if (ctx->path.data == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + ctx->redirect.data = ngx_cpymem(ctx->path.data, clcf->root.data, + clcf->root.len); + ctx->last = ngx_cpystrn(ctx->redirect.data, r->uri.data, r->uri.len + 1); } @@ -255,8 +292,14 @@ ngx_int_t ngx_http_index_handler(ngx_http_request_t *r) ctx->redirect.data = index[ctx->index].data; } else { - ctx->redirect.len = r->uri.len + index[ctx->index].len; + if (clcf->alias) { + ngx_memcpy(ctx->redirect.data, clcf->name.data, clcf->name.len); + } + + ctx->redirect.len = r->uri.len + index[ctx->index].len + - clcf->alias * clcf->name.len; r->file.name.len = clcf->root.len + r->uri.len + - clcf->alias * clcf->name.len + index[ctx->index].len; } @@ -364,11 +407,9 @@ static ngx_int_t ngx_http_index_error(ngx_http_request_t *r, static ngx_int_t ngx_http_index_init(ngx_cycle_t *cycle) { ngx_http_handler_pt *h; - ngx_http_conf_ctx_t *ctx; ngx_http_core_main_conf_t *cmcf; - ctx = (ngx_http_conf_ctx_t *) cycle->conf_ctx[ngx_http_module.index]; - cmcf = ctx->main_conf[ngx_http_core_module.ctx_index]; + cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module); h = ngx_push_array(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers); if (h == NULL) { diff --git a/src/http/modules/ngx_http_rewrite_handler.c b/src/http/modules/ngx_http_rewrite_handler.c index 7d36b131a..5c25c89e4 100644 --- a/src/http/modules/ngx_http_rewrite_handler.c +++ b/src/http/modules/ngx_http_rewrite_handler.c @@ -369,11 +369,9 @@ static char *ngx_http_rewrite_rule(ngx_conf_t *cf, ngx_command_t *cmd, static ngx_int_t ngx_http_rewrite_init(ngx_cycle_t *cycle) { ngx_http_handler_pt *h; - ngx_http_conf_ctx_t *ctx; ngx_http_core_main_conf_t *cmcf; - ctx = (ngx_http_conf_ctx_t *) cycle->conf_ctx[ngx_http_module.index]; - cmcf = ctx->main_conf[ngx_http_core_module.ctx_index]; + cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module); h = ngx_push_array(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers); if (h == NULL) { diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c index 3a8b863a2..699bd8f6a 100644 --- a/src/http/modules/ngx_http_ssl_module.c +++ b/src/http/modules/ngx_http_ssl_module.c @@ -105,7 +105,8 @@ static char *ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, return NGX_CONF_ERROR; } - if (SSL_CTX_use_certificate_file(conf->ssl_ctx, conf->certificate.data, + if (SSL_CTX_use_certificate_file(conf->ssl_ctx, + (char *) conf->certificate.data, SSL_FILETYPE_PEM) == 0) { ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, "SSL_CTX_use_certificate_file(\"%s\") failed", @@ -113,7 +114,8 @@ static char *ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, return NGX_CONF_ERROR; } - if (SSL_CTX_use_PrivateKey_file(conf->ssl_ctx, conf->certificate_key.data, + if (SSL_CTX_use_PrivateKey_file(conf->ssl_ctx, + (char *) conf->certificate_key.data, SSL_FILETYPE_PEM) == 0) { ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, "SSL_CTX_use_PrivateKey_file(\"%s\") failed", diff --git a/src/http/modules/ngx_http_static_handler.c b/src/http/modules/ngx_http_static_handler.c index 9c11c7eb1..bc32cc539 100644 --- a/src/http/modules/ngx_http_static_handler.c +++ b/src/http/modules/ngx_http_static_handler.c @@ -537,11 +537,9 @@ static char *ngx_http_static_merge_loc_conf(ngx_conf_t *cf, static ngx_int_t ngx_http_static_init(ngx_cycle_t *cycle) { ngx_http_handler_pt *h; - ngx_http_conf_ctx_t *ctx; ngx_http_core_main_conf_t *cmcf; - - ctx = (ngx_http_conf_ctx_t *) cycle->conf_ctx[ngx_http_module.index]; - cmcf = ctx->main_conf[ngx_http_core_module.ctx_index]; + + cmcf = ngx_http_cycle_get_module_main_conf(cycle, ngx_http_core_module); h = ngx_push_array(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers); if (h == NULL) { diff --git a/src/http/modules/ngx_http_status_handler.c b/src/http/modules/ngx_http_status_handler.c index adf9d0285..57d7aa077 100644 --- a/src/http/modules/ngx_http_status_handler.c +++ b/src/http/modules/ngx_http_status_handler.c @@ -299,11 +299,9 @@ static ngx_int_t ngx_http_status(ngx_http_status_ctx_t *ctx) static char *ngx_http_set_status(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { - ngx_http_conf_ctx_t *ctx; ngx_http_core_loc_conf_t *clcf; - ctx = cf->ctx; - clcf = ctx->loc_conf[ngx_http_core_module.ctx_index]; + clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); clcf->handler = ngx_http_status_handler; return NGX_CONF_OK; diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.c b/src/http/modules/proxy/ngx_http_proxy_handler.c index 4f8fbda67..711aad2f4 100644 --- a/src/http/modules/proxy/ngx_http_proxy_handler.c +++ b/src/http/modules/proxy/ngx_http_proxy_handler.c @@ -1062,7 +1062,6 @@ static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd, in_addr_t addr; ngx_str_t *value; struct hostent *h; - ngx_http_conf_ctx_t *ctx; ngx_http_core_loc_conf_t *clcf; @@ -1177,10 +1176,11 @@ static char *ngx_http_proxy_set_pass(ngx_conf_t *cf, ngx_command_t *cmd, lcf->upstream->port_text.len + 1); } - ctx = cf->ctx; - clcf = ctx->loc_conf[ngx_http_core_module.ctx_index]; + clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module); + lcf->upstream->location = &clcf->name; clcf->handler = ngx_http_proxy_handler; + if (clcf->name.data[clcf->name.len - 1] == '/') { clcf->auto_redirect = 1; } diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c index 6fca25400..4b61d56f9 100644 --- a/src/http/ngx_http.c +++ b/src/http/ngx_http.c @@ -6,7 +6,11 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); - +static char *ngx_http_merge_locations(ngx_conf_t *cf, + ngx_array_t *locations, + void **loc_conf, + ngx_http_module_t *module, + ngx_uint_t ctx_index); int ngx_http_max_module; @@ -204,7 +208,16 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) /* merge the locations{}' loc_conf's */ - clcfp = (ngx_http_core_loc_conf_t **)cscfp[s]->locations.elts; + rv = ngx_http_merge_locations(cf, &cscfp[s]->locations, + cscfp[s]->ctx->loc_conf, + module, mi); + if (rv != NGX_CONF_OK) { + *cf = pcf; + return rv; + } + +#if 0 + clcfp = (ngx_http_core_loc_conf_t **) cscfp[s]->locations.elts; for (l = 0; l < cscfp[s]->locations.nelts; l++) { rv = module->merge_loc_conf(cf, @@ -215,6 +228,7 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) return rv; } } +#endif } } } @@ -623,3 +637,33 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) return NGX_CONF_OK; } + + +static char *ngx_http_merge_locations(ngx_conf_t *cf, + ngx_array_t *locations, + void **loc_conf, + ngx_http_module_t *module, + ngx_uint_t ctx_index) +{ + char *rv; + ngx_uint_t i; + ngx_http_core_loc_conf_t **clcfp; + + clcfp = /* (ngx_http_core_loc_conf_t **) */ locations->elts; + + for (i = 0; i < locations->nelts; i++) { + rv = module->merge_loc_conf(cf, loc_conf[ctx_index], + clcfp[i]->loc_conf[ctx_index]); + if (rv != NGX_CONF_OK) { + return rv; + } + + rv = ngx_http_merge_locations(cf, &clcfp[i]->locations, + clcfp[i]->loc_conf, module, ctx_index); + if (rv != NGX_CONF_OK) { + return rv; + } + } + + return NGX_CONF_OK; +} diff --git a/src/http/ngx_http_config.h b/src/http/ngx_http_config.h index d2fb8a9ff..d87d4c2c1 100644 --- a/src/http/ngx_http_config.h +++ b/src/http/ngx_http_config.h @@ -43,14 +43,18 @@ typedef struct { #define ngx_http_get_module_srv_conf(r, module) r->srv_conf[module.ctx_index] #define ngx_http_get_module_loc_conf(r, module) r->loc_conf[module.ctx_index] -#define ngx_http_conf_get_module_main_conf(cf, module) \ - ((ngx_http_conf_ctx_t *) cf->ctx)->main_conf[module.ctx_index] /* * ngx_http_conf_get_module_srv_conf() and ngx_http_conf_get_module_loc_conf() - * could not be correctly implemented because at the merge phase cf->ctx - * points to http{}'s ctx + * msut not be used because at the merge phase cf->ctx points to http{}'s ctx */ +#define ngx_http_conf_get_module_main_conf(cf, module) \ + ((ngx_http_conf_ctx_t *) cf->ctx)->main_conf[module.ctx_index] +#define ngx_http_conf_get_module_srv_conf(cf, module) \ + ((ngx_http_conf_ctx_t *) cf->ctx)->srv_conf[module.ctx_index] +#define ngx_http_conf_get_module_loc_conf(cf, module) \ + ((ngx_http_conf_ctx_t *) cf->ctx)->loc_conf[module.ctx_index] + #define ngx_http_cycle_get_module_main_conf(cycle, module) \ ((ngx_http_conf_ctx_t *) \ cycle->conf_ctx[ngx_http_module.index])->main_conf[module.ctx_index] diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c index 911a5aaeb..066d08abc 100644 --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -5,9 +5,16 @@ #include <ngx_http.h> #include <nginx.h> +/* STUB */ +#define NGX_HTTP_LOCATION_EXACT 1 +#define NGX_HTTP_LOCATION_AUTO_REDIRECT 2 +#define NGX_HTTP_LOCATION_REGEX 3 + static void ngx_http_phase_event_handler(ngx_event_t *rev); static void ngx_http_run_phases(ngx_http_request_t *r); +static ngx_int_t ngx_http_find_location(ngx_http_request_t *r, + ngx_array_t *locations); static void *ngx_http_core_create_main_conf(ngx_conf_t *cf); static char *ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf); @@ -103,7 +110,7 @@ static ngx_command_t ngx_http_core_commands[] = { &ngx_http_restrict_host_names }, { ngx_string("location"), - NGX_HTTP_SRV_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12, + NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12, ngx_location_block, NGX_HTTP_SRV_CONF_OFFSET, 0, @@ -463,26 +470,91 @@ static void ngx_http_run_phases(ngx_http_request_t *r) ngx_int_t ngx_http_find_location_config(ngx_http_request_t *r) { - int rc; - ngx_uint_t i; - ngx_str_t *auto_redirect; - ngx_http_core_loc_conf_t *clcf, **clcfp; - ngx_http_core_srv_conf_t *cscf; -#if (HAVE_PCRE) - ngx_uint_t exact; -#endif + ngx_int_t rc; + ngx_http_core_loc_conf_t *clcf; + ngx_http_core_srv_conf_t *cscf; cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); - auto_redirect = NULL; -#if (HAVE_PCRE) - exact = 0; -#endif - clcfp = cscf->locations.elts; - for (i = 0; i < cscf->locations.nelts; i++) { + rc = ngx_http_find_location(r, &cscf->locations); + + if (rc == NGX_HTTP_INTERNAL_SERVER_ERROR) { + return rc; + } + + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + + r->connection->log->file = clcf->err_log->file; + if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) { + r->connection->log->log_level = clcf->err_log->log_level; + } + + if (!(ngx_io.flags & NGX_IO_SENDFILE) || !clcf->sendfile) { + r->sendfile = 0; + + } else { + r->sendfile = 1; + } + + if (!clcf->tcp_nopush) { + /* disable TCP_NOPUSH/TCP_CORK use */ + r->connection->tcp_nopush = NGX_TCP_NOPUSH_DISABLED; + } + + + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "http cl: " SIZE_T_FMT " max: " SIZE_T_FMT, + r->headers_in.content_length_n, + clcf->client_max_body_size); + + if (r->headers_in.content_length_n != -1 + && clcf->client_max_body_size + && clcf->client_max_body_size < (size_t) r->headers_in.content_length_n) + { + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, + "client intented to send too large body: " + SIZE_T_FMT " bytes", + r->headers_in.content_length_n); + + return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE; + } -#if (HAVE_PCRE) + if (rc == NGX_HTTP_LOCATION_AUTO_REDIRECT) { + if (!(r->headers_out.location = + ngx_http_add_header(&r->headers_out, ngx_http_headers_out))) + { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + r->headers_out.location->value = clcf->name; + + return NGX_HTTP_MOVED_PERMANENTLY; + } + + if (clcf->handler) { + r->content_handler = clcf->handler; + } + + return NGX_OK; +} + + +static ngx_int_t ngx_http_find_location(ngx_http_request_t *r, + ngx_array_t *locations) +{ + ngx_int_t n, rc; + ngx_uint_t i, found; + ngx_http_core_loc_conf_t *clcf, **clcfp; + + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "find location"); + + found = 0; + + clcfp = locations->elts; + for (i = 0; i < locations->nelts; i++) { + +#if (HAVE_PCRE) if (clcfp[i]->regex) { break; } @@ -496,135 +568,93 @@ ngx_int_t ngx_http_find_location_config(ngx_http_request_t *r) if (clcfp[i]->auto_redirect && r->uri.len == clcfp[i]->name.len - 1 && ngx_strncmp(r->uri.data, clcfp[i]->name.data, - clcfp[i]->name.len - 1) == 0) + clcfp[i]->name.len - 1) == 0) { - auto_redirect = &clcfp[i]->name; - continue; + /* the locations are lexicographically sorted */ + + r->loc_conf = clcfp[i]->loc_conf; + + return NGX_HTTP_LOCATION_AUTO_REDIRECT; } if (r->uri.len < clcfp[i]->name.len) { continue; } - rc = ngx_strncmp(r->uri.data, clcfp[i]->name.data, clcfp[i]->name.len); + n = ngx_strncmp(r->uri.data, clcfp[i]->name.data, clcfp[i]->name.len); - if (rc < 0) { - /* locations are lexicographically sorted */ + if (n < 0) { + /* the locations are lexicographically sorted */ break; } - if (rc == 0) { - r->loc_conf = clcfp[i]->loc_conf; + if (n == 0) { clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - r->connection->log->file = clcf->err_log->file; - if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) { - r->connection->log->log_level = clcf->err_log->log_level; - } - if (clcfp[i]->exact_match && r->uri.len == clcfp[i]->name.len) { -#if (HAVE_PCRE) - exact = 1; -#endif + if (clcf->name.len >= clcfp[i]->name.len) { + /* the previous match is longer */ break; } - } - } - -#if (HAVE_PCRE) - - if (!exact && !auto_redirect) { - /* regex matches */ - for (/* void */; i < cscf->locations.nelts; i++) { + r->loc_conf = clcfp[i]->loc_conf; - if (!clcfp[i]->regex) { - continue; + if (clcfp[i]->exact_match && r->uri.len == clcfp[i]->name.len) { + return NGX_HTTP_LOCATION_EXACT; } - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "find location: %s\"%s\"", - clcfp[i]->exact_match ? "= " : - clcfp[i]->regex ? "~ " : "", - clcfp[i]->name.data); - - rc = ngx_regex_exec(clcfp[i]->regex, &r->uri, NULL, 0); - - if (rc == NGX_DECLINED) { - continue; - } + found = 1; + } + } - if (rc < 0) { - ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, - ngx_regex_exec_n - " failed: %d on \"%s\" using \"%s\"", - rc, r->uri.data, clcfp[i]->name.data); - return NGX_HTTP_INTERNAL_SERVER_ERROR; - } + if (found) { + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - /* match */ + if (clcf->locations.nelts) { + rc = ngx_http_find_location(r, &clcf->locations); - r->loc_conf = clcfp[i]->loc_conf; - clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - r->connection->log->file = clcf->err_log->file; - if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) { - r->connection->log->log_level = clcf->err_log->log_level; + if (rc != NGX_OK) { + return rc; } - - break; } } -#endif /* HAVE_PCRE */ - - clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); - - if (!(ngx_io.flags & NGX_IO_SENDFILE) || !clcf->sendfile) { - r->sendfile = 0; - - } else { - r->sendfile = 1; - } +#if (HAVE_PCRE) - if (!clcf->tcp_nopush) { - /* disable TCP_NOPUSH/TCP_CORK use */ - r->connection->tcp_nopush = NGX_TCP_NOPUSH_DISABLED; - } + /* regex matches */ + for (/* void */; i < locations->nelts; i++) { - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "http cl: " SIZE_T_FMT " max: " SIZE_T_FMT, - r->headers_in.content_length_n, - clcf->client_max_body_size); + if (!clcfp[i]->regex) { + continue; + } - if (r->headers_in.content_length_n != -1 - && clcf->client_max_body_size - && clcf->client_max_body_size < (size_t) r->headers_in.content_length_n) - { - ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, - "client intented to send too large body: " - SIZE_T_FMT " bytes", - r->headers_in.content_length_n); + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "find location: ~ \"%s\"", + clcfp[i]->name.data); - return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE; - } + n = ngx_regex_exec(clcfp[i]->regex, &r->uri, NULL, 0); + if (n == NGX_DECLINED) { + continue; + } - if (auto_redirect) { - if (!(r->headers_out.location = - ngx_http_add_header(&r->headers_out, ngx_http_headers_out))) - { + if (n < 0) { + ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, + ngx_regex_exec_n + " failed: %d on \"%s\" using \"%s\"", + n, r->uri.data, clcfp[i]->name.data); return NGX_HTTP_INTERNAL_SERVER_ERROR; } - r->headers_out.location->value = *auto_redirect; + /* match */ - return NGX_HTTP_MOVED_PERMANENTLY; - } + r->loc_conf = clcfp[i]->loc_conf; - if (clcf->handler) { - r->content_handler = clcf->handler; + return NGX_HTTP_LOCATION_REGEX; } +#endif /* HAVE_PCRE */ + return NGX_OK; } @@ -799,7 +829,7 @@ ngx_int_t ngx_http_internal_redirect(ngx_http_request_t *r, } -#if 1 /* STUB: test the delay http handler */ +#if 0 /* STUB: test the delay http handler */ int ngx_http_delay_handler(ngx_http_request_t *r) { @@ -863,7 +893,7 @@ static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) char *rv; ngx_http_module_t *module; ngx_conf_t pvcf; - ngx_http_conf_ctx_t *ctx, *hctx; + ngx_http_conf_ctx_t *ctx, *http_ctx; ngx_http_core_main_conf_t *cmcf; ngx_http_core_srv_conf_t *cscf, **cscfp; @@ -871,8 +901,8 @@ static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)), NGX_CONF_ERROR); - hctx = (ngx_http_conf_ctx_t *) cf->ctx; - ctx->main_conf = hctx->main_conf; + http_ctx = cf->ctx; + ctx->main_conf = http_ctx->main_conf; /* the server{}'s srv_conf */ @@ -928,7 +958,7 @@ static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) } ngx_qsort(cscf->locations.elts, (size_t) cscf->locations.nelts, - sizeof(void *), ngx_cmp_locations); + sizeof(ngx_http_core_loc_conf_t *), ngx_cmp_locations); return rv; } @@ -936,20 +966,21 @@ static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) static int ngx_cmp_locations(const void *one, const void *two) { - ngx_http_core_loc_conf_t *first = *(ngx_http_core_loc_conf_t **) one; - ngx_http_core_loc_conf_t *second = *(ngx_http_core_loc_conf_t **) two; + ngx_int_t rc; + ngx_http_core_loc_conf_t *first, *second; - ngx_int_t rc; + first = *(ngx_http_core_loc_conf_t **) one; + second = *(ngx_http_core_loc_conf_t **) two; #if (HAVE_PCRE) if (first->regex && !second->regex) { - /* shift regex matches to the end */ + /* shift the regex matches to the end */ return 1; } if (first->regex || second->regex) { - /* do not sort regex matches */ + /* do not sort the regex matches */ return 0; } @@ -971,11 +1002,11 @@ static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) char *rv; ngx_int_t m; ngx_str_t *value; + ngx_conf_t pcf; ngx_http_module_t *module; - ngx_conf_t pvcf; - ngx_http_conf_ctx_t *ctx, *pvctx; + ngx_http_conf_ctx_t *ctx, *pctx; ngx_http_core_srv_conf_t *cscf; - ngx_http_core_loc_conf_t *clcf, **clcfp; + ngx_http_core_loc_conf_t *clcf, *pclcf, **clcfp; #if (HAVE_PCRE) ngx_str_t err; u_char errstr[NGX_MAX_CONF_ERRSTR]; @@ -985,9 +1016,9 @@ static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) return NGX_CONF_ERROR; } - pvctx = (ngx_http_conf_ctx_t *) cf->ctx; - ctx->main_conf = pvctx->main_conf; - ctx->srv_conf = pvctx->srv_conf; + pctx = cf->ctx; + ctx->main_conf = pctx->main_conf; + ctx->srv_conf = pctx->srv_conf; ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module); if (ctx->loc_conf == NULL) { @@ -1060,17 +1091,52 @@ static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) clcf->name.data = value[1].data; } - cscf = ctx->srv_conf[ngx_http_core_module.ctx_index]; - if (!(clcfp = ngx_push_array(&cscf->locations))) { - return NGX_CONF_ERROR; + pclcf = pctx->loc_conf[ngx_http_core_module.ctx_index]; + + if (pclcf->name.len == 0) { + cscf = ctx->srv_conf[ngx_http_core_module.ctx_index]; + if (!(clcfp = ngx_push_array(&cscf->locations))) { + return NGX_CONF_ERROR; + } + + } else { + clcf->prev_location = pclcf; + + if (pclcf->exact_match) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "location \"%s\" could not be inside " + "the exact location \"%s\"", + clcf->name.data, pclcf->name.data); + return NGX_CONF_ERROR; + } + + if (clcf->regex == NULL + && ngx_strncmp(clcf->name.data, pclcf->name.data, pclcf->name.len) + != 0) + { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "location \"%s\" is outside location \"%s\"", + clcf->name.data, pclcf->name.data); + return NGX_CONF_ERROR; + } + + if (pclcf->locations.elts == NULL) { + ngx_init_array(pclcf->locations, cf->pool, 5, sizeof(void *), + NGX_CONF_ERROR); + } + + if (!(clcfp = ngx_push_array(&pclcf->locations))) { + return NGX_CONF_ERROR; + } } + *clcfp = clcf; - pvcf = *cf; + pcf = *cf; cf->ctx = ctx; cf->cmd_type = NGX_HTTP_LOC_CONF; rv = ngx_conf_parse(cf, NULL); - *cf = pvcf; + *cf = pcf; return rv; } @@ -1220,9 +1286,12 @@ static char *ngx_http_core_merge_srv_conf(ngx_conf_t *cf, n->name.len = ngx_strlen(n->name.data); n->core_srv_conf = conf; +#if 0 ctx = (ngx_http_conf_ctx_t *) cf->cycle->conf_ctx[ngx_http_module.index]; cmcf = ctx->main_conf[ngx_http_core_module.ctx_index]; +#endif + cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); if (cmcf->max_server_name_len < n->name.len) { cmcf->max_server_name_len = n->name.len; @@ -1478,8 +1547,11 @@ static char *ngx_set_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) /* TODO: several names */ /* TODO: warn about duplicate 'server_name' directives */ +#if 0 ctx = (ngx_http_conf_ctx_t *) cf->cycle->conf_ctx[ngx_http_module.index]; cmcf = ctx->main_conf[ngx_http_core_module.ctx_index]; +#endif + cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); value = cf->args->elts; diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h index b71979b57..6c0e7a1b0 100644 --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -124,9 +124,24 @@ typedef struct { } ngx_http_err_page_t; -typedef struct { +typedef struct ngx_http_core_loc_conf_s ngx_http_core_loc_conf_t; + +struct ngx_http_core_loc_conf_s { ngx_str_t name; /* location name */ - void **loc_conf ; /* pointer to the modules' loc_conf */ + +#if (HAVE_PCRE) + ngx_regex_t *regex; +#endif + + unsigned exact_match:1; + unsigned auto_redirect:1; + unsigned alias:1; + + /* array of inclusive ngx_http_core_loc_conf_t */ + ngx_array_t locations; + + /* pointer to the modules' loc_conf */ + void **loc_conf ; ngx_http_handler_pt handler; @@ -157,16 +172,10 @@ typedef struct { ngx_http_cache_hash_t *open_files; -#if (HAVE_PCRE) - ngx_regex_t *regex; -#endif - - unsigned exact_match:1; - unsigned auto_redirect:1; - unsigned alias:1; - ngx_log_t *err_log; -} ngx_http_core_loc_conf_t; + + ngx_http_core_loc_conf_t *prev_location; +}; extern ngx_http_module_t ngx_http_core_module_ctx; diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c index e1463bafd..25d75c6f5 100644 --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -7,7 +7,7 @@ static void ngx_http_init_request(ngx_event_t *ev); #if (NGX_HTTP_SSL) -static void ngx_http_check_ssl_handshake(ngx_event_t *rev); +static void ngx_http_ssl_handshake(ngx_event_t *rev); #endif static void ngx_http_process_request_line(ngx_event_t *rev); static void ngx_http_process_request_headers(ngx_event_t *rev); @@ -238,22 +238,32 @@ static void ngx_http_init_request(ngx_event_t *rev) rev->event_handler = ngx_http_process_request_line; - r->recv = ngx_recv; - r->send_chain = ngx_send_chain; - #if (NGX_HTTP_SSL) sscf = ngx_http_get_module_srv_conf(r, ngx_http_ssl_module); if (sscf->enable) { - if (ngx_ssl_create_session(sscf->ssl_ctx, c, NGX_SSL_BUFFER) + + if (c->ssl == NULL) { + if (ngx_ssl_create_session(sscf->ssl_ctx, c, NGX_SSL_BUFFER) == NGX_ERROR) - { - ngx_http_close_connection(c); - return; + { + ngx_http_close_connection(c); + return; + } + + /* + * The majority of browsers do not send the "close notify" alert. + * Among them are MSIE, Mozilla, Netscape 4, Konqueror, and Links. + * And what is more MSIE ignores the server's alert. + * + * Opera always sends the alert. + */ + + c->ssl->no_rcv_shut = 1; + rev->event_handler = ngx_http_ssl_handshake; } r->filter_need_in_memory = 1; - rev->event_handler = ngx_http_check_ssl_handshake; } #endif @@ -339,9 +349,10 @@ static void ngx_http_init_request(ngx_event_t *rev) #if (NGX_HTTP_SSL) -static void ngx_http_check_ssl_handshake(ngx_event_t *rev) +static void ngx_http_ssl_handshake(ngx_event_t *rev) { int n; + ngx_int_t rc; u_char buf[1]; ngx_connection_t *c; ngx_http_request_t *r; @@ -368,8 +379,20 @@ static void ngx_http_check_ssl_handshake(ngx_event_t *rev) ngx_log_debug1(NGX_LOG_DEBUG_HTTP, rev->log, 0, "https ssl handshake: 0x%X", buf[0]); - r->recv = ngx_ssl_recv; - r->send_chain = ngx_ssl_send_chain; + c->recv = ngx_ssl_recv; + c->send_chain = ngx_ssl_send_chain; + + rc = ngx_ssl_handshake(c); + + if (rc == NGX_ERROR) { + ngx_http_close_request(r, NGX_HTTP_BAD_REQUEST); + ngx_http_close_connection(r->connection); + return; + } + + if (rc != NGX_OK) { + return; + } } else { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0, @@ -892,8 +915,8 @@ static ssize_t ngx_http_read_request_header(ngx_http_request_t *r) return NGX_AGAIN; } - n = r->recv(r->connection, r->header_in->last, - r->header_in->end - r->header_in->last); + n = r->connection->recv(r->connection, r->header_in->last, + r->header_in->end - r->header_in->last); if (n == NGX_AGAIN) { if (!r->header_timeout_set) { @@ -963,7 +986,10 @@ static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r) clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); r->connection->log->file = clcf->err_log->file; - r->connection->log->log_level = clcf->err_log->log_level; + if (!(r->connection->log->log_level & NGX_LOG_DEBUG_CONNECTION)) + { + r->connection->log->log_level = clcf->err_log->log_level; + } break; } @@ -1040,6 +1066,12 @@ static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r) if (ua[4] == ' ' && ua[5] == '4' && ua[6] == '.') { r->headers_in.msie4 = 1; } + +#if 0 + /* MSIE ignores the SSL "close notify" alert */ + + ngx_ssl_set_nosendshut(r->connection->ssl); +#endif } } @@ -1355,7 +1387,8 @@ static ngx_int_t ngx_http_read_discarded_body(ngx_http_request_t *r) size = (ssize_t) clcf->discarded_buffer_size; } - n = ngx_recv(r->connection, r->discarded_buffer, size); + n = r->connection->recv(r->connection, r->discarded_buffer, size); + if (n == NGX_ERROR) { r->closed = 1; @@ -1502,7 +1535,8 @@ static void ngx_http_keepalive_handler(ngx_event_t *rev) c->log_error = NGX_ERROR_IGNORE_ECONNRESET; ngx_set_socket_errno(0); - n = ngx_recv(c, c->buffer->last, c->buffer->end - c->buffer->last); + + n = c->recv(c, c->buffer->last, c->buffer->end - c->buffer->last); c->log_error = NGX_ERROR_INFO; if (n == NGX_AGAIN) { @@ -1533,7 +1567,7 @@ static void ngx_http_keepalive_handler(ngx_event_t *rev) static void ngx_http_set_lingering_close(ngx_http_request_t *r) -{ +{ ngx_event_t *rev, *wev; ngx_connection_t *c; ngx_http_core_loc_conf_t *clcf; @@ -1640,7 +1674,7 @@ static void ngx_http_lingering_close_handler(ngx_event_t *rev) } do { - n = ngx_recv(c, r->discarded_buffer, clcf->discarded_buffer_size); + n = c->recv(c, r->discarded_buffer, clcf->discarded_buffer_size); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "lingering read: %d", n); diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h index a80e0a57d..d987c515a 100644 --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -218,9 +218,6 @@ struct ngx_http_request_s { ngx_connection_t *connection; - ngx_recv_pt recv; - ngx_send_chain_pt send_chain; - void **ctx; void **main_conf; void **srv_conf; diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c index a1e2c5a40..800f5491e 100644 --- a/src/http/ngx_http_request_body.c +++ b/src/http/ngx_http_request_body.c @@ -140,7 +140,7 @@ static ngx_int_t ngx_http_do_read_client_request_body(ngx_http_request_t *r) size = r->request_body->rest; } - n = ngx_recv(c, r->request_body->buf->last, size); + n = c->recv(c, r->request_body->buf->last, size); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http client request body recv " SIZE_T_FMT, n); diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c index dd7e55484..81476696b 100644 --- a/src/http/ngx_http_special_response.c +++ b/src/http/ngx_http_special_response.c @@ -104,9 +104,11 @@ static char error_416_page[] = static char error_497_page[] = "<html>" CRLF -"<head><title>The plain HTTP request was sent to HTTPS port</title></head>" CRLF +"<head><title>400 The plain HTTP request was sent to HTTPS port</title></head>" +CRLF "<body bgcolor=\"white\">" CRLF -"<center><h1>The plain HTTP request was sent to HTTPS por</h1></center>" CRLF +"<center><h1>400 Bad Request</h1></center>" CRLF +"<center>The plain HTTP request was sent to HTTPS port</center>" CRLF ; @@ -174,7 +176,7 @@ static ngx_str_t error_pages[] = { ngx_null_string, /* 415 */ ngx_string(error_416_page), - ngx_string(error_400_page), /* 497, http to https */ + ngx_string(error_497_page), /* 497, http to https */ ngx_string(error_404_page), /* 498, invalid host name */ ngx_null_string, /* 499, client closed connection */ diff --git a/src/http/ngx_http_write_filter.c b/src/http/ngx_http_write_filter.c index 8b1447a44..412d4f9bc 100644 --- a/src/http/ngx_http_write_filter.c +++ b/src/http/ngx_http_write_filter.c @@ -45,6 +45,7 @@ ngx_int_t ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in) int last; off_t size, flush, sent; ngx_chain_t *cl, *ln, **ll, *chain; + ngx_connection_t *c; ngx_http_core_loc_conf_t *clcf; ngx_http_write_filter_ctx_t *ctx; @@ -95,7 +96,9 @@ ngx_int_t ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in) } } - ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + c = r->connection; + + ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, "http write filter: l:%d f:" OFF_T_FMT " s:" OFF_T_FMT, last, flush, size); @@ -112,7 +115,7 @@ ngx_int_t ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in) return NGX_OK; } - if (r->connection->write->delayed) { + if (c->write->delayed) { return NGX_AGAIN; } @@ -124,17 +127,17 @@ ngx_int_t ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in) return NGX_OK; } - sent = r->connection->sent; + sent = c->sent; - chain = r->send_chain(r->connection, ctx->out, + chain = c->send_chain(c, ctx->out, clcf->limit_rate ? clcf->limit_rate: OFF_T_MAX_VALUE); - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http write filter %X", chain); if (clcf->limit_rate) { - sent = r->connection->sent - sent; - r->connection->write->delayed = 1; + sent = c->sent - sent; + c->write->delayed = 1; ngx_add_timer(r->connection->write, (ngx_msec_t) (sent * 1000 / clcf->limit_rate)); } |