Browse Source

Properly initialize URI/Matrix vars w/ urlDecode=false

Issue: SPR-16867
pull/1836/head
Rossen Stoyanchev 8 years ago
parent
commit
85e8634810
  1. 54
      spring-webflux/src/test/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMappingTests.java
  2. 7
      spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMapping.java
  3. 8
      spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMappingTests.java

54
spring-webflux/src/test/java/org/springframework/web/reactive/result/method/RequestMappingInfoHandlerMappingTests.java

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2017 the original author or authors. * Copyright 2002-2018 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -91,14 +91,14 @@ public class RequestMappingInfoHandlerMappingTests {
@Before @Before
public void setup() throws Exception { public void setup() {
this.handlerMapping = new TestRequestMappingInfoHandlerMapping(); this.handlerMapping = new TestRequestMappingInfoHandlerMapping();
this.handlerMapping.registerHandler(new TestController()); this.handlerMapping.registerHandler(new TestController());
} }
@Test @Test
public void getHandlerDirectMatch() throws Exception { public void getHandlerDirectMatch() {
Method expected = on(TestController.class).annot(getMapping("/foo").params()).resolveMethod(); Method expected = on(TestController.class).annot(getMapping("/foo").params()).resolveMethod();
ServerWebExchange exchange = MockServerWebExchange.from(get("/foo")); ServerWebExchange exchange = MockServerWebExchange.from(get("/foo"));
HandlerMethod hm = (HandlerMethod) this.handlerMapping.getHandler(exchange).block(); HandlerMethod hm = (HandlerMethod) this.handlerMapping.getHandler(exchange).block();
@ -107,7 +107,7 @@ public class RequestMappingInfoHandlerMappingTests {
} }
@Test @Test
public void getHandlerGlobMatch() throws Exception { public void getHandlerGlobMatch() {
Method expected = on(TestController.class).annot(requestMapping("/ba*").method(GET, HEAD)).resolveMethod(); Method expected = on(TestController.class).annot(requestMapping("/ba*").method(GET, HEAD)).resolveMethod();
ServerWebExchange exchange = MockServerWebExchange.from(get("/bar")); ServerWebExchange exchange = MockServerWebExchange.from(get("/bar"));
HandlerMethod hm = (HandlerMethod) this.handlerMapping.getHandler(exchange).block(); HandlerMethod hm = (HandlerMethod) this.handlerMapping.getHandler(exchange).block();
@ -116,7 +116,7 @@ public class RequestMappingInfoHandlerMappingTests {
} }
@Test @Test
public void getHandlerEmptyPathMatch() throws Exception { public void getHandlerEmptyPathMatch() {
Method expected = on(TestController.class).annot(requestMapping("")).resolveMethod(); Method expected = on(TestController.class).annot(requestMapping("")).resolveMethod();
ServerWebExchange exchange = MockServerWebExchange.from(get("")); ServerWebExchange exchange = MockServerWebExchange.from(get(""));
HandlerMethod hm = (HandlerMethod) this.handlerMapping.getHandler(exchange).block(); HandlerMethod hm = (HandlerMethod) this.handlerMapping.getHandler(exchange).block();
@ -128,7 +128,7 @@ public class RequestMappingInfoHandlerMappingTests {
} }
@Test @Test
public void getHandlerBestMatch() throws Exception { public void getHandlerBestMatch() {
Method expected = on(TestController.class).annot(getMapping("/foo").params("p")).resolveMethod(); Method expected = on(TestController.class).annot(getMapping("/foo").params("p")).resolveMethod();
ServerWebExchange exchange = MockServerWebExchange.from(get("/foo?p=anything")); ServerWebExchange exchange = MockServerWebExchange.from(get("/foo?p=anything"));
HandlerMethod hm = (HandlerMethod) this.handlerMapping.getHandler(exchange).block(); HandlerMethod hm = (HandlerMethod) this.handlerMapping.getHandler(exchange).block();
@ -137,7 +137,7 @@ public class RequestMappingInfoHandlerMappingTests {
} }
@Test @Test
public void getHandlerRequestMethodNotAllowed() throws Exception { public void getHandlerRequestMethodNotAllowed() {
ServerWebExchange exchange = MockServerWebExchange.from(post("/bar")); ServerWebExchange exchange = MockServerWebExchange.from(post("/bar"));
Mono<Object> mono = this.handlerMapping.getHandler(exchange); Mono<Object> mono = this.handlerMapping.getHandler(exchange);
@ -146,7 +146,7 @@ public class RequestMappingInfoHandlerMappingTests {
} }
@Test // SPR-9603 @Test // SPR-9603
public void getHandlerRequestMethodMatchFalsePositive() throws Exception { public void getHandlerRequestMethodMatchFalsePositive() {
ServerWebExchange exchange = MockServerWebExchange.from(get("/users").accept(MediaType.APPLICATION_XML)); ServerWebExchange exchange = MockServerWebExchange.from(get("/users").accept(MediaType.APPLICATION_XML));
this.handlerMapping.registerHandler(new UserController()); this.handlerMapping.registerHandler(new UserController());
Mono<Object> mono = this.handlerMapping.getHandler(exchange); Mono<Object> mono = this.handlerMapping.getHandler(exchange);
@ -157,14 +157,14 @@ public class RequestMappingInfoHandlerMappingTests {
} }
@Test // SPR-8462 @Test // SPR-8462
public void getHandlerMediaTypeNotSupported() throws Exception { public void getHandlerMediaTypeNotSupported() {
testHttpMediaTypeNotSupportedException("/person/1"); testHttpMediaTypeNotSupportedException("/person/1");
testHttpMediaTypeNotSupportedException("/person/1/"); testHttpMediaTypeNotSupportedException("/person/1/");
testHttpMediaTypeNotSupportedException("/person/1.json"); testHttpMediaTypeNotSupportedException("/person/1.json");
} }
@Test @Test
public void getHandlerTestInvalidContentType() throws Exception { public void getHandlerTestInvalidContentType() {
MockServerHttpRequest request = put("/person/1").header("content-type", "bogus").build(); MockServerHttpRequest request = put("/person/1").header("content-type", "bogus").build();
ServerWebExchange exchange = MockServerWebExchange.from(request); ServerWebExchange exchange = MockServerWebExchange.from(request);
Mono<Object> mono = this.handlerMapping.getHandler(exchange); Mono<Object> mono = this.handlerMapping.getHandler(exchange);
@ -175,13 +175,13 @@ public class RequestMappingInfoHandlerMappingTests {
} }
@Test // SPR-8462 @Test // SPR-8462
public void getHandlerTestMediaTypeNotAcceptable() throws Exception { public void getHandlerTestMediaTypeNotAcceptable() {
testMediaTypeNotAcceptable("/persons"); testMediaTypeNotAcceptable("/persons");
testMediaTypeNotAcceptable("/persons/"); testMediaTypeNotAcceptable("/persons/");
} }
@Test // SPR-12854 @Test // SPR-12854
public void getHandlerTestRequestParamMismatch() throws Exception { public void getHandlerTestRequestParamMismatch() {
ServerWebExchange exchange = MockServerWebExchange.from(get("/params")); ServerWebExchange exchange = MockServerWebExchange.from(get("/params"));
Mono<Object> mono = this.handlerMapping.getHandler(exchange); Mono<Object> mono = this.handlerMapping.getHandler(exchange);
assertError(mono, ServerWebInputException.class, ex -> { assertError(mono, ServerWebInputException.class, ex -> {
@ -191,7 +191,7 @@ public class RequestMappingInfoHandlerMappingTests {
} }
@Test @Test
public void getHandlerHttpOptions() throws Exception { public void getHandlerHttpOptions() {
List<HttpMethod> allMethodExceptTrace = new ArrayList<>(Arrays.asList(HttpMethod.values())); List<HttpMethod> allMethodExceptTrace = new ArrayList<>(Arrays.asList(HttpMethod.values()));
allMethodExceptTrace.remove(HttpMethod.TRACE); allMethodExceptTrace.remove(HttpMethod.TRACE);
@ -202,7 +202,7 @@ public class RequestMappingInfoHandlerMappingTests {
} }
@Test @Test
public void getHandlerProducibleMediaTypesAttribute() throws Exception { public void getHandlerProducibleMediaTypesAttribute() {
ServerWebExchange exchange = MockServerWebExchange.from(get("/content").accept(MediaType.APPLICATION_XML)); ServerWebExchange exchange = MockServerWebExchange.from(get("/content").accept(MediaType.APPLICATION_XML));
this.handlerMapping.getHandler(exchange).block(); this.handlerMapping.getHandler(exchange).block();
@ -218,7 +218,7 @@ public class RequestMappingInfoHandlerMappingTests {
@Test @Test
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void handleMatchUriTemplateVariables() throws Exception { public void handleMatchUriTemplateVariables() {
ServerWebExchange exchange = MockServerWebExchange.from(get("/1/2")); ServerWebExchange exchange = MockServerWebExchange.from(get("/1/2"));
RequestMappingInfo key = paths("/{path1}/{path2}").build(); RequestMappingInfo key = paths("/{path1}/{path2}").build();
@ -233,7 +233,7 @@ public class RequestMappingInfoHandlerMappingTests {
} }
@Test // SPR-9098 @Test // SPR-9098
public void handleMatchUriTemplateVariablesDecode() throws Exception { public void handleMatchUriTemplateVariablesDecode() {
RequestMappingInfo key = paths("/{group}/{identifier}").build(); RequestMappingInfo key = paths("/{group}/{identifier}").build();
URI url = URI.create("/group/a%2Fb"); URI url = URI.create("/group/a%2Fb");
ServerWebExchange exchange = MockServerWebExchange.from(method(HttpMethod.GET, url)); ServerWebExchange exchange = MockServerWebExchange.from(method(HttpMethod.GET, url));
@ -250,7 +250,7 @@ public class RequestMappingInfoHandlerMappingTests {
} }
@Test @Test
public void handleMatchBestMatchingPatternAttribute() throws Exception { public void handleMatchBestMatchingPatternAttribute() {
RequestMappingInfo key = paths("/{path1}/2", "/**").build(); RequestMappingInfo key = paths("/{path1}/2", "/**").build();
ServerWebExchange exchange = MockServerWebExchange.from(get("/1/2")); ServerWebExchange exchange = MockServerWebExchange.from(get("/1/2"));
this.handlerMapping.handleMatch(key, handlerMethod, exchange); this.handlerMapping.handleMatch(key, handlerMethod, exchange);
@ -263,7 +263,7 @@ public class RequestMappingInfoHandlerMappingTests {
} }
@Test @Test
public void handleMatchBestMatchingPatternAttributeNoPatternsDefined() throws Exception { public void handleMatchBestMatchingPatternAttributeNoPatternsDefined() {
RequestMappingInfo key = paths().build(); RequestMappingInfo key = paths().build();
ServerWebExchange exchange = MockServerWebExchange.from(get("/1/2")); ServerWebExchange exchange = MockServerWebExchange.from(get("/1/2"));
this.handlerMapping.handleMatch(key, handlerMethod, exchange); this.handlerMapping.handleMatch(key, handlerMethod, exchange);
@ -273,7 +273,7 @@ public class RequestMappingInfoHandlerMappingTests {
} }
@Test @Test
public void handleMatchMatrixVariables() throws Exception { public void handleMatchMatrixVariables() {
MultiValueMap<String, String> matrixVariables; MultiValueMap<String, String> matrixVariables;
Map<String, String> uriVariables; Map<String, String> uriVariables;
@ -290,17 +290,17 @@ public class RequestMappingInfoHandlerMappingTests {
} }
@Test @Test
public void handleMatchMatrixVariablesDecoding() throws Exception { public void handleMatchMatrixVariablesDecoding() {
MockServerHttpRequest request = method(HttpMethod.GET, URI.create("/path;mvar=a%2fb")).build(); MockServerHttpRequest request = method(HttpMethod.GET, URI.create("/cars;mvar=a%2Fb")).build();
ServerWebExchange exchange = MockServerWebExchange.from(request); ServerWebExchange exchange = MockServerWebExchange.from(request);
handleMatch(exchange, "/{filter}"); handleMatch(exchange, "/{cars}");
MultiValueMap<String, String> matrixVariables = getMatrixVariables(exchange, "filter"); MultiValueMap<String, String> matrixVariables = getMatrixVariables(exchange, "cars");
Map<String, String> uriVariables = getUriTemplateVariables(exchange); Map<String, String> uriVariables = getUriTemplateVariables(exchange);
assertNotNull(matrixVariables); assertNotNull(matrixVariables);
assertEquals(Collections.singletonList("a/b"), matrixVariables.get("mvar")); assertEquals(Collections.singletonList("a/b"), matrixVariables.get("mvar"));
assertEquals("path", uriVariables.get("filter")); assertEquals("cars", uriVariables.get("cars"));
} }
@ -314,7 +314,7 @@ public class RequestMappingInfoHandlerMappingTests {
.verify(); .verify();
} }
private void testHttpMediaTypeNotSupportedException(String url) throws Exception { private void testHttpMediaTypeNotSupportedException(String url) {
MockServerHttpRequest request = put(url).contentType(MediaType.APPLICATION_JSON).build(); MockServerHttpRequest request = put(url).contentType(MediaType.APPLICATION_JSON).build();
ServerWebExchange exchange = MockServerWebExchange.from(request); ServerWebExchange exchange = MockServerWebExchange.from(request);
Mono<Object> mono = this.handlerMapping.getHandler(exchange); Mono<Object> mono = this.handlerMapping.getHandler(exchange);
@ -325,7 +325,7 @@ public class RequestMappingInfoHandlerMappingTests {
ex.getSupportedMediaTypes())); ex.getSupportedMediaTypes()));
} }
private void testHttpOptions(String requestURI, Set<HttpMethod> allowedMethods) throws Exception { private void testHttpOptions(String requestURI, Set<HttpMethod> allowedMethods) {
ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.options(requestURI)); ServerWebExchange exchange = MockServerWebExchange.from(MockServerHttpRequest.options(requestURI));
HandlerMethod handlerMethod = (HandlerMethod) this.handlerMapping.getHandler(exchange).block(); HandlerMethod handlerMethod = (HandlerMethod) this.handlerMapping.getHandler(exchange).block();
@ -342,7 +342,7 @@ public class RequestMappingInfoHandlerMappingTests {
assertEquals(allowedMethods, ((HttpHeaders) value).getAllow()); assertEquals(allowedMethods, ((HttpHeaders) value).getAllow());
} }
private void testMediaTypeNotAcceptable(String url) throws Exception { private void testMediaTypeNotAcceptable(String url) {
ServerWebExchange exchange = MockServerWebExchange.from(get(url).accept(MediaType.APPLICATION_JSON)); ServerWebExchange exchange = MockServerWebExchange.from(get(url).accept(MediaType.APPLICATION_JSON));
Mono<Object> mono = this.handlerMapping.getHandler(exchange); Mono<Object> mono = this.handlerMapping.getHandler(exchange);

7
spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMapping.java

@ -113,28 +113,27 @@ public abstract class RequestMappingInfoHandlerMapping extends AbstractHandlerMe
String bestPattern; String bestPattern;
Map<String, String> uriVariables; Map<String, String> uriVariables;
Map<String, String> decodedUriVariables;
Set<String> patterns = info.getPatternsCondition().getPatterns(); Set<String> patterns = info.getPatternsCondition().getPatterns();
if (patterns.isEmpty()) { if (patterns.isEmpty()) {
bestPattern = lookupPath; bestPattern = lookupPath;
uriVariables = Collections.emptyMap(); uriVariables = Collections.emptyMap();
decodedUriVariables = Collections.emptyMap();
} }
else { else {
bestPattern = patterns.iterator().next(); bestPattern = patterns.iterator().next();
uriVariables = getPathMatcher().extractUriTemplateVariables(bestPattern, lookupPath); uriVariables = getPathMatcher().extractUriTemplateVariables(bestPattern, lookupPath);
decodedUriVariables = getUrlPathHelper().decodePathVariables(request, uriVariables);
} }
request.setAttribute(BEST_MATCHING_PATTERN_ATTRIBUTE, bestPattern); request.setAttribute(BEST_MATCHING_PATTERN_ATTRIBUTE, bestPattern);
request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, decodedUriVariables);
if (isMatrixVariableContentAvailable()) { if (isMatrixVariableContentAvailable()) {
Map<String, MultiValueMap<String, String>> matrixVars = extractMatrixVariables(request, uriVariables); Map<String, MultiValueMap<String, String>> matrixVars = extractMatrixVariables(request, uriVariables);
request.setAttribute(HandlerMapping.MATRIX_VARIABLES_ATTRIBUTE, matrixVars); request.setAttribute(HandlerMapping.MATRIX_VARIABLES_ATTRIBUTE, matrixVars);
} }
Map<String, String> decodedUriVariables = getUrlPathHelper().decodePathVariables(request, uriVariables);
request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, decodedUriVariables);
if (!info.getProducesCondition().getProducibleMediaTypes().isEmpty()) { if (!info.getProducesCondition().getProducibleMediaTypes().isEmpty()) {
Set<MediaType> mediaTypes = info.getProducesCondition().getProducibleMediaTypes(); Set<MediaType> mediaTypes = info.getProducesCondition().getProducibleMediaTypes();
request.setAttribute(PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE, mediaTypes); request.setAttribute(PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE, mediaTypes);

8
spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/RequestMappingInfoHandlerMappingTests.java

@ -345,7 +345,7 @@ public class RequestMappingInfoHandlerMappingTests {
assertEquals("", uriVariables.get("params")); assertEquals("", uriVariables.get("params"));
} }
@Test @Test // SPR-10140, SPR-16867
public void handleMatchMatrixVariablesDecoding() { public void handleMatchMatrixVariablesDecoding() {
MockHttpServletRequest request; MockHttpServletRequest request;
@ -357,14 +357,14 @@ public class RequestMappingInfoHandlerMappingTests {
this.handlerMapping.setUrlPathHelper(urlPathHelper); this.handlerMapping.setUrlPathHelper(urlPathHelper);
request = new MockHttpServletRequest(); request = new MockHttpServletRequest();
handleMatch(request, "/path{filter}", "/path;mvar=a%2fb"); handleMatch(request, "/{cars}", "/cars;mvar=a%2Fb");
MultiValueMap<String, String> matrixVariables = getMatrixVariables(request, "filter"); MultiValueMap<String, String> matrixVariables = getMatrixVariables(request, "cars");
Map<String, String> uriVariables = getUriTemplateVariables(request); Map<String, String> uriVariables = getUriTemplateVariables(request);
assertNotNull(matrixVariables); assertNotNull(matrixVariables);
assertEquals(Collections.singletonList("a/b"), matrixVariables.get("mvar")); assertEquals(Collections.singletonList("a/b"), matrixVariables.get("mvar"));
assertEquals(";mvar=a/b", uriVariables.get("filter")); assertEquals("cars", uriVariables.get("cars"));
} }

Loading…
Cancel
Save