Klaus Demo nginx / 390abe0
use hash in gzip_types, ssi_types, and sub_filter_types Igor Sysoev 12 years ago
5 changed file(s) with 57 addition(s) and 289 deletion(s). Raw diff Collapse all Expand all
1414 ngx_flag_t enable;
1515 ngx_flag_t no_buffer;
1616
17 ngx_array_t *types; /* array of ngx_str_t */
17 ngx_hash_t types;
1818
1919 ngx_bufs_t bufs;
2020
2222 size_t wbits;
2323 size_t memlevel;
2424 ssize_t min_length;
25
26 ngx_array_t *types_keys;
2527 } ngx_http_gzip_conf_t;
2628
2729
6769 static void *ngx_http_gzip_create_conf(ngx_conf_t *cf);
6870 static char *ngx_http_gzip_merge_conf(ngx_conf_t *cf,
6971 void *parent, void *child);
70 static char *ngx_http_gzip_types(ngx_conf_t *cf, ngx_command_t *cmd,
71 void *conf);
7272 static char *ngx_http_gzip_window(ngx_conf_t *cf, void *post, void *data);
7373 static char *ngx_http_gzip_hash(ngx_conf_t *cf, void *post, void *data);
7474
100100
101101 { ngx_string("gzip_types"),
102102 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
103 ngx_http_gzip_types,
103 ngx_http_types_slot,
104104 NGX_HTTP_LOC_CONF_OFFSET,
105 0,
106 NULL },
105 offsetof(ngx_http_gzip_conf_t, types_keys),
106 &ngx_http_html_default_types[0] },
107107
108108 { ngx_string("gzip_comp_level"),
109109 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
203203 static ngx_int_t
204204 ngx_http_gzip_header_filter(ngx_http_request_t *r)
205205 {
206 ngx_str_t *type;
207 ngx_uint_t i;
208206 ngx_table_elt_t *h;
209207 ngx_http_gzip_ctx_t *ctx;
210208 ngx_http_gzip_conf_t *conf;
216214 && r->headers_out.status != NGX_HTTP_FORBIDDEN
217215 && r->headers_out.status != NGX_HTTP_NOT_FOUND)
218216 || r->header_only
219 || r->headers_out.content_type.len == 0
220217 || (r->headers_out.content_encoding
221218 && r->headers_out.content_encoding->value.len)
222219 || (r->headers_out.content_length_n != -1
223220 && r->headers_out.content_length_n < conf->min_length)
221 || ngx_http_test_content_type(r, &conf->types) == NULL
224222 || ngx_http_gzip_ok(r) != NGX_OK)
225223 {
226224 return ngx_http_next_header_filter(r);
227225 }
228
229 type = conf->types->elts;
230 for (i = 0; i < conf->types->nelts; i++) {
231 if (r->headers_out.content_type.len >= type[i].len
232 && ngx_strncasecmp(r->headers_out.content_type.data,
233 type[i].data, type[i].len) == 0)
234 {
235 goto found;
236 }
237 }
238
239 return ngx_http_next_header_filter(r);
240
241 found:
242226
243227 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_gzip_ctx_t));
244228 if (ctx == NULL) {
825809 * set by ngx_pcalloc():
826810 *
827811 * conf->bufs.num = 0;
828 * conf->types = NULL;
812 * conf->types = { NULL };
813 * conf->types_keys = NULL;
829814 */
830815
831816 conf->enable = NGX_CONF_UNSET;
845830 {
846831 ngx_http_gzip_conf_t *prev = parent;
847832 ngx_http_gzip_conf_t *conf = child;
848
849 ngx_str_t *type;
850833
851834 ngx_conf_merge_value(conf->enable, prev->enable, 0);
852835
859842 ngx_conf_merge_value(conf->min_length, prev->min_length, 20);
860843 ngx_conf_merge_value(conf->no_buffer, prev->no_buffer, 0);
861844
862 if (conf->types == NULL) {
863 if (prev->types == NULL) {
864 conf->types = ngx_array_create(cf->pool, 1, sizeof(ngx_str_t));
865 if (conf->types == NULL) {
866 return NGX_CONF_ERROR;
867 }
868
869 type = ngx_array_push(conf->types);
870 if (type == NULL) {
871 return NGX_CONF_ERROR;
872 }
873
874 type->len = sizeof("text/html") - 1;
875 type->data = (u_char *) "text/html";
876
877 } else {
878 conf->types = prev->types;
879 }
845 if (ngx_http_merge_types(cf, conf->types_keys, &conf->types,
846 prev->types_keys, &prev->types,
847 ngx_http_html_default_types)
848 != NGX_OK)
849 {
850 return NGX_CONF_ERROR;
880851 }
881852
882853 return NGX_CONF_OK;
897868
898869
899870 static char *
900 ngx_http_gzip_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
901 {
902 ngx_http_gzip_conf_t *gcf = conf;
903
904 ngx_str_t *value, *type;
905 ngx_uint_t i;
906
907 if (gcf->types == NULL) {
908 gcf->types = ngx_array_create(cf->pool, 4, sizeof(ngx_str_t));
909 if (gcf->types == NULL) {
910 return NGX_CONF_ERROR;
911 }
912
913 type = ngx_array_push(gcf->types);
914 if (type == NULL) {
915 return NGX_CONF_ERROR;
916 }
917
918 type->len = sizeof("text/html") - 1;
919 type->data = (u_char *) "text/html";
920 }
921
922 value = cf->args->elts;
923
924 for (i = 1; i < cf->args->nelts; i++) {
925
926 if (ngx_strcmp(value[i].data, "text/html") == 0) {
927 continue;
928 }
929
930 type = ngx_array_push(gcf->types);
931 if (type == NULL) {
932 return NGX_CONF_ERROR;
933 }
934
935 type->len = value[i].len;
936
937 type->data = ngx_pnalloc(cf->pool, type->len + 1);
938 if (type->data == NULL) {
939 return NGX_CONF_ERROR;
940 }
941
942 ngx_cpystrn(type->data, value[i].data, type->len + 1);
943 }
944
945 return NGX_CONF_OK;
946 }
947
948
949 static char *
950871 ngx_http_gzip_window(ngx_conf_t *cf, void *post, void *data)
951872 {
952873 int *np = data;
2121 ngx_flag_t silent_errors;
2222 ngx_flag_t ignore_recycled_buffers;
2323
24 ngx_array_t *types; /* array of ngx_str_t */
24 ngx_hash_t types;
2525
2626 size_t min_file_chunk;
2727 size_t value_len;
28
29 ngx_array_t *types_keys;
2830 } ngx_http_ssi_loc_conf_t;
2931
3032
101103 static ngx_int_t ngx_http_ssi_date_gmt_local_variable(ngx_http_request_t *r,
102104 ngx_http_variable_value_t *v, uintptr_t gmt);
103105
104 static char *ngx_http_ssi_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
105
106106 static ngx_int_t ngx_http_ssi_preconfiguration(ngx_conf_t *cf);
107107 static void *ngx_http_ssi_create_main_conf(ngx_conf_t *cf);
108108 static char *ngx_http_ssi_init_main_conf(ngx_conf_t *cf, void *conf);
152152
153153 { ngx_string("ssi_types"),
154154 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
155 ngx_http_ssi_types,
155 ngx_http_types_slot,
156156 NGX_HTTP_LOC_CONF_OFFSET,
157 0,
158 NULL },
157 offsetof(ngx_http_ssi_loc_conf_t, types_keys),
158 &ngx_http_html_default_types[0] },
159159
160160 ngx_null_command
161161 };
315315 static ngx_int_t
316316 ngx_http_ssi_header_filter(ngx_http_request_t *r)
317317 {
318 ngx_uint_t i;
319 ngx_str_t *type;
320318 ngx_http_ssi_ctx_t *ctx;
321319 ngx_http_ssi_loc_conf_t *slcf;
322320
323321 slcf = ngx_http_get_module_loc_conf(r, ngx_http_ssi_filter_module);
324322
325323 if (!slcf->enable
326 || r->headers_out.content_type.len == 0
327 || r->headers_out.content_length_n == 0)
324 || r->headers_out.content_length_n == 0
325 || ngx_http_test_content_type(r, &slcf->types) == NULL)
328326 {
329327 return ngx_http_next_header_filter(r);
330328 }
331
332
333 type = slcf->types->elts;
334 for (i = 0; i < slcf->types->nelts; i++) {
335 if (r->headers_out.content_type.len >= type[i].len
336 && ngx_strncasecmp(r->headers_out.content_type.data,
337 type[i].data, type[i].len) == 0)
338 {
339 goto found;
340 }
341 }
342
343 return ngx_http_next_header_filter(r);
344
345
346 found:
347329
348330 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_ssi_ctx_t));
349331 if (ctx == NULL) {
26782660 }
26792661
26802662
2681 static char *
2682 ngx_http_ssi_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
2683 {
2684 ngx_http_ssi_loc_conf_t *slcf = conf;
2685
2686 ngx_str_t *value, *type;
2687 ngx_uint_t i;
2688
2689 if (slcf->types == NULL) {
2690 slcf->types = ngx_array_create(cf->pool, 4, sizeof(ngx_str_t));
2691 if (slcf->types == NULL) {
2692 return NGX_CONF_ERROR;
2693 }
2694
2695 type = ngx_array_push(slcf->types);
2696 if (type == NULL) {
2697 return NGX_CONF_ERROR;
2698 }
2699
2700 type->len = sizeof("text/html") - 1;
2701 type->data = (u_char *) "text/html";
2702 }
2703
2704 value = cf->args->elts;
2705
2706 for (i = 1; i < cf->args->nelts; i++) {
2707
2708 if (ngx_strcmp(value[i].data, "text/html") == 0) {
2709 continue;
2710 }
2711
2712 type = ngx_array_push(slcf->types);
2713 if (type == NULL) {
2714 return NGX_CONF_ERROR;
2715 }
2716
2717 type->len = value[i].len;
2718
2719 type->data = ngx_pnalloc(cf->pool, type->len + 1);
2720 if (type->data == NULL) {
2721 return NGX_CONF_ERROR;
2722 }
2723
2724 ngx_cpystrn(type->data, value[i].data, type->len + 1);
2725 }
2726
2727 return NGX_CONF_OK;
2728 }
2729
2730
27312663 static ngx_int_t
27322664 ngx_http_ssi_preconfiguration(ngx_conf_t *cf)
27332665 {
28282760 /*
28292761 * set by ngx_pcalloc():
28302762 *
2831 * conf->types = NULL;
2763 * conf->types = { NULL };
2764 * conf->types_keys = NULL;
28322765 */
28332766
28342767 slcf->enable = NGX_CONF_UNSET;
28482781 ngx_http_ssi_loc_conf_t *prev = parent;
28492782 ngx_http_ssi_loc_conf_t *conf = child;
28502783
2851 ngx_str_t *type;
2852
28532784 ngx_conf_merge_value(conf->enable, prev->enable, 0);
28542785 ngx_conf_merge_value(conf->silent_errors, prev->silent_errors, 0);
28552786 ngx_conf_merge_value(conf->ignore_recycled_buffers,
28582789 ngx_conf_merge_size_value(conf->min_file_chunk, prev->min_file_chunk, 1024);
28592790 ngx_conf_merge_size_value(conf->value_len, prev->value_len, 256);
28602791
2861 if (conf->types == NULL) {
2862 if (prev->types == NULL) {
2863 conf->types = ngx_array_create(cf->pool, 1, sizeof(ngx_str_t));
2864 if (conf->types == NULL) {
2865 return NGX_CONF_ERROR;
2866 }
2867
2868 type = ngx_array_push(conf->types);
2869 if (type == NULL) {
2870 return NGX_CONF_ERROR;
2871 }
2872
2873 type->len = sizeof("text/html") - 1;
2874 type->data = (u_char *) "text/html";
2875
2876 } else {
2877 conf->types = prev->types;
2878 }
2792 if (ngx_http_merge_types(cf, conf->types_keys, &conf->types,
2793 prev->types_keys, &prev->types,
2794 ngx_http_html_default_types)
2795 != NGX_OK)
2796 {
2797 return NGX_CONF_ERROR;
28792798 }
28802799
28812800 return NGX_CONF_OK;
1212 ngx_str_t match;
1313 ngx_str_t sub;
1414
15 ngx_array_t *types; /* array of ngx_str_t */
15 ngx_hash_t types;
1616
1717 ngx_array_t *sub_lengths;
1818 ngx_array_t *sub_values;
1919
2020 ngx_flag_t once;
21
22 ngx_array_t *types_keys;
2123 } ngx_http_sub_loc_conf_t;
2224
2325
5961
6062 static char * ngx_http_sub_filter(ngx_conf_t *cf, ngx_command_t *cmd,
6163 void *conf);
62 static char *ngx_http_sub_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
6364 static void *ngx_http_sub_create_conf(ngx_conf_t *cf);
6465 static char *ngx_http_sub_merge_conf(ngx_conf_t *cf,
6566 void *parent, void *child);
7778
7879 { ngx_string("sub_filter_types"),
7980 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
80 ngx_http_sub_types,
81 ngx_http_types_slot,
8182 NGX_HTTP_LOC_CONF_OFFSET,
82 0,
83 NULL },
83 offsetof(ngx_http_sub_loc_conf_t, types_keys),
84 &ngx_http_html_default_types[0] },
8485
8586 { ngx_string("sub_filter_once"),
8687 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
131132 static ngx_int_t
132133 ngx_http_sub_header_filter(ngx_http_request_t *r)
133134 {
134 ngx_str_t *type;
135 ngx_uint_t i;
136135 ngx_http_sub_ctx_t *ctx;
137136 ngx_http_sub_loc_conf_t *slcf;
138137
139138 slcf = ngx_http_get_module_loc_conf(r, ngx_http_sub_filter_module);
140139
141140 if (slcf->match.len == 0
142 || r->headers_out.content_type.len == 0
143 || r->headers_out.content_length_n == 0)
141 || r->headers_out.content_length_n == 0
142 || ngx_http_test_content_type(r, &slcf->types) == NULL)
144143 {
145144 return ngx_http_next_header_filter(r);
146145 }
147
148 type = slcf->types->elts;
149 for (i = 0; i < slcf->types->nelts; i++) {
150 if (r->headers_out.content_type.len >= type[i].len
151 && ngx_strncasecmp(r->headers_out.content_type.data,
152 type[i].data, type[i].len) == 0)
153 {
154 goto found;
155 }
156 }
157
158 return ngx_http_next_header_filter(r);
159
160 found:
161146
162147 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_sub_ctx_t));
163148 if (ctx == NULL) {
668653 }
669654
670655
671 static char *
672 ngx_http_sub_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
673 {
674 ngx_http_sub_loc_conf_t *slcf = conf;
675
676 ngx_str_t *value, *type;
677 ngx_uint_t i;
678
679 if (slcf->types == NULL) {
680 slcf->types = ngx_array_create(cf->pool, 4, sizeof(ngx_str_t));
681 if (slcf->types == NULL) {
682 return NGX_CONF_ERROR;
683 }
684
685 type = ngx_array_push(slcf->types);
686 if (type == NULL) {
687 return NGX_CONF_ERROR;
688 }
689
690 type->len = sizeof("text/html") - 1;
691 type->data = (u_char *) "text/html";
692 }
693
694 value = cf->args->elts;
695
696 for (i = 1; i < cf->args->nelts; i++) {
697
698 if (ngx_strcmp(value[i].data, "text/html") == 0) {
699 continue;
700 }
701
702 type = ngx_array_push(slcf->types);
703 if (type == NULL) {
704 return NGX_CONF_ERROR;
705 }
706
707 type->len = value[i].len;
708
709 type->data = ngx_pnalloc(cf->pool, type->len + 1);
710 if (type->data == NULL) {
711 return NGX_CONF_ERROR;
712 }
713
714 ngx_cpystrn(type->data, value[i].data, type->len + 1);
715 }
716
717 return NGX_CONF_OK;
718 }
719
720
721656 static void *
722657 ngx_http_sub_create_conf(ngx_conf_t *cf)
723658 {
731666 /*
732667 * set by ngx_pcalloc():
733668 *
734 * conf->match.len = 0;
735 * conf->match.data = NULL;
736 * conf->sub.len = 0;
737 * conf->sub.data = NULL;
669 * conf->match = { 0, NULL };
670 * conf->sub = { 0, NULL };
738671 * conf->sub_lengths = NULL;
739672 * conf->sub_values = NULL;
740 * conf->types = NULL;
673 * conf->types = { NULL };
674 * conf->types_keys = NULL;
741675 */
742676
743677 slcf->once = NGX_CONF_UNSET;
752686 ngx_http_sub_loc_conf_t *prev = parent;
753687 ngx_http_sub_loc_conf_t *conf = child;
754688
755 ngx_str_t *type;
756
757689 ngx_conf_merge_value(conf->once, prev->once, 1);
758690 ngx_conf_merge_str_value(conf->match, prev->match, "");
759691
763695 conf->sub_values = prev->sub_values;
764696 }
765697
766 if (conf->types == NULL) {
767 if (prev->types == NULL) {
768 conf->types = ngx_array_create(cf->pool, 1, sizeof(ngx_str_t));
769 if (conf->types == NULL) {
770 return NGX_CONF_ERROR;
771 }
772
773 type = ngx_array_push(conf->types);
774 if (type == NULL) {
775 return NGX_CONF_ERROR;
776 }
777
778 type->len = sizeof("text/html") - 1;
779 type->data = (u_char *) "text/html";
780
781 } else {
782 conf->types = prev->types;
783 }
698 if (ngx_http_merge_types(cf, conf->types_keys, &conf->types,
699 prev->types_keys, &prev->types,
700 ngx_http_html_default_types)
701 != NGX_OK)
702 {
703 return NGX_CONF_ERROR;
784704 }
785705
786706 return NGX_CONF_OK;
5858 ngx_int_t (*ngx_http_top_body_filter) (ngx_http_request_t *r, ngx_chain_t *ch);
5959
6060
61 ngx_str_t ngx_http_html_default_types[] = {
62 ngx_string("text/html"),
63 ngx_null_string
64 };
65
66
6167 static ngx_command_t ngx_http_commands[] = {
6268
6369 { ngx_string("http"),
116116
117117 extern ngx_module_t ngx_http_module;
118118
119 extern ngx_str_t ngx_http_html_default_types[];
120
119121
120122 extern ngx_http_output_header_filter_pt ngx_http_top_header_filter;
121123 extern ngx_http_output_body_filter_pt ngx_http_top_body_filter;