Unwraper handler to find ContextHandler when logging context path

Previously, only the top-level handlers were examined to find the
ContextHandlers and log the context path. If those handlers had
been wrapped, this prevented the ContextHandlers from being found
and an empty string was always logged.

When finding the context path, this commit unwraps the handler held
by a HandlerWrapper until the ContextHandler is found.

Fixes gh-19969
This commit is contained in:
Andy Wilkinson 2020-01-28 16:53:34 +00:00
parent f506559763
commit 140f5e7baf
2 changed files with 29 additions and 4 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -20,6 +20,7 @@ import java.io.IOException;
import java.net.BindException;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.apache.commons.logging.Log;
@ -206,8 +207,18 @@ public class JettyWebServer implements WebServer {
}
private String getContextPath() {
return Arrays.stream(this.server.getHandlers()).filter(ContextHandler.class::isInstance)
.map(ContextHandler.class::cast).map(ContextHandler::getContextPath).collect(Collectors.joining(" "));
return Arrays.stream(this.server.getHandlers()).map(this::findContextHandler).filter(Objects::nonNull)
.map(ContextHandler::getContextPath).collect(Collectors.joining(" "));
}
private ContextHandler findContextHandler(Handler handler) {
while (handler instanceof HandlerWrapper) {
if (handler instanceof ContextHandler) {
return (ContextHandler) handler;
}
handler = ((HandlerWrapper) handler).getHandler();
}
return null;
}
private void handleDeferredInitialize(Handler... handlers) throws Exception {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -24,7 +24,9 @@ import org.apache.jasper.servlet.JspServlet;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.webapp.WebAppContext;
import org.junit.Test;
import org.springframework.boot.web.server.Compression;
import org.springframework.boot.web.server.PortInUseException;
import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory;
import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactoryTests;
@ -83,4 +85,16 @@ public abstract class AbstractJettyServletWebServerFactoryTests extends Abstract
assertThat(((PortInUseException) ex).getPort()).isEqualTo(blockedPort);
}
@Test
public void contextPathIsLoggedOnStartupWhenCompressionIsEnabled() {
AbstractServletWebServerFactory factory = getFactory();
factory.setContextPath("/custom");
Compression compression = new Compression();
compression.setEnabled(true);
factory.setCompression(compression);
this.webServer = factory.getWebServer(exampleServletRegistration());
this.webServer.start();
assertThat(this.output.toString()).containsOnlyOnce("with context path '/custom'");
}
}