mirror of
				https://github.com/openresty/openresty.git
				synced 2024-10-13 00:29:41 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			70 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			70 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| # HG changeset patch
 | |
| # User Maxim Dounin <mdounin@mdounin.ru>
 | |
| # Date 1315324342 -14400
 | |
| # Node ID 4cf0af103bc382a78f894302d1706929a79df4bb
 | |
| # Parent  d603ce98fada855f0100b422b7b5672fd22fabea
 | |
| Gzip filter: handle 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
 | |
| 
 | |
| diff --git a/src/http/modules/ngx_http_gzip_filter_module.c b/src/http/modules/ngx_http_gzip_filter_module.c
 | |
| --- a/src/http/modules/ngx_http_gzip_filter_module.c
 | |
| +++ b/src/http/modules/ngx_http_gzip_filter_module.c
 | |
| @@ -758,6 +758,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;
 | |
| 
 | |
| @@ -769,7 +770,7 @@ ngx_http_gzip_filter_deflate(ngx_http_re
 | |
| 
 | |
|     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;
 | |
| @@ -818,8 +819,6 @@ ngx_http_gzip_filter_deflate(ngx_http_re
 | |
| 
 | |
|     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);
 | |
| @@ -827,7 +826,22 @@ ngx_http_gzip_filter_deflate(ngx_http_re
 | |
|             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;
 |