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

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

commit 3a09fa8507977eb6e42ebeb7ffc946c1115aa0a4
Author: opencode <[email protected]>
AuthorDate: Wed Oct 7 12:18:21 2026 +0200

    Reset the default host when it is removed from the mapper
    
    Neither removeHost() nor removeHostAlias() updated the default host
    reference when the removed entry was the one the default host name had
    resolved to, including alias entries. Mapping then kept handing the
    removed Host object to requests whose host name matched nothing, and
    when the contexts of the removed host were still registered, those
    requests were dispatched into the contexts of the removed host instead
    of failing with a clean 404.
    
    Clear the default host reference in both removal methods when they
    remove the host or alias it points at. The configured default host name
    is kept, so re-registering the host resolves the default again. Add unit
    tests for both removal paths.
---
 java/org/apache/catalina/mapper/Mapper.java     |  9 +++++
 test/org/apache/catalina/mapper/TestMapper.java | 49 +++++++++++++++++++++++++
 2 files changed, 58 insertions(+)

diff --git a/java/org/apache/catalina/mapper/Mapper.java 
b/java/org/apache/catalina/mapper/Mapper.java
index 2fd12f251f..10b47b64bc 100644
--- a/java/org/apache/catalina/mapper/Mapper.java
+++ b/java/org/apache/catalina/mapper/Mapper.java
@@ -154,6 +154,12 @@ public final class Mapper {
         if (host == null || host.isAlias()) {
             return;
         }
+        // Requests must not keep going to a removed host, even if it was the
+        // default host. A new default host is resolved again if the
+        // configuration still refers to a host that exists.
+        if (defaultHost != null && defaultHost.getRealHost() == host) {
+            defaultHost = null;
+        }
         MappedHost[] newHosts = hosts.clone();
         // Remove real host and all its aliases
         int j = 0;
@@ -229,6 +235,9 @@ public final class Mapper {
         if (removeMap(hosts, newHosts, alias)) {
             hosts = newHosts;
             hostMapping.getRealHost().removeAlias(hostMapping);
+            if (defaultHost == hostMapping) {
+                defaultHost = null;
+            }
         }
 
     }
diff --git a/test/org/apache/catalina/mapper/TestMapper.java 
b/test/org/apache/catalina/mapper/TestMapper.java
index 8445059aed..b9f671de52 100644
--- a/test/org/apache/catalina/mapper/TestMapper.java
+++ b/test/org/apache/catalina/mapper/TestMapper.java
@@ -216,6 +216,55 @@ public class TestMapper extends LoggingBaseTest {
         }
     }
 
+    @Test
+    public void testRemoveDefaultHost() throws Exception {
+        Mapper defaultHostMapper = new Mapper();
+
+        Host host = createHost("defaulthostobject");
+        defaultHostMapper.addHost("defaulthost", new String[0], host);
+        defaultHostMapper.addContextVersion("defaulthost", host, "", "0", 
createContext("defaulthostcontext"),
+                new String[0], null, null);
+        defaultHostMapper.setDefaultHostName("defaulthost");
+
+        defaultHostMapper.removeHost("defaulthost");
+
+        MappingData mappingData = new MappingData();
+        MessageBytes hostMB = MessageBytes.newInstance();
+        hostMB.setString("unknown.example");
+        MessageBytes uriMB = MessageBytes.newInstance();
+        char[] uri = "/index.html".toCharArray();
+        uriMB.setChars(uri, 0, uri.length);
+
+        defaultHostMapper.map(hostMB, uriMB, null, mappingData);
+
+        Assert.assertNull(mappingData.host);
+    }
+
+    @Test
+    public void testRemoveDefaultHostAlias() throws Exception {
+        Mapper defaultHostMapper = new Mapper();
+
+        Host host = createHost("aliasdefaulthostobject");
+        defaultHostMapper.addHost("hostname", new String[0], host);
+        defaultHostMapper.addHostAlias("hostname", "aliasname");
+        defaultHostMapper.addContextVersion("hostname", host, "", "0", 
createContext("aliasdefaulthostcontext"),
+                new String[0], null, null);
+        defaultHostMapper.setDefaultHostName("aliasname");
+
+        defaultHostMapper.removeHostAlias("aliasname");
+
+        MappingData mappingData = new MappingData();
+        MessageBytes hostMB = MessageBytes.newInstance();
+        hostMB.setString("unknown.example");
+        MessageBytes uriMB = MessageBytes.newInstance();
+        char[] uri = "/index.html".toCharArray();
+        uriMB.setChars(uri, 0, uri.length);
+
+        defaultHostMapper.map(hostMB, uriMB, null, mappingData);
+
+        Assert.assertNull(mappingData.host);
+    }
+
     @Test
     @SuppressWarnings("deprecation") // contextPath
     public void testMap() throws Exception {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to