httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From s.@apache.org
Subject svn commit: r1170330 - /httpd/httpd/trunk/modules/filters/mod_deflate.c
Date Tue, 13 Sep 2011 20:17:18 GMT
Author: sf
Date: Tue Sep 13 20:17:18 2011
New Revision: 1170330

URL: http://svn.apache.org/viewvc?rev=1170330&view=rev
Log:
Fix 'Content-Encoding: gzip' missing if the first brigade passed to
deflate_out_buffer contained zero data bytes but no EOS bucket.

Don't compress if the added headers and checksums are larger than
the data to compress (and we know the size of the data in advance).

Modified:
    httpd/httpd/trunk/modules/filters/mod_deflate.c

Modified: httpd/httpd/trunk/modules/filters/mod_deflate.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/filters/mod_deflate.c?rev=1170330&r1=1170329&r2=1170330&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/filters/mod_deflate.c (original)
+++ httpd/httpd/trunk/modules/filters/mod_deflate.c Tue Sep 13 20:17:18 2011
@@ -426,7 +426,7 @@ static apr_status_t deflate_out_filter(a
     request_rec *r = f->r;
     deflate_ctx *ctx = f->ctx;
     int zRC;
-    apr_size_t len;
+    apr_size_t len = 0, blen;
     const char *data;
     deflate_filter_config *c;
 
@@ -448,28 +448,41 @@ static apr_status_t deflate_out_filter(a
         char *token;
         const char *encoding;
 
-        /* Delay initialization until we have seen some data */
-        e = APR_BRIGADE_FIRST(bb);
-        while (1) {
-            apr_status_t rc;
-            if (e == APR_BRIGADE_SENTINEL(bb))
-                return ap_pass_brigade(f->next, bb);
-            if (APR_BUCKET_IS_EOS(e)) {
-                ap_remove_output_filter(f);
-                return ap_pass_brigade(f->next, bb);
-            }
-            if (APR_BUCKET_IS_METADATA(e)) {
-                e = APR_BUCKET_NEXT(e);
-                continue;
-            }
+        e = APR_BRIGADE_LAST(bb);
+        if (APR_BUCKET_IS_EOS(e)) {
+            /*
+             * If we already know the size of the response, we can skip
+             * compression on responses smaller than the compression overhead.
+             * However, if we compress, we must initialize deflate_out before
+             * calling ap_pass_brigade() for the first time.  Otherwise the
+             * headers will be sent to the client without
+             * "Content-Encoding: gzip".
+             */
+            e = APR_BRIGADE_FIRST(bb);
+            while (1) {
+                apr_status_t rc;
+                if (APR_BUCKET_IS_EOS(e)) {
+                    ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r,
+                                  "Not compressing very small response of %"
+                                  APR_SIZE_T_FMT " bytes", len);
+                    ap_remove_output_filter(f);
+                    return ap_pass_brigade(f->next, bb);
+                }
+                if (APR_BUCKET_IS_METADATA(e)) {
+                    e = APR_BUCKET_NEXT(e);
+                    continue;
+                }
 
-            rc = apr_bucket_read(e, &data, &len, APR_BLOCK_READ);
-            if (rc != APR_SUCCESS)
-                return rc;
-            if (len > 0)
-                break;
+                rc = apr_bucket_read(e, &data, &blen, APR_BLOCK_READ);
+                if (rc != APR_SUCCESS)
+                    return rc;
+                len += blen;
+                /* 50 is for Content-Encoding and Vary headers and ETag suffix */
+                if (len > sizeof(gzip_header) + VALIDATION_SIZE + 50)
+                    break;
 
-            e = APR_BUCKET_NEXT(e);
+                e = APR_BUCKET_NEXT(e);
+            }
         }
 
         ctx = f->ctx = apr_pcalloc(r->pool, sizeof(*ctx));



Mime
View raw message