You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2019/11/28 14:44:56 UTC
[tomcat] branch master updated: Fix
https://bz.apache.org/bugzilla/show_bug.cgi?id=63932 ETag & gzip
This is an automated email from the ASF dual-hosted git repository.
markt pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/master by this push:
new 389231b Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=63932 ETag & gzip
389231b is described below
commit 389231bccaa28d9a4142b91bfcdecec9d2fa9764
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Thu Nov 28 14:44:20 2019 +0000
Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=63932 ETag & gzip
By default, do not compress content that has a strong ETag. This
behaviour is configuration for the HTTP/1.1 and HTTP/2 connectors via
the new Connector attribute noCompressionStrongETag
---
java/org/apache/coyote/CompressionConfig.java | 40 ++++++++++++++++++++++
.../coyote/http11/AbstractHttp11Protocol.java | 10 ++++++
java/org/apache/coyote/http2/Http2Protocol.java | 10 ++++++
test/org/apache/coyote/TestCompressionConfig.java | 33 ++++++++++++++----
webapps/docs/changelog.xml | 6 ++++
webapps/docs/config/http.xml | 8 +++++
webapps/docs/config/http2.xml | 8 +++++
7 files changed, 108 insertions(+), 7 deletions(-)
diff --git a/java/org/apache/coyote/CompressionConfig.java b/java/org/apache/coyote/CompressionConfig.java
index 520ed2e..8bb11f9 100644
--- a/java/org/apache/coyote/CompressionConfig.java
+++ b/java/org/apache/coyote/CompressionConfig.java
@@ -46,6 +46,7 @@ public class CompressionConfig {
"text/javascript,application/javascript,application/json,application/xml";
private String[] compressibleMimeTypes = null;
private int compressionMinSize = 2048;
+ private boolean noCompressionStrongETag = true;
/**
@@ -183,6 +184,35 @@ public class CompressionConfig {
/**
+ * Determine if compression is disabled if the resource has a strong ETag.
+ *
+ * @return {@code true} if compression is disabled, otherwise {@code false}
+ *
+ * @deprecated Will be removed in Tomcat 10 where it will be hard-coded to
+ * {@code true}
+ */
+ @Deprecated
+ public boolean getNoCompressionStrongETag() {
+ return noCompressionStrongETag;
+ }
+
+
+ /**
+ * Set whether compression is disabled for resources with a strong ETag.
+ *
+ * @param noCompressionStrongETag {@code true} if compression is disabled,
+ * otherwise {@code false}
+ *
+ * @deprecated Will be removed in Tomcat 10 where it will be hard-coded to
+ * {@code true}
+ */
+ @Deprecated
+ public void setNoCompressionStrongEtag(boolean noCompressionStrongETag) {
+ this.noCompressionStrongETag = noCompressionStrongETag;
+ }
+
+
+ /**
* Determines if compression should be enabled for the given response and if
* it is, sets any necessary headers to mark it as such.
*
@@ -235,6 +265,16 @@ public class CompressionConfig {
}
}
+ // Check if the resource has a strong ETag
+ if (noCompressionStrongETag) {
+ String eTag = responseHeaders.getHeader("ETag");
+ if (eTag != null && !eTag.trim().startsWith("W/")) {
+ // Has an ETag that doesn't start with "W/..." so it must be a
+ // strong ETag
+ return false;
+ }
+ }
+
// If processing reaches this far, the response might be compressed.
// Therefore, set the Vary header to keep proxies happy
ResponseUtil.addVaryFieldName(responseHeaders, "accept-encoding");
diff --git a/java/org/apache/coyote/http11/AbstractHttp11Protocol.java b/java/org/apache/coyote/http11/AbstractHttp11Protocol.java
index 61d9a0c..70387b9 100644
--- a/java/org/apache/coyote/http11/AbstractHttp11Protocol.java
+++ b/java/org/apache/coyote/http11/AbstractHttp11Protocol.java
@@ -279,6 +279,16 @@ public abstract class AbstractHttp11Protocol<S> extends AbstractProtocol<S> {
}
+ @Deprecated
+ public boolean getNoCompressionStrongETag() {
+ return compressionConfig.getNoCompressionStrongETag();
+ }
+ @Deprecated
+ public void setNoCompressionStrongEtag(boolean noCompressionStrongETag) {
+ compressionConfig.setNoCompressionStrongEtag(noCompressionStrongETag);
+ }
+
+
public boolean useCompression(Request request, Response response) {
return compressionConfig.useCompression(request, response);
}
diff --git a/java/org/apache/coyote/http2/Http2Protocol.java b/java/org/apache/coyote/http2/Http2Protocol.java
index 9597b79..1f3dfe0 100644
--- a/java/org/apache/coyote/http2/Http2Protocol.java
+++ b/java/org/apache/coyote/http2/Http2Protocol.java
@@ -405,6 +405,16 @@ public class Http2Protocol implements UpgradeProtocol {
}
+ @Deprecated
+ public boolean getNoCompressionStrongETag() {
+ return compressionConfig.getNoCompressionStrongETag();
+ }
+ @Deprecated
+ public void setNoCompressionStrongEtag(boolean noCompressionStrongETag) {
+ compressionConfig.setNoCompressionStrongEtag(noCompressionStrongETag);
+ }
+
+
public boolean useCompression(Request request, Response response) {
return compressionConfig.useCompression(request, response);
}
diff --git a/test/org/apache/coyote/TestCompressionConfig.java b/test/org/apache/coyote/TestCompressionConfig.java
index 23d9d12..0d8c0a0 100644
--- a/test/org/apache/coyote/TestCompressionConfig.java
+++ b/test/org/apache/coyote/TestCompressionConfig.java
@@ -29,16 +29,24 @@ import org.junit.runners.Parameterized.Parameter;
@RunWith(Parameterized.class)
public class TestCompressionConfig {
- @Parameterized.Parameters(name = "{index}: headers[{0}], compress[{1}]")
+ @Parameterized.Parameters(name = "{index}: accept-encoding[{0}], ETag [{1}], NoCompressionStrongETag[{2}], compress[{3}]")
public static Collection<Object[]> parameters() {
List<Object[]> parameterSets = new ArrayList<>();
- parameterSets.add(new Object[] { new String[] { }, Boolean.FALSE });
- parameterSets.add(new Object[] { new String[] { "gzip" }, Boolean.TRUE });
- parameterSets.add(new Object[] { new String[] { "xgzip" }, Boolean.FALSE });
- parameterSets.add(new Object[] { new String[] { "<>gzip" }, Boolean.FALSE });
- parameterSets.add(new Object[] { new String[] { "foo", "gzip" }, Boolean.TRUE });
- parameterSets.add(new Object[] { new String[] { "<>", "gzip" }, Boolean.TRUE });
+ parameterSets.add(new Object[] { new String[] { }, null, Boolean.TRUE, Boolean.FALSE });
+ parameterSets.add(new Object[] { new String[] { "gzip" }, null, Boolean.TRUE, Boolean.TRUE });
+ parameterSets.add(new Object[] { new String[] { "xgzip" }, null, Boolean.TRUE, Boolean.FALSE });
+ parameterSets.add(new Object[] { new String[] { "<>gzip" }, null, Boolean.TRUE, Boolean.FALSE });
+ parameterSets.add(new Object[] { new String[] { "foo", "gzip" }, null, Boolean.TRUE, Boolean.TRUE });
+ parameterSets.add(new Object[] { new String[] { "<>", "gzip" }, null, Boolean.TRUE, Boolean.TRUE });
+
+ parameterSets.add(new Object[] { new String[] { "gzip" }, null, Boolean.TRUE, Boolean.TRUE });
+ parameterSets.add(new Object[] { new String[] { "gzip" }, "W/", Boolean.TRUE, Boolean.TRUE });
+ parameterSets.add(new Object[] { new String[] { "gzip" }, "XX", Boolean.TRUE, Boolean.FALSE });
+
+ parameterSets.add(new Object[] { new String[] { "gzip" }, null, Boolean.FALSE, Boolean.TRUE });
+ parameterSets.add(new Object[] { new String[] { "gzip" }, "W/", Boolean.FALSE, Boolean.TRUE });
+ parameterSets.add(new Object[] { new String[] { "gzip" }, "XX", Boolean.FALSE, Boolean.TRUE });
return parameterSets;
}
@@ -46,14 +54,20 @@ public class TestCompressionConfig {
@Parameter(0)
public String[] headers;
@Parameter(1)
+ public String eTag;
+ @Parameter(2)
+ public Boolean noCompressionStrongETag;
+ @Parameter(3)
public Boolean compress;
+ @SuppressWarnings("deprecation")
@Test
public void testUseCompression() throws Exception {
CompressionConfig compressionConfig = new CompressionConfig();
// Skip length and MIME type checks
compressionConfig.setCompression("force");
+ compressionConfig.setNoCompressionStrongEtag(noCompressionStrongETag.booleanValue());
Request request = new Request();
Response response = new Response();
@@ -62,6 +76,11 @@ public class TestCompressionConfig {
request.getMimeHeaders().addValue("accept-encoding").setString(header);
}
+ if (eTag != null) {
+ response.getMimeHeaders().addValue("ETag").setString(eTag);
+ }
+
+
Assert.assertEquals(compress, Boolean.valueOf(compressionConfig.useCompression(request, response)));
}
}
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index c303810..3d46430 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -70,6 +70,12 @@
(remm)
</fix>
<fix>
+ <bug>63932</bug>: By default, do not compress content that has a strong
+ ETag. This behaviour is configuration for the HTTP/1.1 and HTTP/2
+ connectors via the new Connector attribute
+ <code>noCompressionStrongETag</code>. (markt)
+ </fix>
+ <fix>
<bug>63949</bug>: Fix non blocking write problems with NIO due to the
need for a write loop. (remm)
</fix>
diff --git a/webapps/docs/config/http.xml b/webapps/docs/config/http.xml
index 0f95e65..057ee47 100644
--- a/webapps/docs/config/http.xml
+++ b/webapps/docs/config/http.xml
@@ -520,6 +520,14 @@
used.</p>
</attribute>
+ <attribute name="noCompressionStrongETag" required="false">
+ <p>This flag configures whether resources with a stong ETag will be
+ considered for compression. If <code>true</code>, resources with a strong
+ ETag will not be compressed. The default value is <code>true</code>.</p>
+ <p>This attribute is deprecated. It will be removed in Tomcat 10 onwards
+ where it will be hard-coded to <code>true</code>.</p>
+ </attribute>
+
<attribute name="noCompressionUserAgents" required="false">
<p>The value is a regular expression (using <code>java.util.regex</code>)
matching the <code>user-agent</code> header of HTTP clients for which
diff --git a/webapps/docs/config/http2.xml b/webapps/docs/config/http2.xml
index 02400e6..00f75cb 100644
--- a/webapps/docs/config/http2.xml
+++ b/webapps/docs/config/http2.xml
@@ -179,6 +179,14 @@
means no limit. If not specified, a default of 8192 is used.</p>
</attribute>
+ <attribute name="noCompressionStrongETag" required="false">
+ <p>This flag configures whether resources with a stong ETag will be
+ considered for compression. If <code>true</code>, resources with a strong
+ ETag will not be compressed. The default value is <code>true</code>.</p>
+ <p>This attribute is deprecated. It will be removed in Tomcat 10 onwards
+ where it will be hard-coded to <code>true</code>.</p>
+ </attribute>
+
<attribute name="noCompressionUserAgents" required="false">
<p>The value is a regular expression (using <code>java.util.regex</code>)
matching the <code>user-agent</code> header of HTTP clients for which
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org