Consider custom server.context-path when configuring dev tools endpoints

Previously, the auto-configuration of DevTools’ debug, restart, and
health handlers assumed that the server was running on its default
context path and, if server.context-path was set to a non-default value,
the handlers would not work as expected.

This commit updates the auto-configuration of the three handlers to 
consider the server’s context path when configuring their URIs. Now,
when a custom server context path is used, no further configuration is
required other than the inclusion of that context path when providing
the remote URL as an argument to RemoteSpringApplication.

Closes gh-4301
pull/4334/head
Andy Wilkinson 9 years ago
parent b5246af148
commit 0adf037410

@ -31,6 +31,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.devtools.remote.server.AccessManager;
import org.springframework.boot.devtools.remote.server.Dispatcher;
@ -76,6 +77,9 @@ public class RemoteDevToolsAutoConfiguration {
@Autowired
private DevToolsProperties properties;
@Autowired
private ServerProperties serverProperties;
@Bean
@ConditionalOnMissingBean
public AccessManager remoteDevToolsAccessManager() {
@ -87,8 +91,9 @@ public class RemoteDevToolsAutoConfiguration {
@Bean
public HandlerMapper remoteDevToolsHealthCheckHandlerMapper() {
Handler handler = new HttpStatusHandler();
return new UrlHandlerMapper(this.properties.getRemote().getContextPath(),
handler);
return new UrlHandlerMapper((this.serverProperties.getContextPath() == null ? ""
: this.serverProperties.getContextPath())
+ this.properties.getRemote().getContextPath(), handler);
}
@Bean
@ -108,6 +113,9 @@ public class RemoteDevToolsAutoConfiguration {
@Autowired
private DevToolsProperties properties;
@Autowired
private ServerProperties serverProperties;
@Bean
@ConditionalOnMissingBean
public SourceFolderUrlFilter remoteRestartSourceFolderUrlFilter() {
@ -124,7 +132,9 @@ public class RemoteDevToolsAutoConfiguration {
@Bean
@ConditionalOnMissingBean(name = "remoteRestartHanderMapper")
public UrlHandlerMapper remoteRestartHanderMapper(HttpRestartServer server) {
String url = this.properties.getRemote().getContextPath() + "/restart";
String url = (this.serverProperties.getContextPath() == null ? ""
: this.serverProperties.getContextPath())
+ this.properties.getRemote().getContextPath() + "/restart";
logger.warn("Listening for remote restart updates on " + url);
Handler handler = new HttpRestartServerHandler(server);
return new UrlHandlerMapper(url, handler);
@ -141,11 +151,16 @@ public class RemoteDevToolsAutoConfiguration {
@Autowired
private DevToolsProperties properties;
@Autowired
private ServerProperties serverProperties;
@Bean
@ConditionalOnMissingBean(name = "remoteDebugHanderMapper")
public UrlHandlerMapper remoteDebugHanderMapper(
@Qualifier("remoteDebugHttpTunnelServer") HttpTunnelServer server) {
String url = this.properties.getRemote().getContextPath() + "/debug";
String url = (this.serverProperties.getContextPath() == null ? ""
: this.serverProperties.getContextPath())
+ this.properties.getRemote().getContextPath() + "/debug";
logger.warn("Listening for remote debug traffic on " + url);
Handler handler = new HttpTunnelServerHandler(server);
return new UrlHandlerMapper(url, handler);

@ -137,6 +137,17 @@ public class RemoteDevToolsAutoConfigurationTests {
assertRestartInvoked(true);
}
@Test
public void invokeRestartWithCustomServerContextPath() throws Exception {
loadContext("spring.devtools.remote.secret:supersecret",
"server.context-path:/test");
DispatcherFilter filter = this.context.getBean(DispatcherFilter.class);
this.request.setRequestURI("/test" + DEFAULT_CONTEXT_PATH + "/restart");
this.request.addHeader(DEFAULT_SECRET_HEADER_NAME, "supersecret");
filter.doFilter(this.request, this.response, this.chain);
assertRestartInvoked(true);
}
@Test
public void disableRestart() throws Exception {
loadContext("spring.devtools.remote.secret:supersecret",
@ -155,6 +166,17 @@ public class RemoteDevToolsAutoConfigurationTests {
assertTunnelInvoked(true);
}
@Test
public void invokeTunnelWithCustomServerContextPath() throws Exception {
loadContext("spring.devtools.remote.secret:supersecret",
"server.context-path:/test");
DispatcherFilter filter = this.context.getBean(DispatcherFilter.class);
this.request.setRequestURI("/test" + DEFAULT_CONTEXT_PATH + "/debug");
this.request.addHeader(DEFAULT_SECRET_HEADER_NAME, "supersecret");
filter.doFilter(this.request, this.response, this.chain);
assertTunnelInvoked(true);
}
@Test
public void invokeTunnelWithCustomHeaderName() throws Exception {
loadContext("spring.devtools.remote.secret:supersecret",
@ -185,6 +207,18 @@ public class RemoteDevToolsAutoConfigurationTests {
assertThat(this.response.getStatus(), equalTo(200));
}
@Test
public void devToolsHealthWithCustomServerContextPathReturns200() throws Exception {
loadContext("spring.devtools.remote.secret:supersecret",
"server.context-path:/test");
DispatcherFilter filter = this.context.getBean(DispatcherFilter.class);
this.request.setRequestURI("/test" + DEFAULT_CONTEXT_PATH);
this.request.addHeader(DEFAULT_SECRET_HEADER_NAME, "supersecret");
this.response.setStatus(500);
filter.doFilter(this.request, this.response, this.chain);
assertThat(this.response.getStatus(), equalTo(200));
}
private void assertTunnelInvoked(boolean value) {
assertThat(this.context.getBean(MockHttpTunnelServer.class).invoked,
equalTo(value));

Loading…
Cancel
Save