comparison src/http/modules/ngx_http_gzip_filter.c @ 2:cc9f381affaa NGINX_0_1_1

nginx 0.1.1 *) Feature: the gzip_types directive. *) Feature: the tcp_nodelay directive. *) Feature: the send_lowat directive is working not only on OSes that support kqueue NOTE_LOWAT, but also on OSes that support SO_SNDLOWAT. *) Feature: the setproctitle() emulation for Linux and Solaris. *) Bugfix: the "Location" header rewrite bug fixed while the proxying. *) Bugfix: the ngx_http_chunked_module module may get caught in an endless loop. *) Bugfix: the /dev/poll module bugs fixed. *) Bugfix: the responses were corrupted when the temporary files were used while the proxying. *) Bugfix: the unescaped requests were passed to the backend. *) Bugfix: while the build configuration on Linux 2.4 the --with-poll_module parameter was required.
author Igor Sysoev <http://sysoev.ru>
date Mon, 11 Oct 2004 00:00:00 +0400
parents f0b350454894
children 4b2dafa26fe2
comparison
equal deleted inserted replaced
1:80bdda0151b0 2:cc9f381affaa
12 12
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
18 ngx_array_t *types; /* array of ngx_http_gzip_type_t */
17 19
18 ngx_bufs_t bufs; 20 ngx_bufs_t bufs;
19 21
20 ngx_uint_t http_version; 22 ngx_uint_t http_version;
21 ngx_uint_t proxied; 23 ngx_uint_t proxied;
23 int level; 25 int level;
24 size_t wbits; 26 size_t wbits;
25 size_t memlevel; 27 size_t memlevel;
26 ssize_t min_length; 28 ssize_t min_length;
27 } ngx_http_gzip_conf_t; 29 } ngx_http_gzip_conf_t;
30
31
32 typedef struct {
33 ngx_str_t name;
34 ngx_uint_t enable;
35 } ngx_http_gzip_type_t;
28 36
29 37
30 #define NGX_HTTP_GZIP_PROXIED_OFF 0x0002 38 #define NGX_HTTP_GZIP_PROXIED_OFF 0x0002
31 #define NGX_HTTP_GZIP_PROXIED_EXPIRED 0x0004 39 #define NGX_HTTP_GZIP_PROXIED_EXPIRED 0x0004
32 #define NGX_HTTP_GZIP_PROXIED_NO_CACHE 0x0008 40 #define NGX_HTTP_GZIP_PROXIED_NO_CACHE 0x0008
55 ngx_uint_t allocated; 63 ngx_uint_t allocated;
56 64
57 unsigned flush:4; 65 unsigned flush:4;
58 unsigned redo:1; 66 unsigned redo:1;
59 unsigned done:1; 67 unsigned done:1;
60 #if 0
61 unsigned pass:1;
62 unsigned blocked:1;
63 #endif
64 68
65 size_t zin; 69 size_t zin;
66 size_t zout; 70 size_t zout;
67 71
68 uint32_t crc32; 72 uint32_t crc32;
84 static ngx_int_t ngx_http_gzip_pre_conf(ngx_conf_t *cf); 88 static ngx_int_t ngx_http_gzip_pre_conf(ngx_conf_t *cf);
85 static ngx_int_t ngx_http_gzip_filter_init(ngx_cycle_t *cycle); 89 static ngx_int_t ngx_http_gzip_filter_init(ngx_cycle_t *cycle);
86 static void *ngx_http_gzip_create_conf(ngx_conf_t *cf); 90 static void *ngx_http_gzip_create_conf(ngx_conf_t *cf);
87 static char *ngx_http_gzip_merge_conf(ngx_conf_t *cf, 91 static char *ngx_http_gzip_merge_conf(ngx_conf_t *cf,
88 void *parent, void *child); 92 void *parent, void *child);
93 static char *ngx_http_gzip_set_types(ngx_conf_t *cf, ngx_command_t *cmd,
94 void *conf);
89 static char *ngx_http_gzip_set_window(ngx_conf_t *cf, void *post, void *data); 95 static char *ngx_http_gzip_set_window(ngx_conf_t *cf, void *post, void *data);
90 static char *ngx_http_gzip_set_hash(ngx_conf_t *cf, void *post, void *data); 96 static char *ngx_http_gzip_set_hash(ngx_conf_t *cf, void *post, void *data);
91 97
92 98
93 static ngx_conf_num_bounds_t ngx_http_gzip_comp_level_bounds = { 99 static ngx_conf_num_bounds_t ngx_http_gzip_comp_level_bounds = {
136 ngx_conf_set_bufs_slot, 142 ngx_conf_set_bufs_slot,
137 NGX_HTTP_LOC_CONF_OFFSET, 143 NGX_HTTP_LOC_CONF_OFFSET,
138 offsetof(ngx_http_gzip_conf_t, bufs), 144 offsetof(ngx_http_gzip_conf_t, bufs),
139 NULL }, 145 NULL },
140 146
147 { ngx_string("gzip_types"),
148 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
149 ngx_http_gzip_set_types,
150 NGX_HTTP_LOC_CONF_OFFSET,
151 0,
152 NULL },
153
141 { ngx_string("gzip_comp_level"), 154 { ngx_string("gzip_comp_level"),
142 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, 155 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
143 ngx_conf_set_num_slot, 156 ngx_conf_set_num_slot,
144 NGX_HTTP_LOC_CONF_OFFSET, 157 NGX_HTTP_LOC_CONF_OFFSET,
145 offsetof(ngx_http_gzip_conf_t, level), 158 offsetof(ngx_http_gzip_conf_t, level),
209 NGX_MODULE, 222 NGX_MODULE,
210 &ngx_http_gzip_filter_module_ctx, /* module context */ 223 &ngx_http_gzip_filter_module_ctx, /* module context */
211 ngx_http_gzip_filter_commands, /* module directives */ 224 ngx_http_gzip_filter_commands, /* module directives */
212 NGX_HTTP_MODULE, /* module type */ 225 NGX_HTTP_MODULE, /* module type */
213 ngx_http_gzip_filter_init, /* init module */ 226 ngx_http_gzip_filter_init, /* init module */
214 NULL /* init child */ 227 NULL /* init process */
215 }; 228 };
216 229
217 230
218 static ngx_http_log_op_name_t ngx_http_gzip_log_fmt_ops[] = { 231 static ngx_http_log_op_name_t ngx_http_gzip_log_fmt_ops[] = {
219 { ngx_string("gzip_ratio"), NGX_INT32_LEN + 3, ngx_http_gzip_log_ratio }, 232 { ngx_string("gzip_ratio"), NGX_INT32_LEN + 3, ngx_http_gzip_log_ratio },
245 static ngx_http_output_body_filter_pt ngx_http_next_body_filter; 258 static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
246 259
247 260
248 static ngx_int_t ngx_http_gzip_header_filter(ngx_http_request_t *r) 261 static ngx_int_t ngx_http_gzip_header_filter(ngx_http_request_t *r)
249 { 262 {
263 ngx_uint_t i, found;
250 ngx_http_gzip_ctx_t *ctx; 264 ngx_http_gzip_ctx_t *ctx;
251 ngx_http_gzip_conf_t *conf; 265 ngx_http_gzip_conf_t *conf;
266 ngx_http_gzip_type_t *type;
252 267
253 conf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_filter_module); 268 conf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_filter_module);
254 269
255 if (!conf->enable 270 if (!conf->enable
256 || r->headers_out.status != NGX_HTTP_OK 271 || (r->headers_out.status != NGX_HTTP_OK
272 && r->headers_out.status != NGX_HTTP_FORBIDDEN
273 && r->headers_out.status != NGX_HTTP_NOT_FOUND)
257 || r->header_only 274 || r->header_only
258 || r->http_version < conf->http_version 275 || r->http_version < conf->http_version
276 || r->headers_out.content_type == NULL
259 || (r->headers_out.content_encoding 277 || (r->headers_out.content_encoding
260 && r->headers_out.content_encoding->value.len) 278 && r->headers_out.content_encoding->value.len)
261 || r->headers_in.accept_encoding == NULL 279 || r->headers_in.accept_encoding == NULL
262 || (r->headers_out.content_length_n != -1 280 || (r->headers_out.content_length_n != -1
263 && r->headers_out.content_length_n < conf->min_length) 281 && r->headers_out.content_length_n < conf->min_length)
265 ) 283 )
266 { 284 {
267 return ngx_http_next_header_filter(r); 285 return ngx_http_next_header_filter(r);
268 } 286 }
269 287
270 /* TODO: "text/html" -> custom types */ 288
271 if (r->headers_out.content_type 289 found = 0;
272 && ngx_strncasecmp(r->headers_out.content_type->value.data, 290 type = conf->types->elts;
273 "text/html", 9) != 0) 291
274 { 292 for (i = 0; i < conf->types->nelts; i++) {
293 if (r->headers_out.content_type->value.len >= type[i].name.len
294 && ngx_strncasecmp(r->headers_out.content_type->value.data,
295 type[i].name.data, type[i].name.len) == 0)
296 {
297 found = 1;
298 break;
299 }
300 }
301
302 if (!found) {
275 return ngx_http_next_header_filter(r); 303 return ngx_http_next_header_filter(r);
276 } 304 }
277 305
278 306
279 if (r->headers_in.via) { 307 if (r->headers_in.via) {
570 &ngx_http_gzip_filter_module; 598 &ngx_http_gzip_filter_module;
571 ctx->out_buf->recycled = 1; 599 ctx->out_buf->recycled = 1;
572 ctx->bufs++; 600 ctx->bufs++;
573 601
574 } else { 602 } else {
575 #if 0
576 ctx->blocked = 1;
577 #endif
578 break; 603 break;
579 } 604 }
580 605
581 #if 0
582 ctx->blocked = 0;
583 #endif
584 ctx->zstream.next_out = ctx->out_buf->pos; 606 ctx->zstream.next_out = ctx->out_buf->pos;
585 ctx->zstream.avail_out = conf->bufs.size; 607 ctx->zstream.avail_out = conf->bufs.size;
586 } 608 }
587 609
588 ngx_log_debug6(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 610 ngx_log_debug6(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
643 665
644 ngx_alloc_link_and_set_buf(cl, ctx->out_buf, r->pool, 666 ngx_alloc_link_and_set_buf(cl, ctx->out_buf, r->pool,
645 ngx_http_gzip_error(ctx)); 667 ngx_http_gzip_error(ctx));
646 *ctx->last_out = cl; 668 *ctx->last_out = cl;
647 ctx->last_out = &cl->next; 669 ctx->last_out = &cl->next;
648
649 #if 0
650 ctx->pass = 1;
651 #endif
652 670
653 break; 671 break;
654 } 672 }
655 673
656 if (rc == Z_STREAM_END) { 674 if (rc == Z_STREAM_END) {
710 728
711 ctx->zstream.avail_in = 0; 729 ctx->zstream.avail_in = 0;
712 ctx->zstream.avail_out = 0; 730 ctx->zstream.avail_out = 0;
713 731
714 ctx->done = 1; 732 ctx->done = 1;
715 #if 0
716 ctx->pass = 1;
717 #endif
718 733
719 break; 734 break;
720 } 735 }
721 736
722 if (conf->no_buffer && ctx->in == NULL) { 737 if (conf->no_buffer && ctx->in == NULL) {
723 ngx_alloc_link_and_set_buf(cl, ctx->out_buf, r->pool, 738 ngx_alloc_link_and_set_buf(cl, ctx->out_buf, r->pool,
724 ngx_http_gzip_error(ctx)); 739 ngx_http_gzip_error(ctx));
725 *ctx->last_out = cl; 740 *ctx->last_out = cl;
726 ctx->last_out = &cl->next; 741 ctx->last_out = &cl->next;
727 742
728 #if 0
729 ctx->pass = 1;
730 #endif
731
732 break; 743 break;
733 } 744 }
734 } 745 }
735
736 #if 0
737
738 /* OLD CODE */
739
740 if (ctx->out) {
741 if (ctx->pass) {
742 ctx->pass = 0;
743
744 } else if (last == NGX_AGAIN) {
745 return last;
746 }
747
748 } else if (ctx->busy->buf && ngx_buf_size(ctx->busy->buf)) {
749 if (last != NGX_NONE) {
750 return last;
751 }
752
753 } else if (ctx->blocked) {
754 if (last != NGX_NONE) {
755 return last;
756 }
757
758 } else {
759 if (last == NGX_NONE) {
760 return NGX_OK;
761 }
762
763 return last;
764 }
765 #endif
766
767 /* NEW CODE */
768 746
769 if (last == NGX_AGAIN) { 747 if (last == NGX_AGAIN) {
770 return NGX_AGAIN; 748 return NGX_AGAIN;
771 } 749 }
772 750
773 if (ctx->out == NULL && ctx->busy == NULL) { 751 if (ctx->out == NULL && ctx->busy == NULL) {
774 return NGX_OK; 752 return NGX_OK;
775 } 753 }
776
777 /**/
778 754
779 last = ngx_http_next_body_filter(r, ctx->out); 755 last = ngx_http_next_body_filter(r, ctx->out);
780 756
781 /* 757 /*
782 * we do not check NGX_AGAIN here because the downstream filters 758 * we do not check NGX_AGAIN here because the downstream filters
864 #if 0 840 #if 0
865 return buf + ngx_snprintf((char *) buf, NGX_INT32_LEN + 4, "%.2f", 841 return buf + ngx_snprintf((char *) buf, NGX_INT32_LEN + 4, "%.2f",
866 (float) ctx->zin / ctx->zout); 842 (float) ctx->zin / ctx->zout);
867 #endif 843 #endif
868 844
869 /* we prefer do not use FPU */ 845 /* we prefer do not use the FPU */
870 846
871 zint = (ngx_uint_t) (ctx->zin / ctx->zout); 847 zint = (ngx_uint_t) (ctx->zin / ctx->zout);
872 zfrac = (ngx_uint_t) ((ctx->zin * 100 / ctx->zout) % 100); 848 zfrac = (ngx_uint_t) ((ctx->zin * 100 / ctx->zout) % 100);
873 849
874 if ((ctx->zin * 1000 / ctx->zout) %10 > 4) { 850 if ((ctx->zin * 1000 / ctx->zout) %10 > 4) {
945 set by ngx_pcalloc(): 921 set by ngx_pcalloc():
946 922
947 conf->bufs.num = 0; 923 conf->bufs.num = 0;
948 conf->proxied = 0; 924 conf->proxied = 0;
949 925
926 conf->types = NULL;
927
950 */ 928 */
951 929
952 conf->enable = NGX_CONF_UNSET; 930 conf->enable = NGX_CONF_UNSET;
953 conf->no_buffer = NGX_CONF_UNSET; 931 conf->no_buffer = NGX_CONF_UNSET;
954 932
966 static char *ngx_http_gzip_merge_conf(ngx_conf_t *cf, 944 static char *ngx_http_gzip_merge_conf(ngx_conf_t *cf,
967 void *parent, void *child) 945 void *parent, void *child)
968 { 946 {
969 ngx_http_gzip_conf_t *prev = parent; 947 ngx_http_gzip_conf_t *prev = parent;
970 ngx_http_gzip_conf_t *conf = child; 948 ngx_http_gzip_conf_t *conf = child;
949
950 ngx_http_gzip_type_t *type;
971 951
972 ngx_conf_merge_value(conf->enable, prev->enable, 0); 952 ngx_conf_merge_value(conf->enable, prev->enable, 0);
973 953
974 ngx_conf_merge_bufs_value(conf->bufs, prev->bufs, 4, ngx_pagesize); 954 ngx_conf_merge_bufs_value(conf->bufs, prev->bufs, 4, ngx_pagesize);
975 955
984 ngx_conf_merge_size_value(conf->memlevel, prev->memlevel, 964 ngx_conf_merge_size_value(conf->memlevel, prev->memlevel,
985 MAX_MEM_LEVEL - 1); 965 MAX_MEM_LEVEL - 1);
986 ngx_conf_merge_value(conf->min_length, prev->min_length, 0); 966 ngx_conf_merge_value(conf->min_length, prev->min_length, 0);
987 ngx_conf_merge_value(conf->no_buffer, prev->no_buffer, 0); 967 ngx_conf_merge_value(conf->no_buffer, prev->no_buffer, 0);
988 968
969 if (conf->types == NULL) {
970 if (prev->types == NULL) {
971 conf->types = ngx_array_create(cf->pool, 1,
972 sizeof(ngx_http_gzip_type_t));
973 if (conf->types == NULL) {
974 return NGX_CONF_ERROR;
975 }
976
977 if (!(type = ngx_array_push(conf->types))) {
978 return NGX_CONF_ERROR;
979 }
980
981 type->name.len = sizeof("text/html") - 1;
982 type->name.data = (u_char *) "text/html";
983 type->enable = 1;
984
985 } else {
986 conf->types = prev->types;
987 }
988 }
989
990 return NGX_CONF_OK;
991 }
992
993
994 static char *ngx_http_gzip_set_types(ngx_conf_t *cf, ngx_command_t *cmd,
995 void *conf)
996 {
997 ngx_http_gzip_conf_t *gcf = conf;
998
999 ngx_str_t *value;
1000 ngx_uint_t i;
1001 ngx_http_gzip_type_t *type;
1002
1003 if (gcf->types == NULL) {
1004 gcf->types = ngx_array_create(cf->pool, 5,
1005 sizeof(ngx_http_gzip_type_t));
1006 if (gcf->types == NULL) {
1007 return NGX_CONF_ERROR;
1008 }
1009
1010 if (!(type = ngx_array_push(gcf->types))) {
1011 return NGX_CONF_ERROR;
1012 }
1013
1014 type->name.len = sizeof("text/html") - 1;
1015 type->name.data = (u_char *) "text/html";
1016 type->enable = 1;
1017 }
1018
1019 value = cf->args->elts;
1020
1021 for (i = 1; i < cf->args->nelts; i++) {
1022
1023 if (ngx_strcmp(value[i].data, "text/html") == 0) {
1024 continue;
1025 }
1026
1027 if (!(type = ngx_array_push(gcf->types))) {
1028 return NGX_CONF_ERROR;
1029 }
1030
1031 type->name.len = value[i].len;
1032
1033 if (!(type->name.data = ngx_palloc(cf->pool, type->name.len + 1))) {
1034 return NGX_CONF_ERROR;
1035 }
1036
1037 ngx_cpystrn(type->name.data, value[i].data, type->name.len + 1);
1038 }
1039
989 return NGX_CONF_OK; 1040 return NGX_CONF_OK;
990 } 1041 }
991 1042
992 1043
993 static char *ngx_http_gzip_set_window(ngx_conf_t *cf, void *post, void *data) 1044 static char *ngx_http_gzip_set_window(ngx_conf_t *cf, void *post, void *data)