]> granicus.if.org Git - apache/commitdiff
Merge r1484832, r1484914 from trunk:
authorJim Jagielski <jim@apache.org>
Sun, 7 Jul 2013 13:51:48 +0000 (13:51 +0000)
committerJim Jagielski <jim@apache.org>
Sun, 7 Jul 2013 13:51:48 +0000 (13:51 +0000)
mod_deflate: Remove assumptions as to when an EOS bucket might arrive.
Gracefully step aside if the body size is zero.

mod_deflate: Make sure we process any EOS bucket in our brigade and
save going the long way round.

Submitted by: minfrin
Reviewed/backported by: jim

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1500429 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
STATUS
modules/filters/mod_deflate.c

diff --git a/CHANGES b/CHANGES
index 4ddbde05871be479d82d0d5adb0dd2d07f1c46fc..6cf9cd9b748a219c1ceecf286b29f50f25f88013 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,9 @@
 
 Changes with Apache 2.4.5
 
+  *) mod_deflate: Remove assumptions as to when an EOS bucket might arrive.
+     Gracefully step aside if the body size is zero. [Graham Leggett]
+
   *) mod_session_dbd: Make sure that dirty flag is respected when saving
      sessions, and ensure the session ID is changed each time the session
      changes. [Takashi Sato <takashi tks.st>, Graham Leggett]
diff --git a/STATUS b/STATUS
index 8a3d7840de812f95cfe82782baa4d2a34cef326e..371ae12c486ba47434b68ec355ca8affbab71ab0 100644 (file)
--- a/STATUS
+++ b/STATUS
@@ -91,27 +91,6 @@ RELEASE SHOWSTOPPERS:
 PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
   [ start all new proposals below, under PATCHES PROPOSED. ]
 
-  * mod_deflate: Remove assumptions as to when an EOS bucket might arrive.
-    Gracefully step aside if the body size is zero.
-    trunk patch: http://svn.apache.org/r1484832
-                 http://svn.apache.org/r1484914
-    2.4.x patch: trunk works, modulo CHANGES
-    +1: minfrin, jim, sf
-    sf: The check for data after the compressed stream does not work
-        (see commented out test in r1499704).
-        But I think this can be fixed/removed later and vote +1 to get
-        the other fixes into 2.4.5.
-
-  * mod_session_dbd: Make sure that dirty flag is respected when saving 
-    sessions, and ensure the session ID is changed each time the session 
-    changes.
-    trunk patch: http://svn.apache.org/r1488158
-    trunk patch: http://svn.apache.org/r1488164
-    2.4.x patch: trunk patch works modulo CHANGES
-    +1: minfrin, jim, sf
-    sf says: Something like this should be added to CHANGES:
-        This changes the format of the updatesession SQL statement. Existing
-        configurations must be changed.
 
 
 PATCHES PROPOSED TO BACKPORT FROM TRUNK:
index 48d37b139289e1a3bae3692e5a44d9a8af4d7de4..79f6f8d1caf7881955b67b2a7a8a7bb76f7dc825 100644 (file)
@@ -304,8 +304,9 @@ typedef struct deflate_ctx_t
     int (*libz_end_func)(z_streamp);
     unsigned char *validation_buffer;
     apr_size_t validation_buffer_length;
-    int inflate_init;
-    int filter_init;
+    unsigned int inflate_init:1;
+    unsigned int filter_init:1;
+    unsigned int done:1;
 } deflate_ctx;
 
 /* Number of validation bytes (CRC and length) after the compressed data */
@@ -942,6 +943,13 @@ static apr_status_t deflate_in_filter(ap_filter_t *f,
             return rv;
         }
 
+        /* zero length body? step aside */
+        bkt = APR_BRIGADE_FIRST(ctx->bb);
+        if (APR_BUCKET_IS_EOS(bkt)) {
+            ap_remove_input_filter(f);
+            return ap_get_brigade(f->next, bb, mode, block, readbytes);
+        }
+
         apr_table_unset(r->headers_in, "Content-Length");
         apr_table_unset(r->headers_in, "Content-MD5");
 
@@ -1002,12 +1010,19 @@ static apr_status_t deflate_in_filter(ap_filter_t *f,
             const char *data;
             apr_size_t len;
 
-            /* If we actually see the EOS, that means we screwed up! */
             if (APR_BUCKET_IS_EOS(bkt)) {
-                inflateEnd(&ctx->stream);
-                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01390)
-                              "Encountered EOS bucket in inflate filter (bug?)");
-                return APR_EGENERAL;
+                if (!ctx->done) {
+                    inflateEnd(&ctx->stream);
+                    ap_log_rerror(
+                            APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02481) "Encountered premature end-of-stream while inflating");
+                    return APR_EGENERAL;
+                }
+
+                /* Move everything to the returning brigade. */
+                APR_BUCKET_REMOVE(bkt);
+                APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, bkt);
+                ap_remove_input_filter(f);
+                break;
             }
 
             if (APR_BUCKET_IS_FLUSH(bkt)) {
@@ -1036,6 +1051,13 @@ static apr_status_t deflate_in_filter(ap_filter_t *f,
                 break;
             }
 
+            /* sanity check - data after completed compressed body and before eos? */
+            if (ctx->done) {
+                ap_log_rerror(
+                        APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02482) "Encountered extra data after compressed data");
+                return APR_EGENERAL;
+            }
+
             /* read */
             apr_bucket_read(bkt, &data, &len, APR_BLOCK_READ);
 
@@ -1073,7 +1095,7 @@ static apr_status_t deflate_in_filter(ap_filter_t *f,
                 }
             }
             if (zRC == Z_STREAM_END) {
-                apr_bucket *tmp_heap, *eos;
+                apr_bucket *tmp_heap;
 
                 ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01393)
                               "Zlib: Inflated %ld to %ld : URL %s",
@@ -1120,9 +1142,7 @@ static apr_status_t deflate_in_filter(ap_filter_t *f,
 
                 inflateEnd(&ctx->stream);
 
-                eos = apr_bucket_eos_create(f->c->bucket_alloc);
-                APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, eos);
-                break;
+                ctx->done = 1;
             }
 
         }
@@ -1356,7 +1376,8 @@ static apr_status_t inflate_out_filter(ap_filter_t *f,
         apr_bucket_read(e, &data, &len, APR_BLOCK_READ);
 
         /* first bucket contains zlib header */
-        if (!ctx->inflate_init++) {
+        if (!ctx->inflate_init) {
+            ctx->inflate_init = 1;
             if (len < 10) {
                 ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01403)
                               "Insufficient data for inflate");