This is an automated email from the ASF dual-hosted git repository.
markt-asf pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/main by this push:
new 9bd09fa687 Follow-on to "Ignore malformed Accept-Encoding q-values ..."
9bd09fa687 is described below
commit 9bd09fa68725252f779697b8d347907698f8fbbc
Author: Mark Thomas <[email protected]>
AuthorDate: Mon Oct 12 17:41:35 2026 +0100
Follow-on to "Ignore malformed Accept-Encoding q-values ..."
Refactor to use standard Accept-Encoding parser.
# Conflicts:
# webapps/docs/changelog.xml
---
.../apache/catalina/servlets/DefaultServlet.java | 79 ++++++++++------------
.../catalina/servlets/LocalStrings.properties | 1 +
.../catalina/servlets/TestDefaultServlet.java | 4 +-
webapps/docs/changelog.xml | 4 ++
4 files changed, 44 insertions(+), 44 deletions(-)
diff --git a/java/org/apache/catalina/servlets/DefaultServlet.java
b/java/org/apache/catalina/servlets/DefaultServlet.java
index 988bd894e6..9b998bf021 100644
--- a/java/org/apache/catalina/servlets/DefaultServlet.java
+++ b/java/org/apache/catalina/servlets/DefaultServlet.java
@@ -79,6 +79,7 @@ import org.apache.tomcat.util.buf.B2CConverter;
import org.apache.tomcat.util.http.FastHttpDateFormat;
import org.apache.tomcat.util.http.Method;
import org.apache.tomcat.util.http.ResponseUtil;
+import org.apache.tomcat.util.http.parser.AcceptEncoding;
import org.apache.tomcat.util.http.parser.ContentRange;
import org.apache.tomcat.util.http.parser.EntityTag;
import org.apache.tomcat.util.http.parser.Ranges;
@@ -1474,58 +1475,50 @@ public class DefaultServlet extends HttpServlet {
private PrecompressedResource
getBestPrecompressedResource(HttpServletRequest request,
List<PrecompressedResource> precompressedResources) {
Enumeration<String> headers = request.getHeaders("Accept-Encoding");
+ List<AcceptEncoding> acceptEncodings = new ArrayList<>();
+ while (headers.hasMoreElements()) {
+ String header = headers.nextElement();
+ try {
+ acceptEncodings.addAll(AcceptEncoding.parse(new
StringReader(header)));
+ } catch (IOException e) {
+ // StringReader should not throw IOException
+ log(sm.getString("defaultServlet.acceptEncoding.ioe", header));
+ }
+ }
PrecompressedResource bestResource = null;
double bestResourceQuality = 0;
int bestResourcePreference = Integer.MAX_VALUE;
- while (headers.hasMoreElements()) {
- String header = headers.nextElement();
- for (String preference : header.split(",")) {
- double quality = 1;
- int qualityIdx = preference.indexOf(';');
- if (qualityIdx > 0) {
- int equalsIdx = preference.indexOf('=', qualityIdx + 1);
- if (equalsIdx == -1) {
- continue;
- }
- try {
- quality =
Double.parseDouble(preference.substring(equalsIdx + 1).trim());
- } catch (NumberFormatException nfe) {
- // Invalid q-value: ignore this preference
- continue;
- }
+
+ for (AcceptEncoding acceptEncoding : acceptEncodings) {
+ double quality = acceptEncoding.getQuality();
+ if (quality >= bestResourceQuality) {
+ String encoding = acceptEncoding.getEncoding();
+ if ("identity".equalsIgnoreCase(encoding)) {
+ bestResource = null;
+ bestResourceQuality = quality;
+ bestResourcePreference = Integer.MAX_VALUE;
+ continue;
}
- if (quality >= bestResourceQuality) {
- String encoding = preference;
- if (qualityIdx > 0) {
- encoding = encoding.substring(0, qualityIdx);
- }
- encoding = encoding.trim();
- if ("identity".equals(encoding)) {
- bestResource = null;
- bestResourceQuality = quality;
- bestResourcePreference = Integer.MAX_VALUE;
- continue;
- }
- if ("*".equals(encoding)) {
- bestResource = precompressedResources.getFirst();
- bestResourceQuality = quality;
- bestResourcePreference = 0;
- continue;
- }
- for (int i = 0; i < precompressedResources.size(); ++i) {
- PrecompressedResource resource =
precompressedResources.get(i);
- if (encoding.equals(resource.format.encoding)) {
- if (quality > bestResourceQuality || i <
bestResourcePreference) {
- bestResource = resource;
- bestResourceQuality = quality;
- bestResourcePreference = i;
- }
- break;
+ if ("*".equals(encoding)) {
+ bestResource = precompressedResources.getFirst();
+ bestResourceQuality = quality;
+ bestResourcePreference = 0;
+ continue;
+ }
+ for (int i = 0; i < precompressedResources.size(); ++i) {
+ PrecompressedResource resource =
precompressedResources.get(i);
+ if (encoding.equalsIgnoreCase(resource.format.encoding)) {
+ if (quality > bestResourceQuality || i <
bestResourcePreference) {
+ bestResource = resource;
+ bestResourceQuality = quality;
+ bestResourcePreference = i;
}
+ break;
}
}
}
}
+
return bestResource;
}
diff --git a/java/org/apache/catalina/servlets/LocalStrings.properties
b/java/org/apache/catalina/servlets/LocalStrings.properties
index 896d0c0aa1..3e5d9fd14b 100644
--- a/java/org/apache/catalina/servlets/LocalStrings.properties
+++ b/java/org/apache/catalina/servlets/LocalStrings.properties
@@ -38,6 +38,7 @@ cgiServlet.runStdErrCount=Received [{0}] lines on stderr
cgiServlet.runStdErrFail=I/O problems with stderr
cgiServlet.runStdErrReaderFail=I/O problems closing stderr reader
+defaultServlet.acceptEncoding.ioe=Failed to process the Accept-Encoding header
[{0}]
defaultServlet.blockExternalEntity=Blocked access to external entity with
publicId [{0}] and systemId [{0}]
defaultServlet.blockExternalEntity2=Blocked access to external entity with
name [{0}], publicId [{1}], baseURI [{2}] and systemId [{3}]
defaultServlet.blockExternalSubset=Blocked access to external subset with name
[{0}] and baseURI [{1}]
diff --git a/test/org/apache/catalina/servlets/TestDefaultServlet.java
b/test/org/apache/catalina/servlets/TestDefaultServlet.java
index ca7ef94873..2b661880ab 100644
--- a/test/org/apache/catalina/servlets/TestDefaultServlet.java
+++ b/test/org/apache/catalina/servlets/TestDefaultServlet.java
@@ -423,7 +423,9 @@ public class TestDefaultServlet extends TomcatBaseTest {
client.processRequest();
Assert.assertTrue(client.isResponse200());
List<String> responseHeaders = client.getResponseHeaders();
- Assert.assertFalse(responseHeaders.contains("Content-Encoding"));
+ for (String responseHeader : responseHeaders) {
+ Assert.assertFalse(responseHeader.startsWith("Content-Encoding"));
+ }
Assert.assertTrue(responseHeaders.contains("Content-Length: " +
indexSize));
Assert.assertTrue(responseHeaders.contains("vary: accept-encoding"));
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 763d9ac374..b581dbab88 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -391,6 +391,10 @@
It now resolves to undefined, expanding to an empty string, instead of
silently turning ident-based rules into authentication checks. (remm)
</fix>
+ <fix>
+ Refactor the default Servlet <code>Accept-Encoding</code> handling to
+ use the common HTTP header parser for processing these headers. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Coyote">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]