This is an automated email from the ASF dual-hosted git repository. rmaucher pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit c3ae5b6bfbac436596e3aba32ce730d181d32e62 Author: opencode <[email protected]> AuthorDate: Sat Oct 17 14:53:25 2026 +0200 Remove stray raw path entry added to the WebSocket template match map when a programmatic registration duplicates an annotated POJO template path The template match map is keyed by the normalized path in which named template parameters are replaced with numeric indices. In the case in which a programmatic registration duplicates the template path of an annotated POJO for the same endpoint class, the specification requires the new match to be ignored. The code copied from the exact match branch below restored the old match into the map using the raw path as the key. Unlike the exact match branch, the template branch uses putIfAbsent() which does not modify the map when a match already exists, so no restoration is required and the put instead added a second, raw path keyed entry to the map for every such registration, both keys referencing the same match. The redundant put is removed. The exact match branch is unchanged since there the preceding put() does overwrite the old match and the restoration is required. The regression test extends testDuplicatePaths22, which exercises this code path, to assert via reflection on the template match map that exactly one entry, keyed by the normalized path, remains after the duplicate registration is ignored. --- .../apache/tomcat/websocket/server/WsServerContainer.java | 5 +++-- .../tomcat/websocket/server/TestWsServerContainer.java | 13 +++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/java/org/apache/tomcat/websocket/server/WsServerContainer.java b/java/org/apache/tomcat/websocket/server/WsServerContainer.java index d104d344b4..2492af2700 100644 --- a/java/org/apache/tomcat/websocket/server/WsServerContainer.java +++ b/java/org/apache/tomcat/websocket/server/WsServerContainer.java @@ -166,8 +166,9 @@ public class WsServerContainer extends WsWebSocketContainer implements ServerCon // before POJOs in WsSci#onStartup() if (oldMatch.fromAnnotatedPojo() && !newMatch.fromAnnotatedPojo() && oldMatch.config().getEndpointClass() == newMatch.config().getEndpointClass()) { - // The WebSocket spec says to ignore the new match in this case - templateMatches.put(path, oldMatch); + // The WebSocket spec says to ignore the new match in this case. The old + // match has not been replaced by putIfAbsent() above so, unlike the exact + // match case below, there is no need to restore the old match in the map. } else { // Duplicate uriTemplate; throw new DeploymentException(sm.getString("serverContainer.duplicatePaths", path, diff --git a/test/org/apache/tomcat/websocket/server/TestWsServerContainer.java b/test/org/apache/tomcat/websocket/server/TestWsServerContainer.java index 17fbffd462..7a7222f687 100644 --- a/test/org/apache/tomcat/websocket/server/TestWsServerContainer.java +++ b/test/org/apache/tomcat/websocket/server/TestWsServerContainer.java @@ -364,6 +364,19 @@ public class TestWsServerContainer extends WebSocketBaseTest { sc.addEndpoint(configA); Assert.assertNotEquals(configA, sc.findMapping("/foo/{a}").config()); + + // The old match must remain stored under the normalized path. Ignoring the new match must + // not add an additional entry to the map. + Field configTemplateMatchMapField = WsServerContainer.class.getDeclaredField("configTemplateMatchMap"); + configTemplateMatchMapField.setAccessible(true); + @SuppressWarnings("unchecked") + Map<Integer, ConcurrentSkipListMap<String, Object>> configTemplateMatchMap = + (Map<Integer, ConcurrentSkipListMap<String, Object>>) configTemplateMatchMapField.get(sc); + + ConcurrentSkipListMap<String, Object> templateMatches = configTemplateMatchMap.get(Integer.valueOf(2)); + + Assert.assertEquals(1, templateMatches.size()); + Assert.assertTrue(templateMatches.containsKey("/foo/{0}")); } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
