From: Graham Leggett Date: Mon, 17 Jul 2023 20:40:44 +0000 (+0000) Subject: Backport to v2.4: X-Git-Tag: 2.4.58-rc1-candidate~68 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3ca0947ffe1b64e54e3f7e810d0fa5a523204bb0;p=thirdparty%2Fapache%2Fhttpd.git Backport to v2.4: *) 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 --- diff --git a/CHANGES b/CHANGES index 90a77313ac8..7fc19d1f2da 100644 --- 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 dcf9f906812..01c7fa6df30 100644 --- 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 diff --git a/docs/manual/mod/mod_deflate.xml b/docs/manual/mod/mod_deflate.xml index b903b8de0f8..11141cc7f55 100644 --- a/docs/manual/mod/mod_deflate.xml +++ b/docs/manual/mod/mod_deflate.xml @@ -207,6 +207,36 @@ content RewriteRule "\.css\.gz$" "-" [T=text/css,E=no-gzip:1] RewriteRule "\.js\.gz$" "-" [T=text/javascript,E=no-gzip:1] + +DeflateAlterETag +How the outgoing ETag header should be modified during compression +DeflateAlterETag AddSuffix|NoChange|Remove +DeflateAlterETag AddSuffix +server configvirtual host + + + +

The DeflateAlterETag directive specifies + how the ETag hader should be altered when a response is compressed.

+
+
AddSuffix
+

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.

+
NoChange
+

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

+
Remove
+

Remove the ETag header from compressed responses. This prevents + some conditional requests from being possible, but avoids the + shortcomings of the preceding options.

+
+
+
+ <FilesMatch "(\.js\.gz|\.css\.gz)$"> # Serve correct encoding type. diff --git a/modules/filters/mod_deflate.c b/modules/filters/mod_deflate.c index 2431fd7e8c9..de18606c795 100644 --- a/modules/filters/mod_deflate.c +++ b/modules/filters/mod_deflate.c @@ -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} };