httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From n..@apache.org
Subject svn commit: r562507 - /httpd/httpd/trunk/modules/filters/mod_deflate.c
Date Fri, 03 Aug 2007 15:42:31 GMT
Author: niq
Date: Fri Aug  3 08:42:30 2007
New Revision: 562507

URL: http://svn.apache.org/viewvc?view=rev&rev=562507
Log:
Generalise the content encoding detection and protocol:
so it aslo works in inflate out filter, as suggested by rpluem.

NOTE: this fails with some generators (cgi, asis) due to a deeper bug:
content-encoding is set later than mod_deflate sees it.  This has always
been the case, and could use a separate fix if anyone wants inflate_out
other than in a proxy situation.  And it's not mod_deflate's problem.

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?view=diff&rev=562507&r1=562506&r2=562507
==============================================================================
--- httpd/httpd/trunk/modules/filters/mod_deflate.c (original)
+++ httpd/httpd/trunk/modules/filters/mod_deflate.c Fri Aug  3 08:42:30 2007
@@ -83,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.
  */
@@ -655,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 */
@@ -673,49 +722,7 @@
          *
          * If not, we just remove ourself.
          */
-        encoding = apr_table_get(r->headers_in, "Content-Encoding");
-        if (encoding && *encoding) {
-
-            /* check the usual/simple case first */
-            if (!strcasecmp(encoding, "gzip")
-                || !strcasecmp(encoding, "x-gzip")) {
-                found = 1;
-                apr_table_unset(r->headers_in, "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(r->pool, encoding);
-                char *ptr;
-                for(;;) {
-                    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(r->headers_in, "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(r->headers_in, "Content-Encoding",
-                                       new_encoding);
-                        found = 1;
-                    }
-                    else if (!strcasecmp(ptr, "identity")) {
-                        *token = '\0';
-                        continue; /* strip the token and find the next one */
-                    }
-                    break; /* found a non-identity token */
-                }
-            }
-        }
-
-        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);
         }
@@ -953,9 +960,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)) {
@@ -965,29 +969,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))) {
@@ -995,6 +982,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