diff options
author | Maxim Dounin <mdounin@mdounin.ru> | 2012-02-13 15:23:43 +0000 |
---|---|---|
committer | Maxim Dounin <mdounin@mdounin.ru> | 2012-02-13 15:23:43 +0000 |
commit | 71ce7a13edff6180702f4982d6fb5744c9b81d5e (patch) | |
tree | f4172b08d3a79c840a57a293b2ddd9a1a51a791b /src | |
parent | 37c6228d43a26fbac3f251da69954207e6aae531 (diff) | |
download | nginx-71ce7a13edff6180702f4982d6fb5744c9b81d5e.tar.gz nginx-71ce7a13edff6180702f4982d6fb5744c9b81d5e.zip |
Gzip filter: handling of empty flush buffers.
Empty flush buffers are legitimate and may happen e.g. due to $r->flush()
calls in embedded perl. If there are no data buffered in zlib, deflate()
will return Z_BUF_ERROR (i.e. no progress possible) without adding anything
to output. Don't treat Z_BUF_ERROR as fatal and correctly send empty flush
buffer if we have no data in output at all.
See this thread for details:
http://mailman.nginx.org/pipermail/nginx/2010-November/023693.html
Diffstat (limited to 'src')
-rw-r--r-- | src/http/modules/ngx_http_gzip_filter_module.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/src/http/modules/ngx_http_gzip_filter_module.c b/src/http/modules/ngx_http_gzip_filter_module.c index 4429e01ba..128d3d9c8 100644 --- a/src/http/modules/ngx_http_gzip_filter_module.c +++ b/src/http/modules/ngx_http_gzip_filter_module.c @@ -759,6 +759,7 @@ static ngx_int_t ngx_http_gzip_filter_deflate(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx) { int rc; + ngx_buf_t *b; ngx_chain_t *cl; ngx_http_gzip_conf_t *conf; @@ -770,7 +771,7 @@ ngx_http_gzip_filter_deflate(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx) rc = deflate(&ctx->zstream, ctx->flush); - if (rc != Z_OK && rc != Z_STREAM_END) { + if (rc != Z_OK && rc != Z_STREAM_END && rc != Z_BUF_ERROR) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, "deflate() failed: %d, %d", ctx->flush, rc); return NGX_ERROR; @@ -819,8 +820,6 @@ ngx_http_gzip_filter_deflate(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx) if (ctx->flush == Z_SYNC_FLUSH) { - ctx->zstream.avail_out = 0; - ctx->out_buf->flush = 1; ctx->flush = Z_NO_FLUSH; cl = ngx_alloc_chain_link(r->pool); @@ -828,7 +827,22 @@ ngx_http_gzip_filter_deflate(ngx_http_request_t *r, ngx_http_gzip_ctx_t *ctx) return NGX_ERROR; } - cl->buf = ctx->out_buf; + b = ctx->out_buf; + + if (ngx_buf_size(b) == 0) { + + b = ngx_calloc_buf(ctx->request->pool); + if (b == NULL) { + return NGX_ERROR; + } + + } else { + ctx->zstream.avail_out = 0; + } + + b->flush = 1; + + cl->buf = b; cl->next = NULL; *ctx->last_out = cl; ctx->last_out = &cl->next; |