]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Attempt to make progress on PR39727/PR45023 blocking migration
authorEric Covener <covener@apache.org>
Fri, 11 Apr 2014 02:42:05 +0000 (02:42 +0000)
committerEric Covener <covener@apache.org>
Fri, 11 Apr 2014 02:42:05 +0000 (02:42 +0000)
to 2.4.  Provide DeflateAlterETag directive to choose between
2.2 behavior, 2.4 behavior, or dropping ETag from the compressed
representation.

Preserves 2.4 default which breas 304 responses for compressed content.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1586542 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
docs/manual/mod/mod_deflate.xml
modules/filters/mod_deflate.c

diff --git a/CHANGES b/CHANGES
index 2d95509c95d5e8370213d3fb50583a315761fdf2..34e86044c7510e3f50430d1f15db66f93c9e0047 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,10 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.5.0
 
+  *) mod_deflate: Add DeflateAlterETag to control how the ETag
+     is modified. The 'NoChange' parameter mimics 2.2.x behavior.
+     PR 45023, PR 39727. [Eric Covener]
+
   *) mod_ssl: fix merging of global and vhost-level settings with the
      SSLCertificateFile, SSLCertificateKeyFile, and SSLOpenSSLConfCmd
      directives. PR 56353. [Kaspar Brand]
index a8da0c245540167057e20e3f8fd49c2826f06ad5..6cb4c7ed635cc5ecf3aa67919caced9a6b83437f 100644 (file)
@@ -298,6 +298,36 @@ CustomLog logs/deflate_log deflate
 </usage>
 </directivesynopsis>
 
+<directivesynopsis>
+<name>DeflateAlterETag</name>
+<description>How the outgoing ETag header should be modified during compression</description>
+<syntax>DeflateAlterETag AddSuffix|NoChange|Remove</syntax>
+<default>DeflateAlterETag AddSuffix</default>
+<contextlist><context>server config</context><context>virtual host</context>
+</contextlist>
+
+<usage>
+    <p>The <directive>DeflateAlterETag</directive> directive specifies
+    how the ETag hader should be altered when a response is compressed.</p>
+    <dl>
+    <dt>AddSuffix</dt>
+    <dd><p>Append the compression method onto the end of the ETag, causing 
+        compressed and uncompressed representatins to have unique ETags.  
+        This has been the default since 2.4.0, but prevents serving 
+        "HTTP Not Modified" (304) responses to conditional requests for 
+        compressed content.</p></dd>
+    <dt>NoChange</dt>
+    <dd><p>Don't change the ETag on a compressed response. This was the default
+        prior to 2.4.0, but does not satisfy the HTTP/1.1 property that all
+        representations of the same resource have unique ETags </p></dd>
+    <dt>Remove</dt>
+    <dd><p>Remove the ETag header from compressed responses. This prevents 
+        some conditional requests from being possible, but avoids the 
+        shortcomings of the preceding options.  </p></dd>
+    </dl>
+</usage>
+</directivesynopsis>
+
 
 </modulesynopsis>
 
index 74d6dd1ab2ac46c7c00b3c358f3ec527f8ea9dbe..55fe883501394118b1be454c15c1c9f3f7004dd9 100644 (file)
 static const char deflateFilterName[] = "DEFLATE";
 module AP_MODULE_DECLARE_DATA deflate_module;
 
+#define AP_DEFLATE_ETAG_ADDSUFFIX 0
+#define AP_DEFLATE_ETAG_NOCHANGE  1
+#define AP_DEFLATE_ETAG_REMOVE    2
+
 typedef struct deflate_filter_config_t
 {
     int windowSize;
@@ -63,6 +67,7 @@ typedef struct deflate_filter_config_t
     char *note_ratio_name;
     char *note_input_name;
     char *note_output_name;
+    int etag_opt;
 } deflate_filter_config;
 
 /* RFC 1952 Section 2.3 defines the gzip header:
@@ -280,6 +285,29 @@ static const char *deflate_set_memlevel(cmd_parms *cmd, void *dummy,
     return NULL;
 }
 
+static const char *deflate_set_etag(cmd_parms *cmd, void *dummy,
+                                        const char *arg)
+{
+    deflate_filter_config *c = ap_get_module_config(cmd->server->module_config,
+                                                    &deflate_module);
+
+    if (!strcasecmp(arg, "NoChange")) { 
+      c->etag_opt = AP_DEFLATE_ETAG_NOCHANGE;
+    }
+    else if (!strcasecmp(arg, "AddSuffix")) { 
+      c->etag_opt = AP_DEFLATE_ETAG_ADDSUFFIX;
+    }
+    else if (!strcasecmp(arg, "Remove")) { 
+      c->etag_opt = AP_DEFLATE_ETAG_REMOVE;
+    }
+    else { 
+        return "DeflateAlterETAG accepts only 'NoChange', 'AddSuffix', and 'Remove'";
+    }
+
+    return NULL;
+}
+
+
 static const char *deflate_set_compressionlevel(cmd_parms *cmd, void *dummy,
                                         const char *arg)
 {
@@ -398,11 +426,16 @@ static apr_status_t deflate_ctx_cleanup(void *data)
  * value inside the double-quotes if an ETag has already been set
  * and its value already contains double-quotes. PR 39727
  */
-static void deflate_check_etag(request_rec *r, const char *transform)
+static void deflate_check_etag(request_rec *r, const char *transform, int etag_opt)
 {
     const char *etag = apr_table_get(r->headers_out, "ETag");
     apr_size_t etaglen;
 
+    if (etag_opt == AP_DEFLATE_ETAG_REMOVE) { 
+        apr_table_unset(r->headers_out, "ETag");
+        return;
+    }
+
     if ((etag && ((etaglen = strlen(etag)) > 2))) {
         if (etag[etaglen - 1] == '"') {
             apr_size_t transformlen = strlen(transform);
@@ -708,7 +741,9 @@ static apr_status_t deflate_out_filter(ap_filter_t *f,
         }
         apr_table_unset(r->headers_out, "Content-Length");
         apr_table_unset(r->headers_out, "Content-MD5");
-        deflate_check_etag(r, "gzip");
+        if (c->etag_opt != AP_DEFLATE_ETAG_NOCHANGE) {  
+            deflate_check_etag(r, "gzip", c->etag_opt);
+        }
 
         /* For a 304 response, only change the headers */
         if (r->status == HTTP_NOT_MODIFIED) {
@@ -1401,7 +1436,9 @@ static apr_status_t inflate_out_filter(ap_filter_t *f,
          */
         apr_table_unset(r->headers_out, "Content-Length");
         apr_table_unset(r->headers_out, "Content-MD5");
-        deflate_check_etag(r, "gunzip");
+        if (c->etag_opt != AP_DEFLATE_ETAG_NOCHANGE) {
+            deflate_check_etag(r, "gunzip", c->etag_opt);
+        }
 
         /* For a 304 response, only change the headers */
         if (r->status == HTTP_NOT_MODIFIED) {
@@ -1741,6 +1778,9 @@ static const command_rec deflate_filter_cmds[] = {
                   "Set the Deflate Memory Level (1-9)"),
     AP_INIT_TAKE1("DeflateCompressionLevel", deflate_set_compressionlevel, NULL, RSRC_CONF,
                   "Set the Deflate Compression Level (1-9)"),
+    AP_INIT_TAKE1("DeflateAlterEtag", deflate_set_etag, NULL, RSRC_CONF,
+                  "Set how mod_deflate should modify ETAG response headers: 'AddSuffix' (default), 'NoChange' (2.2.x behavior), 'Remove'"),
     {NULL}
 };