AbstractMockHttpServletRequestBuilder#buildRequest is not idempotent

See gh-35493

Signed-off-by: Réda Housni Alaoui <reda-alaoui@hey.com>
This commit is contained in:
Réda Housni Alaoui 2025-09-17 11:09:40 +02:00 committed by rstoyanchev
parent a19b51b7e0
commit 636523a2f5
2 changed files with 14 additions and 3 deletions

View File

@ -74,6 +74,7 @@ import org.springframework.web.util.UrlPathHelper;
* @author Arjen Poutsma * @author Arjen Poutsma
* @author Sam Brannen * @author Sam Brannen
* @author Kamill Sokol * @author Kamill Sokol
* @author Réda Housni Alaoui
* @since 6.2 * @since 6.2
* @param <B> a self reference to the builder type * @param <B> a self reference to the builder type
*/ */
@ -854,16 +855,17 @@ public abstract class AbstractMockHttpServletRequestBuilder<B extends AbstractMo
request.setContextPath(this.contextPath); request.setContextPath(this.contextPath);
request.setServletPath(this.servletPath); request.setServletPath(this.servletPath);
if ("".equals(this.pathInfo)) { String pathInfoToUse = this.pathInfo;
if ("".equals(pathInfoToUse)) {
if (!requestUri.startsWith(this.contextPath + this.servletPath)) { if (!requestUri.startsWith(this.contextPath + this.servletPath)) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Invalid servlet path [" + this.servletPath + "] for request URI [" + requestUri + "]"); "Invalid servlet path [" + this.servletPath + "] for request URI [" + requestUri + "]");
} }
String extraPath = requestUri.substring(this.contextPath.length() + this.servletPath.length()); String extraPath = requestUri.substring(this.contextPath.length() + this.servletPath.length());
this.pathInfo = (StringUtils.hasText(extraPath) ? pathInfoToUse = (StringUtils.hasText(extraPath) ?
UrlPathHelper.defaultInstance.decodeRequestString(request, extraPath) : null); UrlPathHelper.defaultInstance.decodeRequestString(request, extraPath) : null);
} }
request.setPathInfo(this.pathInfo); request.setPathInfo(pathInfoToUse);
} }
private void addRequestParams(MockHttpServletRequest request, MultiValueMap<String, String> map) { private void addRequestParams(MockHttpServletRequest request, MultiValueMap<String, String> map) {

View File

@ -31,6 +31,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* Tests for {@link AbstractMockHttpServletRequestBuilder} * Tests for {@link AbstractMockHttpServletRequestBuilder}
* *
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Réda Housni Alaoui
*/ */
class AbstractMockHttpServletRequestBuilderTests { class AbstractMockHttpServletRequestBuilderTests {
@ -97,6 +98,14 @@ class AbstractMockHttpServletRequestBuilderTests {
} }
@Test
void pathInfoIsNotMutatedByBuildMethod() {
TestRequestBuilder builder = new TestRequestBuilder(HttpMethod.GET).uri("/b");
assertThat(buildRequest(builder).getPathInfo()).isEqualTo("/b");
builder.uri("/a");
assertThat(buildRequest(builder).getPathInfo()).isEqualTo("/a");
}
private MockHttpServletRequest buildRequest(AbstractMockHttpServletRequestBuilder<?> builder) { private MockHttpServletRequest buildRequest(AbstractMockHttpServletRequestBuilder<?> builder) {
return builder.buildRequest(this.servletContext); return builder.buildRequest(this.servletContext);
} }