Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nginx/nginx.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/http/ngx_http_core_module.c')
-rw-r--r--src/http/ngx_http_core_module.c205
1 files changed, 134 insertions, 71 deletions
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index c100bee75..e42023b1f 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -164,6 +164,20 @@ static ngx_command_t ngx_http_core_commands[] = {
0,
NULL },
+ { ngx_string("types_hash_max_size"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_num_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_core_loc_conf_t, types_hash_max_size),
+ NULL },
+
+ { ngx_string("types_hash_bucket_size"),
+ NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+ ngx_conf_set_num_slot,
+ NGX_HTTP_LOC_CONF_OFFSET,
+ offsetof(ngx_http_core_loc_conf_t, types_hash_bucket_size),
+ NULL },
+
{ ngx_string("types"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF
|NGX_CONF_BLOCK|NGX_CONF_NOARGS,
@@ -849,9 +863,8 @@ ngx_int_t
ngx_http_set_content_type(ngx_http_request_t *r)
{
u_char c, *p, *exten;
- uint32_t key;
+ ngx_str_t *type;
ngx_uint_t i;
- ngx_http_type_t *type;
ngx_http_core_loc_conf_t *clcf;
clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
@@ -876,11 +889,7 @@ ngx_http_set_content_type(ngx_http_request_t *r)
for (i = 0; i < r->exten.len; i++) {
c = r->exten.data[i];
- if (c >= 'A' && c <= 'Z') {
- *p++ = (u_char) (c | 0x20);
- } else {
- *p++ = c;
- }
+ *p++ = ngx_tolower(c);
}
r->exten.data = exten;
@@ -889,26 +898,17 @@ ngx_http_set_content_type(ngx_http_request_t *r)
r->low_case_exten = 1;
}
- ngx_http_types_hash_key(key, r->exten);
-
- type = clcf->types[key].elts;
- for (i = 0; i < clcf->types[key].nelts; i++) {
- if (r->exten.len != type[i].exten.len) {
- continue;
- }
+ type = ngx_hash_find(&clcf->types_hash,
+ ngx_hash_key(r->exten.data, r->exten.len),
+ r->exten.data, r->exten.len);
- if (ngx_memcmp(r->exten.data, type[i].exten.data, r->exten.len)
- == 0)
- {
- r->headers_out.content_type = type[i].type;
- break;
- }
+ if (type) {
+ r->headers_out.content_type = *type;
+ return NGX_OK;
}
}
- if (r->headers_out.content_type.len == 0) {
- r->headers_out.content_type= clcf->default_type;
- }
+ r->headers_out.content_type = clcf->default_type;
return NGX_OK;
}
@@ -1636,39 +1636,55 @@ ngx_http_core_type(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
{
ngx_http_core_loc_conf_t *lcf = conf;
- uint32_t key;
- ngx_uint_t i;
- ngx_str_t *value;
- ngx_http_type_t *type;
+ ngx_str_t *value, *content_type, *old;
+ ngx_uint_t i, n;
+ ngx_hash_key_t *type;
if (lcf->types == NULL) {
- lcf->types = ngx_palloc(cf->pool, NGX_HTTP_TYPES_HASH_PRIME
- * sizeof(ngx_array_t));
+ lcf->types = ngx_array_create(cf->pool, 64, sizeof(ngx_hash_key_t));
if (lcf->types == NULL) {
return NGX_CONF_ERROR;
}
+ }
- for (i = 0; i < NGX_HTTP_TYPES_HASH_PRIME; i++) {
- if (ngx_array_init(&lcf->types[i], cf->pool, 4,
- sizeof(ngx_http_type_t)) == NGX_ERROR)
- {
- return NGX_CONF_ERROR;
- }
- }
+ content_type = ngx_palloc(cf->pool, sizeof(ngx_str_t));
+ if (content_type == NULL) {
+ return NGX_CONF_ERROR;
}
value = cf->args->elts;
+ *content_type = value[0];
for (i = 1; i < cf->args->nelts; i++) {
- ngx_http_types_hash_key(key, value[i]);
- type = ngx_array_push(&lcf->types[key]);
+ for (n = 0; n < value[i].len; n++) {
+ value[i].data[n] = ngx_tolower(value[i].data[n]);
+ }
+
+ type = lcf->types->elts;
+ for (n = 0; n < lcf->types->nelts; n++) {
+ if (ngx_strcmp(value[i].data, type[n].key.data) == 0) {
+ old = type[n].value;
+ type[n].value = content_type;
+
+ ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
+ "duplicate extention \"%V\", "
+ "content type: \"%V\", "
+ "old content type: \"%V\"",
+ &value[i], content_type, old);
+ continue;
+ }
+ }
+
+
+ type = ngx_array_push(lcf->types);
if (type == NULL) {
return NGX_CONF_ERROR;
}
- type->exten = value[i];
- type->type = value[0];
+ type->key = value[i];
+ type->key_hash = ngx_hash_key(value[i].data, value[i].len);
+ type->value = content_type;
}
return NGX_CONF_OK;
@@ -1905,29 +1921,34 @@ ngx_http_core_create_loc_conf(ngx_conf_t *cf)
lcf->port_in_redirect = NGX_CONF_UNSET;
lcf->msie_padding = NGX_CONF_UNSET;
lcf->log_not_found = NGX_CONF_UNSET;
+ lcf->types_hash_max_size = NGX_CONF_UNSET_UINT;
+ lcf->types_hash_bucket_size = NGX_CONF_UNSET_UINT;
return lcf;
}
-static ngx_http_type_t ngx_http_core_default_types[] = {
- { ngx_string("html"), ngx_string("text/html") },
- { ngx_string("gif"), ngx_string("image/gif") },
- { ngx_string("jpg"), ngx_string("image/jpeg") },
- { ngx_null_string, ngx_null_string }
+static ngx_str_t ngx_http_core_text_html_type = ngx_string("text/html");
+static ngx_str_t ngx_http_core_image_gif_type = ngx_string("image/gif");
+static ngx_str_t ngx_http_core_image_jpeg_type = ngx_string("image/jpeg");
+
+static ngx_hash_key_t ngx_http_core_default_types[] = {
+ { ngx_string("html"), 0, &ngx_http_core_text_html_type },
+ { ngx_string("gif"), 0, &ngx_http_core_image_gif_type },
+ { ngx_string("jpg"), 0, &ngx_http_core_image_jpeg_type },
+ { ngx_null_string, 0, NULL }
};
static char *
-ngx_http_core_merge_loc_conf(ngx_conf_t *cf,
- void *parent, void *child)
+ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
{
ngx_http_core_loc_conf_t *prev = parent;
ngx_http_core_loc_conf_t *conf = child;
- uint32_t key;
ngx_uint_t i;
- ngx_http_type_t *type;
+ ngx_hash_key_t *type;
+ ngx_hash_init_t types_hash;
ngx_conf_merge_str_value(conf->root, prev->root, "html");
@@ -1939,36 +1960,77 @@ ngx_http_core_merge_loc_conf(ngx_conf_t *cf,
conf->post_action = prev->post_action;
}
+ ngx_conf_merge_unsigned_value(conf->types_hash_max_size,
+ prev->types_hash_max_size, 512);
+
+ ngx_conf_merge_unsigned_value(conf->types_hash_bucket_size,
+ prev->types_hash_bucket_size,
+ ngx_cacheline_size);
+
+ conf->types_hash_bucket_size = ngx_align(conf->types_hash_bucket_size,
+ ngx_cacheline_size);
+
+ /*
+ * the special handling the "types" directive in the "http" section
+ * to inherit the http's conf->types_hash to all servers
+ */
+
+ if (prev->types && prev->types_hash.buckets == NULL) {
+
+ types_hash.hash = &prev->types_hash;
+ types_hash.key = ngx_hash_key_lc;
+ types_hash.max_size = conf->types_hash_max_size;
+ types_hash.bucket_size = conf->types_hash_bucket_size;
+ types_hash.name = "mime_types";
+ types_hash.pool = cf->pool;
+ types_hash.temp_pool = NULL;
+
+ if (ngx_hash_init(&types_hash, prev->types->elts, prev->types->nelts)
+ != NGX_OK)
+ {
+ return NGX_CONF_ERROR;
+ }
+ }
+
if (conf->types == NULL) {
- if (prev->types) {
- conf->types = prev->types;
+ conf->types = prev->types;
+ conf->types_hash = prev->types_hash;
+ }
- } else {
- conf->types = ngx_palloc(cf->pool, NGX_HTTP_TYPES_HASH_PRIME
- * sizeof(ngx_array_t));
- if (conf->types == NULL) {
+ if (conf->types == NULL) {
+ conf->types = ngx_array_create(cf->pool, 4, sizeof(ngx_hash_key_t));
+ if (conf->types == NULL) {
+ return NGX_CONF_ERROR;
+ }
+
+ for (i = 0; ngx_http_core_default_types[i].key.len; i++) {
+ type = ngx_array_push(conf->types);
+ if (type == NULL) {
return NGX_CONF_ERROR;
}
- for (i = 0; i < NGX_HTTP_TYPES_HASH_PRIME; i++) {
- if (ngx_array_init(&conf->types[i], cf->pool, 4,
- sizeof(ngx_http_type_t)) == NGX_ERROR)
- {
- return NGX_CONF_ERROR;
- }
- }
+ type->key = ngx_http_core_default_types[i].key;
+ type->key_hash =
+ ngx_hash_key_lc(ngx_http_core_default_types[i].key.data,
+ ngx_http_core_default_types[i].key.len);
+ type->value = ngx_http_core_default_types[i].value;
+ }
+ }
- for (i = 0; ngx_http_core_default_types[i].exten.len; i++) {
- ngx_http_types_hash_key(key,
- ngx_http_core_default_types[i].exten);
+ if (conf->types_hash.buckets == NULL) {
- type = ngx_array_push(&conf->types[key]);
- if (type == NULL) {
- return NGX_CONF_ERROR;
- }
+ types_hash.hash = &conf->types_hash;
+ types_hash.key = ngx_hash_key_lc;
+ types_hash.max_size = conf->types_hash_max_size;
+ types_hash.bucket_size = conf->types_hash_bucket_size;
+ types_hash.name = "mime_types";
+ types_hash.pool = cf->pool;
+ types_hash.temp_pool = NULL;
- *type = ngx_http_core_default_types[i];
- }
+ if (ngx_hash_init(&types_hash, conf->types->elts, conf->types->nelts)
+ != NGX_OK)
+ {
+ return NGX_CONF_ERROR;
}
}
@@ -2115,6 +2177,7 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
if (ngx_strcmp(value[2].data, "default") == 0) {
ls->conf.default_server = 1;
n = 3;
+
} else {
n = 2;
}