mirror of
https://github.com/nginx/nginx.git
synced 2026-06-25 11:26:50 +00:00
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).
This commit is contained in:
parent
9369cf8df3
commit
97e618c556
2 changed files with 16 additions and 4 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue