From 95196e1aee35d98a7866b43c7e0650c1474c1b8c Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 6 Jun 2017 17:44:39 -0400 Subject: [PATCH] Use undecoded pathWithinApplication in WebFlux Introduce pathWithinApplication() in ServerHttpRequest and use it for request mapping purposes instead of LookupPath. In turn this means that for request mapping purposes: 1) the path is not decoded 2) suffix pattern matching is not supported Issue: SPR-15640 --- .../reactive/ContextPathCompositeHandler.java | 22 +--- .../server/reactive/ServerHttpRequest.java | 29 ++++- .../UrlBasedCorsConfigurationSource.java | 3 +- .../server/support/HttpRequestPathHelper.java | 22 +--- .../web/server/support/LookupPath.java | 109 ------------------ .../UrlBasedCorsConfigurationSourceTests.java | 5 - .../web/server/support/LookupPathTests.java | 60 ---------- .../handler/AbstractUrlHandlerMapping.java | 22 ++-- .../resource/ResourceUrlProvider.java | 5 +- .../condition/PatternsRequestCondition.java | 33 ++---- .../method/AbstractHandlerMethodMapping.java | 15 ++- .../RequestMappingInfoHandlerMapping.java | 29 +++-- .../view/ViewResolutionResultHandler.java | 3 +- .../handler/SimpleUrlHandlerMappingTests.java | 2 - .../PatternsRequestConditionTests.java | 88 ++------------ .../condition/RequestMappingInfoTests.java | 11 +- ...RequestMappingInfoHandlerMappingTests.java | 52 ++++----- .../ViewResolutionResultHandlerTests.java | 9 +- .../web/reactive/handler/map.xml | 1 - 19 files changed, 109 insertions(+), 411 deletions(-) delete mode 100644 spring-web/src/main/java/org/springframework/web/server/support/LookupPath.java delete mode 100644 spring-web/src/test/java/org/springframework/web/server/support/LookupPathTests.java diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ContextPathCompositeHandler.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ContextPathCompositeHandler.java index 03e0e967869..98a27177a24 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ContextPathCompositeHandler.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ContextPathCompositeHandler.java @@ -4,11 +4,10 @@ package org.springframework.http.server.reactive; import java.util.LinkedHashMap; import java.util.Map; +import reactor.core.publisher.Mono; + import org.springframework.http.HttpStatus; import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -import reactor.core.publisher.Mono; /** * {@code HttpHandler} delegating requests to one of several {@code HttpHandler}'s @@ -49,7 +48,8 @@ public class ContextPathCompositeHandler implements HttpHandler { @Override public Mono handle(ServerHttpRequest request, ServerHttpResponse response) { - String path = getPathWithinApplication(request); + // Remove underlying context path first (e.g. Servlet container) + String path = request.getPathWithinApplication(); return this.handlerMap.entrySet().stream() .filter(entry -> path.startsWith(entry.getKey())) .findFirst() @@ -65,18 +65,4 @@ public class ContextPathCompositeHandler implements HttpHandler { }); } - /** - * Get the path within the "native" context path of the underlying server, - * for example when running on a Servlet container. - */ - private String getPathWithinApplication(ServerHttpRequest request) { - String path = request.getURI().getRawPath(); - String contextPath = request.getContextPath(); - if (!StringUtils.hasText(contextPath)) { - return path; - } - int length = contextPath.length(); - return (path.length() > length ? path.substring(length) : ""); - } - } diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpRequest.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpRequest.java index 14d08e498a3..76d6161cccb 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ServerHttpRequest.java @@ -24,6 +24,7 @@ import org.springframework.http.HttpRequest; import org.springframework.http.ReactiveHttpInputMessage; import org.springframework.lang.Nullable; import org.springframework.util.MultiValueMap; +import org.springframework.util.StringUtils; /** * Represents a reactive server-side HTTP request @@ -35,16 +36,36 @@ import org.springframework.util.MultiValueMap; public interface ServerHttpRequest extends HttpRequest, ReactiveHttpInputMessage { /** - * Returns the portion of the URL path that represents the context path for the - * current {@link HttpHandler}. The context path is always at the beginning of - * the request path. It starts with "/" but but does not end with "/". - *

This method may return an empty string if no context path is configured. + * Returns the portion of the URL path that represents the application. + * The context path is always at the beginning of the path and starts but + * does not end with "/". It is shared for URLs of the same application. + *

The context path may come from the underlying runtime API such as + * when deploying as a WAR to a Servlet container or it may also be assigned + * through the use of {@link ContextPathCompositeHandler} or both. + *

The context path is not decoded. * @return the context path (not decoded) or an empty string */ default String getContextPath() { return ""; } + /** + * Returns the portion of the URL path after the {@link #getContextPath() + * contextPath}. The returned path is not decoded. + * @return the path under the contextPath + */ + default String getPathWithinApplication() { + String path = getURI().getRawPath(); + String contextPath = getContextPath(); + if (StringUtils.hasText(contextPath)) { + int length = contextPath.length(); + return (path.length() > length ? path.substring(length) : ""); + } + else { + return path; + } + } + /** * Return a read-only map with parsed and decoded query parameter values. */ diff --git a/spring-web/src/main/java/org/springframework/web/cors/reactive/UrlBasedCorsConfigurationSource.java b/spring-web/src/main/java/org/springframework/web/cors/reactive/UrlBasedCorsConfigurationSource.java index 3d59efa40d9..d59c1e84273 100644 --- a/spring-web/src/main/java/org/springframework/web/cors/reactive/UrlBasedCorsConfigurationSource.java +++ b/spring-web/src/main/java/org/springframework/web/cors/reactive/UrlBasedCorsConfigurationSource.java @@ -25,7 +25,6 @@ import org.springframework.util.Assert; import org.springframework.util.PathMatcher; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.server.ServerWebExchange; -import org.springframework.web.server.support.LookupPath; import org.springframework.web.util.pattern.ParsingPathMatcher; /** @@ -81,7 +80,7 @@ public class UrlBasedCorsConfigurationSource implements CorsConfigurationSource @Override public CorsConfiguration getCorsConfiguration(ServerWebExchange exchange) { - String lookupPath = LookupPath.getCurrent(exchange).getPath(); + String lookupPath = exchange.getRequest().getPathWithinApplication(); for (Map.Entry entry : this.corsConfigurations.entrySet()) { if (this.pathMatcher.match(entry.getKey(), lookupPath)) { return entry.getValue(); diff --git a/spring-web/src/main/java/org/springframework/web/server/support/HttpRequestPathHelper.java b/spring-web/src/main/java/org/springframework/web/server/support/HttpRequestPathHelper.java index 3476de157ae..2b4f00c7e89 100644 --- a/spring-web/src/main/java/org/springframework/web/server/support/HttpRequestPathHelper.java +++ b/spring-web/src/main/java/org/springframework/web/server/support/HttpRequestPathHelper.java @@ -36,7 +36,7 @@ import org.springframework.web.util.UriUtils; */ public class HttpRequestPathHelper { - private boolean urlDecode = true; + private boolean urlDecode = false; // TODO: sanitize path, default/request encoding?, remove path params? @@ -58,26 +58,6 @@ public class HttpRequestPathHelper { } - public LookupPath getLookupPathForRequest(ServerWebExchange exchange) { - String path = getPathWithinApplication(exchange.getRequest()); - path = (shouldUrlDecode() ? decode(exchange, path) : path); - int begin = path.lastIndexOf('/') + 1; - int end = path.length(); - int paramIndex = path.indexOf(';', begin); - int extIndex = path.lastIndexOf('.', paramIndex != -1 ? paramIndex : end); - return new LookupPath(path, extIndex, paramIndex); - } - - private String getPathWithinApplication(ServerHttpRequest request) { - String contextPath = request.getContextPath(); - String path = request.getURI().getRawPath(); - if (!StringUtils.hasText(contextPath)) { - return path; - } - int contextLength = contextPath.length(); - return (path.length() > contextLength ? path.substring(contextLength) : ""); - } - private String decode(ServerWebExchange exchange, String path) { // TODO: look up request encoding? try { diff --git a/spring-web/src/main/java/org/springframework/web/server/support/LookupPath.java b/spring-web/src/main/java/org/springframework/web/server/support/LookupPath.java deleted file mode 100644 index be5e247ad9a..00000000000 --- a/spring-web/src/main/java/org/springframework/web/server/support/LookupPath.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.server.support; - -import org.springframework.lang.Nullable; -import org.springframework.web.server.ServerWebExchange; - -/** - * Lookup path information of an incoming HTTP request. - * - * @author Brian Clozel - * @author Rossen Stoyanchev - * @since 5.0 - * @see HttpRequestPathHelper - */ -public final class LookupPath { - - /** - * Name of request attribute under which the LookupPath is stored via - * {@link #getOrCreate} and accessed via {@link #getCurrent}. - */ - public static final String LOOKUP_PATH_ATTRIBUTE_NAME = LookupPath.class.getName(); - - - private final String path; - - private final int fileExtStartIndex; - - private final int fileExtEndIndex; - - - public LookupPath(String path, int fileExtStartIndex, int fileExtEndIndex) { - this.path = path; - this.fileExtStartIndex = fileExtStartIndex; - this.fileExtEndIndex = fileExtEndIndex; - } - - - public String getPath() { - return this.path; - } - - public String getPathWithoutExtension() { - if (this.fileExtStartIndex != -1) { - return this.path.substring(0, this.fileExtStartIndex); - } - else { - return this.path; - } - } - - @Nullable - public String getFileExtension() { - if (this.fileExtStartIndex == -1) { - return null; - } - else if (this.fileExtEndIndex == -1) { - return this.path.substring(this.fileExtStartIndex); - } - else { - return this.path.substring(this.fileExtStartIndex, this.fileExtEndIndex); - } - } - - - /** - * Get the LookupPath for the current request from the request attribute - * {@link #LOOKUP_PATH_ATTRIBUTE_NAME} or otherwise create and stored it - * under that attribute for subsequent use. - * @param exchange the current exchange - * @param pathHelper the pathHelper to create the LookupPath with - * @return the LookupPath for the current request - */ - public static LookupPath getOrCreate(ServerWebExchange exchange, HttpRequestPathHelper pathHelper) { - return exchange.getAttribute(LookupPath.LOOKUP_PATH_ATTRIBUTE_NAME) - .orElseGet(() -> { - LookupPath lookupPath = pathHelper.getLookupPathForRequest(exchange); - exchange.getAttributes().put(LookupPath.LOOKUP_PATH_ATTRIBUTE_NAME, lookupPath); - return lookupPath; - }); - } - - /** - * Get the LookupPath for the current request from the request attribute - * {@link #LOOKUP_PATH_ATTRIBUTE_NAME} or raise an {@link IllegalStateException} - * if not found. - * @param exchange the current exchange - * @return the LookupPath, never {@code null} - */ - public static LookupPath getCurrent(ServerWebExchange exchange) { - return exchange.getAttribute(LookupPath.LOOKUP_PATH_ATTRIBUTE_NAME) - .orElseThrow(() -> new IllegalStateException("No LookupPath attribute.")); - } - -} diff --git a/spring-web/src/test/java/org/springframework/web/cors/reactive/UrlBasedCorsConfigurationSourceTests.java b/spring-web/src/test/java/org/springframework/web/cors/reactive/UrlBasedCorsConfigurationSourceTests.java index ae74e368141..75775e790e2 100644 --- a/spring-web/src/test/java/org/springframework/web/cors/reactive/UrlBasedCorsConfigurationSourceTests.java +++ b/spring-web/src/test/java/org/springframework/web/cors/reactive/UrlBasedCorsConfigurationSourceTests.java @@ -21,8 +21,6 @@ import org.junit.Test; import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.server.ServerWebExchange; -import org.springframework.web.server.support.HttpRequestPathHelper; -import org.springframework.web.server.support.LookupPath; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; @@ -41,7 +39,6 @@ public class UrlBasedCorsConfigurationSourceTests { @Test public void empty() { ServerWebExchange exchange = MockServerHttpRequest.get("/bar/test.html").toExchange(); - LookupPath.getOrCreate(exchange, new HttpRequestPathHelper()); assertNull(this.configSource.getCorsConfiguration(exchange)); } @@ -51,11 +48,9 @@ public class UrlBasedCorsConfigurationSourceTests { this.configSource.registerCorsConfiguration("/bar/**", config); ServerWebExchange exchange = MockServerHttpRequest.get("/foo/test.html").toExchange(); - LookupPath.getOrCreate(exchange, new HttpRequestPathHelper()); assertNull(this.configSource.getCorsConfiguration(exchange)); exchange = MockServerHttpRequest.get("/bar/test.html").toExchange(); - LookupPath.getOrCreate(exchange, new HttpRequestPathHelper()); assertEquals(config, this.configSource.getCorsConfiguration(exchange)); } diff --git a/spring-web/src/test/java/org/springframework/web/server/support/LookupPathTests.java b/spring-web/src/test/java/org/springframework/web/server/support/LookupPathTests.java deleted file mode 100644 index 97ecce43c28..00000000000 --- a/spring-web/src/test/java/org/springframework/web/server/support/LookupPathTests.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2002-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.server.support; - -import org.junit.Test; - -import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest; -import org.springframework.web.server.ServerWebExchange; - -import static org.junit.Assert.assertEquals; - -/** - * Unit tests for {@link LookupPath} - * @author Brian Clozel - */ -public class LookupPathTests { - - @Test - public void parsePath() { - LookupPath path = create("/foo"); - assertEquals("/foo", path.getPath()); - assertEquals("/foo", path.getPathWithoutExtension()); - } - - @Test - public void parsePathWithExtension() { - LookupPath path = create("/foo.txt"); - assertEquals("/foo.txt", path.getPath()); - assertEquals("/foo", path.getPathWithoutExtension()); - assertEquals(".txt", path.getFileExtension()); - } - - @Test - public void parsePathWithParams() { - LookupPath path = create("/test;spring=framework/foo.txt;foo=bar?framework=spring"); - assertEquals("/test;spring=framework/foo.txt;foo=bar", path.getPath()); - assertEquals("/test;spring=framework/foo", path.getPathWithoutExtension()); - assertEquals(".txt", path.getFileExtension()); - } - - private LookupPath create(String path) { - HttpRequestPathHelper helper = new HttpRequestPathHelper(); - ServerWebExchange exchange = MockServerHttpRequest.get(path).build().toExchange(); - return helper.getLookupPathForRequest(exchange); - } -} diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/handler/AbstractUrlHandlerMapping.java b/spring-webflux/src/main/java/org/springframework/web/reactive/handler/AbstractUrlHandlerMapping.java index f61d88803ed..408f6cb18c0 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/handler/AbstractUrlHandlerMapping.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/handler/AbstractUrlHandlerMapping.java @@ -28,7 +28,6 @@ import reactor.core.publisher.Mono; import org.springframework.beans.BeansException; import org.springframework.lang.Nullable; import org.springframework.util.Assert; -import org.springframework.web.server.support.LookupPath; import org.springframework.web.server.ServerWebExchange; /** @@ -101,7 +100,7 @@ public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping { @Override public Mono getHandlerInternal(ServerWebExchange exchange) { - LookupPath lookupPath = LookupPath.getOrCreate(exchange, getPathHelper()); + String lookupPath = exchange.getRequest().getPathWithinApplication(); Object handler; try { handler = lookupHandler(lookupPath, exchange); @@ -111,10 +110,10 @@ public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping { } if (handler != null && logger.isDebugEnabled()) { - logger.debug("Mapping [" + lookupPath.getPath() + "] to " + handler); + logger.debug("Mapping [" + lookupPath + "] to " + handler); } else if (handler == null && logger.isTraceEnabled()) { - logger.trace("No handler mapping found for [" + lookupPath.getPath() + "]"); + logger.trace("No handler mapping found for [" + lookupPath + "]"); } return Mono.justOrEmpty(handler); @@ -133,29 +132,28 @@ public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping { * @see org.springframework.web.util.pattern.ParsingPathMatcher */ @Nullable - protected Object lookupHandler(LookupPath lookupPath, ServerWebExchange exchange) throws Exception { + protected Object lookupHandler(String lookupPath, ServerWebExchange exchange) throws Exception { // Direct match? - String urlPath = lookupPath.getPath(); - Object handler = this.handlerMap.get(urlPath); + Object handler = this.handlerMap.get(lookupPath); if (handler != null) { - return handleMatch(handler, urlPath, urlPath, exchange); + return handleMatch(handler, lookupPath, lookupPath, exchange); } // Pattern match? List matches = new ArrayList<>(); for (String pattern : this.handlerMap.keySet()) { - if (getPathMatcher().match(pattern, urlPath)) { + if (getPathMatcher().match(pattern, lookupPath)) { matches.add(pattern); } else if (useTrailingSlashMatch()) { - if (!pattern.endsWith("/") && getPathMatcher().match(pattern + "/", urlPath)) { + if (!pattern.endsWith("/") && getPathMatcher().match(pattern + "/", lookupPath)) { matches.add(pattern +"/"); } } } String bestMatch = null; - Comparator comparator = getPathMatcher().getPatternComparator(urlPath); + Comparator comparator = getPathMatcher().getPatternComparator(lookupPath); if (!matches.isEmpty()) { Collections.sort(matches, comparator); if (logger.isDebugEnabled()) { @@ -174,7 +172,7 @@ public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping { "Could not find handler for best pattern match [" + bestMatch + "]"); } } - String pathWithinMapping = getPathMatcher().extractPathWithinPattern(bestMatch, urlPath); + String pathWithinMapping = getPathMatcher().extractPathWithinPattern(bestMatch, lookupPath); return handleMatch(handler, bestMatch, pathWithinMapping, exchange); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceUrlProvider.java b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceUrlProvider.java index 6c54ef199f6..b60259ade61 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceUrlProvider.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceUrlProvider.java @@ -38,7 +38,6 @@ import org.springframework.util.PathMatcher; import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping; import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.support.HttpRequestPathHelper; -import org.springframework.web.server.support.LookupPath; import org.springframework.web.util.pattern.ParsingPathMatcher; /** @@ -186,8 +185,8 @@ public class ResourceUrlProvider implements ApplicationListener matches = getMatchingPatterns(lookupPath); return matches.isEmpty() ? null : @@ -204,7 +203,7 @@ public final class PatternsRequestCondition extends AbstractRequestCondition getMatchingPatterns(LookupPath lookupPath) { + public List getMatchingPatterns(String lookupPath) { List matches = new ArrayList<>(); for (String pattern : this.patterns) { String match = getMatchingPattern(pattern, lookupPath); @@ -212,33 +211,19 @@ public final class PatternsRequestCondition extends AbstractRequestCondition patternComparator = this.pathMatcher.getPatternComparator(path); + String lookupPath = exchange.getRequest().getPathWithinApplication(); + Comparator patternComparator = this.pathMatcher.getPatternComparator(lookupPath); Iterator iterator = this.patterns.iterator(); Iterator iteratorOther = other.patterns.iterator(); while (iterator.hasNext() && iteratorOther.hasNext()) { diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/AbstractHandlerMethodMapping.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/AbstractHandlerMethodMapping.java index 30cdb626fda..5ce446927e6 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/AbstractHandlerMethodMapping.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/AbstractHandlerMethodMapping.java @@ -45,7 +45,6 @@ import org.springframework.web.method.HandlerMethod; import org.springframework.web.reactive.HandlerMapping; import org.springframework.web.reactive.handler.AbstractHandlerMapping; import org.springframework.web.server.ServerWebExchange; -import org.springframework.web.server.support.LookupPath; /** * Abstract base class for {@link HandlerMapping} implementations that define @@ -258,7 +257,7 @@ public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMap */ @Override public Mono getHandlerInternal(ServerWebExchange exchange) { - LookupPath lookupPath = LookupPath.getOrCreate(exchange, getPathHelper()); + String lookupPath = exchange.getRequest().getPathWithinApplication(); if (logger.isDebugEnabled()) { logger.debug("Looking up handler method for path " + lookupPath); } @@ -295,15 +294,15 @@ public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMap * @param lookupPath the lookup path within the current mapping * @param exchange the current exchange * @return the best-matching handler method, or {@code null} if no match - * @see #handleMatch(Object, LookupPath, ServerWebExchange) - * @see #handleNoMatch(Set, LookupPath, ServerWebExchange) + * @see #handleMatch(Object, String, ServerWebExchange) + * @see #handleNoMatch(Set, String, ServerWebExchange) */ @Nullable - protected HandlerMethod lookupHandlerMethod(LookupPath lookupPath, ServerWebExchange exchange) + protected HandlerMethod lookupHandlerMethod(String lookupPath, ServerWebExchange exchange) throws Exception { List matches = new ArrayList(); - List directPathMatches = this.mappingRegistry.getMappingsByUrl(lookupPath.getPath()); + List directPathMatches = this.mappingRegistry.getMappingsByUrl(lookupPath); if (directPathMatches != null) { addMatchingMappings(directPathMatches, matches, exchange); } @@ -355,7 +354,7 @@ public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMap * @param lookupPath the lookup path within the current mapping * @param exchange the current exchange */ - protected void handleMatch(T mapping, LookupPath lookupPath, ServerWebExchange exchange) { + protected void handleMatch(T mapping, String lookupPath, ServerWebExchange exchange) { } /** @@ -367,7 +366,7 @@ public abstract class AbstractHandlerMethodMapping extends AbstractHandlerMap * @throws Exception provides details that can be translated into an error status code */ @Nullable - protected HandlerMethod handleNoMatch(Set mappings, LookupPath lookupPath, ServerWebExchange exchange) + protected HandlerMethod handleNoMatch(Set mappings, String lookupPath, ServerWebExchange exchange) throws Exception { return null; diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMapping.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMapping.java index 44fea7cc212..bbc59ee3b58 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMapping.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMapping.java @@ -27,7 +27,6 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import java.util.StringTokenizer; import java.util.stream.Collectors; import org.springframework.http.HttpHeaders; @@ -35,9 +34,7 @@ import org.springframework.http.HttpMethod; import org.springframework.http.InvalidMediaTypeException; import org.springframework.http.MediaType; import org.springframework.http.server.reactive.ServerHttpRequest; -import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; -import org.springframework.util.StringUtils; import org.springframework.web.method.HandlerMethod; import org.springframework.web.reactive.HandlerMapping; import org.springframework.web.reactive.result.condition.NameValueExpression; @@ -46,7 +43,6 @@ import org.springframework.web.server.NotAcceptableStatusException; import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebInputException; import org.springframework.web.server.UnsupportedMediaTypeStatusException; -import org.springframework.web.server.support.LookupPath; /** @@ -105,30 +101,33 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe * @see HandlerMapping#PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE */ @Override - protected void handleMatch(RequestMappingInfo info, LookupPath lookupPath, ServerWebExchange exchange) { + protected void handleMatch(RequestMappingInfo info, String lookupPath, ServerWebExchange exchange) { super.handleMatch(info, lookupPath, exchange); String bestPattern; Map uriVariables; - Map decodedUriVariables; Set patterns = info.getPatternsCondition().getPatterns(); if (patterns.isEmpty()) { - bestPattern = lookupPath.getPath(); + bestPattern = lookupPath; uriVariables = Collections.emptyMap(); - decodedUriVariables = Collections.emptyMap(); } else { bestPattern = patterns.iterator().next(); - uriVariables = getPathMatcher().extractUriTemplateVariables(bestPattern, lookupPath.getPath()); - decodedUriVariables = getPathHelper().decodePathVariables(exchange, uriVariables); + uriVariables = getPathMatcher().extractUriTemplateVariables(bestPattern, lookupPath); + } + + // Let URI vars be stripped of semicolon content.. + Map> matrixVars = extractMatrixVariables(exchange, uriVariables); + exchange.getAttributes().put(MATRIX_VARIABLES_ATTRIBUTE, matrixVars); + + // Now decode URI variables + if (!uriVariables.isEmpty()) { + uriVariables = getPathHelper().decodePathVariables(exchange, uriVariables); } exchange.getAttributes().put(BEST_MATCHING_PATTERN_ATTRIBUTE, bestPattern); - exchange.getAttributes().put(URI_TEMPLATE_VARIABLES_ATTRIBUTE, decodedUriVariables); - - Map> matrixVars = extractMatrixVariables(exchange, uriVariables); - exchange.getAttributes().put(MATRIX_VARIABLES_ATTRIBUTE, matrixVars); + exchange.getAttributes().put(URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriVariables); if (!info.getProducesCondition().getProducibleMediaTypes().isEmpty()) { Set mediaTypes = info.getProducesCondition().getProducibleMediaTypes(); @@ -174,7 +173,7 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe * method but not by query parameter conditions */ @Override - protected HandlerMethod handleNoMatch(Set infos, LookupPath lookupPath, + protected HandlerMethod handleNoMatch(Set infos, String lookupPath, ServerWebExchange exchange) throws Exception { PartialMatchHelper helper = new PartialMatchHelper(infos, exchange); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java index fd177d39177..de88bb1c160 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandler.java @@ -51,7 +51,6 @@ import org.springframework.web.reactive.accept.RequestedContentTypeResolver; import org.springframework.web.reactive.result.HandlerResultHandlerSupport; import org.springframework.web.server.NotAcceptableStatusException; import org.springframework.web.server.ServerWebExchange; -import org.springframework.web.server.support.LookupPath; /** * {@code HandlerResultHandler} that encapsulates the view resolution algorithm @@ -259,7 +258,7 @@ public class ViewResolutionResultHandler extends HandlerResultHandlerSupport * Use the request path the leading and trailing slash stripped. */ private String getDefaultViewName(ServerWebExchange exchange) { - String path = LookupPath.getCurrent(exchange).getPath(); + String path = exchange.getRequest().getPathWithinApplication(); if (path.startsWith("/")) { path = path.substring(1); } diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/handler/SimpleUrlHandlerMappingTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/handler/SimpleUrlHandlerMappingTests.java index 9f4e9e74968..6f2cead1ab4 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/handler/SimpleUrlHandlerMappingTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/handler/SimpleUrlHandlerMappingTests.java @@ -94,8 +94,6 @@ public class SimpleUrlHandlerMappingTests { testUrl("/anotherTest", mainController, handlerMapping, "anotherTest"); testUrl("/stillAnotherTest", null, handlerMapping, null); testUrl("outofpattern*ye", null, handlerMapping, null); - testUrl("/test%26t%20est/path%26m%20atching.html", null, handlerMapping, null); - } private void testUrl(String url, Object bean, HandlerMapping handlerMapping, String pathWithinMapping) { diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/condition/PatternsRequestConditionTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/condition/PatternsRequestConditionTests.java index 13b1c78a8db..8ca1c96fea8 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/condition/PatternsRequestConditionTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/condition/PatternsRequestConditionTests.java @@ -16,15 +16,10 @@ package org.springframework.web.reactive.result.condition; -import java.util.Collections; -import java.util.Set; - import org.junit.Test; import org.springframework.mock.http.server.reactive.test.MockServerWebExchange; import org.springframework.web.server.ServerWebExchange; -import org.springframework.web.server.support.HttpRequestPathHelper; -import org.springframework.web.server.support.LookupPath; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -82,7 +77,7 @@ public class PatternsRequestConditionTests { @Test public void matchDirectPath() throws Exception { PatternsRequestCondition condition = new PatternsRequestCondition("/foo"); - PatternsRequestCondition match = condition.getMatchingCondition(initExchange("/foo")); + PatternsRequestCondition match = condition.getMatchingCondition(get("/foo").toExchange()); assertNotNull(match); } @@ -90,7 +85,7 @@ public class PatternsRequestConditionTests { @Test public void matchPattern() throws Exception { PatternsRequestCondition condition = new PatternsRequestCondition("/foo/*"); - PatternsRequestCondition match = condition.getMatchingCondition(initExchange("/foo/bar")); + PatternsRequestCondition match = condition.getMatchingCondition(get("/foo/bar").toExchange()); assertNotNull(match); } @@ -98,69 +93,15 @@ public class PatternsRequestConditionTests { @Test public void matchSortPatterns() throws Exception { PatternsRequestCondition condition = new PatternsRequestCondition("/*/*", "/foo/bar", "/foo/*"); - PatternsRequestCondition match = condition.getMatchingCondition(initExchange("/foo/bar")); + PatternsRequestCondition match = condition.getMatchingCondition(get("/foo/bar").toExchange()); PatternsRequestCondition expected = new PatternsRequestCondition("/foo/bar", "/foo/*", "/*/*"); assertEquals(expected, match); } - @Test - public void matchSuffixPattern() throws Exception { - ServerWebExchange exchange = initExchange("/foo.html"); - - PatternsRequestCondition condition = new PatternsRequestCondition("/{foo}"); - PatternsRequestCondition match = condition.getMatchingCondition(exchange); - - assertNotNull(match); - assertEquals("/{foo}.*", match.getPatterns().iterator().next()); - - condition = new PatternsRequestCondition(new String[] {"/{foo}"}, null,false, false, null); - match = condition.getMatchingCondition(exchange); - - assertNotNull(match); - assertEquals("/{foo}", match.getPatterns().iterator().next()); - } - - // SPR-8410 - - @Test - public void matchSuffixPatternUsingFileExtensions() throws Exception { - String[] patterns = new String[] {"/jobs/{jobName}"}; - Set extensions = Collections.singleton("json"); - PatternsRequestCondition condition = new PatternsRequestCondition(patterns, null, true, false, extensions); - - MockServerWebExchange exchange = initExchange("/jobs/my.job"); - PatternsRequestCondition match = condition.getMatchingCondition(exchange); - - assertNotNull(match); - assertEquals("/jobs/{jobName}", match.getPatterns().iterator().next()); - - exchange = initExchange("/jobs/my.job.json"); - match = condition.getMatchingCondition(exchange); - - assertNotNull(match); - assertEquals("/jobs/{jobName}.json", match.getPatterns().iterator().next()); - } - - @Test - public void matchSuffixPatternUsingFileExtensions2() throws Exception { - PatternsRequestCondition condition1 = new PatternsRequestCondition( - new String[] {"/prefix"}, null, true, false, Collections.singleton("json")); - - PatternsRequestCondition condition2 = new PatternsRequestCondition( - new String[] {"/suffix"}, null, true, false, null); - - PatternsRequestCondition combined = condition1.combine(condition2); - - MockServerWebExchange exchange = initExchange("/prefix/suffix.json"); - PatternsRequestCondition match = combined.getMatchingCondition(exchange); - - assertNotNull(match); - } - @Test public void matchTrailingSlash() throws Exception { - MockServerWebExchange exchange = initExchange("/foo/"); + MockServerWebExchange exchange = get("/foo/").toExchange(); PatternsRequestCondition condition = new PatternsRequestCondition("/foo"); PatternsRequestCondition match = condition.getMatchingCondition(exchange); @@ -175,9 +116,8 @@ public class PatternsRequestConditionTests { assertEquals("Trailing slash should be insensitive to useSuffixPatternMatch settings (SPR-6164, SPR-5636)", "/foo/", match.getPatterns().iterator().next()); - exchange = initExchange("/foo/"); condition = new PatternsRequestCondition(new String[] {"/foo"}, null, false, false, null); - match = condition.getMatchingCondition(exchange); + match = condition.getMatchingCondition(get("/foo/").toExchange()); assertNull(match); } @@ -185,7 +125,7 @@ public class PatternsRequestConditionTests { @Test public void matchPatternContainsExtension() throws Exception { PatternsRequestCondition condition = new PatternsRequestCondition("/foo.jpg"); - PatternsRequestCondition match = condition.getMatchingCondition(initExchange("/foo.html")); + PatternsRequestCondition match = condition.getMatchingCondition(get("/foo.html").toExchange()); assertNull(match); } @@ -195,7 +135,7 @@ public class PatternsRequestConditionTests { PatternsRequestCondition c1 = new PatternsRequestCondition("/foo*"); PatternsRequestCondition c2 = new PatternsRequestCondition("/foo*"); - assertEquals(0, c1.compareTo(c2, initExchange("/foo"))); + assertEquals(0, c1.compareTo(c2, get("/foo").toExchange())); } @Test @@ -203,15 +143,15 @@ public class PatternsRequestConditionTests { PatternsRequestCondition c1 = new PatternsRequestCondition("/fo*"); PatternsRequestCondition c2 = new PatternsRequestCondition("/foo"); - assertEquals(1, c1.compareTo(c2, initExchange("/foo"))); + assertEquals(1, c1.compareTo(c2, get("/foo").toExchange())); } @Test public void compareNumberOfMatchingPatterns() throws Exception { - ServerWebExchange exchange = initExchange("/foo.html"); + ServerWebExchange exchange = get("/foo.html").toExchange(); - PatternsRequestCondition c1 = new PatternsRequestCondition("/foo", "*.jpeg"); - PatternsRequestCondition c2 = new PatternsRequestCondition("/foo", "*.html"); + PatternsRequestCondition c1 = new PatternsRequestCondition("/foo.*", "/foo.jpeg"); + PatternsRequestCondition c2 = new PatternsRequestCondition("/foo.*", "/foo.html"); PatternsRequestCondition match1 = c1.getMatchingCondition(exchange); PatternsRequestCondition match2 = c2.getMatchingCondition(exchange); @@ -220,10 +160,4 @@ public class PatternsRequestConditionTests { assertEquals(1, match1.compareTo(match2, exchange)); } - private MockServerWebExchange initExchange(String path) { - MockServerWebExchange exchange = get(path).toExchange(); - LookupPath.getOrCreate(exchange, new HttpRequestPathHelper()); - return exchange; - } - } diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/condition/RequestMappingInfoTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/condition/RequestMappingInfoTests.java index ae0badb2e4b..c5ff5245de7 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/condition/RequestMappingInfoTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/condition/RequestMappingInfoTests.java @@ -30,8 +30,6 @@ import org.springframework.mock.http.server.reactive.test.MockServerWebExchange; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.reactive.result.method.RequestMappingInfo; import org.springframework.web.server.ServerWebExchange; -import org.springframework.web.server.support.HttpRequestPathHelper; -import org.springframework.web.server.support.LookupPath; import static java.util.Arrays.asList; import static org.junit.Assert.assertEquals; @@ -67,7 +65,6 @@ public class RequestMappingInfoTests { @Test public void matchPatternsCondition() { MockServerWebExchange exchange = MockServerHttpRequest.get("/foo").toExchange(); - LookupPath.getOrCreate(exchange, new HttpRequestPathHelper()); RequestMappingInfo info = paths("/foo*", "/bar").build(); RequestMappingInfo expected = paths("/foo*").build(); @@ -83,7 +80,6 @@ public class RequestMappingInfoTests { @Test public void matchParamsCondition() { ServerWebExchange exchange = MockServerHttpRequest.get("/foo?foo=bar").toExchange(); - LookupPath.getOrCreate(exchange, new HttpRequestPathHelper()); RequestMappingInfo info = paths("/foo").params("foo=bar").build(); RequestMappingInfo match = info.getMatchingCondition(exchange); @@ -99,7 +95,6 @@ public class RequestMappingInfoTests { @Test public void matchHeadersCondition() { ServerWebExchange exchange = MockServerHttpRequest.get("/foo").header("foo", "bar").toExchange(); - LookupPath.getOrCreate(exchange, new HttpRequestPathHelper()); RequestMappingInfo info = paths("/foo").headers("foo=bar").build(); RequestMappingInfo match = info.getMatchingCondition(exchange); @@ -115,7 +110,6 @@ public class RequestMappingInfoTests { @Test public void matchConsumesCondition() { ServerWebExchange exchange = MockServerHttpRequest.post("/foo").contentType(MediaType.TEXT_PLAIN).toExchange(); - LookupPath.getOrCreate(exchange, new HttpRequestPathHelper()); RequestMappingInfo info = paths("/foo").consumes("text/plain").build(); RequestMappingInfo match = info.getMatchingCondition(exchange); @@ -131,7 +125,6 @@ public class RequestMappingInfoTests { @Test public void matchProducesCondition() { ServerWebExchange exchange = MockServerHttpRequest.get("/foo").accept(MediaType.TEXT_PLAIN).toExchange(); - LookupPath.getOrCreate(exchange, new HttpRequestPathHelper()); RequestMappingInfo info = paths("/foo").produces("text/plain").build(); RequestMappingInfo match = info.getMatchingCondition(exchange); @@ -147,8 +140,7 @@ public class RequestMappingInfoTests { @Test public void matchCustomCondition() { ServerWebExchange exchange = MockServerHttpRequest.get("/foo?foo=bar").toExchange(); - LookupPath.getOrCreate(exchange, new HttpRequestPathHelper()); - + RequestMappingInfo info = paths("/foo").params("foo=bar").build(); RequestMappingInfo match = info.getMatchingCondition(exchange); @@ -169,7 +161,6 @@ public class RequestMappingInfoTests { RequestMappingInfo oneMethodOneParam = paths().methods(RequestMethod.GET).params("foo").build(); ServerWebExchange exchange = MockServerHttpRequest.get("/foo").toExchange(); - LookupPath.getOrCreate(exchange, new HttpRequestPathHelper()); Comparator comparator = (info, otherInfo) -> info.compareTo(otherInfo, exchange); List list = asList(none, oneMethod, oneMethodOneParam); diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMappingTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMappingTests.java index 0def9b7e1ef..f377599417e 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMappingTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMappingTests.java @@ -47,41 +47,41 @@ import org.springframework.web.method.HandlerMethod; import org.springframework.web.reactive.BindingContext; import org.springframework.web.reactive.HandlerMapping; import org.springframework.web.reactive.HandlerResult; -import org.springframework.web.reactive.result.method.RequestMappingInfo.*; +import org.springframework.web.reactive.result.method.RequestMappingInfo.BuilderConfiguration; import org.springframework.web.server.MethodNotAllowedException; import org.springframework.web.server.NotAcceptableStatusException; import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebInputException; import org.springframework.web.server.UnsupportedMediaTypeStatusException; -import org.springframework.web.server.support.HttpRequestPathHelper; -import org.springframework.web.server.support.LookupPath; -import static org.hamcrest.CoreMatchers.*; -import static org.junit.Assert.*; -import static org.springframework.mock.http.server.reactive.test.MockServerHttpRequest.*; -import static org.springframework.web.bind.annotation.RequestMethod.*; -import static org.springframework.web.method.MvcAnnotationPredicates.*; -import static org.springframework.web.method.ResolvableMethod.*; -import static org.springframework.web.reactive.result.method.RequestMappingInfo.*; +import static org.hamcrest.CoreMatchers.containsString; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import static org.springframework.mock.http.server.reactive.test.MockServerHttpRequest.get; +import static org.springframework.mock.http.server.reactive.test.MockServerHttpRequest.method; +import static org.springframework.web.bind.annotation.RequestMethod.GET; +import static org.springframework.web.bind.annotation.RequestMethod.HEAD; +import static org.springframework.web.bind.annotation.RequestMethod.OPTIONS; +import static org.springframework.web.method.MvcAnnotationPredicates.getMapping; +import static org.springframework.web.method.MvcAnnotationPredicates.requestMapping; +import static org.springframework.web.method.ResolvableMethod.on; +import static org.springframework.web.reactive.result.method.RequestMappingInfo.paths; /** * Unit tests for {@link RequestMappingInfoHandlerMapping}. - * * @author Rossen Stoyanchev */ public class RequestMappingInfoHandlerMappingTests { private TestRequestMappingInfoHandlerMapping handlerMapping; - private HttpRequestPathHelper pathHelper; - @Before public void setup() throws Exception { this.handlerMapping = new TestRequestMappingInfoHandlerMapping(); this.handlerMapping.registerHandler(new TestController()); - this.pathHelper = new HttpRequestPathHelper(); - this.handlerMapping.setPathHelper(this.pathHelper); } @@ -174,7 +174,6 @@ public class RequestMappingInfoHandlerMappingTests { public void getHandlerTestMediaTypeNotAcceptable() throws Exception { testMediaTypeNotAcceptable("/persons"); testMediaTypeNotAcceptable("/persons/"); - testMediaTypeNotAcceptable("/persons.json"); } @Test // SPR-12854 @@ -214,7 +213,7 @@ public class RequestMappingInfoHandlerMappingTests { @SuppressWarnings("unchecked") public void handleMatchUriTemplateVariables() throws Exception { ServerWebExchange exchange = get("/1/2").toExchange(); - LookupPath lookupPath = this.pathHelper.getLookupPathForRequest(exchange); + String lookupPath = exchange.getRequest().getPathWithinApplication(); RequestMappingInfo key = paths("/{path1}/{path2}").build(); this.handlerMapping.handleMatch(key, lookupPath, exchange); @@ -231,12 +230,9 @@ public class RequestMappingInfoHandlerMappingTests { public void handleMatchUriTemplateVariablesDecode() throws Exception { RequestMappingInfo key = paths("/{group}/{identifier}").build(); URI url = URI.create("/group/a%2Fb"); - ServerWebExchange exchange = MockServerHttpRequest.method(HttpMethod.GET, url).toExchange(); + ServerWebExchange exchange = method(HttpMethod.GET, url).toExchange(); - this.pathHelper.setUrlDecode(false); - LookupPath lookupPath = this.pathHelper.getLookupPathForRequest(exchange); - this.handlerMapping.setPathHelper(this.pathHelper); - + String lookupPath = exchange.getRequest().getPathWithinApplication(); this.handlerMapping.handleMatch(key, lookupPath, exchange); String name = HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE; @@ -252,7 +248,7 @@ public class RequestMappingInfoHandlerMappingTests { public void handleMatchBestMatchingPatternAttribute() throws Exception { RequestMappingInfo key = paths("/{path1}/2", "/**").build(); ServerWebExchange exchange = get("/1/2").toExchange(); - LookupPath lookupPath = this.pathHelper.getLookupPathForRequest(exchange); + String lookupPath = exchange.getRequest().getPathWithinApplication(); this.handlerMapping.handleMatch(key, lookupPath, exchange); assertEquals("/{path1}/2", exchange.getAttributes().get(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE)); @@ -262,7 +258,7 @@ public class RequestMappingInfoHandlerMappingTests { public void handleMatchBestMatchingPatternAttributeNoPatternsDefined() throws Exception { RequestMappingInfo key = paths().build(); ServerWebExchange exchange = get("/1/2").toExchange(); - LookupPath lookupPath = this.pathHelper.getLookupPathForRequest(exchange); + String lookupPath = exchange.getRequest().getPathWithinApplication(); this.handlerMapping.handleMatch(key, lookupPath, exchange); assertEquals("/1/2", exchange.getAttributes().get(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE)); @@ -309,11 +305,7 @@ public class RequestMappingInfoHandlerMappingTests { @Test public void handleMatchMatrixVariablesDecoding() throws Exception { - HttpRequestPathHelper urlPathHelper = new HttpRequestPathHelper(); - urlPathHelper.setUrlDecode(false); - this.handlerMapping.setPathHelper(urlPathHelper); - - ServerWebExchange exchange = get("/path;mvar=a%2fb").toExchange(); + ServerWebExchange exchange = method(HttpMethod.GET, URI.create("/path;mvar=a%2fb")).toExchange(); handleMatch(exchange, "/path{filter}"); MultiValueMap matrixVariables = getMatrixVariables(exchange, "filter"); @@ -375,7 +367,7 @@ public class RequestMappingInfoHandlerMappingTests { private void handleMatch(ServerWebExchange exchange, String pattern) { RequestMappingInfo info = paths(pattern).build(); - LookupPath lookupPath = this.pathHelper.getLookupPathForRequest(exchange); + String lookupPath = exchange.getRequest().getPathWithinApplication(); this.handlerMapping.handleMatch(info, lookupPath, exchange); } diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandlerTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandlerTests.java index 59fcacbb5d9..7d11620c3eb 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandlerTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/result/view/ViewResolutionResultHandlerTests.java @@ -55,8 +55,6 @@ import org.springframework.web.reactive.accept.HeaderContentTypeResolver; import org.springframework.web.reactive.accept.RequestedContentTypeResolver; import org.springframework.web.server.NotAcceptableStatusException; import org.springframework.web.server.ServerWebExchange; -import org.springframework.web.server.support.HttpRequestPathHelper; -import org.springframework.web.server.support.LookupPath; import static java.nio.charset.StandardCharsets.UTF_8; import static org.junit.Assert.assertEquals; @@ -219,17 +217,14 @@ public class ViewResolutionResultHandlerTests { ViewResolutionResultHandler handler = resultHandler(new TestViewResolver("account")); MockServerWebExchange exchange = get("/account").toExchange(); - LookupPath.getOrCreate(exchange, new HttpRequestPathHelper()); handler.handleResult(exchange, result).block(Duration.ofMillis(5000)); assertResponseBody(exchange, "account: {id=123}"); exchange = get("/account/").toExchange(); - LookupPath.getOrCreate(exchange, new HttpRequestPathHelper()); handler.handleResult(exchange, result).block(Duration.ofMillis(5000)); assertResponseBody(exchange, "account: {id=123}"); exchange = get("/account.123").toExchange(); - LookupPath.getOrCreate(exchange, new HttpRequestPathHelper()); handler.handleResult(exchange, result).block(Duration.ofMillis(5000)); assertResponseBody(exchange, "account: {id=123}"); } @@ -256,8 +251,7 @@ public class ViewResolutionResultHandlerTests { HandlerResult handlerResult = new HandlerResult(new Object(), value, returnType, this.bindingContext); MockServerWebExchange exchange = get("/account").accept(APPLICATION_JSON).toExchange(); - LookupPath.getOrCreate(exchange, new HttpRequestPathHelper()); - + TestView defaultView = new TestView("jsonView", APPLICATION_JSON); resultHandler(Collections.singletonList(defaultView), new TestViewResolver("account")) @@ -328,7 +322,6 @@ public class ViewResolutionResultHandlerTests { model.addAttribute("id", "123"); HandlerResult result = new HandlerResult(new Object(), returnValue, returnType, this.bindingContext); MockServerWebExchange exchange = get(path).toExchange(); - LookupPath.getOrCreate(exchange, new HttpRequestPathHelper()); resultHandler(resolvers).handleResult(exchange, result).block(Duration.ofSeconds(5)); assertResponseBody(exchange, responseBody); return exchange; diff --git a/spring-webflux/src/test/resources/org/springframework/web/reactive/handler/map.xml b/spring-webflux/src/test/resources/org/springframework/web/reactive/handler/map.xml index f2fe52c6d90..74b2a7af612 100644 --- a/spring-webflux/src/test/resources/org/springframework/web/reactive/handler/map.xml +++ b/spring-webflux/src/test/resources/org/springframework/web/reactive/handler/map.xml @@ -29,7 +29,6 @@ /reservation.html=mainController /payment.html=mainController /confirmation.html=mainController - /test%26t%20est/path%26m%20atching.html=mainController