Mercurial > hg > nginx
comparison src/http/modules/ngx_http_gzip_filter.c @ 430:1fa5daf7558e
nginx-0.0.11-2004-09-19-22:27:00 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Sun, 19 Sep 2004 18:27:00 +0000 |
parents | b9bd635011de |
children | 358bbd2561b5 |
comparison
equal
deleted
inserted
replaced
429:694cd6cdb714 | 430:1fa5daf7558e |
---|---|
49 char *free_mem; | 49 char *free_mem; |
50 ngx_uint_t allocated; | 50 ngx_uint_t allocated; |
51 | 51 |
52 unsigned flush:4; | 52 unsigned flush:4; |
53 unsigned redo:1; | 53 unsigned redo:1; |
54 unsigned done:1; | |
55 #if 0 | |
54 unsigned pass:1; | 56 unsigned pass:1; |
55 unsigned done:1; | |
56 unsigned blocked:1; | 57 unsigned blocked:1; |
58 #endif | |
57 | 59 |
58 size_t zin; | 60 size_t zin; |
59 size_t zout; | 61 size_t zout; |
60 | 62 |
61 uint32_t crc32; | 63 uint32_t crc32; |
443 * TODO: 64-bit, autoconf of deflate_state size | 445 * TODO: 64-bit, autoconf of deflate_state size |
444 */ | 446 */ |
445 | 447 |
446 ctx->allocated = 8192 + (1 << (wbits + 2)) + (1 << (memlevel + 9)); | 448 ctx->allocated = 8192 + (1 << (wbits + 2)) + (1 << (memlevel + 9)); |
447 | 449 |
448 ngx_test_null(ctx->preallocated, ngx_palloc(r->pool, ctx->allocated), | 450 if (!(ctx->preallocated = ngx_palloc(r->pool, ctx->allocated))) { |
449 NGX_ERROR); | 451 return NGX_ERROR; |
452 } | |
453 | |
450 ctx->free_mem = ctx->preallocated; | 454 ctx->free_mem = ctx->preallocated; |
451 | 455 |
452 ctx->zstream.zalloc = ngx_http_gzip_filter_alloc; | 456 ctx->zstream.zalloc = ngx_http_gzip_filter_alloc; |
453 ctx->zstream.zfree = ngx_http_gzip_filter_free; | 457 ctx->zstream.zfree = ngx_http_gzip_filter_free; |
454 ctx->zstream.opaque = ctx; | 458 ctx->zstream.opaque = ctx; |
460 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, | 464 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, |
461 "deflateInit2() failed: %d", rc); | 465 "deflateInit2() failed: %d", rc); |
462 return ngx_http_gzip_error(ctx); | 466 return ngx_http_gzip_error(ctx); |
463 } | 467 } |
464 | 468 |
465 ngx_test_null(b, ngx_calloc_buf(r->pool), ngx_http_gzip_error(ctx)); | 469 if (!(b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)))) { |
470 return ngx_http_gzip_error(ctx); | |
471 } | |
466 | 472 |
467 b->memory = 1; | 473 b->memory = 1; |
468 b->pos = gzheader; | 474 b->pos = gzheader; |
469 b->last = b->pos + 10; | 475 b->last = b->pos + 10; |
470 | 476 |
486 | 492 |
487 for ( ;; ) { | 493 for ( ;; ) { |
488 | 494 |
489 for ( ;; ) { | 495 for ( ;; ) { |
490 | 496 |
491 /* is there a data to gzip ? */ | 497 /* does zlib need a new data ? */ |
492 | 498 |
493 if (ctx->zstream.avail_in == 0 | 499 if (ctx->zstream.avail_in == 0 |
494 && ctx->flush == Z_NO_FLUSH | 500 && ctx->flush == Z_NO_FLUSH |
495 && !ctx->redo) | 501 && !ctx->redo) |
496 { | 502 { |
517 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, | 523 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, |
518 "zstream.avail_in is huge"); | 524 "zstream.avail_in is huge"); |
519 ctx->done = 1; | 525 ctx->done = 1; |
520 return NGX_ERROR; | 526 return NGX_ERROR; |
521 } | 527 } |
528 /**/ | |
522 | 529 |
523 if (ctx->in_buf->last_buf) { | 530 if (ctx->in_buf->last_buf) { |
524 ctx->flush = Z_FINISH; | 531 ctx->flush = Z_FINISH; |
525 | 532 |
526 } else if (ctx->in_buf->flush) { | 533 } else if (ctx->in_buf->flush) { |
536 ctx->crc32 = crc32(ctx->crc32, ctx->zstream.next_in, | 543 ctx->crc32 = crc32(ctx->crc32, ctx->zstream.next_in, |
537 ctx->zstream.avail_in); | 544 ctx->zstream.avail_in); |
538 } | 545 } |
539 } | 546 } |
540 | 547 |
548 | |
541 /* is there a space for the gzipped data ? */ | 549 /* is there a space for the gzipped data ? */ |
542 | 550 |
543 if (ctx->zstream.avail_out == 0) { | 551 if (ctx->zstream.avail_out == 0) { |
552 | |
544 if (ctx->free) { | 553 if (ctx->free) { |
545 ctx->out_buf = ctx->free->buf; | 554 ctx->out_buf = ctx->free->buf; |
546 ctx->free = ctx->free->next; | 555 ctx->free = ctx->free->next; |
547 | 556 |
548 } else if (ctx->bufs < conf->bufs.num) { | 557 } else if (ctx->bufs < conf->bufs.num) { |
549 ngx_test_null(ctx->out_buf, | 558 ctx->out_buf = ngx_create_temp_buf(r->pool, |
550 ngx_create_temp_buf(r->pool, conf->bufs.size), | 559 conf->bufs.size); |
551 ngx_http_gzip_error(ctx)); | 560 if (ctx->out_buf == NULL) { |
561 return ngx_http_gzip_error(ctx); | |
562 } | |
563 | |
552 ctx->out_buf->tag = (ngx_buf_tag_t) | 564 ctx->out_buf->tag = (ngx_buf_tag_t) |
553 &ngx_http_gzip_filter_module; | 565 &ngx_http_gzip_filter_module; |
554 ctx->out_buf->recycled = 1; | 566 ctx->out_buf->recycled = 1; |
555 ctx->bufs++; | 567 ctx->bufs++; |
556 | 568 |
557 } else { | 569 } else { |
570 #if 0 | |
558 ctx->blocked = 1; | 571 ctx->blocked = 1; |
572 #endif | |
559 break; | 573 break; |
560 } | 574 } |
561 | 575 |
576 #if 0 | |
562 ctx->blocked = 0; | 577 ctx->blocked = 0; |
578 #endif | |
563 ctx->zstream.next_out = ctx->out_buf->pos; | 579 ctx->zstream.next_out = ctx->out_buf->pos; |
564 ctx->zstream.avail_out = conf->bufs.size; | 580 ctx->zstream.avail_out = conf->bufs.size; |
565 } | 581 } |
566 | 582 |
567 ngx_log_debug6(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 583 ngx_log_debug6(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
569 ctx->zstream.next_in, ctx->zstream.next_out, | 585 ctx->zstream.next_in, ctx->zstream.next_out, |
570 ctx->zstream.avail_in, ctx->zstream.avail_out, | 586 ctx->zstream.avail_in, ctx->zstream.avail_out, |
571 ctx->flush, ctx->redo); | 587 ctx->flush, ctx->redo); |
572 | 588 |
573 rc = deflate(&ctx->zstream, ctx->flush); | 589 rc = deflate(&ctx->zstream, ctx->flush); |
590 | |
574 if (rc != Z_OK && rc != Z_STREAM_END) { | 591 if (rc != Z_OK && rc != Z_STREAM_END) { |
575 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, | 592 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, |
576 "deflate() failed: %d, %d", ctx->flush, rc); | 593 "deflate() failed: %d, %d", ctx->flush, rc); |
577 return ngx_http_gzip_error(ctx); | 594 return ngx_http_gzip_error(ctx); |
578 } | 595 } |
597 } | 614 } |
598 | 615 |
599 ctx->out_buf->last = ctx->zstream.next_out; | 616 ctx->out_buf->last = ctx->zstream.next_out; |
600 | 617 |
601 if (ctx->zstream.avail_out == 0) { | 618 if (ctx->zstream.avail_out == 0) { |
619 | |
620 /* zlib wants to output some more gzipped data */ | |
621 | |
602 ngx_alloc_link_and_set_buf(cl, ctx->out_buf, r->pool, | 622 ngx_alloc_link_and_set_buf(cl, ctx->out_buf, r->pool, |
603 ngx_http_gzip_error(ctx)); | 623 ngx_http_gzip_error(ctx)); |
604 *ctx->last_out = cl; | 624 *ctx->last_out = cl; |
605 ctx->last_out = &cl->next; | 625 ctx->last_out = &cl->next; |
626 | |
606 ctx->redo = 1; | 627 ctx->redo = 1; |
607 | 628 |
608 continue; | 629 continue; |
609 } | 630 } |
610 | 631 |
611 ctx->redo = 0; | 632 ctx->redo = 0; |
612 | 633 |
613 if (ctx->flush == Z_SYNC_FLUSH) { | 634 if (ctx->flush == Z_SYNC_FLUSH) { |
635 | |
614 ctx->out_buf->flush = 0; | 636 ctx->out_buf->flush = 0; |
615 ctx->flush = Z_NO_FLUSH; | 637 ctx->flush = Z_NO_FLUSH; |
616 | 638 |
617 ngx_alloc_link_and_set_buf(cl, ctx->out_buf, r->pool, | 639 ngx_alloc_link_and_set_buf(cl, ctx->out_buf, r->pool, |
618 ngx_http_gzip_error(ctx)); | 640 ngx_http_gzip_error(ctx)); |
619 *ctx->last_out = cl; | 641 *ctx->last_out = cl; |
620 ctx->last_out = &cl->next; | 642 ctx->last_out = &cl->next; |
643 | |
644 #if 0 | |
621 ctx->pass = 1; | 645 ctx->pass = 1; |
646 #endif | |
622 | 647 |
623 break; | 648 break; |
624 } | 649 } |
625 | 650 |
626 if (rc == Z_STREAM_END) { | 651 if (rc == Z_STREAM_END) { |
627 | 652 |
628 ctx->zin = ctx->zstream.total_in; | 653 ctx->zin = ctx->zstream.total_in; |
629 ctx->zout = 10 + ctx->zstream.total_out + 8; | 654 ctx->zout = 10 + ctx->zstream.total_out + 8; |
630 | 655 |
631 rc = deflateEnd(&ctx->zstream); | 656 rc = deflateEnd(&ctx->zstream); |
657 | |
632 if (rc != Z_OK) { | 658 if (rc != Z_OK) { |
633 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, | 659 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, |
634 "deflateEnd() failed: %d", rc); | 660 "deflateEnd() failed: %d", rc); |
635 return ngx_http_gzip_error(ctx); | 661 return ngx_http_gzip_error(ctx); |
636 } | 662 } |
646 trailer = (struct gztrailer *) ctx->out_buf->last; | 672 trailer = (struct gztrailer *) ctx->out_buf->last; |
647 ctx->out_buf->last += 8; | 673 ctx->out_buf->last += 8; |
648 ctx->out_buf->last_buf = 1; | 674 ctx->out_buf->last_buf = 1; |
649 | 675 |
650 } else { | 676 } else { |
651 ngx_test_null(b, ngx_create_temp_buf(r->pool, 8), | 677 if (!(b = ngx_create_temp_buf(r->pool, 8))) { |
652 ngx_http_gzip_error(ctx)); | 678 return ngx_http_gzip_error(ctx); |
679 } | |
653 | 680 |
654 b->last_buf = 1; | 681 b->last_buf = 1; |
655 | 682 |
656 ngx_alloc_link_and_set_buf(cl, b, r->pool, | 683 ngx_alloc_link_and_set_buf(cl, b, r->pool, |
657 ngx_http_gzip_error(ctx)); | 684 ngx_http_gzip_error(ctx)); |
678 | 705 |
679 ctx->zstream.avail_in = 0; | 706 ctx->zstream.avail_in = 0; |
680 ctx->zstream.avail_out = 0; | 707 ctx->zstream.avail_out = 0; |
681 | 708 |
682 ctx->done = 1; | 709 ctx->done = 1; |
710 #if 0 | |
683 ctx->pass = 1; | 711 ctx->pass = 1; |
712 #endif | |
684 | 713 |
685 break; | 714 break; |
686 } | 715 } |
687 | 716 |
688 if (conf->no_buffer && ctx->in == NULL) { | 717 if (conf->no_buffer && ctx->in == NULL) { |
689 ngx_alloc_link_and_set_buf(cl, ctx->out_buf, r->pool, | 718 ngx_alloc_link_and_set_buf(cl, ctx->out_buf, r->pool, |
690 ngx_http_gzip_error(ctx)); | 719 ngx_http_gzip_error(ctx)); |
691 *ctx->last_out = cl; | 720 *ctx->last_out = cl; |
692 ctx->last_out = &cl->next; | 721 ctx->last_out = &cl->next; |
722 | |
723 #if 0 | |
693 ctx->pass = 1; | 724 ctx->pass = 1; |
725 #endif | |
694 | 726 |
695 break; | 727 break; |
696 } | 728 } |
697 } | 729 } |
730 | |
731 #if 0 | |
732 | |
733 /* OLD CODE */ | |
698 | 734 |
699 if (ctx->out) { | 735 if (ctx->out) { |
700 if (ctx->pass) { | 736 if (ctx->pass) { |
701 ctx->pass = 0; | 737 ctx->pass = 0; |
702 | 738 |
703 } else if (last == NGX_AGAIN) { | 739 } else if (last == NGX_AGAIN) { |
704 return last; | 740 return last; |
705 } | 741 } |
706 | 742 |
743 } else if (ctx->busy->buf && ngx_buf_size(ctx->busy->buf)) { | |
744 if (last != NGX_NONE) { | |
745 return last; | |
746 } | |
747 | |
707 } else if (ctx->blocked) { | 748 } else if (ctx->blocked) { |
708 if (last != NGX_NONE) { | 749 if (last != NGX_NONE) { |
709 return last; | 750 return last; |
710 } | 751 } |
711 | 752 |
714 return NGX_OK; | 755 return NGX_OK; |
715 } | 756 } |
716 | 757 |
717 return last; | 758 return last; |
718 } | 759 } |
760 #endif | |
761 | |
762 /* NEW CODE */ | |
763 | |
764 if (last == NGX_AGAIN) { | |
765 return NGX_AGAIN; | |
766 } | |
767 | |
768 if (ctx->out == NULL && ctx->busy == NULL) { | |
769 return NGX_OK; | |
770 } | |
771 | |
772 /**/ | |
719 | 773 |
720 last = ngx_http_next_body_filter(r, ctx->out); | 774 last = ngx_http_next_body_filter(r, ctx->out); |
775 | |
776 /* | |
777 * we do not check NGX_AGAIN here because the downstream filters | |
778 * may free some buffers and zlib may compress some data into them | |
779 */ | |
721 | 780 |
722 if (last == NGX_ERROR) { | 781 if (last == NGX_ERROR) { |
723 return ngx_http_gzip_error(ctx); | 782 return ngx_http_gzip_error(ctx); |
724 } | 783 } |
725 | 784 |
871 | 930 |
872 static void *ngx_http_gzip_create_conf(ngx_conf_t *cf) | 931 static void *ngx_http_gzip_create_conf(ngx_conf_t *cf) |
873 { | 932 { |
874 ngx_http_gzip_conf_t *conf; | 933 ngx_http_gzip_conf_t *conf; |
875 | 934 |
876 ngx_test_null(conf, | 935 if (!(conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_gzip_conf_t)))) { |
877 ngx_pcalloc(cf->pool, sizeof(ngx_http_gzip_conf_t)), | 936 return NGX_CONF_ERROR; |
878 NGX_CONF_ERROR); | 937 } |
879 | 938 |
880 /* set by ngx_pcalloc(): | 939 /* |
940 | |
941 set by ngx_pcalloc(): | |
881 | 942 |
882 conf->bufs.num = 0; | 943 conf->bufs.num = 0; |
883 conf->proxied = 0; | 944 conf->proxied = 0; |
884 | 945 |
885 */ | 946 */ |
886 | |
887 | 947 |
888 conf->enable = NGX_CONF_UNSET; | 948 conf->enable = NGX_CONF_UNSET; |
889 conf->no_buffer = NGX_CONF_UNSET; | 949 conf->no_buffer = NGX_CONF_UNSET; |
890 | |
891 | 950 |
892 conf->http_version = NGX_CONF_UNSET_UINT; | 951 conf->http_version = NGX_CONF_UNSET_UINT; |
893 | 952 |
894 conf->level = NGX_CONF_UNSET; | 953 conf->level = NGX_CONF_UNSET; |
895 conf->wbits = (size_t) NGX_CONF_UNSET; | 954 conf->wbits = (size_t) NGX_CONF_UNSET; |
931 { | 990 { |
932 int *np = data; | 991 int *np = data; |
933 | 992 |
934 int wbits, wsize; | 993 int wbits, wsize; |
935 | 994 |
936 | |
937 ngx_conf_log_error(NGX_LOG_INFO, cf, 0, "WBITS: %d", *np); | |
938 | |
939 wbits = 15; | 995 wbits = 15; |
996 | |
940 for (wsize = 32 * 1024; wsize > 256; wsize >>= 1) { | 997 for (wsize = 32 * 1024; wsize > 256; wsize >>= 1) { |
941 | 998 |
942 if (wsize == *np) { | 999 if (wsize == *np) { |
943 *np = wbits; | 1000 *np = wbits; |
944 ngx_conf_log_error(NGX_LOG_INFO, cf, 0, "WBITS: %d", *np); | 1001 |
945 return NULL; | 1002 return NGX_CONF_OK; |
946 } | 1003 } |
947 | 1004 |
948 wbits--; | 1005 wbits--; |
949 } | 1006 } |
950 | 1007 |
956 { | 1013 { |
957 int *np = data; | 1014 int *np = data; |
958 | 1015 |
959 int memlevel, hsize; | 1016 int memlevel, hsize; |
960 | 1017 |
961 | |
962 ngx_conf_log_error(NGX_LOG_INFO, cf, 0, "MEMLEVEL: %d", *np); | |
963 | |
964 memlevel = 9; | 1018 memlevel = 9; |
1019 | |
965 for (hsize = 128 * 1024; hsize > 256; hsize >>= 1) { | 1020 for (hsize = 128 * 1024; hsize > 256; hsize >>= 1) { |
966 | 1021 |
967 if (hsize == *np) { | 1022 if (hsize == *np) { |
968 *np = memlevel; | 1023 *np = memlevel; |
969 ngx_conf_log_error(NGX_LOG_INFO, cf, 0, "MEMLEVEL: %d", *np); | 1024 |
970 return NULL; | 1025 return NGX_CONF_OK; |
971 } | 1026 } |
972 | 1027 |
973 memlevel--; | 1028 memlevel--; |
974 } | 1029 } |
975 | 1030 |