From df171ff5bb47a761edc8def7ea6c0456d4a4d3ed Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Wed, 23 Sep 2015 17:50:29 -0400 Subject: [PATCH] MockMvc request builder preserves double slashes The MockHttpServletRequestBuilder now uses java.net.URI internally rather than UriComponents. This means that for the MockMvcRequestBuilders method variants that accept a java.net.URI we can use it as is. The difference is almost none but it does mean that you can create a URI with double slashes (for testing purposes) and have it remain that way. Issue: SPR-13435 --- .../MockHttpServletRequestBuilder.java | 45 +++++++++---------- .../MockHttpServletRequestBuilderTests.java | 12 +++++ 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilder.java b/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilder.java index 2d25a246e8..d26e0c985d 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilder.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilder.java @@ -51,7 +51,6 @@ import org.springframework.web.servlet.DispatcherServlet; import org.springframework.web.servlet.FlashMap; import org.springframework.web.servlet.FlashMapManager; import org.springframework.web.servlet.support.SessionFlashMapManager; -import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; import org.springframework.web.util.UriUtils; @@ -72,7 +71,7 @@ public class MockHttpServletRequestBuilder private final HttpMethod method; - private final UriComponents uriComponents; + private final URI url; private final MultiValueMap headers = new LinkedMultiValueMap(); @@ -116,14 +115,11 @@ public class MockHttpServletRequestBuilder * the {@code MockHttpServletRequest} can be plugged in via * {@link #with(RequestPostProcessor)}. * @param httpMethod the HTTP method (GET, POST, etc) - * @param urlTemplate a URL template; the resulting URL will be encoded - * @param urlVariables zero or more URL variables + * @param url a URL template; the resulting URL will be encoded + * @param vars zero or more URL variables */ - MockHttpServletRequestBuilder(HttpMethod httpMethod, String urlTemplate, Object... urlVariables) { - Assert.notNull(httpMethod, "httpMethod is required"); - Assert.notNull(urlTemplate, "uriTemplate is required"); - this.method = httpMethod; - this.uriComponents = UriComponentsBuilder.fromUriString(urlTemplate).buildAndExpand(urlVariables).encode(); + MockHttpServletRequestBuilder(HttpMethod httpMethod, String url, Object... vars) { + this(httpMethod, UriComponentsBuilder.fromUriString(url).buildAndExpand(vars).encode().toUri()); } /** @@ -133,14 +129,14 @@ public class MockHttpServletRequestBuilder * the {@code MockHttpServletRequest} can be plugged in via * {@link #with(RequestPostProcessor)}. * @param httpMethod the HTTP method (GET, POST, etc) - * @param uri the URL + * @param url the URL * @since 4.0.3 */ - MockHttpServletRequestBuilder(HttpMethod httpMethod, URI uri) { + MockHttpServletRequestBuilder(HttpMethod httpMethod, URI url) { Assert.notNull(httpMethod, "httpMethod is required"); - Assert.notNull(uri, "uri is required"); + Assert.notNull(url, "url is required"); this.method = httpMethod; - this.uriComponents = UriComponentsBuilder.fromUri(uri).build(); + this.url = url; } @@ -559,18 +555,18 @@ public class MockHttpServletRequestBuilder public final MockHttpServletRequest buildRequest(ServletContext servletContext) { MockHttpServletRequest request = createServletRequest(servletContext); - String requestUri = this.uriComponents.getPath(); + String requestUri = this.url.getRawPath(); request.setRequestURI(requestUri); updatePathRequestProperties(request, requestUri); - if (this.uriComponents.getScheme() != null) { - request.setScheme(this.uriComponents.getScheme()); + if (this.url.getScheme() != null) { + request.setScheme(this.url.getScheme()); } - if (this.uriComponents.getHost() != null) { - request.setServerName(uriComponents.getHost()); + if (this.url.getHost() != null) { + request.setServerName(this.url.getHost()); } - if (this.uriComponents.getPort() != -1) { - request.setServerPort(this.uriComponents.getPort()); + if (this.url.getPort() != -1) { + request.setServerPort(this.url.getPort()); } request.setMethod(this.method.name()); @@ -582,11 +578,14 @@ public class MockHttpServletRequestBuilder } try { - if (this.uriComponents.getQuery() != null) { - request.setQueryString(this.uriComponents.getQuery()); + if (this.url.getRawQuery() != null) { + request.setQueryString(this.url.getRawQuery()); } - for (Entry> entry : this.uriComponents.getQueryParams().entrySet()) { + MultiValueMap queryParams = + UriComponentsBuilder.fromUri(this.url).build().getQueryParams(); + + for (Entry> entry : queryParams.entrySet()) { for (String value : entry.getValue()) { value = (value != null) ? UriUtils.decode(value, "UTF-8") : null; request.addParameter(UriUtils.decode(entry.getKey(), "UTF-8"), value); diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilderTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilderTests.java index e607080984..200ca53b14 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilderTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilderTests.java @@ -16,6 +16,8 @@ package org.springframework.test.web.servlet.request; import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; import java.security.Principal; import java.util.Arrays; import java.util.Collections; @@ -91,6 +93,16 @@ public class MockHttpServletRequestBuilderTests { assertEquals("/foo%20bar", request.getRequestURI()); } + // SPR-13435 + + @Test + public void requestUriWithDoubleSlashes() throws URISyntaxException { + this.builder = new MockHttpServletRequestBuilder(HttpMethod.GET, new URI("/test//currentlyValid/0")); + MockHttpServletRequest request = this.builder.buildRequest(this.servletContext); + + assertEquals("/test//currentlyValid/0", request.getRequestURI()); + } + @Test public void contextPathEmpty() { this.builder = new MockHttpServletRequestBuilder(HttpMethod.GET, "/foo"); -- GitLab