Skip to content

Commit

Permalink
Gzip, gunzip: flush busy buffers if any.
Browse files Browse the repository at this point in the history
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).
  • Loading branch information
mdounin committed Oct 15, 2014
1 parent 9369cf8 commit 97e618c
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 4 deletions.
10 changes: 8 additions & 2 deletions src/http/modules/ngx_http_gunzip_filter_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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 */

Expand All @@ -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 ( ;; ) {
Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
Expand Down
10 changes: 8 additions & 2 deletions src/http/modules/ngx_http_gzip_filter_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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 */

Expand All @@ -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 ( ;; ) {
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down

0 comments on commit 97e618c

Please sign in to comment.