Skip to content

Commit df171ff

Browse files
committed
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
1 parent fb3e054 commit df171ff

File tree

2 files changed

+34
-23
lines changed

2 files changed

+34
-23
lines changed

spring-test/src/main/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilder.java

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151
import org.springframework.web.servlet.FlashMap;
5252
import org.springframework.web.servlet.FlashMapManager;
5353
import org.springframework.web.servlet.support.SessionFlashMapManager;
54-
import org.springframework.web.util.UriComponents;
5554
import org.springframework.web.util.UriComponentsBuilder;
5655
import org.springframework.web.util.UriUtils;
5756

@@ -72,7 +71,7 @@ public class MockHttpServletRequestBuilder
7271

7372
private final HttpMethod method;
7473

75-
private final UriComponents uriComponents;
74+
private final URI url;
7675

7776
private final MultiValueMap<String, Object> headers = new LinkedMultiValueMap<String, Object>();
7877

@@ -116,14 +115,11 @@ public class MockHttpServletRequestBuilder
116115
* the {@code MockHttpServletRequest} can be plugged in via
117116
* {@link #with(RequestPostProcessor)}.
118117
* @param httpMethod the HTTP method (GET, POST, etc)
119-
* @param urlTemplate a URL template; the resulting URL will be encoded
120-
* @param urlVariables zero or more URL variables
118+
* @param url a URL template; the resulting URL will be encoded
119+
* @param vars zero or more URL variables
121120
*/
122-
MockHttpServletRequestBuilder(HttpMethod httpMethod, String urlTemplate, Object... urlVariables) {
123-
Assert.notNull(httpMethod, "httpMethod is required");
124-
Assert.notNull(urlTemplate, "uriTemplate is required");
125-
this.method = httpMethod;
126-
this.uriComponents = UriComponentsBuilder.fromUriString(urlTemplate).buildAndExpand(urlVariables).encode();
121+
MockHttpServletRequestBuilder(HttpMethod httpMethod, String url, Object... vars) {
122+
this(httpMethod, UriComponentsBuilder.fromUriString(url).buildAndExpand(vars).encode().toUri());
127123
}
128124

129125
/**
@@ -133,14 +129,14 @@ public class MockHttpServletRequestBuilder
133129
* the {@code MockHttpServletRequest} can be plugged in via
134130
* {@link #with(RequestPostProcessor)}.
135131
* @param httpMethod the HTTP method (GET, POST, etc)
136-
* @param uri the URL
132+
* @param url the URL
137133
* @since 4.0.3
138134
*/
139-
MockHttpServletRequestBuilder(HttpMethod httpMethod, URI uri) {
135+
MockHttpServletRequestBuilder(HttpMethod httpMethod, URI url) {
140136
Assert.notNull(httpMethod, "httpMethod is required");
141-
Assert.notNull(uri, "uri is required");
137+
Assert.notNull(url, "url is required");
142138
this.method = httpMethod;
143-
this.uriComponents = UriComponentsBuilder.fromUri(uri).build();
139+
this.url = url;
144140
}
145141

146142

@@ -559,18 +555,18 @@ private boolean containsCookie(Cookie cookie) {
559555
public final MockHttpServletRequest buildRequest(ServletContext servletContext) {
560556
MockHttpServletRequest request = createServletRequest(servletContext);
561557

562-
String requestUri = this.uriComponents.getPath();
558+
String requestUri = this.url.getRawPath();
563559
request.setRequestURI(requestUri);
564560
updatePathRequestProperties(request, requestUri);
565561

566-
if (this.uriComponents.getScheme() != null) {
567-
request.setScheme(this.uriComponents.getScheme());
562+
if (this.url.getScheme() != null) {
563+
request.setScheme(this.url.getScheme());
568564
}
569-
if (this.uriComponents.getHost() != null) {
570-
request.setServerName(uriComponents.getHost());
565+
if (this.url.getHost() != null) {
566+
request.setServerName(this.url.getHost());
571567
}
572-
if (this.uriComponents.getPort() != -1) {
573-
request.setServerPort(this.uriComponents.getPort());
568+
if (this.url.getPort() != -1) {
569+
request.setServerPort(this.url.getPort());
574570
}
575571

576572
request.setMethod(this.method.name());
@@ -582,11 +578,14 @@ public final MockHttpServletRequest buildRequest(ServletContext servletContext)
582578
}
583579

584580
try {
585-
if (this.uriComponents.getQuery() != null) {
586-
request.setQueryString(this.uriComponents.getQuery());
581+
if (this.url.getRawQuery() != null) {
582+
request.setQueryString(this.url.getRawQuery());
587583
}
588584

589-
for (Entry<String, List<String>> entry : this.uriComponents.getQueryParams().entrySet()) {
585+
MultiValueMap<String, String> queryParams =
586+
UriComponentsBuilder.fromUri(this.url).build().getQueryParams();
587+
588+
for (Entry<String, List<String>> entry : queryParams.entrySet()) {
590589
for (String value : entry.getValue()) {
591590
value = (value != null) ? UriUtils.decode(value, "UTF-8") : null;
592591
request.addParameter(UriUtils.decode(entry.getKey(), "UTF-8"), value);

spring-test/src/test/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilderTests.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
package org.springframework.test.web.servlet.request;
1717

1818
import java.io.IOException;
19+
import java.net.URI;
20+
import java.net.URISyntaxException;
1921
import java.security.Principal;
2022
import java.util.Arrays;
2123
import java.util.Collections;
@@ -91,6 +93,16 @@ public void requestUriWithEncoding() {
9193
assertEquals("/foo%20bar", request.getRequestURI());
9294
}
9395

96+
// SPR-13435
97+
98+
@Test
99+
public void requestUriWithDoubleSlashes() throws URISyntaxException {
100+
this.builder = new MockHttpServletRequestBuilder(HttpMethod.GET, new URI("/test//currentlyValid/0"));
101+
MockHttpServletRequest request = this.builder.buildRequest(this.servletContext);
102+
103+
assertEquals("/test//currentlyValid/0", request.getRequestURI());
104+
}
105+
94106
@Test
95107
public void contextPathEmpty() {
96108
this.builder = new MockHttpServletRequestBuilder(HttpMethod.GET, "/foo");

0 commit comments

Comments
 (0)