httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j..@apache.org
Subject svn commit: r563464 - in /httpd/httpd/branches/2.2.x: CHANGES STATUS modules/filters/mod_deflate.c
Date Tue, 07 Aug 2007 12:09:27 GMT
Author: jim
Date: Tue Aug  7 05:09:26 2007
New Revision: 563464

URL: http://svn.apache.org/viewvc?view=rev&rev=563464
Log:
  *) mod_deflate: fix protocol handling in deflate input filter
     PR 23287 [Nick Kew]


Modified:
    httpd/httpd/branches/2.2.x/CHANGES
    httpd/httpd/branches/2.2.x/STATUS
    httpd/httpd/branches/2.2.x/modules/filters/mod_deflate.c

Modified: httpd/httpd/branches/2.2.x/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/CHANGES?view=diff&rev=563464&r1=563463&r2=563464
==============================================================================
--- httpd/httpd/branches/2.2.x/CHANGES [utf-8] (original)
+++ httpd/httpd/branches/2.2.x/CHANGES [utf-8] Tue Aug  7 05:09:26 2007
@@ -26,6 +26,9 @@
      values could previously point to cleaned up storage.  PR 41551.
      [Davi Arnaut <davi haxent.com.br>]
 
+  *) mod_deflate: fix protocol handling in deflate input filter
+     PR 23287 [Nick Kew]
+
   *) mime.types: add Registered Javascript/ECMAScript MIME types (RFC4329)
      PR 40299 [Dave Hodder <dmh dmh.org.uk>]
 

Modified: httpd/httpd/branches/2.2.x/STATUS
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/STATUS?view=diff&rev=563464&r1=563463&r2=563464
==============================================================================
--- httpd/httpd/branches/2.2.x/STATUS (original)
+++ httpd/httpd/branches/2.2.x/STATUS Tue Aug  7 05:09:26 2007
@@ -78,11 +78,6 @@
 PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
   [ start all new proposals below, under PATCHES PROPOSED. ]
 
-    * mod_deflate: fix protocol handling in input filter
-      PR: 23287
-      http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/filters/mod_deflate.c?r1=556113&r2=563133
-      +1: niq, rpluem, jim
-
     * mod_deflate: don't try to operate on a Content-Range
       trunk: http://svn.apache.org/viewvc?view=rev&revision=563154
              http://svn.apache.org/viewvc?view=rev&revision=563229

Modified: httpd/httpd/branches/2.2.x/modules/filters/mod_deflate.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/modules/filters/mod_deflate.c?view=diff&rev=563464&r1=563463&r2=563464
==============================================================================
--- httpd/httpd/branches/2.2.x/modules/filters/mod_deflate.c (original)
+++ httpd/httpd/branches/2.2.x/modules/filters/mod_deflate.c Tue Aug  7 05:09:26 2007
@@ -37,6 +37,7 @@
 #include "httpd.h"
 #include "http_config.h"
 #include "http_log.h"
+#include "apr_lib.h"
 #include "apr_strings.h"
 #include "apr_general.h"
 #include "util_filter.h"
@@ -82,6 +83,57 @@
 #define DEFAULT_MEMLEVEL 9
 #define DEFAULT_BUFFERSIZE 8096
 
+
+/* Check whether a request is gzipped, so we can un-gzip it.
+ * If a request has multiple encodings, we need the gzip
+ * to be the outermost non-identity encoding.
+ */
+static int check_gzip(apr_pool_t *pool, apr_table_t *hdrs)
+{
+    int found = 0;
+    const char *encoding = apr_table_get(hdrs, "Content-Encoding");
+    if (encoding && *encoding) {
+
+        /* check the usual/simple case first */
+        if (!strcasecmp(encoding, "gzip")
+            || !strcasecmp(encoding, "x-gzip")) {
+            found = 1;
+            apr_table_unset(hdrs, "Content-Encoding");
+        }
+        else if (ap_strchr_c(encoding, ',') != NULL) {
+            /* If the outermost encoding isn't gzip, there's nowt
+             * we can do.  So only check the last non-identity token
+             */
+            char *new_encoding = apr_pstrdup(pool, encoding);
+            char *ptr;
+            for(;;) {
+                char *token = ap_strrchr(new_encoding, ',');
+                if (!token) {        /* gzip:identity or other:identity */
+                    if (!strcasecmp(new_encoding, "gzip")
+                        || !strcasecmp(new_encoding, "x-gzip")) {
+                        apr_table_unset(hdrs, "Content-Encoding");
+                        found = 1;
+                    }
+                    break; /* seen all tokens */
+                }
+                for (ptr=token+1; apr_isspace(*ptr); ++ptr);
+                if (!strcasecmp(ptr, "gzip")
+                    || !strcasecmp(ptr, "x-gzip")) {
+                    *token = '\0';
+                    apr_table_setn(hdrs, "Content-Encoding", new_encoding);
+                    found = 1;
+                }
+                else if (!ptr[0] || !strcasecmp(ptr, "identity")) {
+                    *token = '\0';
+                    continue; /* strip the token and find the next one */
+                }
+                break; /* found a non-identity token */
+            }
+        }
+    }
+    return found;
+}
+
 /* Outputs a long in LSB order to the given file
  * only the bottom 4 bits are required for the deflate file format.
  */
@@ -654,9 +706,7 @@
     c = ap_get_module_config(r->server->module_config, &deflate_module);
 
     if (!ctx) {
-        int found = 0;
-        char *token, deflate_hdr[10];
-        const char *encoding;
+        char deflate_hdr[10];
         apr_size_t len;
 
         /* only work on main request/no subrequests */
@@ -665,26 +715,14 @@
             return ap_get_brigade(f->next, bb, mode, block, readbytes);
         }
 
-        /* Let's see what our current Content-Encoding is.
-         * If gzip is present, don't gzip again.  (We could, but let's not.)
+        /* Check whether request body is gzipped.
+         *
+         * If it is, we're transforming the contents, invalidating
+         * some request headers including Content-Encoding.
+         *
+         * If not, we just remove ourself.
          */
-        encoding = apr_table_get(r->headers_in, "Content-Encoding");
-        if (encoding) {
-            const char *tmp = encoding;
-
-            token = ap_get_token(r->pool, &tmp, 0);
-            while (token && token[0]) {
-                if (!strcasecmp(token, "gzip")) {
-                    found = 1;
-                    break;
-                }
-                /* Otherwise, skip token */
-                tmp++;
-                token = ap_get_token(r->pool, &tmp, 0);
-            }
-        }
-
-        if (found == 0) {
+        if (check_gzip(r->pool, r->headers_in) == 0) {
             ap_remove_input_filter(f);
             return ap_get_brigade(f->next, bb, mode, block, readbytes);
         }
@@ -699,6 +737,10 @@
             return rv;
         }
 
+        apr_table_unset(r->headers_in, "Content-Length");
+        apr_table_unset(r->headers_in, "Content-MD5");
+        apr_table_unset(r->headers_in, "Content-Range");
+
         len = 10;
         rv = apr_brigade_flatten(ctx->bb, deflate_hdr, &len);
         if (rv != APR_SUCCESS) {
@@ -919,9 +961,6 @@
     c = ap_get_module_config(r->server->module_config, &deflate_module);
 
     if (!ctx) {
-        int found = 0;
-        char *token;
-        const char *encoding;
 
         /* only work on main request/no subrequests */
         if (!ap_is_initial_req(r)) {
@@ -931,29 +970,12 @@
 
         /*
          * Let's see what our current Content-Encoding is.
-         * Only inflate if gzip is present.
+         * Only inflate if gzipped.
          */
-        encoding = apr_table_get(r->headers_out, "Content-Encoding");
-        if (encoding) {
-            const char *tmp = encoding;
-
-            token = ap_get_token(r->pool, &tmp, 0);
-            while (token && token[0]) {
-                if (!strcasecmp(token, "gzip")) {
-                    found = 1;
-                    break;
-                }
-                /* Otherwise, skip token */
-                tmp++;
-                token = ap_get_token(r->pool, &tmp, 0);
-            }
-        }
-
-        if (found == 0) {
+        if (check_gzip(r->pool, r->headers_out) == 0) {
             ap_remove_output_filter(f);
             return ap_pass_brigade(f->next, bb);
         }
-        apr_table_unset(r->headers_out, "Content-Encoding");
 
         /* No need to inflate HEAD or 204/304 */
         if (APR_BUCKET_IS_EOS(APR_BRIGADE_FIRST(bb))) {
@@ -961,6 +983,10 @@
             return ap_pass_brigade(f->next, bb);
         }
 
+	/* these are unlikely to be set anyway, but ... */
+        apr_table_unset(r->headers_out, "Content-Length");
+        apr_table_unset(r->headers_out, "Content-MD5");
+        apr_table_unset(r->headers_out, "Content-Range");
 
         f->ctx = ctx = apr_pcalloc(f->r->pool, sizeof(*ctx));
         ctx->bb = apr_brigade_create(r->pool, f->c->bucket_alloc);



Mime
View raw message