Mercurial > hg > nginx
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; |