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]

Reply via email to