You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ni...@apache.org on 2007/10/02 13:48:05 UTC

svn commit: r581198 - in /httpd/httpd/trunk: CHANGES modules/filters/mod_deflate.c

Author: niq
Date: Tue Oct  2 04:48:03 2007
New Revision: 581198

URL: http://svn.apache.org/viewvc?rev=581198&view=rev
Log:
mod_deflate: Don't leave a strong ETag in place while transforming the entity.
PR 39727

Comment: Another user just subscribed to this bug.
We need a fix more than we need an inconclusive discussion!

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

Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=581198&r1=581197&r2=581198&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Tue Oct  2 04:48:03 2007
@@ -2,6 +2,10 @@
 Changes with Apache 2.3.0
 [ When backported to 2.2.x, remove entry from this file ]
 
+  *) mod_deflate: Don't leave a strong ETag in place while transforming
+     the entity.
+     PR 39727 [Nick Kew]
+
   *) mod_proxy: Don't by default violate RFC2616 by setting
      Max-Forwards when the client didn't send it to us.
      Leave that as a configuration option.

Modified: httpd/httpd/trunk/modules/filters/mod_deflate.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/filters/mod_deflate.c?rev=581198&r1=581197&r2=581198&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/filters/mod_deflate.c (original)
+++ httpd/httpd/trunk/modules/filters/mod_deflate.c Tue Oct  2 04:48:03 2007
@@ -372,7 +372,28 @@
         ctx->libz_end_func(&ctx->stream);
     return APR_SUCCESS;
 }
-
+/* PR 39727: we're screwing up our clients if we leave a strong ETag
+ * header while transforming content.  A minimal fix that makes us
+ * protocol-compliant is to make it a weak ETag.  Whether we can
+ * use this ourselves (e.g. in mod_cache) is a different issue.
+ *
+ * Henrik Nordstrom suggests instead appending ";gzip", commenting:
+ *   "This should allows for easy bidirectional mapping, simplifying most
+ *   conditionals as no transformation of the entity body is needed to find
+ *   the etag, and the simple format makes it easier to trace should any
+ *   misunderstandings occur."
+ *
+ * We might consider such a strategy in future if we implement support
+ * for such a scheme.
+ */
+static void deflate_check_etag(request_rec *r)
+{
+    const char *etag = apr_table_get(r->headers_out, "ETag");
+    if (etag && (((etag[0] != 'W') && (etag[0] !='w')) || (etag[1] != '/'))) {
+        apr_table_set(r->headers_out, "ETag",
+                      apr_pstrcat(r->pool, "W/", etag, NULL));
+    }
+}
 static apr_status_t deflate_out_filter(ap_filter_t *f,
                                        apr_bucket_brigade *bb)
 {
@@ -570,6 +591,7 @@
         }
         apr_table_unset(r->headers_out, "Content-Length");
         apr_table_unset(r->headers_out, "Content-MD5");
+        deflate_check_etag(r);
 
         /* initialize deflate output buffer */
         ctx->stream.next_out = ctx->buffer;
@@ -1062,6 +1084,7 @@
         /* these are unlikely to be set anyway, but ... */
         apr_table_unset(r->headers_out, "Content-Length");
         apr_table_unset(r->headers_out, "Content-MD5");
+        deflate_check_etag(r);
 
         /* initialize inflate output buffer */
         ctx->stream.next_out = ctx->buffer;