diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphiQlHandler.java b/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphiQlHandler.java index b59f532c..c07cea0e 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphiQlHandler.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphiQlHandler.java @@ -78,23 +78,21 @@ public class GraphiQlHandler { } private URI getRedirectUrl(ServerRequest request) { - String contextPath = request.requestPath().contextPath().toString(); - String path = request.requestPath().pathWithinApplication().toString(); - UriBuilder builder = request.uriBuilder().replacePath(contextPath).path(path); - - String pathQueryParam = applyContextPath(request, this.graphQlPath); + UriBuilder builder = request.uriBuilder(); + String pathQueryParam = applyPathPrefix(request, this.graphQlPath); builder.queryParam("path", pathQueryParam); - if (StringUtils.hasText(this.graphQlWsPath)) { - String wsPathQueryParam = applyContextPath(request, this.graphQlWsPath); + String wsPathQueryParam = applyPathPrefix(request, this.graphQlWsPath); builder.queryParam("wsPath", wsPathQueryParam); } return builder.build(); } - private String applyContextPath(ServerRequest request, String path) { - String contextPath = request.requestPath().contextPath().toString(); - return StringUtils.hasText(contextPath) ? contextPath + path : path; + private String applyPathPrefix(ServerRequest request, String path) { + String fullPath = request.requestPath().value(); + String pathWithinApplication = request.requestPath().pathWithinApplication().toString(); + int pathWithinApplicationIndex = fullPath.indexOf(pathWithinApplication); + return (pathWithinApplicationIndex != -1) ? fullPath.substring(0, pathWithinApplicationIndex) + path : path; } } diff --git a/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphiQlHandlerTests.java b/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphiQlHandlerTests.java index 4a4801b9..355a8d45 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphiQlHandlerTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphiQlHandlerTests.java @@ -23,6 +23,7 @@ import java.util.Collections; import java.util.List; import jakarta.servlet.ServletException; +import jakarta.servlet.http.MappingMatch; import org.junit.jupiter.api.Test; @@ -31,10 +32,12 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.ResourceHttpMessageConverter; +import org.springframework.mock.web.MockHttpServletMapping; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.web.servlet.function.ServerRequest; import org.springframework.web.servlet.function.ServerResponse; +import org.springframework.web.util.ServletRequestPathUtils; import static org.assertj.core.api.Assertions.assertThat; @@ -96,6 +99,21 @@ class GraphiQlHandlerTests { assertThat(response.headers().getLocation().toASCIIString()).isEqualTo("http://localhost/context/graphiql?path=/context/graphql&wsPath=/context/graphql"); } + @Test + void shouldConsiderServletPathWhenRedirecting() { + MockHttpServletRequest servletRequest = new MockHttpServletRequest("GET", "/context/servlet/graphiql"); + servletRequest.setContextPath("/context"); + servletRequest.setServletPath("/servlet"); + servletRequest.setHttpServletMapping(new MockHttpServletMapping( + "/graphiql", "/context", "myServlet", MappingMatch.PATH)); + ServletRequestPathUtils.parseAndCache(servletRequest); + ServerRequest request = ServerRequest.create(servletRequest, MESSAGE_READERS); + ServerResponse response = this.handler.handleRequest(request); + assertThat(response.statusCode()).isEqualTo(HttpStatus.TEMPORARY_REDIRECT); + assertThat(response.headers().getLocation()).isNotNull(); + assertThat(response.headers().getLocation().toASCIIString()).isEqualTo("http://localhost/context/servlet/graphiql?path=/context/servlet/graphql"); + } + private String getResponseContent(MockHttpServletRequest servletRequest, ServerResponse response) throws ServletException, IOException { MockHttpServletResponse servletResponse = new MockHttpServletResponse(); response.writeTo(servletRequest, servletResponse, new DefaultContext());