comparison src/http/modules/ngx_http_gzip_filter.c @ 469:2ff194b74f1e release-0.1.9

nginx-0.1.9-RELEASE import *) Bugfix: the proxied request was sent without arguments if the request contains "//", "/./", "/../" or "%XX". *) Bugfix: the large compressed responses may be transferred not completely. *) Bugfix: the files bigger than 2G was not transferred on Linux that does not support sendfile64(). *) Bugfix: while the build configuration on Linux the --with-poll_module parameter was required; the bug had appeared in 0.1.8.
author Igor Sysoev <igor@sysoev.ru>
date Thu, 25 Nov 2004 16:17:31 +0000
parents a88a3e4e158f
children c52408583801
comparison
equal deleted inserted replaced
468:1a67596d0349 469:2ff194b74f1e
235 235
236 236
237 237
238 static u_char gzheader[10] = { 0x1f, 0x8b, Z_DEFLATED, 0, 0, 0, 0, 0, 0, 3 }; 238 static u_char gzheader[10] = { 0x1f, 0x8b, Z_DEFLATED, 0, 0, 0, 0, 0, 0, 3 };
239 239
240 #if (HAVE_LITTLE_ENDIAN) 240 #if (NGX_HAVE_LITTLE_ENDIAN)
241 241
242 struct gztrailer { 242 struct gztrailer {
243 uint32_t crc32; 243 uint32_t crc32;
244 uint32_t zlen; 244 uint32_t zlen;
245 }; 245 };
246 246
247 #else /* HAVE_BIG_ENDIAN */ 247 #else /* NGX_HAVE_BIG_ENDIAN */
248 248
249 struct gztrailer { 249 struct gztrailer {
250 u_char crc32[4]; 250 u_char crc32[4];
251 u_char zlen[4]; 251 u_char zlen[4];
252 }; 252 };
435 435
436 436
437 static ngx_int_t ngx_http_gzip_body_filter(ngx_http_request_t *r, 437 static ngx_int_t ngx_http_gzip_body_filter(ngx_http_request_t *r,
438 ngx_chain_t *in) 438 ngx_chain_t *in)
439 { 439 {
440 int rc, wbits, memlevel, last; 440 int rc, wbits, memlevel;
441 ngx_int_t last;
441 struct gztrailer *trailer; 442 struct gztrailer *trailer;
442 ngx_buf_t *b; 443 ngx_buf_t *b;
443 ngx_chain_t *cl; 444 ngx_chain_t *cl;
444 ngx_http_gzip_ctx_t *ctx; 445 ngx_http_gzip_ctx_t *ctx;
445 ngx_http_gzip_conf_t *conf; 446 ngx_http_gzip_conf_t *conf;
467 } 468 }
468 469
469 /* 470 /*
470 * We preallocate a memory for zlib in one buffer (200K-400K), this 471 * We preallocate a memory for zlib in one buffer (200K-400K), this
471 * dicreases a number of malloc() and free() calls and also probably 472 * dicreases a number of malloc() and free() calls and also probably
472 * dicreases a number of syscalls (sbrk() or so). 473 * dicreases a number of syscalls (sbrk() and so on).
473 * Besides we free this memory as soon as the gzipping will complete 474 * Besides we free this memory as soon as the gzipping will complete
474 * and do not wait while a whole response will be sent to a client. 475 * and do not wait while a whole response will be sent to a client.
475 * 476 *
476 * 8K is for zlib deflate_state, it takes 477 * 8K is for zlib deflate_state, it takes
477 * * 5816 bytes on x86 and sparc64 (32-bit mode) 478 * * 5816 bytes on x86 and sparc64 (32-bit mode)
510 if (!(cl = ngx_alloc_chain_link(r->pool))) { 511 if (!(cl = ngx_alloc_chain_link(r->pool))) {
511 return ngx_http_gzip_error(ctx); 512 return ngx_http_gzip_error(ctx);
512 } 513 }
513 cl->buf = b; 514 cl->buf = b;
514 cl->next = NULL; 515 cl->next = NULL;
515 ctx->out = cl; 516
516 ctx->last_out = &cl->next; 517 /*
518 * We pass the gzheader to the next filter now to avoid its linking
519 * to the ctx->busy chain. zlib does not usually output the compressed
520 * 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().
522 */
523
524 if (ngx_http_next_body_filter(r, cl) == NGX_ERROR) {
525 return ngx_http_gzip_error(ctx);
526 }
527
528 ctx->last_out = &ctx->out;
517 529
518 ctx->crc32 = crc32(0L, Z_NULL, 0); 530 ctx->crc32 = crc32(0L, Z_NULL, 0);
519 ctx->flush = Z_NO_FLUSH; 531 ctx->flush = Z_NO_FLUSH;
520 } 532 }
521 533
725 ctx->last_out = &cl->next; 737 ctx->last_out = &cl->next;
726 trailer = (struct gztrailer *) b->pos; 738 trailer = (struct gztrailer *) b->pos;
727 b->last += 8; 739 b->last += 8;
728 } 740 }
729 741
730 #if (HAVE_LITTLE_ENDIAN) 742 #if (NGX_HAVE_LITTLE_ENDIAN)
731 trailer->crc32 = ctx->crc32; 743 trailer->crc32 = ctx->crc32;
732 trailer->zlen = ctx->zin; 744 trailer->zlen = ctx->zin;
733 #else 745 #else
734 trailer->crc32[0] = ctx->crc32 & 0xff; 746 trailer->crc32[0] = ctx->crc32 & 0xff;
735 trailer->crc32[1] = (ctx->crc32 >> 8) & 0xff; 747 trailer->crc32[1] = (ctx->crc32 >> 8) & 0xff;
761 773
762 break; 774 break;
763 } 775 }
764 } 776 }
765 777
766 if (last == NGX_AGAIN) { 778 if (last == NGX_AGAIN && !ctx->done) {
767 return NGX_AGAIN; 779 return NGX_AGAIN;
768 } 780 }
769 781
770 if (ctx->out == NULL && ctx->busy == NULL) { 782 if (ctx->out == NULL && ctx->busy == NULL) {
771 return NGX_OK; 783 return NGX_OK;
879 891
880 static int ngx_http_gzip_error(ngx_http_gzip_ctx_t *ctx) 892 static int ngx_http_gzip_error(ngx_http_gzip_ctx_t *ctx)
881 { 893 {
882 deflateEnd(&ctx->zstream); 894 deflateEnd(&ctx->zstream);
883 895
884 ngx_pfree(ctx->request->pool, ctx->preallocated); 896 if (ctx->preallocated) {
897 ngx_pfree(ctx->request->pool, ctx->preallocated);
898 }
885 899
886 ctx->zstream.avail_in = 0; 900 ctx->zstream.avail_in = 0;
887 ctx->zstream.avail_out = 0; 901 ctx->zstream.avail_out = 0;
888 902
889 ctx->done = 1; 903 ctx->done = 1;