This is an automated email from the ASF dual-hosted git repository.
markt pushed a commit to branch 7.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/7.0.x by this push:
new 0c756e4 Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=63829
0c756e4 is described below
commit 0c756e4252cd1d3669fdb693990bc8da9820a615
Author: Mark Thomas <[email protected]>
AuthorDate: Wed Oct 23 11:30:54 2019 +0200
Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=63829
Improve the check of the Content-Encoding header when looking to see if
Tomcat is serving pre-compressed content. Ensure that only a full token
is matched and that the match is case insensitive.
---
.../coyote/http11/AbstractHttp11Processor.java | 35 +++++++++++-----------
.../apache/coyote/http11/LocalStrings.properties | 1 +
.../apache/tomcat/util/http/parser/TokenList.java | 24 ++++++++++++++-
webapps/docs/changelog.xml | 6 ++++
4 files changed, 47 insertions(+), 19 deletions(-)
diff --git a/java/org/apache/coyote/http11/AbstractHttp11Processor.java
b/java/org/apache/coyote/http11/AbstractHttp11Processor.java
index 37ecc9a..2064f93 100644
--- a/java/org/apache/coyote/http11/AbstractHttp11Processor.java
+++ b/java/org/apache/coyote/http11/AbstractHttp11Processor.java
@@ -19,7 +19,6 @@ package org.apache.coyote.http11;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.io.StringReader;
-import java.util.Collection;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
@@ -611,10 +610,21 @@ public abstract class AbstractHttp11Processor<S> extends
AbstractProcessor<S> {
// Check if content is not already compressed
MessageBytes contentEncodingMB =
response.getMimeHeaders().getValue("Content-Encoding");
- if ((contentEncodingMB != null) &&
- (contentEncodingMB.indexOf("gzip") != -1 ||
- contentEncodingMB.indexOf("br") != -1)) {
- return false;
+ if (contentEncodingMB != null) {
+ // Content-Encoding values are ordered but order is not important
+ // for this check so use a Set rather than a List
+ Set<String> tokens = new HashSet<String>();
+ try {
+
TokenList.parseTokenList(response.getMimeHeaders().values("Content-Encoding"),
tokens);
+ } catch (IOException e) {
+ // Because we are using StringReader, any exception here is a
+ // Tomcat bug.
+
getLog().warn(sm.getString("http11Processor.contentEncodingParseFail"), e);
+ return false;
+ }
+ if (tokens.contains("gzip") || tokens.contains("br")) {
+ return false;
+ }
}
// If force mode, always compress (test purposes only)
@@ -1342,7 +1352,7 @@ public abstract class AbstractHttp11Processor<S> extends
AbstractProcessor<S> {
MessageBytes connectionValueMB =
headers.getValue(Constants.CONNECTION);
if (connectionValueMB != null && !connectionValueMB.isNull()) {
Set<String> tokens = new HashSet<String>();
- parseConnectionTokens(headers, tokens);
+ TokenList.parseTokenList(headers.values(Constants.CONNECTION),
tokens);
if (tokens.contains(Constants.CLOSE)) {
keepAlive = false;
} else if (tokens.contains(Constants.KEEPALIVE)) {
@@ -1758,22 +1768,11 @@ public abstract class AbstractHttp11Processor<S>
extends AbstractProcessor<S> {
}
Set<String> tokens = new HashSet<String>();
- parseConnectionTokens(headers, tokens);
+ TokenList.parseTokenList(headers.values(Constants.CONNECTION), tokens);
return tokens.contains(token);
}
- private static void parseConnectionTokens(MimeHeaders headers,
Collection<String> tokens) throws IOException {
- Enumeration<String> values = headers.values(Constants.CONNECTION);
- while (values.hasMoreElements()) {
- String nextHeaderValue = values.nextElement();
- if (nextHeaderValue != null) {
- TokenList.parseTokenList(new StringReader(nextHeaderValue),
tokens);
- }
- }
- }
-
-
protected abstract boolean prepareSendfile(OutputFilter[] outputFilters);
diff --git a/java/org/apache/coyote/http11/LocalStrings.properties
b/java/org/apache/coyote/http11/LocalStrings.properties
index 7f3eb7e..ad41849 100644
--- a/java/org/apache/coyote/http11/LocalStrings.properties
+++ b/java/org/apache/coyote/http11/LocalStrings.properties
@@ -16,6 +16,7 @@
http11Processor.upgrade=An internal error has occurred as upgraded connections
should only be processed by the dedicated upgrade processor implementations
http11processor.comet.notsupported=The Comet protocol is not supported by this
connector
+http11Processor.contentEncodingParseFail=Failed to parse Content-Encoding
header when chekcing to see if compression was already in use
http11processor.fallToDebug=\n\
\ Note: further occurrences of HTTP request parsing errors will be logged at
DEBUG level.
http11processor.filter.error=Error intializing filter [{0}]
diff --git a/java/org/apache/tomcat/util/http/parser/TokenList.java
b/java/org/apache/tomcat/util/http/parser/TokenList.java
index 3837b51..7ba886c 100644
--- a/java/org/apache/tomcat/util/http/parser/TokenList.java
+++ b/java/org/apache/tomcat/util/http/parser/TokenList.java
@@ -18,7 +18,9 @@ package org.apache.tomcat.util.http.parser;
import java.io.IOException;
import java.io.Reader;
+import java.io.StringReader;
import java.util.Collection;
+import java.util.Enumeration;
import java.util.Locale;
import org.apache.tomcat.util.http.parser.HttpParser.SkipResult;
@@ -31,12 +33,32 @@ public class TokenList {
/**
+ * Parses an enumeration of header values of the form 1#token, forcing all
+ * parsed values to lower case.
+ *
+ * @param inputs The headers to parse
+ * @param result The Collection (usually a list of a set) to which the
+ * parsed tokens should be added
+ *
+ * @throws IOException If an I/O error occurs reading the header
+ */
+ public static void parseTokenList(Enumeration<String> inputs,
Collection<String> result) throws IOException {
+ while (inputs.hasMoreElements()) {
+ String nextHeaderValue = inputs.nextElement();
+ if (nextHeaderValue != null) {
+ TokenList.parseTokenList(new StringReader(nextHeaderValue),
result);
+ }
+ }
+ }
+
+
+ /**
* Parses a header of the form 1#token, forcing all parsed values to lower
* case. This is typically used when header values are case-insensitive.
*
* @param input The header to parse
* @param result The Collection (usually a list of a set) to which the
- * parsed token should be added
+ * parsed tokens should be added
*
* @throws IOException If an I/O error occurs reading the header
*/
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index a6a0734..16c7cb4 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -92,6 +92,12 @@
<code>Connection</code> HTTP headers looking for a specific token, be
stricter in ensuring that the exact token is present. (markt)
</fix>
+ <fix>
+ <bug>63829</bug>: Improve the check of the
<code>Content-Encoding</code>
+ header when looking to see if Tomcat is serving pre-compressed content.
+ Ensure that only a full token is matched and that the match is case
+ insensitive. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Other">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]