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;
 |