comparison src/http/modules/ngx_http_gzip_filter_module.c @ 2287:baa61933d5ed

use nomem flag to flush busy bufs, thus gzip filter does not depend on NGX_AGAIN return code
author Igor Sysoev <igor@sysoev.ru>
date Wed, 05 Nov 2008 15:46:41 +0000
parents 723df5089c05
children c28e47fb834c
comparison
equal deleted inserted replaced
2286:d795199b41ad 2287:baa61933d5ed
45 ngx_uint_t allocated; 45 ngx_uint_t allocated;
46 46
47 unsigned flush:4; 47 unsigned flush:4;
48 unsigned redo:1; 48 unsigned redo:1;
49 unsigned done:1; 49 unsigned done:1;
50 unsigned nomem:1;
50 51
51 size_t zin; 52 size_t zin;
52 size_t zout; 53 size_t zout;
53 54
54 uint32_t crc32; 55 uint32_t crc32;
260 261
261 static ngx_int_t 262 static ngx_int_t
262 ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in) 263 ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
263 { 264 {
264 int rc, wbits, memlevel; 265 int rc, wbits, memlevel;
265 ngx_int_t last;
266 struct gztrailer *trailer; 266 struct gztrailer *trailer;
267 ngx_buf_t *b; 267 ngx_buf_t *b;
268 ngx_chain_t *cl, out; 268 ngx_chain_t *cl, out;
269 ngx_http_gzip_ctx_t *ctx; 269 ngx_http_gzip_ctx_t *ctx;
270 ngx_http_gzip_conf_t *conf; 270 ngx_http_gzip_conf_t *conf;
364 ngx_http_gzip_error(ctx); 364 ngx_http_gzip_error(ctx);
365 return NGX_ERROR; 365 return NGX_ERROR;
366 } 366 }
367 } 367 }
368 368
369 last = NGX_NONE; 369 if (ctx->nomem) {
370 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
371 "gzip nomem");
372
373 if (ngx_http_next_body_filter(r, NULL) == NGX_ERROR) {
374 ngx_http_gzip_error(ctx);
375 return NGX_ERROR;
376 }
377
378 cl = NULL;
379
380 ngx_chain_update_chains(&ctx->free, &ctx->busy, &cl,
381 (ngx_buf_tag_t) &ngx_http_gzip_filter_module);
382 ctx->nomem = 0;
383 }
370 384
371 for ( ;; ) { 385 for ( ;; ) {
372 386
373 for ( ;; ) { 387 for ( ;; ) {
374 388
444 &ngx_http_gzip_filter_module; 458 &ngx_http_gzip_filter_module;
445 ctx->out_buf->recycled = 1; 459 ctx->out_buf->recycled = 1;
446 ctx->bufs++; 460 ctx->bufs++;
447 461
448 } else { 462 } else {
463 ctx->nomem = 1;
449 break; 464 break;
450 } 465 }
451 466
452 ctx->zstream.next_out = ctx->out_buf->pos; 467 ctx->zstream.next_out = ctx->out_buf->pos;
453 ctx->zstream.avail_out = conf->bufs.size; 468 ctx->zstream.avail_out = conf->bufs.size;
629 break; 644 break;
630 } 645 }
631 } 646 }
632 647
633 if (ctx->out == NULL) { 648 if (ctx->out == NULL) {
634 649 return NGX_AGAIN;
635 if (last == NGX_AGAIN) { 650 }
636 return NGX_AGAIN; 651
637 } 652 rc = ngx_http_next_body_filter(r, ctx->out);
638 653
639 if (ctx->busy == NULL) { 654 if (rc == NGX_ERROR) {
640 return NGX_OK;
641 }
642 }
643
644 last = ngx_http_next_body_filter(r, ctx->out);
645
646 /*
647 * we do not check NGX_AGAIN here because the downstream filters
648 * may free some buffers and zlib may compress some data into them
649 */
650
651 if (last == NGX_ERROR) {
652 ngx_http_gzip_error(ctx); 655 ngx_http_gzip_error(ctx);
653 return NGX_ERROR; 656 return NGX_ERROR;
654 } 657 }
655 658
656 ngx_chain_update_chains(&ctx->free, &ctx->busy, &ctx->out, 659 ngx_chain_update_chains(&ctx->free, &ctx->busy, &ctx->out,
657 (ngx_buf_tag_t) &ngx_http_gzip_filter_module); 660 (ngx_buf_tag_t) &ngx_http_gzip_filter_module);
658 ctx->last_out = &ctx->out; 661 ctx->last_out = &ctx->out;
659 662
663 ctx->nomem = 0;
664
660 if (ctx->done) { 665 if (ctx->done) {
661 return last; 666 return rc;
662 } 667 }
663 } 668 }
664 } 669 }
665 670
666 671