From 5fddbf9bb157725216d34cb0804391e008f564ca Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Tue, 21 Jun 2022 15:24:39 -0500 Subject: [PATCH] Issue #8184 - Correcting match logic for multiple servlet suffix url-pattern (#8185) Signed-off-by: Joakim Erdfelt --- .../jetty/http/pathmap/PathMappings.java | 17 +++++++----- .../jetty/http/pathmap/PathMappingsTest.java | 26 +++++++++++++++++++ 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathMappings.java b/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathMappings.java index 2012d5fec9c..c2871a58cab 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathMappings.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/pathmap/PathMappings.java @@ -176,16 +176,15 @@ public class PathMappings implements Iterable>, Dumpable int i = path.length(); while (i >= 0) { - MappedResource candidate = _exactMap.getBest(path, 0, i); + MappedResource candidate = _exactMap.getBest(path, 0, i--); if (candidate == null) - break; + continue; matchedPath = candidate.getPathSpec().matched(path); if (matchedPath != null) { return new MatchedResource<>(candidate.getResource(), candidate.getPathSpec(), matchedPath); } - i--; } // If we reached here, there's NO optimized EXACT Match possible, skip simple match below skipRestOfGroup = true; @@ -200,14 +199,13 @@ public class PathMappings implements Iterable>, Dumpable int i = path.length(); while (i >= 0) { - MappedResource candidate = _prefixMap.getBest(path, 0, i); + MappedResource candidate = _prefixMap.getBest(path, 0, i--); if (candidate == null) - break; + continue; matchedPath = candidate.getPathSpec().matched(path); if (matchedPath != null) return new MatchedResource<>(candidate.getResource(), candidate.getPathSpec(), matchedPath); - i--; } // If we reached here, there's NO optimized PREFIX Match possible, skip simple match below skipRestOfGroup = true; @@ -220,11 +218,16 @@ public class PathMappings implements Iterable>, Dumpable if (_optimizedSuffix) { int i = 0; + // Loop through each suffix mark + // Input is "/a.b.c.foo" + // Loop 1: "b.c.foo" + // Loop 2: "c.foo" + // Loop 3: "foo" while ((i = path.indexOf('.', i + 1)) > 0) { MappedResource candidate = _suffixMap.get(path, i + 1, path.length() - i - 1); if (candidate == null) - break; + continue; matchedPath = candidate.getPathSpec().matched(path); if (matchedPath != null) diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/PathMappingsTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/PathMappingsTest.java index 3af0a9e2563..24b417bad00 100644 --- a/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/PathMappingsTest.java +++ b/jetty-http/src/test/java/org/eclipse/jetty/http/pathmap/PathMappingsTest.java @@ -319,6 +319,32 @@ public class PathMappingsTest assertThat(p.get(new RegexPathSpec("/a/b/c")), nullValue()); } + @Test + public void testServletMultipleSuffixMappings() + { + PathMappings p = new PathMappings<>(); + p.put(new ServletPathSpec("*.foo"), "resourceFoo"); + p.put(new ServletPathSpec("*.bar"), "resourceBar"); + p.put(new ServletPathSpec("*.zed"), "resourceZed"); + + MatchedResource matched; + + matched = p.getMatched("/a.b.c.foo"); + assertThat(matched.getResource(), is("resourceFoo")); + + matched = p.getMatched("/a.b.c.bar"); + assertThat(matched.getResource(), is("resourceBar")); + + matched = p.getMatched("/a.b.c.pop"); + assertNull(matched); + + matched = p.getMatched("/a.foo.c.pop"); + assertNull(matched); + + matched = p.getMatched("/a%2Efoo"); + assertNull(matched); + } + @Test public void testRemoveUriTemplatePathSpec() {