From 03a9d6b399479122a07cd251f451806c201929eb Mon Sep 17 00:00:00 2001 From: Igor Sysoev Date: Tue, 12 Aug 2008 13:11:36 +0000 Subject: [PATCH] use hash in gzip_types, ssi_types, and sub_filter_types --- .../modules/ngx_http_gzip_filter_module.c | 109 +++------------- src/http/modules/ngx_http_ssi_filter_module.c | 113 +++-------------- src/http/modules/ngx_http_sub_filter_module.c | 116 +++--------------- src/http/ngx_http.c | 6 + src/http/ngx_http.h | 2 + 5 files changed, 57 insertions(+), 289 deletions(-) diff --git a/src/http/modules/ngx_http_gzip_filter_module.c b/src/http/modules/ngx_http_gzip_filter_module.c index 1ff45ea76..8c307aec1 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 @@ typedef struct { 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 @@ typedef struct { 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 ngx_int_t ngx_http_gzip_filter_init(ngx_conf_t *cf); 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 @@ static ngx_command_t ngx_http_gzip_filter_commands[] = { { 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_http_output_body_filter_pt ngx_http_next_body_filter; 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 @@ ngx_http_gzip_header_filter(ngx_http_request_t *r) && 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 @@ ngx_http_gzip_create_conf(ngx_conf_t *cf) * 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_merge_conf(ngx_conf_t *cf, void *parent, void *child) 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_http_gzip_merge_conf(ngx_conf_t *cf, void *parent, void *child) 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; @@ -897,56 +868,6 @@ ngx_http_gzip_filter_init(ngx_conf_t *cf) } -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) { diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c index 5de41f325..04ab04200 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 @@ typedef struct { 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_endblock(ngx_http_request_t *r, 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 @@ static ngx_command_t ngx_http_ssi_filter_commands[] = { { 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_http_variable_t ngx_http_ssi_vars[] = { 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 @@ ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r, } -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 @@ ngx_http_ssi_create_loc_conf(ngx_conf_t *cf) /* * 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_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) 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_http_ssi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child) 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 62a8f0814..f40a3c654 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 @@ typedef struct { 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 ngx_int_t ngx_http_sub_parse(ngx_http_request_t *r, 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 @@ static ngx_command_t ngx_http_sub_filter_commands[] = { { 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_http_output_body_filter_pt ngx_http_next_body_filter; 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 @@ 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) -{ - 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 @@ ngx_http_sub_create_conf(ngx_conf_t *cf) /* * 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_merge_conf(ngx_conf_t *cf, void *parent, void *child) 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 @@ ngx_http_sub_merge_conf(ngx_conf_t *cf, void *parent, void *child) 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 1a5db19bf..024170f45 100644 --- a/src/http/ngx_http.c +++ b/src/http/ngx_http.c @@ -59,6 +59,12 @@ ngx_int_t (*ngx_http_top_header_filter) (ngx_http_request_t *r); 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 180da8194..afbc69de9 100644 --- a/src/http/ngx_http.h +++ b/src/http/ngx_http.h @@ -117,6 +117,8 @@ char *ngx_http_set_default_types(ngx_conf_t *cf, ngx_array_t **types, 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;