comparison src/http/modules/ngx_http_gzip_filter.c @ 28:7ca9bdc82b3f NGINX_0_1_14

nginx 0.1.14 *) Feature: the autoconfiguration directives: --http-client-body-temp-path=PATH, --http-proxy-temp-path=PATH, and --http-fastcgi-temp-path=PATH *) Change: the directory name for the temporary files with the client request body is specified by directive client_body_temp_path, by default it is <prefix>/client_body_temp. *) Feature: the ngx_http_fastcgi_module and the directives: fastcgi_pass, fastcgi_root, fastcgi_index, fastcgi_params, fastcgi_connect_timeout, fastcgi_send_timeout, fastcgi_read_timeout, fastcgi_send_lowat, fastcgi_header_buffer_size, fastcgi_buffers, fastcgi_busy_buffers_size, fastcgi_temp_path, fastcgi_max_temp_file_size, fastcgi_temp_file_write_size, fastcgi_next_upstream, and fastcgi_x_powered_by. *) Bugfix: the "[alert] zero size buf" error; bug appeared in 0.1.3. *) Change: the URI must be specified after the host name in the proxy_pass directive. *) Change: the %3F symbol in the URI was considered as the argument string start. *) Feature: the unix domain sockets support in the ngx_http_proxy_module. *) Feature: the ssl_engine and ssl_ciphers directives. Thanks to Sergey Skvortsov for SSL-accelerator.
author Igor Sysoev <http://sysoev.ru>
date Tue, 18 Jan 2005 00:00:00 +0300
parents 6f8b0dc0f8dd
children da8c190bdaba
comparison
equal deleted inserted replaced
27:66901c2556fd 28:7ca9bdc82b3f
78 static ngx_int_t ngx_http_gzip_proxied(ngx_http_request_t *r, 78 static ngx_int_t ngx_http_gzip_proxied(ngx_http_request_t *r,
79 ngx_http_gzip_conf_t *conf); 79 ngx_http_gzip_conf_t *conf);
80 static void *ngx_http_gzip_filter_alloc(void *opaque, u_int items, 80 static void *ngx_http_gzip_filter_alloc(void *opaque, u_int items,
81 u_int size); 81 u_int size);
82 static void ngx_http_gzip_filter_free(void *opaque, void *address); 82 static void ngx_http_gzip_filter_free(void *opaque, void *address);
83 static int ngx_http_gzip_error(ngx_http_gzip_ctx_t *ctx); 83 static void ngx_http_gzip_error(ngx_http_gzip_ctx_t *ctx);
84 84
85 static u_char *ngx_http_gzip_log_ratio(ngx_http_request_t *r, u_char *buf, 85 static u_char *ngx_http_gzip_log_ratio(ngx_http_request_t *r, u_char *buf,
86 uintptr_t data); 86 ngx_http_log_op_t *op);
87 87
88 static ngx_int_t ngx_http_gzip_pre_conf(ngx_conf_t *cf); 88 static ngx_int_t ngx_http_gzip_add_log_formats(ngx_conf_t *cf);
89
89 static ngx_int_t ngx_http_gzip_filter_init(ngx_cycle_t *cycle); 90 static ngx_int_t ngx_http_gzip_filter_init(ngx_cycle_t *cycle);
90 static void *ngx_http_gzip_create_conf(ngx_conf_t *cf); 91 static void *ngx_http_gzip_create_conf(ngx_conf_t *cf);
91 static char *ngx_http_gzip_merge_conf(ngx_conf_t *cf, 92 static char *ngx_http_gzip_merge_conf(ngx_conf_t *cf,
92 void *parent, void *child); 93 void *parent, void *child);
93 static char *ngx_http_gzip_set_types(ngx_conf_t *cf, ngx_command_t *cmd, 94 static char *ngx_http_gzip_set_types(ngx_conf_t *cf, ngx_command_t *cmd,
203 ngx_null_command 204 ngx_null_command
204 }; 205 };
205 206
206 207
207 static ngx_http_module_t ngx_http_gzip_filter_module_ctx = { 208 static ngx_http_module_t ngx_http_gzip_filter_module_ctx = {
208 ngx_http_gzip_pre_conf, /* pre conf */ 209 ngx_http_gzip_add_log_formats, /* pre conf */
209 210
210 NULL, /* create main configuration */ 211 NULL, /* create main configuration */
211 NULL, /* init main configuration */ 212 NULL, /* init main configuration */
212 213
213 NULL, /* create server configuration */ 214 NULL, /* create server configuration */
227 NULL /* init process */ 228 NULL /* init process */
228 }; 229 };
229 230
230 231
231 static ngx_http_log_op_name_t ngx_http_gzip_log_fmt_ops[] = { 232 static ngx_http_log_op_name_t ngx_http_gzip_log_fmt_ops[] = {
232 { ngx_string("gzip_ratio"), NGX_INT32_LEN + 3, ngx_http_gzip_log_ratio }, 233 { ngx_string("gzip_ratio"), NGX_INT32_LEN + 3,
233 { ngx_null_string, 0, NULL } 234 NULL, NULL, ngx_http_gzip_log_ratio },
235 { ngx_null_string, 0, NULL, NULL, NULL }
234 }; 236 };
235 237
236 238
237 239
238 static u_char gzheader[10] = { 0x1f, 0x8b, Z_DEFLATED, 0, 0, 0, 0, 0, 0, 3 }; 240 static u_char gzheader[10] = { 0x1f, 0x8b, Z_DEFLATED, 0, 0, 0, 0, 0, 0, 3 };
239 241
240 #if (NGX_HAVE_LITTLE_ENDIAN) 242 #if (NGX_HAVE_LITTLE_ENDIAN && NGX_HAVE_NONALIGNED)
241 243
242 struct gztrailer { 244 struct gztrailer {
243 uint32_t crc32; 245 uint32_t crc32;
244 uint32_t zlen; 246 uint32_t zlen;
245 }; 247 };
246 248
247 #else /* NGX_HAVE_BIG_ENDIAN */ 249 #else /* NGX_HAVE_BIG_ENDIAN || !NGX_HAVE_NONALIGNED */
248 250
249 struct gztrailer { 251 struct gztrailer {
250 u_char crc32[4]; 252 u_char crc32[4];
251 u_char zlen[4]; 253 u_char zlen[4];
252 }; 254 };
495 -wbits, memlevel, Z_DEFAULT_STRATEGY); 497 -wbits, memlevel, Z_DEFAULT_STRATEGY);
496 498
497 if (rc != Z_OK) { 499 if (rc != Z_OK) {
498 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, 500 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
499 "deflateInit2() failed: %d", rc); 501 "deflateInit2() failed: %d", rc);
500 return ngx_http_gzip_error(ctx); 502 ngx_http_gzip_error(ctx);
503 return NGX_ERROR;
501 } 504 }
502 505
503 if (!(b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)))) { 506 if (!(b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)))) {
504 return ngx_http_gzip_error(ctx); 507 ngx_http_gzip_error(ctx);
508 return NGX_ERROR;
505 } 509 }
506 510
507 b->memory = 1; 511 b->memory = 1;
508 b->pos = gzheader; 512 b->pos = gzheader;
509 b->last = b->pos + 10; 513 b->last = b->pos + 10;
510 514
511 if (!(cl = ngx_alloc_chain_link(r->pool))) { 515 if (!(cl = ngx_alloc_chain_link(r->pool))) {
512 return ngx_http_gzip_error(ctx); 516 ngx_http_gzip_error(ctx);
517 return NGX_ERROR;
513 } 518 }
514 cl->buf = b; 519 cl->buf = b;
515 cl->next = NULL; 520 cl->next = NULL;
516 521
517 /* 522 /*
520 * data in the initial iterations, so the gzheader that was linked 525 * data in the initial iterations, so the gzheader that was linked
521 * to the ctx->busy chain would be flushed by ngx_http_write_filter(). 526 * to the ctx->busy chain would be flushed by ngx_http_write_filter().
522 */ 527 */
523 528
524 if (ngx_http_next_body_filter(r, cl) == NGX_ERROR) { 529 if (ngx_http_next_body_filter(r, cl) == NGX_ERROR) {
525 return ngx_http_gzip_error(ctx); 530 ngx_http_gzip_error(ctx);
531 return NGX_ERROR;
526 } 532 }
527 533
528 ctx->last_out = &ctx->out; 534 ctx->last_out = &ctx->out;
529 535
530 ctx->crc32 = crc32(0L, Z_NULL, 0); 536 ctx->crc32 = crc32(0L, Z_NULL, 0);
531 ctx->flush = Z_NO_FLUSH; 537 ctx->flush = Z_NO_FLUSH;
532 } 538 }
533 539
534 if (in) { 540 if (in) {
535 if (ngx_chain_add_copy(r->pool, &ctx->in, in) == NGX_ERROR) { 541 if (ngx_chain_add_copy(r->pool, &ctx->in, in) == NGX_ERROR) {
536 return ngx_http_gzip_error(ctx); 542 ngx_http_gzip_error(ctx);
543 return NGX_ERROR;
537 } 544 }
538 } 545 }
539 546
540 last = NGX_NONE; 547 last = NGX_NONE;
541 548
605 612
606 } else if (ctx->bufs < conf->bufs.num) { 613 } else if (ctx->bufs < conf->bufs.num) {
607 ctx->out_buf = ngx_create_temp_buf(r->pool, 614 ctx->out_buf = ngx_create_temp_buf(r->pool,
608 conf->bufs.size); 615 conf->bufs.size);
609 if (ctx->out_buf == NULL) { 616 if (ctx->out_buf == NULL) {
610 return ngx_http_gzip_error(ctx); 617 ngx_http_gzip_error(ctx);
618 return NGX_ERROR;
611 } 619 }
612 620
613 ctx->out_buf->tag = (ngx_buf_tag_t) 621 ctx->out_buf->tag = (ngx_buf_tag_t)
614 &ngx_http_gzip_filter_module; 622 &ngx_http_gzip_filter_module;
615 ctx->out_buf->recycled = 1; 623 ctx->out_buf->recycled = 1;
632 rc = deflate(&ctx->zstream, ctx->flush); 640 rc = deflate(&ctx->zstream, ctx->flush);
633 641
634 if (rc != Z_OK && rc != Z_STREAM_END) { 642 if (rc != Z_OK && rc != Z_STREAM_END) {
635 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, 643 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
636 "deflate() failed: %d, %d", ctx->flush, rc); 644 "deflate() failed: %d, %d", ctx->flush, rc);
637 return ngx_http_gzip_error(ctx); 645 ngx_http_gzip_error(ctx);
646 return NGX_ERROR;
638 } 647 }
639 648
640 ngx_log_debug5(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 649 ngx_log_debug5(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
641 "deflate out: ni:%p no:%p ai:%ud ao:%ud rc:%d", 650 "deflate out: ni:%p no:%p ai:%ud ao:%ud rc:%d",
642 ctx->zstream.next_in, ctx->zstream.next_out, 651 ctx->zstream.next_in, ctx->zstream.next_out,
661 if (ctx->zstream.avail_out == 0) { 670 if (ctx->zstream.avail_out == 0) {
662 671
663 /* zlib wants to output some more gzipped data */ 672 /* zlib wants to output some more gzipped data */
664 673
665 if (!(cl = ngx_alloc_chain_link(r->pool))) { 674 if (!(cl = ngx_alloc_chain_link(r->pool))) {
666 return ngx_http_gzip_error(ctx); 675 ngx_http_gzip_error(ctx);
676 return NGX_ERROR;
667 } 677 }
668 cl->buf = ctx->out_buf; 678 cl->buf = ctx->out_buf;
669 cl->next = NULL; 679 cl->next = NULL;
670 *ctx->last_out = cl; 680 *ctx->last_out = cl;
671 ctx->last_out = &cl->next; 681 ctx->last_out = &cl->next;
681 691
682 ctx->out_buf->flush = 0; 692 ctx->out_buf->flush = 0;
683 ctx->flush = Z_NO_FLUSH; 693 ctx->flush = Z_NO_FLUSH;
684 694
685 if (!(cl = ngx_alloc_chain_link(r->pool))) { 695 if (!(cl = ngx_alloc_chain_link(r->pool))) {
686 return ngx_http_gzip_error(ctx); 696 ngx_http_gzip_error(ctx);
697 return NGX_ERROR;
687 } 698 }
688 cl->buf = ctx->out_buf; 699 cl->buf = ctx->out_buf;
689 cl->next = NULL; 700 cl->next = NULL;
690 *ctx->last_out = cl; 701 *ctx->last_out = cl;
691 ctx->last_out = &cl->next; 702 ctx->last_out = &cl->next;
701 rc = deflateEnd(&ctx->zstream); 712 rc = deflateEnd(&ctx->zstream);
702 713
703 if (rc != Z_OK) { 714 if (rc != Z_OK) {
704 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, 715 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
705 "deflateEnd() failed: %d", rc); 716 "deflateEnd() failed: %d", rc);
706 return ngx_http_gzip_error(ctx); 717 ngx_http_gzip_error(ctx);
718 return NGX_ERROR;
707 } 719 }
708 720
709 ngx_pfree(r->pool, ctx->preallocated); 721 ngx_pfree(r->pool, ctx->preallocated);
710 722
711 if (!(cl = ngx_alloc_chain_link(r->pool))) { 723 if (!(cl = ngx_alloc_chain_link(r->pool))) {
712 return ngx_http_gzip_error(ctx); 724 ngx_http_gzip_error(ctx);
725 return NGX_ERROR;
713 } 726 }
714 cl->buf = ctx->out_buf; 727 cl->buf = ctx->out_buf;
715 cl->next = NULL; 728 cl->next = NULL;
716 *ctx->last_out = cl; 729 *ctx->last_out = cl;
717 ctx->last_out = &cl->next; 730 ctx->last_out = &cl->next;
721 ctx->out_buf->last += 8; 734 ctx->out_buf->last += 8;
722 ctx->out_buf->last_buf = 1; 735 ctx->out_buf->last_buf = 1;
723 736
724 } else { 737 } else {
725 if (!(b = ngx_create_temp_buf(r->pool, 8))) { 738 if (!(b = ngx_create_temp_buf(r->pool, 8))) {
726 return ngx_http_gzip_error(ctx); 739 ngx_http_gzip_error(ctx);
740 return NGX_ERROR;
727 } 741 }
728 742
729 b->last_buf = 1; 743 b->last_buf = 1;
730 744
731 if (!(cl = ngx_alloc_chain_link(r->pool))) { 745 if (!(cl = ngx_alloc_chain_link(r->pool))) {
732 return ngx_http_gzip_error(ctx); 746 ngx_http_gzip_error(ctx);
747 return NGX_ERROR;
733 } 748 }
734 cl->buf = b; 749 cl->buf = b;
735 cl->next = NULL; 750 cl->next = NULL;
736 *ctx->last_out = cl; 751 *ctx->last_out = cl;
737 ctx->last_out = &cl->next; 752 ctx->last_out = &cl->next;
738 trailer = (struct gztrailer *) b->pos; 753 trailer = (struct gztrailer *) b->pos;
739 b->last += 8; 754 b->last += 8;
740 } 755 }
741 756
742 #if (NGX_HAVE_LITTLE_ENDIAN) 757 #if (NGX_HAVE_LITTLE_ENDIAN && NGX_HAVE_NONALIGNED)
758
743 trailer->crc32 = ctx->crc32; 759 trailer->crc32 = ctx->crc32;
744 trailer->zlen = ctx->zin; 760 trailer->zlen = ctx->zin;
761
745 #else 762 #else
746 trailer->crc32[0] = ctx->crc32 & 0xff; 763 trailer->crc32[0] = (u_char) (ctx->crc32 & 0xff);
747 trailer->crc32[1] = (ctx->crc32 >> 8) & 0xff; 764 trailer->crc32[1] = (u_char) ((ctx->crc32 >> 8) & 0xff);
748 trailer->crc32[2] = (ctx->crc32 >> 16) & 0xff; 765 trailer->crc32[2] = (u_char) ((ctx->crc32 >> 16) & 0xff);
749 trailer->crc32[3] = (ctx->crc32 >> 24) & 0xff; 766 trailer->crc32[3] = (u_char) ((ctx->crc32 >> 24) & 0xff);
750 767
751 trailer->zlen[0] = ctx->zin & 0xff; 768 trailer->zlen[0] = (u_char) (ctx->zin & 0xff);
752 trailer->zlen[1] = (ctx->zin >> 8) & 0xff; 769 trailer->zlen[1] = (u_char) ((ctx->zin >> 8) & 0xff);
753 trailer->zlen[2] = (ctx->zin >> 16) & 0xff; 770 trailer->zlen[2] = (u_char) ((ctx->zin >> 16) & 0xff);
754 trailer->zlen[3] = (ctx->zin >> 24) & 0xff; 771 trailer->zlen[3] = (u_char) ((ctx->zin >> 24) & 0xff);
755 #endif 772 #endif
756 773
757 ctx->zstream.avail_in = 0; 774 ctx->zstream.avail_in = 0;
758 ctx->zstream.avail_out = 0; 775 ctx->zstream.avail_out = 0;
759 776
762 break; 779 break;
763 } 780 }
764 781
765 if (conf->no_buffer && ctx->in == NULL) { 782 if (conf->no_buffer && ctx->in == NULL) {
766 if (!(cl = ngx_alloc_chain_link(r->pool))) { 783 if (!(cl = ngx_alloc_chain_link(r->pool))) {
767 return ngx_http_gzip_error(ctx); 784 ngx_http_gzip_error(ctx);
785 return NGX_ERROR;
768 } 786 }
769 cl->buf = ctx->out_buf; 787 cl->buf = ctx->out_buf;
770 cl->next = NULL; 788 cl->next = NULL;
771 *ctx->last_out = cl; 789 *ctx->last_out = cl;
772 ctx->last_out = &cl->next; 790 ctx->last_out = &cl->next;
789 * we do not check NGX_AGAIN here because the downstream filters 807 * we do not check NGX_AGAIN here because the downstream filters
790 * may free some buffers and zlib may compress some data into them 808 * may free some buffers and zlib may compress some data into them
791 */ 809 */
792 810
793 if (last == NGX_ERROR) { 811 if (last == NGX_ERROR) {
794 return ngx_http_gzip_error(ctx); 812 ngx_http_gzip_error(ctx);
813 return NGX_ERROR;
795 } 814 }
796 815
797 ngx_chain_update_chains(&ctx->free, &ctx->busy, &ctx->out, 816 ngx_chain_update_chains(&ctx->free, &ctx->busy, &ctx->out,
798 (ngx_buf_tag_t) &ngx_http_gzip_filter_module); 817 (ngx_buf_tag_t) &ngx_http_gzip_filter_module);
799 ctx->last_out = &ctx->out; 818 ctx->last_out = &ctx->out;
856 #endif 875 #endif
857 } 876 }
858 877
859 878
860 static u_char *ngx_http_gzip_log_ratio(ngx_http_request_t *r, u_char *buf, 879 static u_char *ngx_http_gzip_log_ratio(ngx_http_request_t *r, u_char *buf,
861 uintptr_t data) 880 ngx_http_log_op_t *op)
862 { 881 {
863 ngx_uint_t zint, zfrac; 882 ngx_uint_t zint, zfrac;
864 ngx_http_gzip_ctx_t *ctx; 883 ngx_http_gzip_ctx_t *ctx;
865 884
866 ctx = ngx_http_get_module_ctx(r, ngx_http_gzip_filter_module); 885 ctx = ngx_http_get_module_ctx(r, ngx_http_gzip_filter_module);
887 906
888 return ngx_sprintf(buf, "%ui.%02ui", zint, zfrac); 907 return ngx_sprintf(buf, "%ui.%02ui", zint, zfrac);
889 } 908 }
890 909
891 910
892 static int ngx_http_gzip_error(ngx_http_gzip_ctx_t *ctx) 911 static void ngx_http_gzip_error(ngx_http_gzip_ctx_t *ctx)
893 { 912 {
894 deflateEnd(&ctx->zstream); 913 deflateEnd(&ctx->zstream);
895 914
896 if (ctx->preallocated) { 915 if (ctx->preallocated) {
897 ngx_pfree(ctx->request->pool, ctx->preallocated); 916 ngx_pfree(ctx->request->pool, ctx->preallocated);
900 ctx->zstream.avail_in = 0; 919 ctx->zstream.avail_in = 0;
901 ctx->zstream.avail_out = 0; 920 ctx->zstream.avail_out = 0;
902 921
903 ctx->done = 1; 922 ctx->done = 1;
904 923
905 return NGX_ERROR; 924 return;
906 } 925 }
907 926
908 927
909 static ngx_int_t ngx_http_gzip_pre_conf(ngx_conf_t *cf) 928 static ngx_int_t ngx_http_gzip_add_log_formats(ngx_conf_t *cf)
910 { 929 {
911 ngx_http_log_op_name_t *op; 930 ngx_http_log_op_name_t *op;
912 931
913 for (op = ngx_http_gzip_log_fmt_ops; op->name.len; op++) { /* void */ } 932 for (op = ngx_http_gzip_log_fmt_ops; op->name.len; op++) { /* void */ }
914 op->op = NULL; 933 op->run = NULL;
915 934
916 op = ngx_http_log_fmt_ops; 935 for (op = ngx_http_log_fmt_ops; op->run; op++) {
917
918 for (op = ngx_http_log_fmt_ops; op->op; op++) {
919 if (op->name.len == 0) { 936 if (op->name.len == 0) {
920 op = (ngx_http_log_op_name_t *) op->op; 937 op = (ngx_http_log_op_name_t *) op->run;
921 } 938 }
922 } 939 }
923 940
924 op->op = (ngx_http_log_op_pt) ngx_http_gzip_log_fmt_ops; 941 op->run = (ngx_http_log_op_run_pt) ngx_http_gzip_log_fmt_ops;
925 942
926 return NGX_OK; 943 return NGX_OK;
927 } 944 }
928 945
929 946
946 if (!(conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_gzip_conf_t)))) { 963 if (!(conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_gzip_conf_t)))) {
947 return NGX_CONF_ERROR; 964 return NGX_CONF_ERROR;
948 } 965 }
949 966
950 /* 967 /*
951 968 * set by ngx_pcalloc():
952 set by ngx_pcalloc(): 969 *
953 970 * conf->bufs.num = 0;
954 conf->bufs.num = 0; 971 * conf->proxied = 0;
955 conf->proxied = 0; 972 * conf->types = NULL;
956
957 conf->types = NULL;
958
959 */ 973 */
960 974
961 conf->enable = NGX_CONF_UNSET; 975 conf->enable = NGX_CONF_UNSET;
962 conf->no_buffer = NGX_CONF_UNSET; 976 conf->no_buffer = NGX_CONF_UNSET;
963 977