diff options
| author | Maxim Dounin <mdounin@mdounin.ru> | 2014-10-15 22:57:23 +0400 |
|---|---|---|
| committer | Maxim Dounin <mdounin@mdounin.ru> | 2014-10-15 22:57:23 +0400 |
| commit | 97e618c55602aeb241c2adcb2fc8d00c02104653 (patch) | |
| tree | 65850d8e01d4fc17ad99b2d914958de71bd51010 | |
| parent | 9369cf8df3d38b3a5782a60d58afff33b87aae79 (diff) | |
| download | nginx-97e618c55602aeb241c2adcb2fc8d00c02104653.tar.gz nginx-97e618c55602aeb241c2adcb2fc8d00c02104653.tar.bz2 | |
Gzip, gunzip: flush busy buffers if any.
Previous code resulted in transfer stalls when client happened
to read all the data in buffers at once, while all gzip buffers
were exhausted (but ctx->nomem wasn't set). Make sure to call
next body filter at least once per call if there are busy buffers.
Additionally, handling of calls with NULL chain was changed to follow
the same logic, i.e., next body filter is only called with NULL chain
if there are busy buffers. This is expected to fix "output chain is empty"
alerts as reported by some users after c52a761a2029 (1.5.7).
Diffstat (limited to '')
| -rw-r--r-- | src/http/modules/ngx_http_gunzip_filter_module.c | 10 | ||||
| -rw-r--r-- | src/http/modules/ngx_http_gzip_filter_module.c | 10 |
2 files changed, 16 insertions, 4 deletions
diff --git a/src/http/modules/ngx_http_gunzip_filter_module.c b/src/http/modules/ngx_http_gunzip_filter_module.c index 70ec0aace..c1341f562 100644 --- a/src/http/modules/ngx_http_gunzip_filter_module.c +++ b/src/http/modules/ngx_http_gunzip_filter_module.c @@ -175,6 +175,7 @@ static ngx_int_t ngx_http_gunzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in) { int rc; + ngx_uint_t flush; ngx_chain_t *cl; ngx_http_gunzip_ctx_t *ctx; @@ -199,7 +200,7 @@ ngx_http_gunzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in) } } - if (ctx->nomem || in == NULL) { + if (ctx->nomem) { /* flush busy buffers */ @@ -212,6 +213,10 @@ ngx_http_gunzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in) ngx_chain_update_chains(r->pool, &ctx->free, &ctx->busy, &cl, (ngx_buf_tag_t) &ngx_http_gunzip_filter_module); ctx->nomem = 0; + flush = 0; + + } else { + flush = ctx->busy ? 1 : 0; } for ( ;; ) { @@ -258,7 +263,7 @@ ngx_http_gunzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in) /* rc == NGX_AGAIN */ } - if (ctx->out == NULL) { + if (ctx->out == NULL && !flush) { return ctx->busy ? NGX_AGAIN : NGX_OK; } @@ -276,6 +281,7 @@ ngx_http_gunzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in) "gunzip out: %p", ctx->out); ctx->nomem = 0; + flush = 0; if (ctx->done) { return rc; diff --git a/src/http/modules/ngx_http_gzip_filter_module.c b/src/http/modules/ngx_http_gzip_filter_module.c index c57a4a3c7..f941e6397 100644 --- a/src/http/modules/ngx_http_gzip_filter_module.c +++ b/src/http/modules/ngx_http_gzip_filter_module.c @@ -316,6 +316,7 @@ static ngx_int_t ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in) { int rc; + ngx_uint_t flush; ngx_chain_t *cl; ngx_http_gzip_ctx_t *ctx; @@ -372,7 +373,7 @@ ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in) r->connection->buffered |= NGX_HTTP_GZIP_BUFFERED; } - if (ctx->nomem || in == NULL) { + if (ctx->nomem) { /* flush busy buffers */ @@ -385,6 +386,10 @@ ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in) ngx_chain_update_chains(r->pool, &ctx->free, &ctx->busy, &cl, (ngx_buf_tag_t) &ngx_http_gzip_filter_module); ctx->nomem = 0; + flush = 0; + + } else { + flush = ctx->busy ? 1 : 0; } for ( ;; ) { @@ -432,7 +437,7 @@ ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in) /* rc == NGX_AGAIN */ } - if (ctx->out == NULL) { + if (ctx->out == NULL && !flush) { ngx_http_gzip_filter_free_copy_buf(r, ctx); return ctx->busy ? NGX_AGAIN : NGX_OK; @@ -457,6 +462,7 @@ ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in) ctx->last_out = &ctx->out; ctx->nomem = 0; + flush = 0; if (ctx->done) { return rc; |
