This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 8.5.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/8.5.x by this push:
     new f4a6c16e05 Make Host header / request line consistency check case 
insensitive
f4a6c16e05 is described below

commit f4a6c16e050eb32d15cbd22708dee2748b74bb15
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Fri Dec 15 09:36:02 2023 +0000

    Make Host header / request line consistency check case insensitive
---
 java/org/apache/coyote/http11/Http11Processor.java |  2 +-
 java/org/apache/tomcat/util/buf/ByteChunk.java     | 22 ++++++++++++++
 .../apache/coyote/http11/TestHttp11Processor.java  | 35 ++++++++++++++++++++++
 webapps/docs/changelog.xml                         |  5 ++++
 4 files changed, 63 insertions(+), 1 deletion(-)

diff --git a/java/org/apache/coyote/http11/Http11Processor.java 
b/java/org/apache/coyote/http11/Http11Processor.java
index 4c8fee89e8..0e310ee854 100644
--- a/java/org/apache/coyote/http11/Http11Processor.java
+++ b/java/org/apache/coyote/http11/Http11Processor.java
@@ -959,7 +959,7 @@ public class Http11Processor extends AbstractProcessor {
                     if (hostValueMB != null) {
                         // Any host in the request line must be consistent with
                         // the Host header
-                        if (!hostValueMB.getByteChunk().equals(uriB, 
uriBCStart + pos, slashPos - pos)) {
+                        if (!hostValueMB.getByteChunk().equalsIgnoreCase(uriB, 
uriBCStart + pos, slashPos - pos)) {
                             if (protocol.getAllowHostHeaderMismatch()) {
                                 // The requirements of RFC 2616 are being
                                 // applied. If the host header and the request
diff --git a/java/org/apache/tomcat/util/buf/ByteChunk.java 
b/java/org/apache/tomcat/util/buf/ByteChunk.java
index b4d56883ac..4a1ea0efa0 100644
--- a/java/org/apache/tomcat/util/buf/ByteChunk.java
+++ b/java/org/apache/tomcat/util/buf/ByteChunk.java
@@ -721,6 +721,28 @@ public final class ByteChunk extends AbstractChunk {
     }
 
 
+    public boolean equalsIgnoreCase(byte b2[], int off2, int len2) {
+        byte b1[] = buff;
+        if (b1 == null && b2 == null) {
+            return true;
+        }
+
+        int len = end - start;
+        if (len != len2 || b1 == null || b2 == null) {
+            return false;
+        }
+
+        int off1 = start;
+
+        while (len-- > 0) {
+            if (Ascii.toLower(b1[off1++]) != Ascii.toLower(b2[off2++])) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+
     public boolean equals(CharChunk cc) {
         return equals(cc.getChars(), cc.getStart(), cc.getLength());
     }
diff --git a/test/org/apache/coyote/http11/TestHttp11Processor.java 
b/test/org/apache/coyote/http11/TestHttp11Processor.java
index dc7efc18e4..3ed7bfd449 100644
--- a/test/org/apache/coyote/http11/TestHttp11Processor.java
+++ b/test/org/apache/coyote/http11/TestHttp11Processor.java
@@ -1358,6 +1358,41 @@ public class TestHttp11Processor extends TomcatBaseTest {
                 client.getResponseBody());
     }
 
+    /*
+     * Request line host is case insensitive match for Host header (no port, 
no user info)
+     */
+    @Test
+    public void testConsistentHostHeader04() throws Exception {
+        Tomcat tomcat = getTomcatInstance();
+
+        // This setting means the connection will be closed at the end of the
+        // request
+        
Assert.assertTrue(tomcat.getConnector().setProperty("maxKeepAliveRequests", 
"1"));
+
+        // No file system docBase required
+        Context ctx = getProgrammaticRootContext();
+
+        // Add servlet
+        Tomcat.addServlet(ctx, "TesterServlet", new ServerNameTesterServlet());
+        ctx.addServletMappingDecoded("/foo", "TesterServlet");
+
+        tomcat.start();
+
+        String request = "GET http://a/foo HTTP/1.1" + SimpleHttpClient.CRLF + 
"Host: A" +
+                SimpleHttpClient.CRLF + SimpleHttpClient.CRLF;
+
+        Client client = new Client(tomcat.getConnector().getLocalPort());
+        client.setRequest(new String[] { request });
+
+        client.connect();
+        client.processRequest();
+
+        // Expected response is a 200 response.
+        Assert.assertTrue(client.isResponse200());
+        Assert.assertEquals("request.getServerName() is [A] and 
request.getServerPort() is 80",
+                client.getResponseBody());
+    }
+
     /*
      * Host header exists but its value is an empty string. This is valid if 
the request line does not include a
      * hostname/port. Added for bug 62739.
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index dfc8a96cf7..e610b2bdf2 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -123,6 +123,11 @@
         fixing a regression caused by the introduction of a second
         <code>addSslHostConfig</code> method. (remm)
       </fix>
+      <fix>
+        Relax the check that the HTTP Host header is consistent with the host
+        used in the request line, if any, to make the check case insensitive
+        since host names are case insensitive. (markt)
+      </fix>
     </changelog>
   </subsection>
 </section>


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to