@Override @Nullable public CorsConfiguration getCorsConfiguration(ServerWebExchange exchange) { PathContainer lookupPath = exchange.getRequest().getPath().pathWithinApplication(); return this.corsConfigurations.entrySet().stream() .filter(entry -> entry.getKey().matches(lookupPath)) .map(Map.Entry::getValue) .findFirst() .orElse(null); }
/** * Look up a handler instance for the given URL lookup path. * <p>Supports direct matches, e.g. a registered "/test" matches "/test", * and various path pattern matches, e.g. a registered "/t*" matches * both "/test" and "/team". For details, see the PathPattern class. * @param lookupPath the URL the handler is mapped to * @param exchange the current exchange * @return the associated handler instance, or {@code null} if not found * @see org.springframework.web.util.pattern.PathPattern */ @Nullable protected Object lookupHandler(PathContainer lookupPath, ServerWebExchange exchange) throws Exception { List<PathPattern> matches = this.handlerMap.keySet().stream() .filter(key -> key.matches(lookupPath)) .collect(Collectors.toList()); if (matches.isEmpty()) { return null; } if (matches.size() > 1) { matches.sort(PathPattern.SPECIFICITY_COMPARATOR); if (logger.isTraceEnabled()) { logger.debug(exchange.getLogPrefix() + "Matching patterns " + matches); } } PathPattern pattern = matches.get(0); PathContainer pathWithinMapping = pattern.extractPathWithinPattern(lookupPath); return handleMatch(this.handlerMap.get(pattern), pattern, pathWithinMapping, exchange); }
/** * Find the patterns matching the given lookup path. Invoking this method should * yield results equivalent to those of calling * {@link #getMatchingCondition(ServerWebExchange)}. * This method is provided as an alternative to be used if no request is available * (e.g. introspection, tooling, etc). * @param exchange the current exchange * @return a sorted set of matching patterns sorted with the closest match first */ private SortedSet<PathPattern> getMatchingPatterns(ServerWebExchange exchange) { PathContainer lookupPath = exchange.getRequest().getPath().pathWithinApplication(); return this.patterns.stream() .filter(pattern -> pattern.matches(lookupPath)) .collect(Collectors.toCollection(TreeSet::new)); }
@Override @Nullable public CorsConfiguration getCorsConfiguration(ServerWebExchange exchange) { PathContainer lookupPath = exchange.getRequest().getPath().pathWithinApplication(); return this.corsConfigurations.entrySet().stream() .filter(entry -> entry.getKey().matches(lookupPath)) .map(Map.Entry::getValue) .findFirst() .orElse(null); }
private Mono<String> resolveResourceUrl(ServerWebExchange exchange, PathContainer lookupPath) { return this.handlerMap.entrySet().stream() .filter(entry -> entry.getKey().matches(lookupPath)) .min((entry1, entry2) -> PathPattern.SPECIFICITY_COMPARATOR.compare(entry1.getKey(), entry2.getKey())) .map(entry -> { PathContainer path = entry.getKey().extractPathWithinPattern(lookupPath); int endIndex = lookupPath.elements().size() - path.elements().size(); PathContainer mapping = lookupPath.subPath(0, endIndex); ResourceWebHandler handler = entry.getValue(); List<ResourceResolver> resolvers = handler.getResourceResolvers(); ResourceResolverChain chain = new DefaultResourceResolverChain(resolvers); return chain.resolveUrlPath(path.value(), handler.getLocations()) .map(resolvedPath -> mapping.value() + resolvedPath); }) .orElseGet(() ->{ if (logger.isTraceEnabled()) { logger.trace(exchange.getLogPrefix() + "No match for \"" + lookupPath + "\""); } return Mono.empty(); }); }
matches(PathContainer.parsePath(pattern2string.patternString))) { return pattern2string;
@Override public Mono<Resource> apply(ServerRequest request) { PathContainer pathContainer = request.pathContainer(); if (!this.pattern.matches(pathContainer)) { return Mono.empty(); } pathContainer = this.pattern.extractPathWithinPattern(pathContainer); String path = processPath(pathContainer.value()); if (path.contains("%")) { path = StringUtils.uriDecode(path, StandardCharsets.UTF_8); } if (!StringUtils.hasLength(path) || isInvalidPath(path)) { return Mono.empty(); } try { Resource resource = this.location.createRelative(path); if (resource.exists() && resource.isReadable() && isResourceUnderLocation(resource)) { return Mono.just(resource); } else { return Mono.empty(); } } catch (IOException ex) { throw new UncheckedIOException(ex); } }
private void assertNoMatch(PathPattern pp, String path) { assertFalse(pp.matches(toPathContainer(path))); }
private void assertMatches(PathPattern pp, String path) { assertTrue(pp.matches(PathPatternTests.toPathContainer(path))); }
private void assertNoMatch(PathPattern pp, String path) { assertFalse(pp.matches(PathPatternTests.toPathContainer(path))); }
private void assertMatches(PathPattern pp, String path) { assertTrue(pp.matches(toPathContainer(path))); }
matches(PathContainer.parsePath(pattern2string.patternString))) { return pattern2string;
@Override protected String getMatchingMapping(String pattern, ServerWebExchange exchange) { PathContainer lookupPath = exchange.getRequest().getPath().pathWithinApplication(); PathPattern parsedPattern = this.parser.parse(pattern); return (parsedPattern.matches(lookupPath) ? pattern : null); }
@Override public Predicate<ServerWebExchange> apply(Config config) { final ArrayList<PathPattern> pathPatterns = new ArrayList<>(); synchronized (this.pathPatternParser) { pathPatternParser.setMatchOptionalTrailingSeparator(config.isMatchOptionalTrailingSeparator()); config.getPatterns().forEach(pattern -> { PathPattern pathPattern = this.pathPatternParser.parse(pattern); pathPatterns.add(pathPattern); }); } return exchange -> { PathContainer path = parsePath(exchange.getRequest().getURI().getPath()); Optional<PathPattern> optionalPathPattern = pathPatterns.stream() .filter(pattern -> pattern.matches(path)) .findFirst(); if (optionalPathPattern.isPresent()) { PathPattern pathPattern = optionalPathPattern.get(); traceMatch("Pattern", pathPattern.getPatternString(), path, true); PathMatchInfo pathMatchInfo = pathPattern.matchAndExtract(path); putUriTemplateVariables(exchange, pathMatchInfo.getUriVariables()); return true; } else { traceMatch("Pattern", config.getPatterns(), path, false); return false; } }; }
private void checkNoMatch(String uriTemplate, String path) { PathPatternParser p = new PathPatternParser(); PathPattern pattern = p.parse(uriTemplate); PathContainer PathContainer = toPathContainer(path); assertFalse(pattern.matches(PathContainer)); }
private void checkMatches(String uriTemplate, String path) { PathPatternParser parser = new PathPatternParser(); parser.setMatchOptionalTrailingSeparator(true); PathPattern p = parser.parse(uriTemplate); PathContainer pc = toPathContainer(path); assertTrue(p.matches(pc)); }
@Test public void wildcards() { checkMatches("/*/bar", "/foo/bar"); checkNoMatch("/*/bar", "/foo/baz"); checkNoMatch("/*/bar", "//bar"); checkMatches("/f*/bar", "/foo/bar"); checkMatches("/*/bar", "/foo/bar"); checkMatches("a/*","a/"); checkMatches("/*","/"); checkMatches("/*/bar", "/foo/bar"); checkNoMatch("/*/bar", "/foo/baz"); checkMatches("/f*/bar", "/foo/bar"); checkMatches("/*/bar", "/foo/bar"); checkMatches("/a*b*c*d/bar", "/abcd/bar"); checkMatches("*a*", "testa"); checkMatches("a/*", "a/"); checkNoMatch("a/*", "a//"); // no data for * checkMatches("a/*", "a/a/"); // trailing slash, so is allowed PathPatternParser ppp = new PathPatternParser(); ppp.setMatchOptionalTrailingSeparator(false); assertFalse(ppp.parse("a/*").matches(toPathContainer("a//"))); checkMatches("a/*", "a/a"); checkMatches("a/*", "a/a/"); // trailing slash is optional checkMatches("/resource/**", "/resource"); checkNoMatch("/resource/**", "/resourceX"); checkNoMatch("/resource/**", "/resourceX/foobar"); checkMatches("/resource/**", "/resource/foobar"); }
@Override @Nullable public CorsConfiguration getCorsConfiguration(ServerWebExchange exchange) { PathContainer lookupPath = exchange.getRequest().getPath().pathWithinApplication(); return this.corsConfigurations.entrySet().stream() .filter(entry -> entry.getKey().matches(lookupPath)) .map(Map.Entry::getValue) .findFirst() .orElse(null); }
@Override @Nullable public CorsConfiguration getCorsConfiguration(ServerWebExchange exchange) { PathContainer lookupPath = exchange.getRequest().getPath().pathWithinApplication(); return this.corsConfigurations.entrySet().stream() .filter(entry -> entry.getKey().matches(lookupPath)) .map(Map.Entry::getValue) .findFirst() .orElse(null); }
@Override public Mono<MatchResult> matches(ServerWebExchange exchange) { ServerHttpRequest request = exchange.getRequest(); if(this.method != null && !this.method.equals(request.getMethod())) { return MatchResult.notMatch(); } PathContainer path = request.getPath().pathWithinApplication(); boolean match = this.pattern.matches(path); if(!match) { return MatchResult.notMatch(); } Map<String,String> pathVariables = this.pattern.matchAndExtract(path).getUriVariables(); Map<String,Object> variables = new HashMap<>(pathVariables); return MatchResult.match(variables); }