comparison src/http/modules/ngx_http_gzip_filter_module.c @ 394:05981f639d21 NGINX_0_7_9

nginx 0.7.9 *) Change: now ngx_http_charset_module works by default with following MIME types: text/html, text/css, text/xml, text/plain, text/vnd.wap.wml, application/x-javascript, and application/rss+xml. *) Feature: the "charset_types" and "addition_types" directives. *) Feature: now the "gzip_types", "ssi_types", and "sub_filter_types" directives use hash. *) Feature: the ngx_cpp_test_module. *) Feature: the "expires" directive supports daily time. *) Feature: the ngx_http_xslt_module improvements and bug fixing. Thanks to Denis F. Latypoff and Maxim Dounin. *) Bugfix: the "log_not_found" directive did not work for index files tests. *) Bugfix: HTTPS connections might hang, if kqueue, epoll, rtsig, or eventport methods were used; the bug had appeared in 0.7.7. *) Bugfix: if the "server_name", "valid_referers", and "map" directives used an "*.domain.tld" wildcard and exact name "domain.tld" was not set, then the exact name was matched by the wildcard; the bugs had appeared in 0.3.18.
author Igor Sysoev <http://sysoev.ru>
date Tue, 12 Aug 2008 00:00:00 +0400
parents 984bb0b1399b
children b4f69f2ef02c
comparison
equal deleted inserted replaced
393:040b8c84d040 394:05981f639d21
13 13
14 typedef struct { 14 typedef struct {
15 ngx_flag_t enable; 15 ngx_flag_t enable;
16 ngx_flag_t no_buffer; 16 ngx_flag_t no_buffer;
17 17
18 ngx_array_t *types; /* array of ngx_str_t */ 18 ngx_hash_t types;
19 19
20 ngx_bufs_t bufs; 20 ngx_bufs_t bufs;
21 21
22 ngx_int_t level; 22 ngx_int_t level;
23 size_t wbits; 23 size_t wbits;
24 size_t memlevel; 24 size_t memlevel;
25 ssize_t min_length; 25 ssize_t min_length;
26
27 ngx_array_t *types_keys;
26 } ngx_http_gzip_conf_t; 28 } ngx_http_gzip_conf_t;
27 29
28 30
29 typedef struct { 31 typedef struct {
30 ngx_chain_t *in; 32 ngx_chain_t *in;
66 68
67 static ngx_int_t ngx_http_gzip_filter_init(ngx_conf_t *cf); 69 static ngx_int_t ngx_http_gzip_filter_init(ngx_conf_t *cf);
68 static void *ngx_http_gzip_create_conf(ngx_conf_t *cf); 70 static void *ngx_http_gzip_create_conf(ngx_conf_t *cf);
69 static char *ngx_http_gzip_merge_conf(ngx_conf_t *cf, 71 static char *ngx_http_gzip_merge_conf(ngx_conf_t *cf,
70 void *parent, void *child); 72 void *parent, void *child);
71 static char *ngx_http_gzip_types(ngx_conf_t *cf, ngx_command_t *cmd,
72 void *conf);
73 static char *ngx_http_gzip_window(ngx_conf_t *cf, void *post, void *data); 73 static char *ngx_http_gzip_window(ngx_conf_t *cf, void *post, void *data);
74 static char *ngx_http_gzip_hash(ngx_conf_t *cf, void *post, void *data); 74 static char *ngx_http_gzip_hash(ngx_conf_t *cf, void *post, void *data);
75 75
76 76
77 static ngx_conf_num_bounds_t ngx_http_gzip_comp_level_bounds = { 77 static ngx_conf_num_bounds_t ngx_http_gzip_comp_level_bounds = {
99 offsetof(ngx_http_gzip_conf_t, bufs), 99 offsetof(ngx_http_gzip_conf_t, bufs),
100 NULL }, 100 NULL },
101 101
102 { ngx_string("gzip_types"), 102 { ngx_string("gzip_types"),
103 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE, 103 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
104 ngx_http_gzip_types, 104 ngx_http_types_slot,
105 NGX_HTTP_LOC_CONF_OFFSET, 105 NGX_HTTP_LOC_CONF_OFFSET,
106 0, 106 offsetof(ngx_http_gzip_conf_t, types_keys),
107 NULL }, 107 &ngx_http_html_default_types[0] },
108 108
109 { ngx_string("gzip_comp_level"), 109 { ngx_string("gzip_comp_level"),
110 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, 110 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
111 ngx_conf_set_num_slot, 111 ngx_conf_set_num_slot,
112 NGX_HTTP_LOC_CONF_OFFSET, 112 NGX_HTTP_LOC_CONF_OFFSET,
202 202
203 203
204 static ngx_int_t 204 static ngx_int_t
205 ngx_http_gzip_header_filter(ngx_http_request_t *r) 205 ngx_http_gzip_header_filter(ngx_http_request_t *r)
206 { 206 {
207 ngx_str_t *type;
208 ngx_uint_t i;
209 ngx_table_elt_t *h; 207 ngx_table_elt_t *h;
210 ngx_http_gzip_ctx_t *ctx; 208 ngx_http_gzip_ctx_t *ctx;
211 ngx_http_gzip_conf_t *conf; 209 ngx_http_gzip_conf_t *conf;
212 210
213 conf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_filter_module); 211 conf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_filter_module);
215 if (!conf->enable 213 if (!conf->enable
216 || (r->headers_out.status != NGX_HTTP_OK 214 || (r->headers_out.status != NGX_HTTP_OK
217 && r->headers_out.status != NGX_HTTP_FORBIDDEN 215 && r->headers_out.status != NGX_HTTP_FORBIDDEN
218 && r->headers_out.status != NGX_HTTP_NOT_FOUND) 216 && r->headers_out.status != NGX_HTTP_NOT_FOUND)
219 || r->header_only 217 || r->header_only
220 || r->headers_out.content_type.len == 0
221 || (r->headers_out.content_encoding 218 || (r->headers_out.content_encoding
222 && r->headers_out.content_encoding->value.len) 219 && r->headers_out.content_encoding->value.len)
223 || (r->headers_out.content_length_n != -1 220 || (r->headers_out.content_length_n != -1
224 && r->headers_out.content_length_n < conf->min_length) 221 && r->headers_out.content_length_n < conf->min_length)
222 || ngx_http_test_content_type(r, &conf->types) == NULL
225 || ngx_http_gzip_ok(r) != NGX_OK) 223 || ngx_http_gzip_ok(r) != NGX_OK)
226 { 224 {
227 return ngx_http_next_header_filter(r); 225 return ngx_http_next_header_filter(r);
228 } 226 }
229
230 type = conf->types->elts;
231 for (i = 0; i < conf->types->nelts; i++) {
232 if (r->headers_out.content_type.len >= type[i].len
233 && ngx_strncasecmp(r->headers_out.content_type.data,
234 type[i].data, type[i].len) == 0)
235 {
236 goto found;
237 }
238 }
239
240 return ngx_http_next_header_filter(r);
241
242 found:
243 227
244 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_gzip_ctx_t)); 228 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_gzip_ctx_t));
245 if (ctx == NULL) { 229 if (ctx == NULL) {
246 return NGX_ERROR; 230 return NGX_ERROR;
247 } 231 }
824 808
825 /* 809 /*
826 * set by ngx_pcalloc(): 810 * set by ngx_pcalloc():
827 * 811 *
828 * conf->bufs.num = 0; 812 * conf->bufs.num = 0;
829 * conf->types = NULL; 813 * conf->types = { NULL };
814 * conf->types_keys = NULL;
830 */ 815 */
831 816
832 conf->enable = NGX_CONF_UNSET; 817 conf->enable = NGX_CONF_UNSET;
833 conf->no_buffer = NGX_CONF_UNSET; 818 conf->no_buffer = NGX_CONF_UNSET;
834 819
844 static char * 829 static char *
845 ngx_http_gzip_merge_conf(ngx_conf_t *cf, void *parent, void *child) 830 ngx_http_gzip_merge_conf(ngx_conf_t *cf, void *parent, void *child)
846 { 831 {
847 ngx_http_gzip_conf_t *prev = parent; 832 ngx_http_gzip_conf_t *prev = parent;
848 ngx_http_gzip_conf_t *conf = child; 833 ngx_http_gzip_conf_t *conf = child;
849
850 ngx_str_t *type;
851 834
852 ngx_conf_merge_value(conf->enable, prev->enable, 0); 835 ngx_conf_merge_value(conf->enable, prev->enable, 0);
853 836
854 ngx_conf_merge_bufs_value(conf->bufs, prev->bufs, 4, ngx_pagesize); 837 ngx_conf_merge_bufs_value(conf->bufs, prev->bufs, 4, ngx_pagesize);
855 838
858 ngx_conf_merge_size_value(conf->memlevel, prev->memlevel, 841 ngx_conf_merge_size_value(conf->memlevel, prev->memlevel,
859 MAX_MEM_LEVEL - 1); 842 MAX_MEM_LEVEL - 1);
860 ngx_conf_merge_value(conf->min_length, prev->min_length, 20); 843 ngx_conf_merge_value(conf->min_length, prev->min_length, 20);
861 ngx_conf_merge_value(conf->no_buffer, prev->no_buffer, 0); 844 ngx_conf_merge_value(conf->no_buffer, prev->no_buffer, 0);
862 845
863 if (conf->types == NULL) { 846 if (ngx_http_merge_types(cf, conf->types_keys, &conf->types,
864 if (prev->types == NULL) { 847 prev->types_keys, &prev->types,
865 conf->types = ngx_array_create(cf->pool, 1, sizeof(ngx_str_t)); 848 ngx_http_html_default_types)
866 if (conf->types == NULL) { 849 != NGX_OK)
867 return NGX_CONF_ERROR; 850 {
868 } 851 return NGX_CONF_ERROR;
869
870 type = ngx_array_push(conf->types);
871 if (type == NULL) {
872 return NGX_CONF_ERROR;
873 }
874
875 type->len = sizeof("text/html") - 1;
876 type->data = (u_char *) "text/html";
877
878 } else {
879 conf->types = prev->types;
880 }
881 } 852 }
882 853
883 return NGX_CONF_OK; 854 return NGX_CONF_OK;
884 } 855 }
885 856
896 return NGX_OK; 867 return NGX_OK;
897 } 868 }
898 869
899 870
900 static char * 871 static char *
901 ngx_http_gzip_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
902 {
903 ngx_http_gzip_conf_t *gcf = conf;
904
905 ngx_str_t *value, *type;
906 ngx_uint_t i;
907
908 if (gcf->types == NULL) {
909 gcf->types = ngx_array_create(cf->pool, 4, sizeof(ngx_str_t));
910 if (gcf->types == NULL) {
911 return NGX_CONF_ERROR;
912 }
913
914 type = ngx_array_push(gcf->types);
915 if (type == NULL) {
916 return NGX_CONF_ERROR;
917 }
918
919 type->len = sizeof("text/html") - 1;
920 type->data = (u_char *) "text/html";
921 }
922
923 value = cf->args->elts;
924
925 for (i = 1; i < cf->args->nelts; i++) {
926
927 if (ngx_strcmp(value[i].data, "text/html") == 0) {
928 continue;
929 }
930
931 type = ngx_array_push(gcf->types);
932 if (type == NULL) {
933 return NGX_CONF_ERROR;
934 }
935
936 type->len = value[i].len;
937
938 type->data = ngx_pnalloc(cf->pool, type->len + 1);
939 if (type->data == NULL) {
940 return NGX_CONF_ERROR;
941 }
942
943 ngx_cpystrn(type->data, value[i].data, type->len + 1);
944 }
945
946 return NGX_CONF_OK;
947 }
948
949
950 static char *
951 ngx_http_gzip_window(ngx_conf_t *cf, void *post, void *data) 872 ngx_http_gzip_window(ngx_conf_t *cf, void *post, void *data)
952 { 873 {
953 int *np = data; 874 int *np = data;
954 875
955 int wbits, wsize; 876 int wbits, wsize;