Mercurial > hg > nginx
comparison src/http/modules/ngx_http_sub_filter_module.c @ 2166:723df5089c05
use hash in gzip_types, ssi_types, and sub_filter_types
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Tue, 12 Aug 2008 13:11:36 +0000 |
parents | 8c6521eedf84 |
children | cc13ff6d5c07 |
comparison
equal
deleted
inserted
replaced
2165:cbf6f2eb57ad | 2166:723df5089c05 |
---|---|
11 | 11 |
12 typedef struct { | 12 typedef struct { |
13 ngx_str_t match; | 13 ngx_str_t match; |
14 ngx_str_t sub; | 14 ngx_str_t sub; |
15 | 15 |
16 ngx_array_t *types; /* array of ngx_str_t */ | 16 ngx_hash_t types; |
17 | 17 |
18 ngx_array_t *sub_lengths; | 18 ngx_array_t *sub_lengths; |
19 ngx_array_t *sub_values; | 19 ngx_array_t *sub_values; |
20 | 20 |
21 ngx_flag_t once; | 21 ngx_flag_t once; |
22 | |
23 ngx_array_t *types_keys; | |
22 } ngx_http_sub_loc_conf_t; | 24 } ngx_http_sub_loc_conf_t; |
23 | 25 |
24 | 26 |
25 typedef enum { | 27 typedef enum { |
26 sub_start_state = 0, | 28 sub_start_state = 0, |
58 static ngx_int_t ngx_http_sub_parse(ngx_http_request_t *r, | 60 static ngx_int_t ngx_http_sub_parse(ngx_http_request_t *r, |
59 ngx_http_sub_ctx_t *ctx); | 61 ngx_http_sub_ctx_t *ctx); |
60 | 62 |
61 static char * ngx_http_sub_filter(ngx_conf_t *cf, ngx_command_t *cmd, | 63 static char * ngx_http_sub_filter(ngx_conf_t *cf, ngx_command_t *cmd, |
62 void *conf); | 64 void *conf); |
63 static char *ngx_http_sub_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); | |
64 static void *ngx_http_sub_create_conf(ngx_conf_t *cf); | 65 static void *ngx_http_sub_create_conf(ngx_conf_t *cf); |
65 static char *ngx_http_sub_merge_conf(ngx_conf_t *cf, | 66 static char *ngx_http_sub_merge_conf(ngx_conf_t *cf, |
66 void *parent, void *child); | 67 void *parent, void *child); |
67 static ngx_int_t ngx_http_sub_filter_init(ngx_conf_t *cf); | 68 static ngx_int_t ngx_http_sub_filter_init(ngx_conf_t *cf); |
68 | 69 |
76 0, | 77 0, |
77 NULL }, | 78 NULL }, |
78 | 79 |
79 { ngx_string("sub_filter_types"), | 80 { ngx_string("sub_filter_types"), |
80 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, | 81 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, |
81 ngx_http_sub_types, | 82 ngx_http_types_slot, |
82 NGX_HTTP_LOC_CONF_OFFSET, | 83 NGX_HTTP_LOC_CONF_OFFSET, |
83 0, | 84 offsetof(ngx_http_sub_loc_conf_t, types_keys), |
84 NULL }, | 85 &ngx_http_html_default_types[0] }, |
85 | 86 |
86 { ngx_string("sub_filter_once"), | 87 { ngx_string("sub_filter_once"), |
87 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | 88 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, |
88 ngx_conf_set_flag_slot, | 89 ngx_conf_set_flag_slot, |
89 NGX_HTTP_LOC_CONF_OFFSET, | 90 NGX_HTTP_LOC_CONF_OFFSET, |
130 | 131 |
131 | 132 |
132 static ngx_int_t | 133 static ngx_int_t |
133 ngx_http_sub_header_filter(ngx_http_request_t *r) | 134 ngx_http_sub_header_filter(ngx_http_request_t *r) |
134 { | 135 { |
135 ngx_str_t *type; | |
136 ngx_uint_t i; | |
137 ngx_http_sub_ctx_t *ctx; | 136 ngx_http_sub_ctx_t *ctx; |
138 ngx_http_sub_loc_conf_t *slcf; | 137 ngx_http_sub_loc_conf_t *slcf; |
139 | 138 |
140 slcf = ngx_http_get_module_loc_conf(r, ngx_http_sub_filter_module); | 139 slcf = ngx_http_get_module_loc_conf(r, ngx_http_sub_filter_module); |
141 | 140 |
142 if (slcf->match.len == 0 | 141 if (slcf->match.len == 0 |
143 || r->headers_out.content_type.len == 0 | 142 || r->headers_out.content_length_n == 0 |
144 || r->headers_out.content_length_n == 0) | 143 || ngx_http_test_content_type(r, &slcf->types) == NULL) |
145 { | 144 { |
146 return ngx_http_next_header_filter(r); | 145 return ngx_http_next_header_filter(r); |
147 } | 146 } |
148 | |
149 type = slcf->types->elts; | |
150 for (i = 0; i < slcf->types->nelts; i++) { | |
151 if (r->headers_out.content_type.len >= type[i].len | |
152 && ngx_strncasecmp(r->headers_out.content_type.data, | |
153 type[i].data, type[i].len) == 0) | |
154 { | |
155 goto found; | |
156 } | |
157 } | |
158 | |
159 return ngx_http_next_header_filter(r); | |
160 | |
161 found: | |
162 | 147 |
163 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_sub_ctx_t)); | 148 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_sub_ctx_t)); |
164 if (ctx == NULL) { | 149 if (ctx == NULL) { |
165 return NGX_ERROR; | 150 return NGX_ERROR; |
166 } | 151 } |
667 | 652 |
668 return NGX_CONF_OK; | 653 return NGX_CONF_OK; |
669 } | 654 } |
670 | 655 |
671 | 656 |
672 static char * | |
673 ngx_http_sub_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
674 { | |
675 ngx_http_sub_loc_conf_t *slcf = conf; | |
676 | |
677 ngx_str_t *value, *type; | |
678 ngx_uint_t i; | |
679 | |
680 if (slcf->types == NULL) { | |
681 slcf->types = ngx_array_create(cf->pool, 4, sizeof(ngx_str_t)); | |
682 if (slcf->types == NULL) { | |
683 return NGX_CONF_ERROR; | |
684 } | |
685 | |
686 type = ngx_array_push(slcf->types); | |
687 if (type == NULL) { | |
688 return NGX_CONF_ERROR; | |
689 } | |
690 | |
691 type->len = sizeof("text/html") - 1; | |
692 type->data = (u_char *) "text/html"; | |
693 } | |
694 | |
695 value = cf->args->elts; | |
696 | |
697 for (i = 1; i < cf->args->nelts; i++) { | |
698 | |
699 if (ngx_strcmp(value[i].data, "text/html") == 0) { | |
700 continue; | |
701 } | |
702 | |
703 type = ngx_array_push(slcf->types); | |
704 if (type == NULL) { | |
705 return NGX_CONF_ERROR; | |
706 } | |
707 | |
708 type->len = value[i].len; | |
709 | |
710 type->data = ngx_pnalloc(cf->pool, type->len + 1); | |
711 if (type->data == NULL) { | |
712 return NGX_CONF_ERROR; | |
713 } | |
714 | |
715 ngx_cpystrn(type->data, value[i].data, type->len + 1); | |
716 } | |
717 | |
718 return NGX_CONF_OK; | |
719 } | |
720 | |
721 | |
722 static void * | 657 static void * |
723 ngx_http_sub_create_conf(ngx_conf_t *cf) | 658 ngx_http_sub_create_conf(ngx_conf_t *cf) |
724 { | 659 { |
725 ngx_http_sub_loc_conf_t *slcf; | 660 ngx_http_sub_loc_conf_t *slcf; |
726 | 661 |
730 } | 665 } |
731 | 666 |
732 /* | 667 /* |
733 * set by ngx_pcalloc(): | 668 * set by ngx_pcalloc(): |
734 * | 669 * |
735 * conf->match.len = 0; | 670 * conf->match = { 0, NULL }; |
736 * conf->match.data = NULL; | 671 * conf->sub = { 0, NULL }; |
737 * conf->sub.len = 0; | |
738 * conf->sub.data = NULL; | |
739 * conf->sub_lengths = NULL; | 672 * conf->sub_lengths = NULL; |
740 * conf->sub_values = NULL; | 673 * conf->sub_values = NULL; |
741 * conf->types = NULL; | 674 * conf->types = { NULL }; |
675 * conf->types_keys = NULL; | |
742 */ | 676 */ |
743 | 677 |
744 slcf->once = NGX_CONF_UNSET; | 678 slcf->once = NGX_CONF_UNSET; |
745 | 679 |
746 return slcf; | 680 return slcf; |
751 ngx_http_sub_merge_conf(ngx_conf_t *cf, void *parent, void *child) | 685 ngx_http_sub_merge_conf(ngx_conf_t *cf, void *parent, void *child) |
752 { | 686 { |
753 ngx_http_sub_loc_conf_t *prev = parent; | 687 ngx_http_sub_loc_conf_t *prev = parent; |
754 ngx_http_sub_loc_conf_t *conf = child; | 688 ngx_http_sub_loc_conf_t *conf = child; |
755 | 689 |
756 ngx_str_t *type; | |
757 | |
758 ngx_conf_merge_value(conf->once, prev->once, 1); | 690 ngx_conf_merge_value(conf->once, prev->once, 1); |
759 ngx_conf_merge_str_value(conf->match, prev->match, ""); | 691 ngx_conf_merge_str_value(conf->match, prev->match, ""); |
760 | 692 |
761 if (conf->sub.data == NULL && conf->sub_lengths == NULL) { | 693 if (conf->sub.data == NULL && conf->sub_lengths == NULL) { |
762 conf->sub = prev->sub; | 694 conf->sub = prev->sub; |
763 conf->sub_lengths = prev->sub_lengths; | 695 conf->sub_lengths = prev->sub_lengths; |
764 conf->sub_values = prev->sub_values; | 696 conf->sub_values = prev->sub_values; |
765 } | 697 } |
766 | 698 |
767 if (conf->types == NULL) { | 699 if (ngx_http_merge_types(cf, conf->types_keys, &conf->types, |
768 if (prev->types == NULL) { | 700 prev->types_keys, &prev->types, |
769 conf->types = ngx_array_create(cf->pool, 1, sizeof(ngx_str_t)); | 701 ngx_http_html_default_types) |
770 if (conf->types == NULL) { | 702 != NGX_OK) |
771 return NGX_CONF_ERROR; | 703 { |
772 } | 704 return NGX_CONF_ERROR; |
773 | |
774 type = ngx_array_push(conf->types); | |
775 if (type == NULL) { | |
776 return NGX_CONF_ERROR; | |
777 } | |
778 | |
779 type->len = sizeof("text/html") - 1; | |
780 type->data = (u_char *) "text/html"; | |
781 | |
782 } else { | |
783 conf->types = prev->types; | |
784 } | |
785 } | 705 } |
786 | 706 |
787 return NGX_CONF_OK; | 707 return NGX_CONF_OK; |
788 } | 708 } |
789 | 709 |