use hash in gzip_types, ssi_types, and sub_filter_types
diff --git a/src/http/modules/ngx_http_gzip_filter_module.c b/src/http/modules/ngx_http_gzip_filter_module.c
index 1ff45ea..8c307ae 100644
--- a/src/http/modules/ngx_http_gzip_filter_module.c
+++ b/src/http/modules/ngx_http_gzip_filter_module.c
@@ -15,7 +15,7 @@
ngx_flag_t enable;
ngx_flag_t no_buffer;
- ngx_array_t *types; /* array of ngx_str_t */
+ ngx_hash_t types;
ngx_bufs_t bufs;
@@ -23,6 +23,8 @@
size_t wbits;
size_t memlevel;
ssize_t min_length;
+
+ ngx_array_t *types_keys;
} ngx_http_gzip_conf_t;
@@ -68,8 +70,6 @@
static void *ngx_http_gzip_create_conf(ngx_conf_t *cf);
static char *ngx_http_gzip_merge_conf(ngx_conf_t *cf,
void *parent, void *child);
-static char *ngx_http_gzip_types(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
static char *ngx_http_gzip_window(ngx_conf_t *cf, void *post, void *data);
static char *ngx_http_gzip_hash(ngx_conf_t *cf, void *post, void *data);
@@ -101,10 +101,10 @@
{ ngx_string("gzip_types"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_http_gzip_types,
+ ngx_http_types_slot,
NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
+ offsetof(ngx_http_gzip_conf_t, types_keys),
+ &ngx_http_html_default_types[0] },
{ ngx_string("gzip_comp_level"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
@@ -204,8 +204,6 @@
static ngx_int_t
ngx_http_gzip_header_filter(ngx_http_request_t *r)
{
- ngx_str_t *type;
- ngx_uint_t i;
ngx_table_elt_t *h;
ngx_http_gzip_ctx_t *ctx;
ngx_http_gzip_conf_t *conf;
@@ -217,30 +215,16 @@
&& r->headers_out.status != NGX_HTTP_FORBIDDEN
&& r->headers_out.status != NGX_HTTP_NOT_FOUND)
|| r->header_only
- || r->headers_out.content_type.len == 0
|| (r->headers_out.content_encoding
&& r->headers_out.content_encoding->value.len)
|| (r->headers_out.content_length_n != -1
&& r->headers_out.content_length_n < conf->min_length)
+ || ngx_http_test_content_type(r, &conf->types) == NULL
|| ngx_http_gzip_ok(r) != NGX_OK)
{
return ngx_http_next_header_filter(r);
}
- type = conf->types->elts;
- for (i = 0; i < conf->types->nelts; i++) {
- if (r->headers_out.content_type.len >= type[i].len
- && ngx_strncasecmp(r->headers_out.content_type.data,
- type[i].data, type[i].len) == 0)
- {
- goto found;
- }
- }
-
- return ngx_http_next_header_filter(r);
-
-found:
-
ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_gzip_ctx_t));
if (ctx == NULL) {
return NGX_ERROR;
@@ -826,7 +810,8 @@
* set by ngx_pcalloc():
*
* conf->bufs.num = 0;
- * conf->types = NULL;
+ * conf->types = { NULL };
+ * conf->types_keys = NULL;
*/
conf->enable = NGX_CONF_UNSET;
@@ -847,8 +832,6 @@
ngx_http_gzip_conf_t *prev = parent;
ngx_http_gzip_conf_t *conf = child;
- ngx_str_t *type;
-
ngx_conf_merge_value(conf->enable, prev->enable, 0);
ngx_conf_merge_bufs_value(conf->bufs, prev->bufs, 4, ngx_pagesize);
@@ -860,24 +843,12 @@
ngx_conf_merge_value(conf->min_length, prev->min_length, 20);
ngx_conf_merge_value(conf->no_buffer, prev->no_buffer, 0);
- if (conf->types == NULL) {
- if (prev->types == NULL) {
- conf->types = ngx_array_create(cf->pool, 1, sizeof(ngx_str_t));
- if (conf->types == NULL) {
- return NGX_CONF_ERROR;
- }
-
- type = ngx_array_push(conf->types);
- if (type == NULL) {
- return NGX_CONF_ERROR;
- }
-
- type->len = sizeof("text/html") - 1;
- type->data = (u_char *) "text/html";
-
- } else {
- conf->types = prev->types;
- }
+ if (ngx_http_merge_types(cf, conf->types_keys, &conf->types,
+ prev->types_keys, &prev->types,
+ ngx_http_html_default_types)
+ != NGX_OK)
+ {
+ return NGX_CONF_ERROR;
}
return NGX_CONF_OK;
@@ -898,56 +869,6 @@
static char *
-ngx_http_gzip_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_gzip_conf_t *gcf = conf;
-
- ngx_str_t *value, *type;
- ngx_uint_t i;
-
- if (gcf->types == NULL) {
- gcf->types = ngx_array_create(cf->pool, 4, sizeof(ngx_str_t));
- if (gcf->types == NULL) {
- return NGX_CONF_ERROR;
- }
-
- type = ngx_array_push(gcf->types);
- if (type == NULL) {
- return NGX_CONF_ERROR;
- }
-
- type->len = sizeof("text/html") - 1;
- type->data = (u_char *) "text/html";
- }
-
- value = cf->args->elts;
-
- for (i = 1; i < cf->args->nelts; i++) {
-
- if (ngx_strcmp(value[i].data, "text/html") == 0) {
- continue;
- }
-
- type = ngx_array_push(gcf->types);
- if (type == NULL) {
- return NGX_CONF_ERROR;
- }
-
- type->len = value[i].len;
-
- type->data = ngx_pnalloc(cf->pool, type->len + 1);
- if (type->data == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ngx_cpystrn(type->data, value[i].data, type->len + 1);
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
ngx_http_gzip_window(ngx_conf_t *cf, void *post, void *data)
{
int *np = data;
diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c
index 5de41f3..04ab042 100644
--- a/src/http/modules/ngx_http_ssi_filter_module.c
+++ b/src/http/modules/ngx_http_ssi_filter_module.c
@@ -22,10 +22,12 @@
ngx_flag_t silent_errors;
ngx_flag_t ignore_recycled_buffers;
- ngx_array_t *types; /* array of ngx_str_t */
+ ngx_hash_t types;
size_t min_file_chunk;
size_t value_len;
+
+ ngx_array_t *types_keys;
} ngx_http_ssi_loc_conf_t;
@@ -102,8 +104,6 @@
static ngx_int_t ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r,
ngx_http_variable_value_t *v, uintptr_t gmt);
-static char *ngx_http_ssi_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
-
static ngx_int_t ngx_http_ssi_preconfiguration(ngx_conf_t *cf);
static void *ngx_http_ssi_create_main_conf(ngx_conf_t *cf);
static char *ngx_http_ssi_init_main_conf(ngx_conf_t *cf, void *conf);
@@ -153,10 +153,10 @@
{ ngx_string("ssi_types"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_http_ssi_types,
+ ngx_http_types_slot,
NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
+ offsetof(ngx_http_ssi_loc_conf_t, types_keys),
+ &ngx_http_html_default_types[0] },
ngx_null_command
};
@@ -316,36 +316,18 @@
static ngx_int_t
ngx_http_ssi_header_filter(ngx_http_request_t *r)
{
- ngx_uint_t i;
- ngx_str_t *type;
ngx_http_ssi_ctx_t *ctx;
ngx_http_ssi_loc_conf_t *slcf;
slcf = ngx_http_get_module_loc_conf(r, ngx_http_ssi_filter_module);
if (!slcf->enable
- || r->headers_out.content_type.len == 0
- || r->headers_out.content_length_n == 0)
+ || r->headers_out.content_length_n == 0
+ || ngx_http_test_content_type(r, &slcf->types) == NULL)
{
return ngx_http_next_header_filter(r);
}
-
- type = slcf->types->elts;
- for (i = 0; i < slcf->types->nelts; i++) {
- if (r->headers_out.content_type.len >= type[i].len
- && ngx_strncasecmp(r->headers_out.content_type.data,
- type[i].data, type[i].len) == 0)
- {
- goto found;
- }
- }
-
- return ngx_http_next_header_filter(r);
-
-
-found:
-
ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_ssi_ctx_t));
if (ctx == NULL) {
return NGX_ERROR;
@@ -2679,56 +2661,6 @@
}
-static char *
-ngx_http_ssi_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_ssi_loc_conf_t *slcf = conf;
-
- ngx_str_t *value, *type;
- ngx_uint_t i;
-
- if (slcf->types == NULL) {
- slcf->types = ngx_array_create(cf->pool, 4, sizeof(ngx_str_t));
- if (slcf->types == NULL) {
- return NGX_CONF_ERROR;
- }
-
- type = ngx_array_push(slcf->types);
- if (type == NULL) {
- return NGX_CONF_ERROR;
- }
-
- type->len = sizeof("text/html") - 1;
- type->data = (u_char *) "text/html";
- }
-
- value = cf->args->elts;
-
- for (i = 1; i < cf->args->nelts; i++) {
-
- if (ngx_strcmp(value[i].data, "text/html") == 0) {
- continue;
- }
-
- type = ngx_array_push(slcf->types);
- if (type == NULL) {
- return NGX_CONF_ERROR;
- }
-
- type->len = value[i].len;
-
- type->data = ngx_pnalloc(cf->pool, type->len + 1);
- if (type->data == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ngx_cpystrn(type->data, value[i].data, type->len + 1);
- }
-
- return NGX_CONF_OK;
-}
-
-
static ngx_int_t
ngx_http_ssi_preconfiguration(ngx_conf_t *cf)
{
@@ -2829,7 +2761,8 @@
/*
* set by ngx_pcalloc():
*
- * conf->types = NULL;
+ * conf->types = { NULL };
+ * conf->types_keys = NULL;
*/
slcf->enable = NGX_CONF_UNSET;
@@ -2849,8 +2782,6 @@
ngx_http_ssi_loc_conf_t *prev = parent;
ngx_http_ssi_loc_conf_t *conf = child;
- ngx_str_t *type;
-
ngx_conf_merge_value(conf->enable, prev->enable, 0);
ngx_conf_merge_value(conf->silent_errors, prev->silent_errors, 0);
ngx_conf_merge_value(conf->ignore_recycled_buffers,
@@ -2859,24 +2790,12 @@
ngx_conf_merge_size_value(conf->min_file_chunk, prev->min_file_chunk, 1024);
ngx_conf_merge_size_value(conf->value_len, prev->value_len, 256);
- if (conf->types == NULL) {
- if (prev->types == NULL) {
- conf->types = ngx_array_create(cf->pool, 1, sizeof(ngx_str_t));
- if (conf->types == NULL) {
- return NGX_CONF_ERROR;
- }
-
- type = ngx_array_push(conf->types);
- if (type == NULL) {
- return NGX_CONF_ERROR;
- }
-
- type->len = sizeof("text/html") - 1;
- type->data = (u_char *) "text/html";
-
- } else {
- conf->types = prev->types;
- }
+ if (ngx_http_merge_types(cf, conf->types_keys, &conf->types,
+ prev->types_keys, &prev->types,
+ ngx_http_html_default_types)
+ != NGX_OK)
+ {
+ return NGX_CONF_ERROR;
}
return NGX_CONF_OK;
diff --git a/src/http/modules/ngx_http_sub_filter_module.c b/src/http/modules/ngx_http_sub_filter_module.c
index 62a8f08..f40a3c6 100644
--- a/src/http/modules/ngx_http_sub_filter_module.c
+++ b/src/http/modules/ngx_http_sub_filter_module.c
@@ -13,12 +13,14 @@
ngx_str_t match;
ngx_str_t sub;
- ngx_array_t *types; /* array of ngx_str_t */
+ ngx_hash_t types;
ngx_array_t *sub_lengths;
ngx_array_t *sub_values;
ngx_flag_t once;
+
+ ngx_array_t *types_keys;
} ngx_http_sub_loc_conf_t;
@@ -60,7 +62,6 @@
static char * ngx_http_sub_filter(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
-static char *ngx_http_sub_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static void *ngx_http_sub_create_conf(ngx_conf_t *cf);
static char *ngx_http_sub_merge_conf(ngx_conf_t *cf,
void *parent, void *child);
@@ -78,10 +79,10 @@
{ ngx_string("sub_filter_types"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
- ngx_http_sub_types,
+ ngx_http_types_slot,
NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
+ offsetof(ngx_http_sub_loc_conf_t, types_keys),
+ &ngx_http_html_default_types[0] },
{ ngx_string("sub_filter_once"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
@@ -132,34 +133,18 @@
static ngx_int_t
ngx_http_sub_header_filter(ngx_http_request_t *r)
{
- ngx_str_t *type;
- ngx_uint_t i;
ngx_http_sub_ctx_t *ctx;
ngx_http_sub_loc_conf_t *slcf;
slcf = ngx_http_get_module_loc_conf(r, ngx_http_sub_filter_module);
if (slcf->match.len == 0
- || r->headers_out.content_type.len == 0
- || r->headers_out.content_length_n == 0)
+ || r->headers_out.content_length_n == 0
+ || ngx_http_test_content_type(r, &slcf->types) == NULL)
{
return ngx_http_next_header_filter(r);
}
- type = slcf->types->elts;
- for (i = 0; i < slcf->types->nelts; i++) {
- if (r->headers_out.content_type.len >= type[i].len
- && ngx_strncasecmp(r->headers_out.content_type.data,
- type[i].data, type[i].len) == 0)
- {
- goto found;
- }
- }
-
- return ngx_http_next_header_filter(r);
-
-found:
-
ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_sub_ctx_t));
if (ctx == NULL) {
return NGX_ERROR;
@@ -669,56 +654,6 @@
}
-static char *
-ngx_http_sub_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_sub_loc_conf_t *slcf = conf;
-
- ngx_str_t *value, *type;
- ngx_uint_t i;
-
- if (slcf->types == NULL) {
- slcf->types = ngx_array_create(cf->pool, 4, sizeof(ngx_str_t));
- if (slcf->types == NULL) {
- return NGX_CONF_ERROR;
- }
-
- type = ngx_array_push(slcf->types);
- if (type == NULL) {
- return NGX_CONF_ERROR;
- }
-
- type->len = sizeof("text/html") - 1;
- type->data = (u_char *) "text/html";
- }
-
- value = cf->args->elts;
-
- for (i = 1; i < cf->args->nelts; i++) {
-
- if (ngx_strcmp(value[i].data, "text/html") == 0) {
- continue;
- }
-
- type = ngx_array_push(slcf->types);
- if (type == NULL) {
- return NGX_CONF_ERROR;
- }
-
- type->len = value[i].len;
-
- type->data = ngx_pnalloc(cf->pool, type->len + 1);
- if (type->data == NULL) {
- return NGX_CONF_ERROR;
- }
-
- ngx_cpystrn(type->data, value[i].data, type->len + 1);
- }
-
- return NGX_CONF_OK;
-}
-
-
static void *
ngx_http_sub_create_conf(ngx_conf_t *cf)
{
@@ -732,13 +667,12 @@
/*
* set by ngx_pcalloc():
*
- * conf->match.len = 0;
- * conf->match.data = NULL;
- * conf->sub.len = 0;
- * conf->sub.data = NULL;
+ * conf->match = { 0, NULL };
+ * conf->sub = { 0, NULL };
* conf->sub_lengths = NULL;
* conf->sub_values = NULL;
- * conf->types = NULL;
+ * conf->types = { NULL };
+ * conf->types_keys = NULL;
*/
slcf->once = NGX_CONF_UNSET;
@@ -753,8 +687,6 @@
ngx_http_sub_loc_conf_t *prev = parent;
ngx_http_sub_loc_conf_t *conf = child;
- ngx_str_t *type;
-
ngx_conf_merge_value(conf->once, prev->once, 1);
ngx_conf_merge_str_value(conf->match, prev->match, "");
@@ -764,24 +696,12 @@
conf->sub_values = prev->sub_values;
}
- if (conf->types == NULL) {
- if (prev->types == NULL) {
- conf->types = ngx_array_create(cf->pool, 1, sizeof(ngx_str_t));
- if (conf->types == NULL) {
- return NGX_CONF_ERROR;
- }
-
- type = ngx_array_push(conf->types);
- if (type == NULL) {
- return NGX_CONF_ERROR;
- }
-
- type->len = sizeof("text/html") - 1;
- type->data = (u_char *) "text/html";
-
- } else {
- conf->types = prev->types;
- }
+ if (ngx_http_merge_types(cf, conf->types_keys, &conf->types,
+ prev->types_keys, &prev->types,
+ ngx_http_html_default_types)
+ != NGX_OK)
+ {
+ return NGX_CONF_ERROR;
}
return NGX_CONF_OK;
diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c
index 1a5db19..024170f 100644
--- a/src/http/ngx_http.c
+++ b/src/http/ngx_http.c
@@ -59,6 +59,12 @@
ngx_int_t (*ngx_http_top_body_filter) (ngx_http_request_t *r, ngx_chain_t *ch);
+ngx_str_t ngx_http_html_default_types[] = {
+ ngx_string("text/html"),
+ ngx_null_string
+};
+
+
static ngx_command_t ngx_http_commands[] = {
{ ngx_string("http"),
diff --git a/src/http/ngx_http.h b/src/http/ngx_http.h
index 180da81..afbc69d 100644
--- a/src/http/ngx_http.h
+++ b/src/http/ngx_http.h
@@ -117,6 +117,8 @@
extern ngx_module_t ngx_http_module;
+extern ngx_str_t ngx_http_html_default_types[];
+
extern ngx_http_output_header_filter_pt ngx_http_top_header_filter;
extern ngx_http_output_body_filter_pt ngx_http_top_body_filter;