Restrict forwards in MockMvcWebConnection to 100

This change restricts the maximum number of forwards in MockMvcWebConnection to 100,
in case a forward is configured in a way that causes a loop. This is necessary in HtmlUnit
backed tests, unlike in classic MockMvc tests in which the forwards are not actually resolved.

See gh-29557
Closes gh-29866

Co-authored-by: Simon Baslé <sbasle@vmware.com>
This commit is contained in:
Manthan Bhatt
2023-02-07 07:23:56 -08:00
committed by Simon Baslé
parent c9841f37b6
commit 4e00aece7a
3 changed files with 21 additions and 1 deletions

View File

@@ -68,6 +68,8 @@ public final class MockMvcWebConnection implements WebConnection {
private WebClient webClient;
private static int MAX_FORWARDS = 100;
/**
* Create a new instance that assumes the context path of the application
@@ -133,10 +135,15 @@ public final class MockMvcWebConnection implements WebConnection {
MockHttpServletResponse httpServletResponse = getResponse(requestBuilder);
String forwardedUrl = httpServletResponse.getForwardedUrl();
while (forwardedUrl != null) {
int forwards = 0;
while (forwardedUrl != null && forwards < MAX_FORWARDS) {
requestBuilder.setForwardPostProcessor(new ForwardRequestPostProcessor(forwardedUrl));
httpServletResponse = getResponse(requestBuilder);
forwardedUrl = httpServletResponse.getForwardedUrl();
forwards += 1;
}
if (forwards == MAX_FORWARDS) {
throw new IllegalStateException("Forwarded more than " + forwards + " times in a row, potential infinite forward loop");
}
storeCookies(webRequest, httpServletResponse.getCookies());

View File

@@ -31,4 +31,9 @@ public class ForwardController {
return "forward:/a";
}
@RequestMapping("/infiniteForward")
public String infiniteForward() {
return "forward:/infiniteForward";
}
}

View File

@@ -29,6 +29,7 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
/**
@@ -80,6 +81,13 @@ public class MockMvcWebConnectionTests {
assertThat(page.getWebResponse().getContentAsString()).isEqualTo("hello");
}
@Test
public void infiniteForward() {
this.webClient.setWebConnection(new MockMvcWebConnection(this.mockMvc, this.webClient, ""));
assertThatIllegalStateException().isThrownBy(() -> this.webClient.getPage("http://localhost/infiniteForward"))
.withMessage("Forwarded more than 100 times in a row, potential infinite forward loop");
}
@Test
@SuppressWarnings("resource")
public void contextPathDoesNotStartWithSlash() throws IOException {