diff options
| author | Igor Sysoev <igor@sysoev.ru> | 2004-12-21 12:30:30 +0000 |
|---|---|---|
| committer | Igor Sysoev <igor@sysoev.ru> | 2004-12-21 12:30:30 +0000 |
| commit | b1dfe478a03ad6919f174812951f6a2bec8befae (patch) | |
| tree | d8802484f8dbf5309b17a95b5fc9749627720a53 /src/http | |
| parent | 5275a8b3ac534ff36973801ec2aa6ce1214d7cc9 (diff) | |
| download | nginx-release-0.1.13.tar.gz nginx-release-0.1.13.tar.bz2 | |
nginx-0.1.13-RELEASE importrelease-0.1.13
*) Feature: the server_names_hash and server_names_hash_threshold
directives.
*) Bugfix: the *.domain.tld names in the "server_name" directive did
not work.
*) Bugfix: the %request_length log parameter logged the incorrect
length.
Diffstat (limited to 'src/http')
| -rw-r--r-- | src/http/modules/ngx_http_charset_filter.c | 34 | ||||
| -rw-r--r-- | src/http/modules/ngx_http_headers_filter.c | 4 | ||||
| -rw-r--r-- | src/http/modules/proxy/ngx_http_proxy_handler.c | 65 | ||||
| -rw-r--r-- | src/http/ngx_http.c | 100 | ||||
| -rw-r--r-- | src/http/ngx_http.h | 1 | ||||
| -rw-r--r-- | src/http/ngx_http_cache.c | 98 | ||||
| -rw-r--r-- | src/http/ngx_http_cache.h | 27 | ||||
| -rw-r--r-- | src/http/ngx_http_core_module.c | 27 | ||||
| -rw-r--r-- | src/http/ngx_http_core_module.h | 91 | ||||
| -rw-r--r-- | src/http/ngx_http_file_cache.c | 175 | ||||
| -rw-r--r-- | src/http/ngx_http_header_filter.c | 2 | ||||
| -rw-r--r-- | src/http/ngx_http_log_handler.c | 6 | ||||
| -rw-r--r-- | src/http/ngx_http_request.c | 205 | ||||
| -rw-r--r-- | src/http/ngx_http_request.h | 4 | ||||
| -rw-r--r-- | src/http/ngx_http_special_response.c | 6 |
15 files changed, 613 insertions, 232 deletions
diff --git a/src/http/modules/ngx_http_charset_filter.c b/src/http/modules/ngx_http_charset_filter.c index cf9d3d2be..0aea91e2f 100644 --- a/src/http/modules/ngx_http_charset_filter.c +++ b/src/http/modules/ngx_http_charset_filter.c @@ -147,12 +147,6 @@ static ngx_int_t ngx_http_charset_header_filter(ngx_http_request_t *r) return ngx_http_next_header_filter(r); } -#if 0 - if (lcf->default_charset.len == 0) { - return ngx_http_next_header_filter(r); - } -#endif - if (r->headers_out.content_type == NULL) { return ngx_http_next_header_filter(r); } @@ -559,12 +553,36 @@ static char *ngx_http_charset_merge_loc_conf(ngx_conf_t *cf, ngx_conf_merge_value(conf->enable, prev->enable, 0); ngx_conf_merge_value(conf->autodetect, prev->autodetect, 0); + + if (conf->default_charset == NGX_CONF_UNSET) { + conf->default_charset = prev->default_charset; + } + if (conf->source_charset == NGX_CONF_UNSET) { conf->source_charset = prev->source_charset; } - ngx_conf_merge_value(conf->default_charset, prev->default_charset, - conf->source_charset); + if (conf->default_charset == NGX_CONF_UNSET + && conf->source_charset != NGX_CONF_UNSET) + { + conf->default_charset = conf->source_charset; + } + + if (conf->source_charset == NGX_CONF_UNSET + && conf->default_charset != NGX_CONF_UNSET) + { + conf->source_charset = conf->default_charset; + } + + if (conf->enable + && (conf->default_charset == NGX_CONF_UNSET + || conf->source_charset == NGX_CONF_UNSET)) + { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "the \"source_charset\" or \"default_charset\" " + "must be specified when \"charset\" is on"); + return NGX_CONF_ERROR; + } return NGX_CONF_OK; } diff --git a/src/http/modules/ngx_http_headers_filter.c b/src/http/modules/ngx_http_headers_filter.c index e86f6ae63..ab334148e 100644 --- a/src/http/modules/ngx_http_headers_filter.c +++ b/src/http/modules/ngx_http_headers_filter.c @@ -128,8 +128,8 @@ static ngx_int_t ngx_http_headers_filter(ngx_http_request_t *r) cc->value.data = (u_char *) "no-cache"; } else { - cc->value.data = ngx_palloc(r->pool, - sizeof("max-age=") + TIME_T_LEN + 1); + cc->value.data = ngx_palloc(r->pool, sizeof("max-age=") + + NGX_TIME_T_LEN + 1); if (cc->value.data == NULL) { return NGX_ERROR; } diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.c b/src/http/modules/proxy/ngx_http_proxy_handler.c index 651dfa67b..62e348e0a 100644 --- a/src/http/modules/proxy/ngx_http_proxy_handler.c +++ b/src/http/modules/proxy/ngx_http_proxy_handler.c @@ -11,6 +11,7 @@ static ngx_int_t ngx_http_proxy_handler(ngx_http_request_t *r); +static ngx_int_t ngx_http_proxy_cache_get(ngx_http_proxy_ctx_t *p); static u_char *ngx_http_proxy_log_proxy_state(ngx_http_request_t *r, u_char *buf, uintptr_t data); @@ -147,14 +148,14 @@ static ngx_command_t ngx_http_proxy_commands[] = { offsetof(ngx_http_proxy_loc_conf_t, busy_buffers_size), NULL }, -#if (NGX_HTTP_FILE_CACHE) +#if 0 { ngx_string("proxy_cache_path"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234, ngx_conf_set_path_slot, NGX_HTTP_LOC_CONF_OFFSET, offsetof(ngx_http_proxy_loc_conf_t, cache_path), - ngx_garbage_collector_http_cache_handler }, + (void *) ngx_http_cache_cleaner_handler }, #endif @@ -351,17 +352,19 @@ static ngx_int_t ngx_http_proxy_handler(ngx_http_request_t *r) /* TODO: we currently support reverse proxy only */ p->accel = 1; - ngx_init_array(p->states, r->pool, p->lcf->peers->number, - sizeof(ngx_http_proxy_state_t), - NGX_HTTP_INTERNAL_SERVER_ERROR); + if (ngx_array_init(&p->states, r->pool, p->lcf->peers->number, + sizeof(ngx_http_proxy_state_t)) == NGX_ERROR) + { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } - if (!(p->state = ngx_push_array(&p->states))) { + if (!(p->state = ngx_array_push(&p->states))) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } ngx_memzero(p->state, sizeof(ngx_http_proxy_state_t)); -#if (NGX_HTTP_FILE_CACHE) +#if 0 if (!p->lcf->cache || (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD)) @@ -387,7 +390,7 @@ static ngx_int_t ngx_http_proxy_handler(ngx_http_request_t *r) return ngx_http_proxy_request_upstream(p); } - return ngx_http_proxy_get_cached_response(p); + return ngx_http_proxy_cache_get(p); #else @@ -399,6 +402,52 @@ static ngx_int_t ngx_http_proxy_handler(ngx_http_request_t *r) } +#if 0 + +static ngx_int_t ngx_http_proxy_cache_get(ngx_http_proxy_ctx_t *p) +{ + u_char *last; + ngx_http_request_t *r; + ngx_http_cache_ctx_t ctx; + ngx_http_proxy_upstream_conf_t *u; + + r = p->request; + u = p->lcf->upstream; + + ctx.key.len = u->url.len + r->uri.len - u->location->len + r->args.len; + if (!(ctx.key.data = ngx_palloc(r->pool, ctx.key.len))) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + + last = ngx_cpymem(ctx.key.data, u->url.data, u->url.len); + + last = ngx_cpymem(last, r->uri.data + u->location->len, + r->uri.len - u->location->len); + + if (r->args.len > 0) { + *(last++) = '?'; + last = ngx_cpymem(last, r->args.data, r->args.len); + } + + p->header_in = ngx_create_temp_buf(r->pool, p->lcf->header_buffer_size); + if (p->header_in == NULL) { + return NGX_HTTP_INTERNAL_SERVER_ERROR; + } + p->header_in->tag = (ngx_buf_tag_t) &ngx_http_proxy_module; + + ctx.buf = p->header_in; + ctx.path = p->lcf->cache_path; + ctx.file = 1; + ctx.primary = 1; + + ngx_http_cache_get(r, &ctx); + + return ngx_http_proxy_request_upstream(p); +} + +#endif + + void ngx_http_proxy_check_broken_connection(ngx_event_t *ev) { int n; diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c index a550acb1d..21d2e5543 100644 --- a/src/http/ngx_http.c +++ b/src/http/ngx_http.c @@ -11,6 +11,7 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static int ngx_cmp_server_names(const void *one, const void *two); static ngx_int_t ngx_http_add_address(ngx_conf_t *cf, ngx_http_in_port_t *in_port, ngx_http_listen_t *lscf, @@ -69,7 +70,7 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { char *rv; ngx_uint_t mi, m, s, l, p, a, n; - ngx_uint_t port_found, addr_found, virtual_names; + ngx_uint_t port_found, addr_found, virtual_names, key; ngx_conf_t pcf; ngx_array_t in_ports; ngx_listening_t *ls; @@ -92,7 +93,9 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ngx_memzero(&in_ports, sizeof(ngx_array_t)); #endif + /* the main http context */ + ngx_test_null(ctx, ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)), NGX_CONF_ERROR); @@ -111,6 +114,7 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) } /* the main http main_conf, it's the same in the all http contexts */ + ngx_test_null(ctx->main_conf, ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module), NGX_CONF_ERROR); @@ -376,6 +380,8 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) in_addr[a].addr = lscf[l].addr; in_addr[a].names.elts = NULL; + in_addr[a].hash = NULL; + in_addr[a].wildcards.elts = NULL; in_addr[a].default_server = lscf[l].default_server; in_addr[a].core_srv_conf = cscfp[s]; @@ -464,6 +470,19 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) } } + if (!virtual_names) { + name = in_addr[a].wildcards.elts; + for (n = 0; n < in_addr[a].wildcards.nelts; n++) { + if (in_addr[a].core_srv_conf != name[n].core_srv_conf + || name[n].core_srv_conf->restrict_host_names + != NGX_HTTP_RESTRICT_HOST_OFF) + { + virtual_names = 1; + break; + } + } + } + /* * if all name-based servers have the same configuration * as the default server, and no servers restrict the host names @@ -472,12 +491,50 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) if (!virtual_names) { in_addr[a].names.nelts = 0; + continue; + } + + + ngx_qsort(in_addr[a].names.elts, in_addr[a].names.nelts, + sizeof(ngx_http_server_name_t), ngx_cmp_server_names); + + + /* create a hash for many names */ + + if (in_addr[a].names.nelts > cmcf->server_names_hash_threshold) { + in_addr[a].hash = ngx_palloc(cf->pool, + cmcf->server_names_hash + * sizeof(ngx_array_t)); + if (in_addr[a].hash == NULL) { + return NGX_CONF_ERROR; + } + + for (n = 0; n < cmcf->server_names_hash; n++) { + if (ngx_array_init(&in_addr[a].hash[n], cf->pool, 5, + sizeof(ngx_http_server_name_t)) == NGX_ERROR) + { + return NGX_CONF_ERROR; + } + } + + name = in_addr[a].names.elts; + for (s = 0; s < in_addr[a].names.nelts; s++) { + ngx_http_server_names_hash_key(key, name[s].name.data, + name[s].name.len, + cmcf->server_names_hash); + + if (!(s_name = ngx_array_push(&in_addr[a].hash[key]))) { + return NGX_CONF_ERROR; + } + + *s_name = name[s]; + } } } /* - * if there's the binding to "*:port" then we need to bind() - * to "*:port" only and ignore the other bindings + * if there is the binding to the "*:port" then we need to bind() + * to the "*:port" only and ignore the other bindings */ if (in_addr[a - 1].addr == INADDR_ANY) { @@ -604,6 +661,15 @@ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) } +static int ngx_cmp_server_names(const void *one, const void *two) +{ + ngx_http_server_name_t *first = (ngx_http_server_name_t *) one; + ngx_http_server_name_t *second = (ngx_http_server_name_t *) two; + + return ngx_strcmp(first->name.data, second->name.data); +} + + /* * add the server address, the server names and the server core module * configurations to the port (in_port) @@ -630,6 +696,8 @@ static ngx_int_t ngx_http_add_address(ngx_conf_t *cf, in_addr->addr = lscf->addr; in_addr->names.elts = NULL; + in_addr->hash = NULL; + in_addr->wildcards.elts = NULL; in_addr->default_server = lscf->default_server; in_addr->core_srv_conf = cscf; @@ -655,7 +723,8 @@ static ngx_int_t ngx_http_add_names(ngx_conf_t *cf, ngx_http_in_addr_t *in_addr, ngx_http_core_srv_conf_t *cscf) { - ngx_uint_t i; + ngx_uint_t i, n; + ngx_array_t *array; ngx_http_server_name_t *server_names, *name; if (in_addr->names.elts == NULL) { @@ -666,15 +735,36 @@ static ngx_int_t ngx_http_add_names(ngx_conf_t *cf, } } + if (in_addr->wildcards.elts == NULL) { + if (ngx_array_init(&in_addr->wildcards, cf->pool, 10, + sizeof(ngx_http_server_name_t)) == NGX_ERROR) + { + return NGX_ERROR; + } + } + server_names = cscf->server_names.elts; for (i = 0; i < cscf->server_names.nelts; i++) { + for (n = 0; n < server_names[i].name.len; n++) { + server_names[i].name.data[n] = + ngx_tolower(server_names[i].name.data[n]); + } + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, cf->log, 0, "name: %V", &server_names[i].name); /* TODO: duplicate names can be checked here */ - if (!(name = ngx_array_push(&in_addr->names))) { + + if (server_names[i].wildcard) { + array = &in_addr->wildcards; + + } else { + array = &in_addr->names; + } + + if (!(name = ngx_array_push(array))) { return NGX_ERROR; } diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h index 46194f34d..42550aa22 100644 --- a/src/http/ngx_http.h +++ b/src/http/ngx_http.h @@ -14,6 +14,7 @@ typedef struct ngx_http_request_s ngx_http_request_t; typedef struct ngx_http_cleanup_s ngx_http_cleanup_t; +typedef struct ngx_http_in_addr_s ngx_http_in_addr_t; #if (NGX_HTTP_CACHE) #include <ngx_http_cache.h> diff --git a/src/http/ngx_http_cache.c b/src/http/ngx_http_cache.c index abdeae989..8471459af 100644 --- a/src/http/ngx_http_cache.c +++ b/src/http/ngx_http_cache.c @@ -9,6 +9,7 @@ #include <ngx_http.h> +#if 0 static ngx_http_module_t ngx_http_cache_module_ctx = { NULL, /* pre conf */ @@ -30,9 +31,101 @@ ngx_module_t ngx_http_cache_module = { NULL, /* module directives */ NGX_HTTP_MODULE, /* module type */ NULL, /* init module */ - NULL /* init child */ + NULL /* init process */ }; +#endif + + +static ngx_int_t ngx_http_cache_create(ngx_http_request_t *r) +{ + ngx_str_t *key; + + if (!(r->cache = ngx_pcalloc(r->pool, sizeof(ngx_http_cache_t)))) { + return NGX_ERROR; + } + + if (ngx_array_init(&r->cache->key, r->pool, 5, sizeof(ngx_str_t)) + == NGX_ERROR) + { + return NGX_ERROR; + } + + /* preallocate the primary key */ + + if (!(key = ngx_array_push(&r->cache->key))) { + return NGX_ERROR; + } + + key->len = 0; + key->data = NULL; + + /* + * we use offsetof() because sizeof() pads the struct size to the int size + */ + + r->cache->header_size = offsetof(ngx_http_cache_header_t, key); + + r->cache->log = r->connection->log; + r->cache->file.log = r->connection->log; + + return NGX_OK; +} + + +ngx_int_t ngx_http_cache_get(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx) +{ + ngx_str_t *key; + ngx_http_cache_t *c; + + if (r->cache == NULL) { + if (ngx_http_cache_create(r) == NGX_ERROR) { + return NGX_ABORT; + } + } + + c = r->cache; + key = c->key.elts; + + if (ctx->primary) { + key[0] = ctx->key; + c->header_size += ctx->key.len; + c->key_len += ctx->key.len; + c->buf = ctx->buf; + + } else { + if (key[0].len == 0) { + key[0] = r->uri; + c->header_size += r->uri.len; + c->key_len += ctx->key.len; + } + + if (!(key = ngx_array_push(&r->cache->key))) { + return NGX_ABORT; + } + + c->header_size += ctx->key.len; + c->key_len += ctx->key.len; + } + +#if 0 + + if (ctx->memory) { + ngx_http_memory_cache_get(r, ctx); + } + +#endif + + if (ctx->file) { + return ngx_http_file_cache_get(r, ctx); + } + + return NGX_DECLINED; +} + + +#if 0 + ngx_http_cache_t *ngx_http_cache_get(ngx_http_cache_hash_t *hash, ngx_http_cleanup_t *cleanup, @@ -478,3 +571,6 @@ char *ngx_http_set_cache_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) return NGX_CONF_OK; } + + +#endif diff --git a/src/http/ngx_http_cache.h b/src/http/ngx_http_cache.h index c882b3006..fb446e471 100644 --- a/src/http/ngx_http_cache.h +++ b/src/http/ngx_http_cache.h @@ -88,18 +88,25 @@ typedef struct { time_t last_modified; time_t date; off_t length; - ssize_t header_size; + size_t key_len; size_t file_start; + ngx_file_uniq_t uniq; ngx_log_t *log; /* STUB */ + ssize_t header_size; ngx_str_t key0; } ngx_http_cache_t; typedef struct { - ngx_path_t path; + ngx_path_t *path; ngx_str_t key; + ngx_buf_t *buf; + + unsigned file:1; + unsigned memory:1; + unsigned primary:1; } ngx_http_cache_ctx_t; @@ -108,6 +115,17 @@ typedef struct { #define NGX_HTTP_CACHE_THE_SAME 3 +ngx_int_t ngx_http_cache_get(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx); + +ngx_int_t ngx_http_file_cache_get(ngx_http_request_t *r, + ngx_http_cache_ctx_t *ctx); + +ngx_int_t ngx_http_file_cache_open(ngx_http_cache_t *c); + +ngx_int_t ngx_http_cache_cleaner_handler(ngx_gc_t *gc, ngx_str_t *name, + ngx_dir_t *dir); + + #if 0 ngx_http_cache_t *ngx_http_cache_get(ngx_http_cache_hash_t *cache, @@ -125,17 +143,12 @@ void ngx_http_cache_lock(ngx_http_cache_hash_t *hash, ngx_http_cache_t *cache); void ngx_http_cache_unlock(ngx_http_cache_hash_t *hash, ngx_http_cache_t *cache, ngx_log_t *log); -int ngx_http_cache_get_file(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx); -int ngx_http_cache_open_file(ngx_http_cache_ctx_t *ctx, ngx_file_uniq_t uniq); int ngx_http_cache_update_file(ngx_http_request_t *r,ngx_http_cache_ctx_t *ctx, ngx_str_t *temp_file); int ngx_http_send_cached(ngx_http_request_t *r); -int ngx_garbage_collector_http_cache_handler(ngx_gc_t *gc, ngx_str_t *name, - ngx_dir_t *dir); - char *ngx_http_set_cache_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); #endif diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c index e3ccd8ff6..478bb0811 100644 --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -60,6 +60,20 @@ static ngx_conf_enum_t ngx_http_restrict_host_names[] = { static ngx_command_t ngx_http_core_commands[] = { + { ngx_string("server_names_hash"), + NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, + ngx_conf_set_num_slot, + NGX_HTTP_MAIN_CONF_OFFSET, + offsetof(ngx_http_core_main_conf_t, server_names_hash), + NULL }, + + { ngx_string("server_names_hash_threshold"), + NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, + ngx_conf_set_num_slot, + NGX_HTTP_MAIN_CONF_OFFSET, + offsetof(ngx_http_core_main_conf_t, server_names_hash_threshold), + NULL }, + { ngx_string("server"), NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, ngx_server_block, @@ -1244,17 +1258,24 @@ static void *ngx_http_core_create_main_conf(ngx_conf_t *cf) 5, sizeof(ngx_http_core_srv_conf_t *), NGX_CONF_ERROR); + cmcf->server_names_hash = NGX_CONF_UNSET_UINT; + cmcf->server_names_hash_threshold = NGX_CONF_UNSET_UINT; + return cmcf; } static char *ngx_http_core_init_main_conf(ngx_conf_t *cf, void *conf) { -#if 0 ngx_http_core_main_conf_t *cmcf = conf; - /* TODO: remove it if no directives */ -#endif + if (cmcf->server_names_hash == NGX_CONF_UNSET_UINT) { + cmcf->server_names_hash = 1009; + } + + if (cmcf->server_names_hash_threshold == NGX_CONF_UNSET_UINT) { + cmcf->server_names_hash_threshold = 50; + } return NGX_CONF_OK; } diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h index a70b472d5..138067d50 100644 --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -14,13 +14,13 @@ typedef struct { - in_addr_t addr; - in_port_t port; - int family; - ngx_str_t file_name; - int line; + in_addr_t addr; + in_port_t port; + int family; + ngx_str_t file_name; + ngx_int_t line; - unsigned default_server:1; + unsigned default_server:1; } ngx_http_listen_t; @@ -37,18 +37,21 @@ typedef enum { typedef struct { - ngx_array_t handlers; - ngx_int_t type; /* NGX_OK, NGX_DECLINED */ + ngx_array_t handlers; + ngx_int_t type; /* NGX_OK, NGX_DECLINED */ } ngx_http_phase_t; typedef struct { - ngx_array_t servers; /* array of ngx_http_core_srv_conf_t */ + ngx_array_t servers; /* array of ngx_http_core_srv_conf_t */ + + ngx_http_phase_t phases[NGX_HTTP_LAST_PHASE]; + ngx_array_t index_handlers; - ngx_http_phase_t phases[NGX_HTTP_LAST_PHASE]; - ngx_array_t index_handlers; + ngx_uint_t server_names_hash; + ngx_uint_t server_names_hash_threshold; - size_t max_server_name_len; + size_t max_server_name_len; } ngx_http_core_main_conf_t; @@ -57,62 +60,76 @@ typedef struct { * array of ngx_http_core_loc_conf_t, used in the translation handler * and in the merge phase */ - ngx_array_t locations; + ngx_array_t locations; /* "listen", array of ngx_http_listen_t */ - ngx_array_t listen; + ngx_array_t listen; /* "server_name", array of ngx_http_server_name_t */ - ngx_array_t server_names; + ngx_array_t server_names; /* server ctx */ - ngx_http_conf_ctx_t *ctx; + ngx_http_conf_ctx_t *ctx; - size_t connection_pool_size; - size_t request_pool_size; - size_t client_header_buffer_size; + size_t connection_pool_size; + size_t request_pool_size; + size_t client_header_buffer_size; - ngx_bufs_t large_client_header_buffers; + ngx_bufs_t large_client_header_buffers; - ngx_msec_t post_accept_timeout; - ngx_msec_t client_header_timeout; + ngx_msec_t post_accept_timeout; + ngx_msec_t client_header_timeout; - ngx_uint_t restrict_host_names; + ngx_uint_t restrict_host_names; } ngx_http_core_srv_conf_t; /* list of structures to find core_srv_conf quickly at run time */ typedef struct { - in_port_t port; - ngx_str_t port_text; - ngx_array_t addrs; /* array of ngx_http_in_addr_t */ + in_port_t port; + ngx_str_t port_text; + ngx_array_t addrs; /* array of ngx_http_in_addr_t */ } ngx_http_in_port_t; -typedef struct { +struct ngx_http_in_addr_s { in_addr_t addr; + ngx_array_t names; /* array of ngx_http_server_name_t */ - ngx_http_core_srv_conf_t *core_srv_conf; /* default server conf - for this address:port */ + ngx_array_t *hash; /* hash of ngx_http_server_name_t */ + ngx_array_t wildcards; /* array of ngx_http_server_name_t */ + + /* the default server configuration for this address:port */ + ngx_http_core_srv_conf_t *core_srv_conf; ngx_uint_t default_server; /* unsigned default_server:1; */ -} ngx_http_in_addr_t; +}; typedef struct { ngx_str_t name; ngx_http_core_srv_conf_t *core_srv_conf; /* virtual name server conf */ - ngx_uint_t wildcard; /*unsigned wildcard:1; */ + ngx_uint_t wildcard; /* unsigned wildcard:1 */ } ngx_http_server_name_t; +#define ngx_http_server_names_hash_key(key, name, len, prime) \ + { \ + ngx_uint_t n; \ + for (key = 0, n = 0; n < len; n++) { \ + key += name[n]; \ + } \ + key %= prime; \ + } + + #define NGX_HTTP_TYPES_HASH_PRIME 13 #define ngx_http_types_hash_key(key, ext) \ { \ - u_int n; \ + ngx_uint_t n; \ for (key = 0, n = 0; n < ext.len; n++) { \ key += ext.data[n]; \ } \ @@ -120,15 +137,15 @@ typedef struct { } typedef struct { - ngx_str_t exten; - ngx_str_t type; + ngx_str_t exten; + ngx_str_t type; } ngx_http_type_t; typedef struct { - ngx_int_t status; - ngx_int_t overwrite; - ngx_str_t uri; + ngx_int_t status; + ngx_int_t overwrite; + ngx_str_t uri; } ngx_http_err_page_t; diff --git a/src/http/ngx_http_file_cache.c b/src/http/ngx_http_file_cache.c index 1b258c943..df40c43f7 100644 --- a/src/http/ngx_http_file_cache.c +++ b/src/http/ngx_http_file_cache.c @@ -22,138 +22,151 @@ #endif -#if 0 - -int ngx_http_cache_get_file(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx) +ngx_int_t ngx_http_file_cache_get(ngx_http_request_t *r, + ngx_http_cache_ctx_t *ctx) { - MD5_CTX md5; + ngx_uint_t i; + ngx_str_t *key; + ngx_http_cache_t *c; + MD5_CTX md5; - /* we use offsetof() because sizeof() pads struct size to int size */ - ctx->header_size = offsetof(ngx_http_cache_header_t, key) - + ctx->key.len + 1; + c = r->cache; - ctx->file.name.len = ctx->path->name.len + 1 + ctx->path->len + 32; - if (!(ctx->file.name.data = ngx_palloc(r->pool, ctx->file.name.len + 1))) { - return NGX_ERROR; + c->file.name.len = ctx->path->name.len + 1 + ctx->path->len + 32; + if (!(c->file.name.data = ngx_palloc(r->pool, c->file.name.len + 1))) { + return NGX_ABORT; } - ngx_memcpy(ctx->file.name.data, ctx->path->name.data, ctx->path->name.len); - MD5Init(&md5); - MD5Update(&md5, (u_char *) ctx->key.data, ctx->key.len); - MD5Final(ctx->md5, &md5); - ngx_md5_text(ctx->file.name.data + ctx->path->name.len + 1 + ctx->path->len, - ctx->md5); + key = c->key.elts; + for (i = 0; i < c->key.nelts; i++) { + MD5Update(&md5, key[i].data, key[i].len); + } + + MD5Update(&md5, ctx->key.data, ctx->key.len); + + MD5Final(c->md5, &md5); + + ngx_memcpy(c->file.name.data, ctx->path->name.data, ctx->path->name.len); + + ngx_md5_text(c->file.name.data + ctx->path->name.len + 1 + ctx->path->len, + c->md5); ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "file cache uri: %s, md5: %s", ctx->key.data, - ctx->file.name.data + ctx->path->name.len + 1 + ctx->path->len); + "file cache key: %V, md5: %s", &ctx->key, + c->file.name.data + ctx->path->name.len + 1 + ctx->path->len); - ngx_create_hashed_filename(&ctx->file, ctx->path); + ngx_create_hashed_filename(&c->file, ctx->path); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "file cache name: %s", ctx->file.name.data); + "file cache name: %s", c->file.name.data); - /* TODO: look open files cache */ - - return ngx_http_cache_open_file(ctx, 0); + return ngx_http_file_cache_open(r->cache); } -int ngx_http_cache_open_file(ngx_http_cache_ctx_t *ctx, ngx_file_uniq_t uniq) +ngx_int_t ngx_http_file_cache_open(ngx_http_cache_t *c) { ssize_t n; ngx_err_t err; ngx_http_cache_header_t *h; - ctx->file.fd = ngx_open_file(ctx->file.name.data, - NGX_FILE_RDONLY, NGX_FILE_OPEN); + c->file.fd = ngx_open_file(c->file.name.data, + NGX_FILE_RDONLY, NGX_FILE_OPEN); - if (ctx->file.fd == NGX_INVALID_FILE) { + if (c->file.fd == NGX_INVALID_FILE) { err = ngx_errno; if (err == NGX_ENOENT || err == NGX_ENOTDIR) { return NGX_DECLINED; } - ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno, - ngx_open_file_n " \"%s\" failed", ctx->file.name.data); + ngx_log_error(NGX_LOG_CRIT, c->log, ngx_errno, + ngx_open_file_n " \"%s\" failed", c->file.name.data); return NGX_ERROR; } - if (uniq) { - if (ngx_fd_info(ctx->file.fd, &ctx->file.info) == NGX_FILE_ERROR) { - ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno, - ngx_fd_info_n " \"%s\" failed", ctx->file.name.data); + if (c->uniq) { + if (ngx_fd_info(c->file.fd, &c->file.info) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_CRIT, c->log, ngx_errno, + ngx_fd_info_n " \"%s\" failed", c->file.name.data); return NGX_ERROR; } - if (ngx_file_uniq(&ctx->file.info) == uniq) { - if (ngx_close_file(ctx->file.fd) == NGX_FILE_ERROR) { - ngx_log_error(NGX_LOG_ALERT, ctx->log, ngx_errno, + if (ngx_file_uniq(&c->file.info) == c->uniq) { + if (ngx_close_file(c->file.fd) == NGX_FILE_ERROR) { + ngx_log_error(NGX_LOG_ALERT, c->log, ngx_errno, ngx_close_file_n " \"%s\" failed", - ctx->file.name.data); + c->file.name.data); } return NGX_HTTP_CACHE_THE_SAME; } } - n = ngx_read_file(&ctx->file, ctx->buf->pos, - ctx->buf->end - ctx->buf->last, 0); + n = ngx_read_file(&c->file, c->buf->pos, c->buf->end - c->buf->last, 0); if (n == NGX_ERROR || n == NGX_AGAIN) { return n; } - if (n <= ctx->header_size) { - ngx_log_error(NGX_LOG_CRIT, ctx->log, 0, - "cache file \"%s\" is too small", ctx->file.name.data); + if (n <= c->header_size) { + ngx_log_error(NGX_LOG_CRIT, c->log, 0, + "cache file \"%s\" is too small", c->file.name.data); return NGX_ERROR; } - h = (ngx_http_cache_header_t *) ctx->buf->pos; - ctx->expires = h->expires; - ctx->last_modified= h->last_modified; - ctx->date = h->date; - ctx->length = h->length; + h = (ngx_http_cache_header_t *) c->buf->pos; + c->expires = h->expires; + c->last_modified= h->last_modified; + c->date = h->date; + c->length = h->length; - if (h->key_len > (size_t) (ctx->buf->end - ctx->buf->pos)) { - ngx_log_error(NGX_LOG_ALERT, ctx->log, 0, + if (h->key_len > (size_t) (c->buf->end - c->buf->pos)) { + ngx_log_error(NGX_LOG_ALERT, c->log, 0, "cache file \"%s\" is probably invalid", - ctx->file.name.data); + c->file.name.data); return NGX_DECLINED; } - if (ctx->key.len - && (h->key_len != ctx->key.len - || ngx_strncmp(h->key, ctx->key.data, h->key_len) != 0)) - { +#if 0 + + /* TODO */ + + if (c->key_len && h->key_len != c->key_len) { + + ngx_strncmp(h->key, c->key_data, h->key_len) != 0)) + h->key[h->key_len] = '\0'; - ngx_log_error(NGX_LOG_ALERT, ctx->log, 0, + ngx_log_error(NGX_LOG_ALERT, c->log, 0, "md5 collision: \"%s\" and \"%s\"", - h->key, ctx->key.data); + h->key, c->key.data); return NGX_DECLINED; } - ctx->buf->last += n; +#endif - if (ctx->expires < ngx_time()) { + c->buf->last += n; - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ctx->log, 0, + if (c->expires < ngx_time()) { + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http file cache expired"); - return NGX_HTTP_CACHE_STALE; } /* TODO: NGX_HTTP_CACHE_AGED */ + /* STUB */ return NGX_DECLINED; + return NGX_OK; } +#if 0 + + int ngx_http_cache_update_file(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx, ngx_str_t *temp_file) { @@ -196,39 +209,45 @@ int ngx_http_cache_update_file(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx, } -int ngx_garbage_collector_http_cache_handler(ngx_gc_t *gc, ngx_str_t *name, - ngx_dir_t *dir) +#endif + + +ngx_int_t ngx_http_cache_cleaner_handler(ngx_gc_t *gc, ngx_str_t *name, + ngx_dir_t *dir) { - int rc; - char data[sizeof(ngx_http_cache_header_t)]; - ngx_hunk_t buf; - ngx_http_cache_ctx_t ctx; + int rc; + ngx_buf_t buf; + ngx_http_cache_t c; + u_char data[sizeof(ngx_http_cache_header_t)]; - ctx.file.fd = NGX_INVALID_FILE; - ctx.file.name = *name; - ctx.file.log = gc->log; + ngx_memzero(&c, sizeof(ngx_http_cache_t)); - ctx.header_size = sizeof(ngx_http_cache_header_t); - ctx.buf = &buf; - ctx.log = gc->log; - ctx.key.len = 0; + c.file.fd = NGX_INVALID_FILE; + c.file.name = *name; + c.file.log = gc->log; - buf.type = NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP; + c.header_size = sizeof(ngx_http_cache_header_t); + c.buf = &buf; + c.log = gc->log; + c.key_len = 0; + + buf.memory = 1; + buf.temporary = 1; buf.pos = data; buf.last = data; buf.start = data; buf.end = data + sizeof(ngx_http_cache_header_t); - rc = ngx_http_cache_open_file(&ctx, 0); + rc = ngx_http_file_cache_open(&c); /* TODO: NGX_AGAIN */ - if (rc != NGX_ERROR && rc != NGX_DECLINED && rc != NGX_HTTP_CACHE_STALE) { + if (rc != NGX_ERROR&& rc != NGX_DECLINED && rc != NGX_HTTP_CACHE_STALE) { return NGX_OK; } if (ngx_delete_file(name->data) == NGX_FILE_ERROR) { - ngx_log_error(NGX_LOG_CRIT, gc->log, ngx_errno, + ngx_log_error(NGX_LOG_CRIT, c.log, ngx_errno, ngx_delete_file_n " \"%s\" failed", name->data); return NGX_ERROR; } @@ -238,5 +257,3 @@ int ngx_garbage_collector_http_cache_handler(ngx_gc_t *gc, ngx_str_t *name, return NGX_OK; } - -#endif diff --git a/src/http/ngx_http_header_filter.c b/src/http/ngx_http_header_filter.c index 31fa82635..3610b1e3a 100644 --- a/src/http/ngx_http_header_filter.c +++ b/src/http/ngx_http_header_filter.c @@ -253,7 +253,7 @@ static ngx_int_t ngx_http_header_filter(ngx_http_request_t *r) */ if (clcf->keepalive_header) { - len += sizeof("Keep-Alive: timeout=") - 1 + TIME_T_LEN + 2; + len += sizeof("Keep-Alive: timeout=") - 1 + NGX_TIME_T_LEN + 2; } } else { diff --git a/src/http/ngx_http_log_handler.c b/src/http/ngx_http_log_handler.c index 71cbb2953..6702c4f77 100644 --- a/src/http/ngx_http_log_handler.c +++ b/src/http/ngx_http_log_handler.c @@ -115,12 +115,12 @@ ngx_http_log_op_name_t ngx_http_log_fmt_ops[] = { { ngx_string("pipe"), 1, ngx_http_log_pipe }, { ngx_string("time"), sizeof("28/Sep/1970:12:00:00") - 1, ngx_http_log_time }, - { ngx_string("msec"), TIME_T_LEN + 4, ngx_http_log_msec }, + { ngx_string("msec"), NGX_TIME_T_LEN + 4, ngx_http_log_msec }, { ngx_string("request"), 0, ngx_http_log_request }, { ngx_string("status"), 3, ngx_http_log_status }, { ngx_string("length"), NGX_OFF_T_LEN, ngx_http_log_length }, { ngx_string("apache_length"), NGX_OFF_T_LEN, ngx_http_log_apache_length }, - { ngx_string("request_length"), NGX_OFF_T_LEN, + { ngx_string("request_length"), NGX_SIZE_T_LEN, ngx_http_log_request_length }, { ngx_string("i"), NGX_HTTP_LOG_ARG, ngx_http_log_header_in }, { ngx_string("o"), NGX_HTTP_LOG_ARG, ngx_http_log_header_out }, @@ -290,7 +290,7 @@ static u_char *ngx_http_log_apache_length(ngx_http_request_t *r, u_char *buf, static u_char *ngx_http_log_request_length(ngx_http_request_t *r, u_char *buf, uintptr_t data) { - return ngx_sprintf(buf, "%O", r->request_length); + return ngx_sprintf(buf, "%z", r->request_length); } diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c index b2c35169e..b1b84fe6f 100644 --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -20,6 +20,7 @@ static ssize_t ngx_http_read_request_header(ngx_http_request_t *r); static ngx_int_t ngx_http_alloc_large_header_buffer(ngx_http_request_t *r, ngx_uint_t request_line); static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r); +static ngx_int_t ngx_http_find_virtual_server(ngx_http_request_t *r); static void ngx_http_set_write_handler(ngx_http_request_t *r); @@ -246,7 +247,7 @@ static void ngx_http_init_request(ngx_event_t *rev) } #if (NGX_STAT_STUB) - r->stat_reading = 1; + (*ngx_stat_reading)--; #endif c->data = r; @@ -310,7 +311,7 @@ static void ngx_http_init_request(ngx_event_t *rev) r->in_addr = in_addr[0].addr; } - r->virtual_names = &in_addr[i].names; + r->virtual_names = &in_addr[i]; /* the default server configuration for the address:port */ cscf = in_addr[i].core_srv_conf; @@ -334,6 +335,8 @@ static void ngx_http_init_request(ngx_event_t *rev) return; } + rev->event_handler = ngx_http_ssl_handshake; + /* * The majority of browsers do not send the "close notify" alert. * Among them are MSIE, Mozilla, Netscape 4, Konqueror, and Links. @@ -343,7 +346,6 @@ static void ngx_http_init_request(ngx_event_t *rev) */ c->ssl->no_rcv_shut = 1; - rev->event_handler = ngx_http_ssl_handshake; } r->filter_need_in_memory = 1; @@ -416,6 +418,8 @@ static void ngx_http_init_request(ngx_event_t *rev) r->http_state = NGX_HTTP_READING_REQUEST_STATE; #if (NGX_STAT_STUB) + (*ngx_stat_reading)++; + r->stat_reading = 1; (*ngx_stat_requests)++; #endif @@ -1054,81 +1058,23 @@ static ngx_int_t ngx_http_alloc_large_header_buffer(ngx_http_request_t *r, static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r) { - u_char *ua, *user_agent; - size_t len; - ngx_uint_t i; - ngx_http_server_name_t *name; - ngx_http_core_srv_conf_t *cscf; - ngx_http_core_loc_conf_t *clcf; + u_char *ua, *user_agent, ch; + size_t len; if (r->headers_in.host) { for (len = 0; len < r->headers_in.host->value.len; len++) { - if (r->headers_in.host->value.data[len] == ':') { - break; - } - } - r->headers_in.host_name_len = len; - - /* find the name based server configuration */ - - name = r->virtual_names->elts; - for (i = 0; i < r->virtual_names->nelts; i++) { - - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, - "server name: %V", &name[i].name); - - if (name[i].wildcard) { - if (r->headers_in.host_name_len <= name[i].name.len) { - continue; - } - - if (ngx_rstrncasecmp(r->headers_in.host->value.data, - name[i].name.data, - name[i].name.len) == 0) - { - continue; - } - - } else { - if (r->headers_in.host_name_len != name[i].name.len) { - continue; - } - - if (ngx_strncasecmp(r->headers_in.host->value.data, - name[i].name.data, - name[i].name.len) != 0) - { - continue; - } - } - - r->srv_conf = name[i].core_srv_conf->ctx->srv_conf; - r->loc_conf = name[i].core_srv_conf->ctx->loc_conf; - - if (name[i].wildcard) { - r->server_name.len = r->headers_in.host_name_len; - r->server_name.data = r->headers_in.host->value.data; - - } else { - r->server_name = name[i].name; - } + ch = r->headers_in.host->value.data[len]; - 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 (ch == ':') { + break; } - break; + r->headers_in.host->value.data[len] = ngx_tolower(ch); } + r->headers_in.host_name_len = len; - if (i == r->virtual_names->nelts) { - cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); - - if (cscf->restrict_host_names != NGX_HTTP_RESTRICT_HOST_OFF) { - return NGX_HTTP_PARSE_INVALID_HOST; - } + if (ngx_http_find_virtual_server(r) != NGX_OK) { + return NGX_HTTP_PARSE_INVALID_HOST; } } else { @@ -1225,11 +1171,117 @@ static ngx_int_t ngx_http_process_request_header(ngx_http_request_t *r) } +static ngx_int_t ngx_http_find_virtual_server(ngx_http_request_t *r) +{ + ngx_int_t rc; + ngx_uint_t i, n, key, found; + ngx_http_server_name_t *name; + ngx_http_core_main_conf_t *cmcf; + ngx_http_core_srv_conf_t *cscf; + ngx_http_core_loc_conf_t *clcf; + + if (r->virtual_names->hash) { + cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); + + ngx_http_server_names_hash_key(key, + r->headers_in.host->value.data, + r->headers_in.host_name_len, + cmcf->server_names_hash); + + name = r->virtual_names->hash[key].elts; + n = r->virtual_names->hash[key].nelts; + + } else { + name = r->virtual_names->names.elts; + n = r->virtual_names->names.nelts; + } + + found = 0; + + for (i = 0; i < n; i++) { + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "server name: %V", &name[i].name); + + if (r->headers_in.host_name_len != name[i].name.len) { + continue; + } + + rc = ngx_strncmp(r->headers_in.host->value.data, + name[i].name.data, name[i].name.len); + + if (rc == 0) { + r->server_name = name[i].name; + + found = 1; + break; + } + + if (rc < 0) { + /* the server names are lexicographically sorted */ + break; + } + } + + if (!found && r->virtual_names->wildcards.nelts) { + + name = r->virtual_names->wildcards.elts; + for (i = 0; i < r->virtual_names->wildcards.nelts; i++) { + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "server name: %V", &name[i].name); + + if (r->headers_in.host_name_len <= name[i].name.len) { + continue; + } + + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "server name: %s", + r->headers_in.host->value.data + + (r->headers_in.host_name_len - name[i].name.len)); + + if (ngx_strncmp(r->headers_in.host->value.data + + (r->headers_in.host_name_len - name[i].name.len), + name[i].name.data, name[i].name.len) == 0) + { + r->server_name.len = r->headers_in.host_name_len; + r->server_name.data = r->headers_in.host->value.data; + + found = 1; + break; + } + } + } + + if (found) { + r->srv_conf = name[i].core_srv_conf->ctx->srv_conf; + r->loc_conf = name[i].core_srv_conf->ctx->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; + } + + return NGX_OK; + } + + cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module); + + if (cscf->restrict_host_names != NGX_HTTP_RESTRICT_HOST_OFF) { + return NGX_ERROR; + } + + return NGX_OK; +} + + void ngx_http_finalize_request(ngx_http_request_t *r, int rc) { ngx_http_core_loc_conf_t *clcf; - /* r can be already destroyed when rc == NGX_DONE */ + /* r may be already destroyed when rc == NGX_DONE */ if (rc == NGX_DONE || r->main) { return; @@ -1587,6 +1639,7 @@ static void ngx_http_set_keepalive(ngx_http_request_t *r) cscf->large_client_header_buffers.num * sizeof(ngx_buf_t *)); if (hc->free == NULL) { + ngx_http_close_request(r, 0); ngx_http_close_connection(c); return; } @@ -1604,10 +1657,11 @@ static void ngx_http_set_keepalive(ngx_http_request_t *r) } } + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + ngx_http_close_request(r, 0); c->data = hc; - clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); ngx_add_timer(rev, clcf->keepalive_timeout); if (ngx_handle_level_read_event(rev) == NGX_ERROR) { @@ -1877,12 +1931,14 @@ static void ngx_http_set_lingering_close(ngx_http_request_t *r) if (ngx_del_event(wev, NGX_WRITE_EVENT, NGX_DISABLE_EVENT) == NGX_ERROR) { + ngx_http_close_request(r, 0); ngx_http_close_connection(c); return; } } else if (ngx_event_flags & NGX_USE_LEVEL_EVENT) { if (ngx_del_event(wev, NGX_WRITE_EVENT, 0) == NGX_ERROR) { + ngx_http_close_request(r, 0); ngx_http_close_connection(c); return; } @@ -1945,6 +2001,7 @@ static void ngx_http_lingering_close_handler(ngx_event_t *rev) } while (rev->ready); if (ngx_handle_level_read_event(rev) == NGX_ERROR) { + ngx_http_close_request(r, 0); ngx_http_close_connection(c); return; } @@ -1958,8 +2015,6 @@ static void ngx_http_lingering_close_handler(ngx_event_t *rev) } ngx_add_timer(rev, timer); - - return; } @@ -2093,8 +2148,6 @@ void ngx_http_close_request(ngx_http_request_t *r, int error) r->request_line.len = 0; ngx_destroy_pool(r->pool); - - return; } diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h index bdc9cb2e5..eef929271 100644 --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -254,7 +254,7 @@ struct ngx_http_request_s { void **srv_conf; void **loc_conf; - ngx_http_cache_entry_t *cache; + ngx_http_cache_t *cache; ngx_file_t file; @@ -287,7 +287,7 @@ struct ngx_http_request_s { ngx_uint_t port; ngx_str_t *port_text; /* ":80" */ ngx_str_t server_name; - ngx_array_t *virtual_names; + ngx_http_in_addr_t *virtual_names; ngx_uint_t phase; ngx_int_t phase_handler; diff --git a/src/http/ngx_http_special_response.c b/src/http/ngx_http_special_response.c index 1af8746e5..5702a855a 100644 --- a/src/http/ngx_http_special_response.c +++ b/src/http/ngx_http_special_response.c @@ -232,15 +232,21 @@ ngx_int_t ngx_http_special_response_handler(ngx_http_request_t *r, int error) clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); if (r->err_ctx == NULL && clcf->error_pages) { + err_page = clcf->error_pages->elts; + for (i = 0; i < clcf->error_pages->nelts; i++) { + if (err_page[i].status == error) { + if (err_page[i].overwrite) { r->err_status = err_page[i].overwrite; } else { r->err_status = error; } + r->err_ctx = r->ctx; + return ngx_http_internal_redirect(r, &err_page[i].uri, NULL); } } |
