diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/mapping/PathMatcher.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/mapping/PathMatcher.java index d13d30d0fddbe..bb94ca823e1a7 100644 --- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/mapping/PathMatcher.java +++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/mapping/PathMatcher.java @@ -1,5 +1,7 @@ package org.jboss.resteasy.reactive.server.mapping; +import java.util.ArrayList; +import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Set; @@ -34,24 +36,28 @@ class PathMatcher implements Dumpable { * @param path The relative path to match * @return The match match. This will never be null, however if none matched its value field will be */ - PathMatch match(String path) { + List> match(String path) { int length = path.length(); final int[] lengths = this.lengths; + ArrayList> matches = new ArrayList<>(); for (int i = 0; i < lengths.length; ++i) { int pathLength = lengths[i]; if (pathLength == length) { SubstringMap.SubstringMatch next = paths.get(path, length); if (next != null) { - return new PathMatch<>(path, "", next.getValue()); + matches.add(new PathMatch<>(path, "", next.getValue())); } } else if (pathLength < length) { SubstringMap.SubstringMatch next = paths.get(path, pathLength); if (next != null) { - return new PathMatch<>(next.getKey(), path.substring(pathLength), next.getValue()); + matches.add(new PathMatch<>(next.getKey(), path.substring(pathLength), next.getValue())); } } } - return defaultMatch(path); + if (!matches.isEmpty()) { + return matches; + } + return Collections.singletonList(defaultMatch(path)); } PathMatch defaultMatch(String path) { diff --git a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/mapping/RequestMapper.java b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/mapping/RequestMapper.java index e85367904451a..4462c019c5a16 100644 --- a/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/mapping/RequestMapper.java +++ b/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/mapping/RequestMapper.java @@ -4,6 +4,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.function.BiConsumer; import java.util.regex.Matcher; @@ -48,9 +49,12 @@ public void accept(String stem, ArrayList> list) { * @return best RequestMatch, or null if the path has no match */ public RequestMatch map(String path) { - var result = mapFromPathMatcher(path, requestPaths.match(path), 0); - if (result != null) { - return result; + List>>> matches = requestPaths.match(path); + for (PathMatcher.PathMatch>> match : matches) { + var result = mapFromPathMatcher(path, match, 0); + if (result != null) { + return result; + } } // the following code is meant to handle cases like https://github.com/quarkusio/quarkus/issues/30667 @@ -68,16 +72,21 @@ public RequestMatch continueMatching(String path, RequestMatch lastMatch) return null; } - var initialMatches = requestPaths.match(path); - var result = mapFromPathMatcher(path, initialMatches, 0); - if (result != null) { - int idx = nextMatchStartingIndex(initialMatches, lastMatch); - return mapFromPathMatcher(path, initialMatches, idx); + var initialMatchesList = requestPaths.match(path); + for (var initialMatches: initialMatchesList) { + var result = mapFromPathMatcher(path, initialMatches, 0); + if (result != null) { + int idx = nextMatchStartingIndex(initialMatches, lastMatch); + RequestMatch match = mapFromPathMatcher(path, initialMatches, idx); + if (match != null) { + return match; + } + } } // the following code is meant to handle cases like https://github.com/quarkusio/quarkus/issues/30667 - initialMatches = requestPaths.defaultMatch(path); - result = mapFromPathMatcher(path, initialMatches, 0); + var initialMatches = requestPaths.defaultMatch(path); + var result = mapFromPathMatcher(path, initialMatches, 0); if (result != null) { int idx = nextMatchStartingIndex(initialMatches, lastMatch); return mapFromPathMatcher(path, initialMatches, idx); @@ -101,7 +110,7 @@ private int nextMatchStartingIndex(PathMatcher.PathMatch