diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnection.java b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnection.java index ecc4b00514..96dcbc2e0c 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnection.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnection.java @@ -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()); diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/ForwardController.java b/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/ForwardController.java index 0a96d54bac..da8c10fddc 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/ForwardController.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/ForwardController.java @@ -31,4 +31,9 @@ public class ForwardController { return "forward:/a"; } + @RequestMapping("/infiniteForward") + public String infiniteForward() { + return "forward:/infiniteForward"; + } + } diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnectionTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnectionTests.java index 051cabaf01..6d4caaa3c7 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnectionTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/htmlunit/MockMvcWebConnectionTests.java @@ -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 {