This is an automated email from the ASF dual-hosted git repository. rmaucher pushed a commit to branch 10.1.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit f5c38da8ddb70c052e1606a5969fdd6c00bf3a4d 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 0e1fe472ac..5e7f341aa9 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.isFromAnnotatedPojo() && !newMatch.isFromAnnotatedPojo() && oldMatch.getConfig().getEndpointClass() == newMatch.getConfig().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 6ebb47775a..3c77c07ad3 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}").getConfig()); + + // 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]
