]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Backport to v2.4:
authorGraham Leggett <minfrin@apache.org>
Mon, 17 Jul 2023 20:40:44 +0000 (20:40 +0000)
committerGraham Leggett <minfrin@apache.org>
Mon, 17 Jul 2023 20:40:44 +0000 (20:40 +0000)
  *) mod_deflate: Add DeflateAlterETag to control how the ETag
     is modified. The 'NoChange' parameter mimics 2.2.x behavior.
     PR 45023, PR 39727.
     Trunk version of patch:
        https://svn.apache.org/r1586542
     Backport version for 2.4.x of patch:
      https://raw.githubusercontent.com/jfclere/patch/main/mod_deflate.patch
     +1: jfclere, rpluem, ylavic
     rpluem says: Does anyone know why we don't merge the server config?

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

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

diff --git a/CHANGES b/CHANGES
index 90a77313ac8c793e7ba2c2c0c3f156b75ee1c135..7fc19d1f2da8fe5463bf89f7a1a45012438eb602 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,10 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.4.58
 
+  *) 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]
+
   *) core: Optimize send_brigade_nonblocking(). [Christophe Jaillet]
 
   *) Easy patches: synch 2.4.x and trunk
diff --git a/STATUS b/STATUS
index dcf9f9068128ae1b9ef48ec7e9c957eb95687075..01c7fa6df30469aa7beed09d964c27f627d53d12 100644 (file)
--- a/STATUS
+++ b/STATUS
@@ -152,16 +152,6 @@ RELEASE SHOWSTOPPERS:
 PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
   [ start all new proposals below, under PATCHES PROPOSED. ]
 
-  *) mod_deflate: Add DeflateAlterETag to control how the ETag
-     is modified. The 'NoChange' parameter mimics 2.2.x behavior.
-     PR 45023, PR 39727.
-     Trunk version of patch:
-        https://svn.apache.org/r1586542
-     Backport version for 2.4.x of patch:
-      https://raw.githubusercontent.com/jfclere/patch/main/mod_deflate.patch
-     +1: jfclere, rpluem, ylavic
-     rpluem says: Does anyone know why we don't merge the server config?
-
   *) mime.types update to sync with trunk
      Trunk version of patch:
         https://svn.apache.org/r1884511
index b903b8de0f8d7b7a578178b4bffc4896169c551c..11141cc7f55117a9e6d8e2d7c7c1eb670c7a9aff 100644 (file)
@@ -207,6 +207,36 @@ content</title>
     RewriteRule "\.css\.gz$" "-" [T=text/css,E=no-gzip:1]
     RewriteRule "\.js\.gz$"  "-" [T=text/javascript,E=no-gzip:1]
 
+<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>
+
 
     &lt;FilesMatch "(\.js\.gz|\.css\.gz)$"&gt;
       # Serve correct encoding type.
index 2431fd7e8c9d3764c128948e613678b36add2ca4..de18606c79566a20b7c7780b103fa0b81385b689 100644 (file)
@@ -57,6 +57,10 @@ module AP_MODULE_DECLARE_DATA deflate_module;
 #define AP_INFLATE_RATIO_LIMIT 200
 #define AP_INFLATE_RATIO_BURST 3
 
+#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;
@@ -66,6 +70,7 @@ typedef struct deflate_filter_config_t
     const char *note_ratio_name;
     const char *note_input_name;
     const char *note_output_name;
+    int etag_opt;
 } deflate_filter_config;
 
 typedef struct deflate_dirconf_t {
@@ -295,6 +300,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)
 {
@@ -464,11 +492,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);
@@ -809,7 +842,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) {
@@ -1566,7 +1601,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) {
@@ -1922,6 +1959,9 @@ static const command_rec deflate_filter_cmds[] = {
     AP_INIT_TAKE1("DeflateInflateRatioBurst", deflate_set_inflate_ratio_burst, NULL, OR_ALL,
                   "Set the maximum number of following inflate ratios above limit "
                   "(default: " APR_STRINGIFY(AP_INFLATE_RATIO_BURST) ")"),
+   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}
 };