mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-07-05 00:56:58 +08:00
Upgrade to Jetty 12
Closes gh-36073
This commit is contained in:
parent
02fd570b7d
commit
ed5d16de84
|
@ -161,9 +161,7 @@ dependencies {
|
|||
testImplementation("org.assertj:assertj-core")
|
||||
testImplementation("org.awaitility:awaitility")
|
||||
testImplementation("org.cache2k:cache2k-api")
|
||||
testImplementation("org.eclipse.jetty:jetty-webapp") {
|
||||
exclude group: "org.eclipse.jetty.toolchain", module: "jetty-jakarta-servlet-api"
|
||||
}
|
||||
testImplementation("org.eclipse.jetty.ee10:jetty-ee10-webapp")
|
||||
testImplementation("org.glassfish.jersey.ext:jersey-spring6")
|
||||
testImplementation("org.glassfish.jersey.media:jersey-media-json-jackson")
|
||||
testImplementation("org.hamcrest:hamcrest")
|
||||
|
|
|
@ -31,7 +31,6 @@ import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactor
|
|||
import org.springframework.boot.context.event.ApplicationStartedEvent;
|
||||
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.boot.testsupport.web.servlet.Servlet5ClassPathOverrides;
|
||||
import org.springframework.boot.web.embedded.jetty.JettyReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
|
||||
import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext;
|
||||
|
@ -50,7 +49,6 @@ import static org.mockito.Mockito.mock;
|
|||
* @author Andy Wilkinson
|
||||
* @author Chris Bono
|
||||
*/
|
||||
@Servlet5ClassPathOverrides
|
||||
class JettyMetricsAutoConfigurationTests {
|
||||
|
||||
@Test
|
||||
|
|
|
@ -78,20 +78,10 @@ dependencies {
|
|||
optional("nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect")
|
||||
optional("org.aspectj:aspectjweaver")
|
||||
optional("org.cache2k:cache2k-spring")
|
||||
optional("org.eclipse.jetty:jetty-webapp") {
|
||||
exclude(group: "org.eclipse.jetty", module: "jetty-jndi")
|
||||
exclude(group: "org.eclipse.jetty.toolchain", module: "jetty-jakarta-servlet-api")
|
||||
}
|
||||
optional("org.eclipse.jetty.ee10:jetty-ee10-webapp")
|
||||
optional("org.eclipse.jetty:jetty-reactive-httpclient")
|
||||
optional("org.eclipse.jetty.websocket:websocket-jakarta-server") {
|
||||
exclude(group: "org.eclipse.jetty", module: "jetty-jndi")
|
||||
exclude(group: "org.eclipse.jetty.toolchain", module: "jetty-jakarta-servlet-api")
|
||||
exclude(group: "org.eclipse.jetty.toolchain", module: "jetty-jakarta-websocket-api")
|
||||
}
|
||||
optional("org.eclipse.jetty.websocket:websocket-jetty-server") {
|
||||
exclude(group: "org.eclipse.jetty", module: "jetty-jndi")
|
||||
exclude(group: "org.eclipse.jetty.toolchain", module: "jetty-jakarta-servlet-api")
|
||||
}
|
||||
optional("org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jakarta-server")
|
||||
optional("org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jetty-server")
|
||||
optional("org.ehcache:ehcache") {
|
||||
artifact {
|
||||
classifier = 'jakarta'
|
||||
|
|
|
@ -19,9 +19,9 @@ package org.springframework.boot.autoconfigure.web.embedded;
|
|||
import io.undertow.Undertow;
|
||||
import org.apache.catalina.startup.Tomcat;
|
||||
import org.apache.coyote.UpgradeProtocol;
|
||||
import org.eclipse.jetty.ee10.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.util.Loader;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.xnio.SslClientAuthMode;
|
||||
import reactor.netty.http.server.HttpServer;
|
||||
|
||||
|
|
|
@ -18,7 +18,9 @@ package org.springframework.boot.autoconfigure.web.embedded;
|
|||
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.server.AbstractConnector;
|
||||
import org.eclipse.jetty.server.ConnectionFactory;
|
||||
import org.eclipse.jetty.server.CustomRequestLog;
|
||||
|
@ -26,9 +28,6 @@ import org.eclipse.jetty.server.Handler;
|
|||
import org.eclipse.jetty.server.HttpConfiguration;
|
||||
import org.eclipse.jetty.server.RequestLogWriter;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.server.handler.HandlerCollection;
|
||||
import org.eclipse.jetty.server.handler.HandlerWrapper;
|
||||
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.cloud.CloudPlatform;
|
||||
|
@ -131,17 +130,21 @@ public class JettyWebServerFactoryCustomizer
|
|||
setHandlerMaxHttpFormPostSize(server.getHandlers());
|
||||
}
|
||||
|
||||
private void setHandlerMaxHttpFormPostSize(Handler... handlers) {
|
||||
private void setHandlerMaxHttpFormPostSize(List<Handler> handlers) {
|
||||
for (Handler handler : handlers) {
|
||||
if (handler instanceof ContextHandler contextHandler) {
|
||||
contextHandler.setMaxFormContentSize(maxHttpFormPostSize);
|
||||
}
|
||||
else if (handler instanceof HandlerWrapper wrapper) {
|
||||
setHandlerMaxHttpFormPostSize(wrapper.getHandler());
|
||||
}
|
||||
else if (handler instanceof HandlerCollection collection) {
|
||||
setHandlerMaxHttpFormPostSize(collection.getHandlers());
|
||||
}
|
||||
setHandlerMaxHttpFormPostSize(handler);
|
||||
}
|
||||
}
|
||||
|
||||
private void setHandlerMaxHttpFormPostSize(Handler handler) {
|
||||
if (handler instanceof ServletContextHandler contextHandler) {
|
||||
contextHandler.setMaxFormContentSize(maxHttpFormPostSize);
|
||||
}
|
||||
else if (handler instanceof Handler.Wrapper wrapper) {
|
||||
setHandlerMaxHttpFormPostSize(wrapper.getHandler());
|
||||
}
|
||||
else if (handler instanceof Handler.Collection collection) {
|
||||
setHandlerMaxHttpFormPostSize(collection.getHandlers());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
package org.springframework.boot.autoconfigure.web.reactive;
|
||||
|
||||
import io.undertow.Undertow;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.eclipse.jetty.ee10.servlet.ServletHolder;
|
||||
import reactor.netty.http.server.HttpServer;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
|
@ -39,7 +39,6 @@ import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory;
|
|||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.client.reactive.JettyResourceFactory;
|
||||
import org.springframework.http.client.reactive.ReactorResourceFactory;
|
||||
|
||||
/**
|
||||
|
@ -97,17 +96,10 @@ abstract class ReactiveWebServerFactoryConfiguration {
|
|||
static class EmbeddedJetty {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
JettyResourceFactory jettyServerResourceFactory() {
|
||||
return new JettyResourceFactory();
|
||||
}
|
||||
|
||||
@Bean
|
||||
JettyReactiveWebServerFactory jettyReactiveWebServerFactory(JettyResourceFactory resourceFactory,
|
||||
JettyReactiveWebServerFactory jettyReactiveWebServerFactory(
|
||||
ObjectProvider<JettyServerCustomizer> serverCustomizers) {
|
||||
JettyReactiveWebServerFactory serverFactory = new JettyReactiveWebServerFactory();
|
||||
serverFactory.getServerCustomizers().addAll(serverCustomizers.orderedStream().toList());
|
||||
serverFactory.setResourceFactory(resourceFactory);
|
||||
return serverFactory;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,6 @@ import org.springframework.web.reactive.function.client.WebClient;
|
|||
@ConditionalOnClass(WebClient.class)
|
||||
@AutoConfigureAfter(SslAutoConfiguration.class)
|
||||
@Import({ ClientHttpConnectorFactoryConfiguration.ReactorNetty.class,
|
||||
ClientHttpConnectorFactoryConfiguration.JettyClient.class,
|
||||
ClientHttpConnectorFactoryConfiguration.HttpClient5.class,
|
||||
ClientHttpConnectorFactoryConfiguration.JdkClient.class })
|
||||
public class ClientHttpConnectorAutoConfiguration {
|
||||
|
|
|
@ -27,7 +27,6 @@ import org.springframework.boot.autoconfigure.reactor.netty.ReactorNettyConfigur
|
|||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.client.reactive.JettyResourceFactory;
|
||||
import org.springframework.http.client.reactive.ReactorResourceFactory;
|
||||
|
||||
/**
|
||||
|
@ -55,24 +54,6 @@ class ClientHttpConnectorFactoryConfiguration {
|
|||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(org.eclipse.jetty.reactive.client.ReactiveRequest.class)
|
||||
@ConditionalOnMissingBean(ClientHttpConnectorFactory.class)
|
||||
static class JettyClient {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
JettyResourceFactory jettyClientResourceFactory() {
|
||||
return new JettyResourceFactory();
|
||||
}
|
||||
|
||||
@Bean
|
||||
JettyClientHttpConnectorFactory jettyClientHttpConnectorFactory(JettyResourceFactory jettyResourceFactory) {
|
||||
return new JettyClientHttpConnectorFactory(jettyResourceFactory);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass({ HttpAsyncClients.class, AsyncRequestProducer.class, ReactiveResponseConsumer.class })
|
||||
@ConditionalOnMissingBean(ClientHttpConnectorFactory.class)
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-2023 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.web.reactive.function.client;
|
||||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
|
||||
import org.eclipse.jetty.io.ClientConnector;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
|
||||
import org.springframework.boot.ssl.SslBundle;
|
||||
import org.springframework.boot.ssl.SslOptions;
|
||||
import org.springframework.http.client.reactive.JettyClientHttpConnector;
|
||||
import org.springframework.http.client.reactive.JettyResourceFactory;
|
||||
|
||||
/**
|
||||
* {@link ClientHttpConnectorFactory} for {@link JettyClientHttpConnector}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class JettyClientHttpConnectorFactory implements ClientHttpConnectorFactory<JettyClientHttpConnector> {
|
||||
|
||||
private final JettyResourceFactory jettyResourceFactory;
|
||||
|
||||
JettyClientHttpConnectorFactory(JettyResourceFactory jettyResourceFactory) {
|
||||
this.jettyResourceFactory = jettyResourceFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JettyClientHttpConnector createClientHttpConnector(SslBundle sslBundle) {
|
||||
SslContextFactory.Client sslContextFactory = new SslContextFactory.Client();
|
||||
if (sslBundle != null) {
|
||||
SslOptions options = sslBundle.getOptions();
|
||||
if (options.getCiphers() != null) {
|
||||
sslContextFactory.setIncludeCipherSuites(options.getCiphers());
|
||||
sslContextFactory.setExcludeCipherSuites();
|
||||
}
|
||||
if (options.getEnabledProtocols() != null) {
|
||||
sslContextFactory.setIncludeProtocols(options.getEnabledProtocols());
|
||||
sslContextFactory.setExcludeProtocols();
|
||||
}
|
||||
sslContextFactory.setSslContext(sslBundle.createSslContext());
|
||||
}
|
||||
ClientConnector connector = new ClientConnector();
|
||||
connector.setSslContextFactory(sslContextFactory);
|
||||
HttpClientTransportOverHTTP transport = new HttpClientTransportOverHTTP(connector);
|
||||
HttpClient httpClient = new HttpClient(transport);
|
||||
return new JettyClientHttpConnector(httpClient, this.jettyResourceFactory);
|
||||
}
|
||||
|
||||
}
|
|
@ -20,9 +20,9 @@ import io.undertow.Undertow;
|
|||
import jakarta.servlet.Servlet;
|
||||
import org.apache.catalina.startup.Tomcat;
|
||||
import org.apache.coyote.UpgradeProtocol;
|
||||
import org.eclipse.jetty.ee10.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.util.Loader;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.xnio.SslClientAuthMode;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
|
|
|
@ -17,15 +17,13 @@
|
|||
package org.springframework.boot.autoconfigure.websocket.reactive;
|
||||
|
||||
import jakarta.servlet.ServletContext;
|
||||
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.ee10.websocket.jakarta.server.JakartaWebSocketServerContainer;
|
||||
import org.eclipse.jetty.ee10.websocket.server.JettyWebSocketServerContainer;
|
||||
import org.eclipse.jetty.ee10.websocket.servlet.WebSocketUpgradeFilter;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.handler.HandlerCollection;
|
||||
import org.eclipse.jetty.server.handler.HandlerWrapper;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.websocket.core.server.WebSocketMappings;
|
||||
import org.eclipse.jetty.websocket.core.server.WebSocketServerComponents;
|
||||
import org.eclipse.jetty.websocket.jakarta.server.internal.JakartaWebSocketServerContainer;
|
||||
import org.eclipse.jetty.websocket.server.JettyWebSocketServerContainer;
|
||||
import org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter;
|
||||
|
||||
import org.springframework.boot.web.embedded.jetty.JettyReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
|
@ -47,13 +45,13 @@ public class JettyWebSocketReactiveWebServerCustomizer
|
|||
if (servletContextHandler != null) {
|
||||
ServletContext servletContext = servletContextHandler.getServletContext();
|
||||
if (JettyWebSocketServerContainer.getContainer(servletContext) == null) {
|
||||
WebSocketServerComponents.ensureWebSocketComponents(server, servletContext);
|
||||
WebSocketServerComponents.ensureWebSocketComponents(server, servletContextHandler);
|
||||
JettyWebSocketServerContainer.ensureContainer(servletContext);
|
||||
}
|
||||
if (JakartaWebSocketServerContainer.getContainer(servletContext) == null) {
|
||||
WebSocketServerComponents.ensureWebSocketComponents(server, servletContext);
|
||||
WebSocketServerComponents.ensureWebSocketComponents(server, servletContextHandler);
|
||||
WebSocketUpgradeFilter.ensureFilter(servletContext);
|
||||
WebSocketMappings.ensureMappings(servletContext);
|
||||
WebSocketMappings.ensureMappings(servletContextHandler);
|
||||
JakartaWebSocketServerContainer.ensureContainer(servletContext);
|
||||
}
|
||||
}
|
||||
|
@ -64,10 +62,10 @@ public class JettyWebSocketReactiveWebServerCustomizer
|
|||
if (handler instanceof ServletContextHandler servletContextHandler) {
|
||||
return servletContextHandler;
|
||||
}
|
||||
if (handler instanceof HandlerWrapper handlerWrapper) {
|
||||
if (handler instanceof Handler.Wrapper handlerWrapper) {
|
||||
return findServletContextHandler(handlerWrapper.getHandler());
|
||||
}
|
||||
if (handler instanceof HandlerCollection handlerCollection) {
|
||||
if (handler instanceof Handler.Collection handlerCollection) {
|
||||
for (Handler contained : handlerCollection.getHandlers()) {
|
||||
ServletContextHandler servletContextHandler = findServletContextHandler(contained);
|
||||
if (servletContextHandler != null) {
|
||||
|
|
|
@ -20,7 +20,7 @@ import jakarta.servlet.Servlet;
|
|||
import jakarta.websocket.server.ServerContainer;
|
||||
import org.apache.catalina.startup.Tomcat;
|
||||
import org.apache.tomcat.websocket.server.WsSci;
|
||||
import org.eclipse.jetty.websocket.jakarta.server.config.JakartaWebSocketServletContainerInitializer;
|
||||
import org.eclipse.jetty.ee10.websocket.jakarta.server.config.JakartaWebSocketServletContainerInitializer;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2021 the original author or authors.
|
||||
* Copyright 2012-2023 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.
|
||||
|
@ -16,13 +16,13 @@
|
|||
|
||||
package org.springframework.boot.autoconfigure.websocket.servlet;
|
||||
|
||||
import org.eclipse.jetty.webapp.AbstractConfiguration;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.ee10.webapp.AbstractConfiguration;
|
||||
import org.eclipse.jetty.ee10.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.ee10.websocket.jakarta.server.JakartaWebSocketServerContainer;
|
||||
import org.eclipse.jetty.ee10.websocket.server.JettyWebSocketServerContainer;
|
||||
import org.eclipse.jetty.ee10.websocket.servlet.WebSocketUpgradeFilter;
|
||||
import org.eclipse.jetty.websocket.core.server.WebSocketMappings;
|
||||
import org.eclipse.jetty.websocket.core.server.WebSocketServerComponents;
|
||||
import org.eclipse.jetty.websocket.jakarta.server.internal.JakartaWebSocketServerContainer;
|
||||
import org.eclipse.jetty.websocket.server.JettyWebSocketServerContainer;
|
||||
import org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter;
|
||||
|
||||
import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
|
@ -41,20 +41,20 @@ public class JettyWebSocketServletWebServerCustomizer
|
|||
|
||||
@Override
|
||||
public void customize(JettyServletWebServerFactory factory) {
|
||||
factory.addConfigurations(new AbstractConfiguration() {
|
||||
factory.addConfigurations(new AbstractConfiguration(new AbstractConfiguration.Builder()) {
|
||||
|
||||
@Override
|
||||
public void configure(WebAppContext context) throws Exception {
|
||||
if (JettyWebSocketServerContainer.getContainer(context.getServletContext()) == null) {
|
||||
WebSocketServerComponents.ensureWebSocketComponents(context.getServer(),
|
||||
context.getServletContext());
|
||||
context.getContext().getContextHandler());
|
||||
JettyWebSocketServerContainer.ensureContainer(context.getServletContext());
|
||||
}
|
||||
if (JakartaWebSocketServerContainer.getContainer(context.getServletContext()) == null) {
|
||||
WebSocketServerComponents.ensureWebSocketComponents(context.getServer(),
|
||||
context.getServletContext());
|
||||
context.getContext().getContextHandler());
|
||||
WebSocketUpgradeFilter.ensureFilter(context.getServletContext());
|
||||
WebSocketMappings.ensureMappings(context.getServletContext());
|
||||
WebSocketMappings.ensureMappings(context.getContext().getContextHandler());
|
||||
JakartaWebSocketServerContainer.ensureContainer(context.getServletContext());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,8 +23,8 @@ import jakarta.servlet.Servlet;
|
|||
import jakarta.websocket.server.ServerContainer;
|
||||
import org.apache.catalina.startup.Tomcat;
|
||||
import org.apache.tomcat.websocket.server.WsSci;
|
||||
import org.eclipse.jetty.websocket.jakarta.server.config.JakartaWebSocketServletContainerInitializer;
|
||||
import org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter;
|
||||
import org.eclipse.jetty.ee10.websocket.jakarta.server.config.JakartaWebSocketServletContainerInitializer;
|
||||
import org.eclipse.jetty.ee10.websocket.servlet.WebSocketUpgradeFilter;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
|
|
|
@ -43,6 +43,7 @@ import org.osjava.sj.loader.JndiLoader;
|
|||
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.boot.testsupport.classpath.ClassPathExclusions;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
@ -62,6 +63,7 @@ import static org.mockito.Mockito.mock;
|
|||
* @author Kazuki Shimizu
|
||||
* @author Nishant Raut
|
||||
*/
|
||||
@ClassPathExclusions("jetty-jndi-*.jar")
|
||||
class JtaAutoConfigurationTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
|
|
@ -16,21 +16,14 @@
|
|||
|
||||
package org.springframework.boot.autoconfigure.web;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Duration;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import io.undertow.UndertowOptions;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServlet;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.apache.catalina.connector.Connector;
|
||||
import org.apache.catalina.core.StandardContext;
|
||||
import org.apache.catalina.core.StandardEngine;
|
||||
|
@ -38,8 +31,7 @@ import org.apache.catalina.valves.AccessLogValve;
|
|||
import org.apache.catalina.valves.RemoteIpValve;
|
||||
import org.apache.coyote.AbstractProtocol;
|
||||
import org.apache.tomcat.util.net.AbstractEndpoint;
|
||||
import org.eclipse.jetty.server.HttpChannel;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -51,21 +43,11 @@ import org.springframework.boot.context.properties.bind.Binder;
|
|||
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
|
||||
import org.springframework.boot.context.properties.source.MapConfigurationPropertySource;
|
||||
import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories;
|
||||
import org.springframework.boot.testsupport.web.servlet.Servlet5ClassPathOverrides;
|
||||
import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.jetty.JettyWebServer;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.boot.web.servlet.ServletContextInitializer;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.unit.DataSize;
|
||||
import org.springframework.web.client.ResponseErrorHandler;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
|
@ -444,7 +426,6 @@ class ServerPropertiesTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Servlet5ClassPathOverrides
|
||||
void jettyThreadPoolPropertyDefaultsShouldMatchServerDefault() {
|
||||
JettyServletWebServerFactory jettyFactory = new JettyServletWebServerFactory(0);
|
||||
JettyWebServer jetty = (JettyWebServer) jettyFactory.getWebServer();
|
||||
|
@ -459,61 +440,12 @@ class ServerPropertiesTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Servlet5ClassPathOverrides
|
||||
void jettyMaxHttpFormPostSizeMatchesDefault() {
|
||||
JettyServletWebServerFactory jettyFactory = new JettyServletWebServerFactory(0);
|
||||
JettyWebServer jetty = (JettyWebServer) jettyFactory
|
||||
.getWebServer((ServletContextInitializer) (servletContext) -> servletContext
|
||||
.addServlet("formPost", new HttpServlet() {
|
||||
|
||||
@Override
|
||||
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
req.getParameterMap();
|
||||
}
|
||||
|
||||
})
|
||||
.addMapping("/form"));
|
||||
jetty.start();
|
||||
org.eclipse.jetty.server.Connector connector = jetty.getServer().getConnectors()[0];
|
||||
final AtomicReference<Throwable> failure = new AtomicReference<>();
|
||||
connector.addBean(new HttpChannel.Listener() {
|
||||
|
||||
@Override
|
||||
public void onDispatchFailure(Request request, Throwable ex) {
|
||||
failure.set(ex);
|
||||
}
|
||||
|
||||
});
|
||||
try {
|
||||
RestTemplate template = new RestTemplate();
|
||||
template.setErrorHandler(new ResponseErrorHandler() {
|
||||
|
||||
@Override
|
||||
public boolean hasError(ClientHttpResponse response) throws IOException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleError(ClientHttpResponse response) throws IOException {
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
|
||||
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
|
||||
body.add("data", "a".repeat(250000));
|
||||
HttpEntity<MultiValueMap<String, Object>> entity = new HttpEntity<>(body, headers);
|
||||
template.postForEntity(URI.create("http://localhost:" + jetty.getPort() + "/form"), entity, Void.class);
|
||||
assertThat(failure.get()).isNotNull();
|
||||
String message = failure.get().getCause().getMessage();
|
||||
int defaultMaxPostSize = Integer.parseInt(message.substring(message.lastIndexOf(' ')).trim());
|
||||
assertThat(this.properties.getJetty().getMaxHttpFormPostSize().toBytes()).isEqualTo(defaultMaxPostSize);
|
||||
}
|
||||
finally {
|
||||
jetty.stop();
|
||||
}
|
||||
JettyWebServer jetty = (JettyWebServer) jettyFactory.getWebServer();
|
||||
Server server = jetty.getServer();
|
||||
assertThat(this.properties.getJetty().getMaxHttpFormPostSize().toBytes())
|
||||
.isEqualTo(((ServletContextHandler) server.getHandler()).getMaxFormContentSize());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -47,7 +47,6 @@ import org.springframework.boot.context.properties.bind.Bindable;
|
|||
import org.springframework.boot.context.properties.bind.Binder;
|
||||
import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
|
||||
import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories;
|
||||
import org.springframework.boot.testsupport.web.servlet.Servlet5ClassPathOverrides;
|
||||
import org.springframework.boot.web.embedded.jetty.ConfigurableJettyWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.jetty.JettyWebServer;
|
||||
|
@ -67,7 +66,6 @@ import static org.mockito.Mockito.mock;
|
|||
* @author HaiTao Zhang
|
||||
*/
|
||||
@DirtiesUrlFactories
|
||||
@Servlet5ClassPathOverrides
|
||||
class JettyWebServerFactoryCustomizerTests {
|
||||
|
||||
private MockEnvironment environment;
|
||||
|
|
|
@ -31,7 +31,6 @@ import org.springframework.boot.ssl.NoSuchSslBundleException;
|
|||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
|
||||
import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories;
|
||||
import org.springframework.boot.testsupport.web.servlet.Servlet5ClassPathOverrides;
|
||||
import org.springframework.boot.web.embedded.jetty.JettyReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer;
|
||||
import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
|
||||
|
@ -231,7 +230,6 @@ class ReactiveWebServerFactoryAutoConfigurationTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Servlet5ClassPathOverrides
|
||||
void jettyServerCustomizerBeanIsAddedToFactory() {
|
||||
new ReactiveWebApplicationContextRunner(AnnotationConfigReactiveWebApplicationContext::new)
|
||||
.withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class))
|
||||
|
@ -244,7 +242,6 @@ class ReactiveWebServerFactoryAutoConfigurationTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Servlet5ClassPathOverrides
|
||||
void jettyServerCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() {
|
||||
new ReactiveWebApplicationContextRunner(AnnotationConfigReactiveWebServerApplicationContext::new)
|
||||
.withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class))
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
package org.springframework.boot.autoconfigure.web.reactive.function.client;
|
||||
|
||||
import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
|
||||
import org.eclipse.jetty.reactive.client.ReactiveRequest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import reactor.netty.http.client.HttpClient;
|
||||
|
||||
|
@ -62,36 +61,20 @@ class ClientHttpConnectorAutoConfigurationTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void whenReactorIsUnavailableThenJettyBeansAreDefined() {
|
||||
void whenReactorIsUnavailableThenHttpClientBeansAreDefined() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader(HttpClient.class)).run((context) -> {
|
||||
BeanDefinition customizerDefinition = context.getBeanFactory()
|
||||
.getBeanDefinition("webClientHttpConnectorCustomizer");
|
||||
assertThat(customizerDefinition.isLazyInit()).isTrue();
|
||||
BeanDefinition connectorDefinition = context.getBeanFactory().getBeanDefinition("webClientHttpConnector");
|
||||
assertThat(connectorDefinition.isLazyInit()).isTrue();
|
||||
assertThat(context).hasBean("jettyClientResourceFactory");
|
||||
assertThat(context).hasBean("jettyClientHttpConnectorFactory");
|
||||
assertThat(context).hasBean("httpComponentsClientHttpConnectorFactory");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenReactorAndJettyAreUnavailableThenHttpClientBeansAreDefined() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader(HttpClient.class, ReactiveRequest.class))
|
||||
.run((context) -> {
|
||||
BeanDefinition customizerDefinition = context.getBeanFactory()
|
||||
.getBeanDefinition("webClientHttpConnectorCustomizer");
|
||||
assertThat(customizerDefinition.isLazyInit()).isTrue();
|
||||
BeanDefinition connectorDefinition = context.getBeanFactory()
|
||||
.getBeanDefinition("webClientHttpConnector");
|
||||
assertThat(connectorDefinition.isLazyInit()).isTrue();
|
||||
assertThat(context).hasBean("httpComponentsClientHttpConnectorFactory");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenReactorJettyAndHttpClientBeansAreUnavailableThenJdkClientBeansAreDefined() {
|
||||
this.contextRunner
|
||||
.withClassLoader(new FilteredClassLoader(HttpClient.class, ReactiveRequest.class, HttpAsyncClients.class))
|
||||
void whenReactorAndHttpClientBeansAreUnavailableThenJdkClientBeansAreDefined() {
|
||||
this.contextRunner.withClassLoader(new FilteredClassLoader(HttpClient.class, HttpAsyncClients.class))
|
||||
.run((context) -> {
|
||||
BeanDefinition customizerDefinition = context.getBeanFactory()
|
||||
.getBeanDefinition("webClientHttpConnectorCustomizer");
|
||||
|
|
|
@ -16,11 +16,6 @@
|
|||
|
||||
package org.springframework.boot.autoconfigure.web.reactive.function.client;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.util.thread.Scheduler;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
|
@ -32,13 +27,9 @@ import org.springframework.boot.test.context.FilteredClassLoader;
|
|||
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.http.client.reactive.HttpComponentsClientHttpConnector;
|
||||
import org.springframework.http.client.reactive.JettyClientHttpConnector;
|
||||
import org.springframework.http.client.reactive.JettyResourceFactory;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.then;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
|
||||
/**
|
||||
|
@ -50,40 +41,6 @@ import static org.mockito.Mockito.spy;
|
|||
*/
|
||||
class ClientHttpConnectorFactoryConfigurationTests {
|
||||
|
||||
@Test
|
||||
void jettyClientHttpConnectorAppliesJettyResourceFactory() {
|
||||
Executor executor = mock(Executor.class);
|
||||
ByteBufferPool byteBufferPool = mock(ByteBufferPool.class);
|
||||
Scheduler scheduler = mock(Scheduler.class);
|
||||
JettyResourceFactory jettyResourceFactory = new JettyResourceFactory();
|
||||
jettyResourceFactory.setExecutor(executor);
|
||||
jettyResourceFactory.setByteBufferPool(byteBufferPool);
|
||||
jettyResourceFactory.setScheduler(scheduler);
|
||||
JettyClientHttpConnectorFactory connectorFactory = getJettyClientHttpConnectorFactory(jettyResourceFactory);
|
||||
JettyClientHttpConnector connector = connectorFactory.createClientHttpConnector();
|
||||
HttpClient httpClient = (HttpClient) ReflectionTestUtils.getField(connector, "httpClient");
|
||||
assertThat(httpClient.getExecutor()).isSameAs(executor);
|
||||
assertThat(httpClient.getByteBufferPool()).isSameAs(byteBufferPool);
|
||||
assertThat(httpClient.getScheduler()).isSameAs(scheduler);
|
||||
}
|
||||
|
||||
@Test
|
||||
void JettyResourceFactoryHasSslContextFactory() {
|
||||
// gh-16810
|
||||
JettyResourceFactory jettyResourceFactory = new JettyResourceFactory();
|
||||
JettyClientHttpConnectorFactory connectorFactory = getJettyClientHttpConnectorFactory(jettyResourceFactory);
|
||||
JettyClientHttpConnector connector = connectorFactory.createClientHttpConnector();
|
||||
HttpClient httpClient = (HttpClient) ReflectionTestUtils.getField(connector, "httpClient");
|
||||
assertThat(httpClient.getSslContextFactory()).isNotNull();
|
||||
}
|
||||
|
||||
private JettyClientHttpConnectorFactory getJettyClientHttpConnectorFactory(
|
||||
JettyResourceFactory jettyResourceFactory) {
|
||||
ClientHttpConnectorFactoryConfiguration.JettyClient jettyClient = new ClientHttpConnectorFactoryConfiguration.JettyClient();
|
||||
// We shouldn't usually call this method directly since it's on a non-proxy config
|
||||
return ReflectionTestUtils.invokeMethod(jettyClient, "jettyClientHttpConnectorFactory", jettyResourceFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldApplyHttpClientMapper() {
|
||||
JksSslStoreDetails storeDetails = JksSslStoreDetails.forLocation("classpath:test.jks");
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-2023 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.web.reactive.function.client;
|
||||
|
||||
import org.springframework.http.client.reactive.JettyResourceFactory;
|
||||
|
||||
/**
|
||||
* Tests for {@link JettyClientHttpConnectorFactory}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class JettyClientHttpConnectorFactoryTests extends AbstractClientHttpConnectorFactoryTests {
|
||||
|
||||
@Override
|
||||
protected ClientHttpConnectorFactory<?> getFactory() {
|
||||
JettyResourceFactory resourceFactory = new JettyResourceFactory();
|
||||
return new JettyClientHttpConnectorFactory(resourceFactory);
|
||||
}
|
||||
|
||||
}
|
|
@ -31,7 +31,6 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
|
|||
import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.boot.testsupport.classpath.ForkedClassPath;
|
||||
import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories;
|
||||
import org.springframework.boot.testsupport.web.servlet.Servlet5ClassPathOverrides;
|
||||
import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
|
||||
|
@ -221,7 +220,6 @@ class MultipartAutoConfigurationTests {
|
|||
|
||||
}
|
||||
|
||||
@Servlet5ClassPathOverrides
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class WebServerWithNoMultipartJetty {
|
||||
|
||||
|
@ -282,7 +280,6 @@ class MultipartAutoConfigurationTests {
|
|||
|
||||
}
|
||||
|
||||
@Servlet5ClassPathOverrides
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class WebServerWithEverythingJetty {
|
||||
|
||||
|
|
|
@ -38,7 +38,6 @@ import org.springframework.boot.test.context.assertj.AssertableWebApplicationCon
|
|||
import org.springframework.boot.test.context.runner.ContextConsumer;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories;
|
||||
import org.springframework.boot.testsupport.web.servlet.Servlet5ClassPathOverrides;
|
||||
import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer;
|
||||
import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
|
||||
|
@ -156,7 +155,6 @@ class ServletWebServerFactoryAutoConfigurationTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Servlet5ClassPathOverrides
|
||||
void jettyServerCustomizerBeanIsAddedToFactory() {
|
||||
WebApplicationContextRunner runner = new WebApplicationContextRunner(
|
||||
AnnotationConfigServletWebServerApplicationContext::new)
|
||||
|
@ -171,7 +169,6 @@ class ServletWebServerFactoryAutoConfigurationTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Servlet5ClassPathOverrides
|
||||
void jettyServerCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() {
|
||||
WebApplicationContextRunner runner = new WebApplicationContextRunner(
|
||||
AnnotationConfigServletWebServerApplicationContext::new)
|
||||
|
|
|
@ -26,7 +26,6 @@ import org.junit.jupiter.params.provider.MethodSource;
|
|||
|
||||
import org.springframework.boot.testsupport.classpath.ForkedClassPath;
|
||||
import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories;
|
||||
import org.springframework.boot.testsupport.web.servlet.Servlet5ClassPathOverrides;
|
||||
import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
|
||||
|
@ -90,7 +89,6 @@ class ServletWebServerServletContextListenerTests {
|
|||
|
||||
}
|
||||
|
||||
@Servlet5ClassPathOverrides
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class JettyConfiguration {
|
||||
|
||||
|
|
|
@ -24,14 +24,13 @@ import jakarta.websocket.server.ServerContainer;
|
|||
import org.apache.catalina.Container;
|
||||
import org.apache.catalina.Context;
|
||||
import org.apache.catalina.startup.Tomcat;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import org.springframework.boot.testsupport.classpath.ForkedClassPath;
|
||||
import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories;
|
||||
import org.springframework.boot.testsupport.web.servlet.Servlet5ClassPathOverrides;
|
||||
import org.springframework.boot.web.embedded.jetty.JettyReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.jetty.JettyWebServer;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory;
|
||||
|
@ -123,7 +122,6 @@ class WebSocketReactiveAutoConfigurationTests {
|
|||
|
||||
}
|
||||
|
||||
@Servlet5ClassPathOverrides
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class JettyConfiguration extends CommonConfiguration {
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ import jakarta.servlet.http.HttpServletResponse;
|
|||
import jakarta.websocket.DeploymentException;
|
||||
import jakarta.websocket.server.ServerContainer;
|
||||
import jakarta.websocket.server.ServerEndpoint;
|
||||
import org.eclipse.jetty.websocket.servlet.WebSocketUpgradeFilter;
|
||||
import org.eclipse.jetty.ee10.websocket.servlet.WebSocketUpgradeFilter;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.Arguments;
|
||||
|
@ -42,7 +42,6 @@ import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
|||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.boot.testsupport.classpath.ForkedClassPath;
|
||||
import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories;
|
||||
import org.springframework.boot.testsupport.web.servlet.Servlet5ClassPathOverrides;
|
||||
import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.WebServer;
|
||||
|
@ -182,7 +181,6 @@ class WebSocketServletAutoConfigurationTests {
|
|||
|
||||
}
|
||||
|
||||
@Servlet5ClassPathOverrides
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class JettyConfiguration extends CommonConfiguration {
|
||||
|
||||
|
|
|
@ -675,7 +675,12 @@ bom {
|
|||
]
|
||||
}
|
||||
}
|
||||
library("Jetty", "11.0.15") {
|
||||
library("Jetty", "12.0.1") {
|
||||
group("org.eclipse.jetty.ee10") {
|
||||
imports = [
|
||||
"jetty-ee10-bom"
|
||||
]
|
||||
}
|
||||
group("org.eclipse.jetty") {
|
||||
imports = [
|
||||
"jetty-bom"
|
||||
|
|
|
@ -65,9 +65,7 @@ dependencies {
|
|||
testImplementation("org.apache.tomcat.embed:tomcat-embed-jasper")
|
||||
testImplementation("org.assertj:assertj-core")
|
||||
testImplementation("org.awaitility:awaitility")
|
||||
testImplementation("org.eclipse.jetty.websocket:websocket-jakarta-client") {
|
||||
exclude group: "org.eclipse.jetty.toolchain", module: "jetty-jakarta-websocket-api"
|
||||
}
|
||||
testImplementation("org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jakarta-client")
|
||||
testImplementation("org.hamcrest:hamcrest-library")
|
||||
testImplementation("org.hsqldb:hsqldb")
|
||||
testImplementation("org.junit.jupiter:junit-jupiter")
|
||||
|
|
|
@ -27,8 +27,8 @@ Spring Boot supports the following embedded servlet containers:
|
|||
| Tomcat 10.1
|
||||
| 6.0
|
||||
|
||||
| Jetty 11.0
|
||||
| 5.0
|
||||
| Jetty 12.0
|
||||
| 6.0
|
||||
|
||||
| Undertow 2.3
|
||||
| 6.0
|
||||
|
|
|
@ -9,16 +9,8 @@ dependencies {
|
|||
api("jakarta.websocket:jakarta.websocket-api")
|
||||
api("jakarta.websocket:jakarta.websocket-client-api")
|
||||
api("org.apache.tomcat.embed:tomcat-embed-el")
|
||||
api("org.eclipse.jetty:jetty-servlets")
|
||||
api("org.eclipse.jetty:jetty-webapp") {
|
||||
exclude(group: "org.eclipse.jetty.toolchain", module: "jetty-jakarta-servlet-api")
|
||||
}
|
||||
api("org.eclipse.jetty.websocket:websocket-jakarta-server") {
|
||||
exclude(group: "org.eclipse.jetty.toolchain", module: "jetty-jakarta-servlet-api")
|
||||
exclude(group: "org.eclipse.jetty.toolchain", module: "jetty-jakarta-websocket-api")
|
||||
}
|
||||
api("org.eclipse.jetty.websocket:websocket-jetty-server") {
|
||||
exclude group: "org.eclipse.jetty", module: "jetty-jndi"
|
||||
exclude(group: "org.eclipse.jetty.toolchain", module: "jetty-jakarta-servlet-api")
|
||||
}
|
||||
api("org.eclipse.jetty.ee10:jetty-ee10-servlets")
|
||||
api("org.eclipse.jetty.ee10:jetty-ee10-webapp")
|
||||
api("org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jakarta-server")
|
||||
api("org.eclipse.jetty.ee10.websocket:jetty-ee10-websocket-jetty-server")
|
||||
}
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-2022 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.testsupport.web.servlet;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.boot.testsupport.classpath.ClassPathExclusions;
|
||||
import org.springframework.boot.testsupport.classpath.ClassPathOverrides;
|
||||
|
||||
/**
|
||||
* Annotation to downgrade to Servlet 5.0.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @since 3.0.0
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||
@Documented
|
||||
@ClassPathExclusions("jakarta.servlet-api-6*.jar")
|
||||
@ClassPathOverrides("jakarta.servlet:jakarta.servlet-api:5.0.0")
|
||||
public @interface Servlet5ClassPathOverrides {
|
||||
|
||||
}
|
|
@ -56,18 +56,12 @@ dependencies {
|
|||
optional("org.assertj:assertj-core")
|
||||
optional("org.apache.groovy:groovy")
|
||||
optional("org.apache.groovy:groovy-xml")
|
||||
optional("org.eclipse.jetty:jetty-servlets")
|
||||
optional("org.eclipse.jetty:jetty-util")
|
||||
optional("org.eclipse.jetty:jetty-webapp") {
|
||||
exclude(group: "org.eclipse.jetty.toolchain", module: "jetty-jakarta-servlet-api")
|
||||
}
|
||||
optional("org.eclipse.jetty:jetty-alpn-conscrypt-server") {
|
||||
exclude(group: "org.eclipse.jetty.toolchain", module: "jetty-jakarta-servlet-api")
|
||||
}
|
||||
optional("org.eclipse.jetty.http2:http2-server") {
|
||||
exclude(group: "org.eclipse.jetty.toolchain", module: "jetty-jakarta-servlet-api")
|
||||
}
|
||||
optional("org.eclipse.jetty:jetty-alpn-conscrypt-server")
|
||||
optional("org.eclipse.jetty:jetty-client")
|
||||
optional("org.eclipse.jetty:jetty-util")
|
||||
optional("org.eclipse.jetty.ee10:jetty-ee10-servlets")
|
||||
optional("org.eclipse.jetty.ee10:jetty-ee10-webapp")
|
||||
optional("org.eclipse.jetty.http2:jetty-http2-server")
|
||||
optional("org.flywaydb:flyway-core")
|
||||
optional("org.hamcrest:hamcrest-library")
|
||||
optional("org.hibernate.orm:hibernate-core")
|
||||
|
@ -120,8 +114,8 @@ dependencies {
|
|||
testImplementation("org.awaitility:awaitility")
|
||||
testImplementation("org.codehaus.janino:janino")
|
||||
testImplementation("org.eclipse.jetty:jetty-client")
|
||||
testImplementation("org.eclipse.jetty.http2:http2-client")
|
||||
testImplementation("org.eclipse.jetty.http2:http2-http-client-transport")
|
||||
testImplementation("org.eclipse.jetty.http2:jetty-http2-client")
|
||||
testImplementation("org.eclipse.jetty.http2:jetty-http2-client-transport")
|
||||
testImplementation("org.firebirdsql.jdbc:jaybird") {
|
||||
exclude group: "javax.resource", module: "connector-api"
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuil
|
|||
import org.apache.hc.client5.http.ssl.DefaultHostnameVerifier;
|
||||
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
|
||||
import org.apache.hc.core5.http.io.SocketConfig;
|
||||
import org.eclipse.jetty.client.dynamic.HttpClientTransportDynamic;
|
||||
import org.eclipse.jetty.client.transport.HttpClientTransportDynamic;
|
||||
import org.eclipse.jetty.io.ClientConnector;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
|
||||
|
|
|
@ -99,6 +99,7 @@ final class GracefulShutdown {
|
|||
while (this.shuttingDown && this.activeRequests.get() > 0) {
|
||||
sleep(100);
|
||||
}
|
||||
System.out.println(this.activeRequests.get());
|
||||
this.shuttingDown = false;
|
||||
long activeRequests = this.activeRequests.get();
|
||||
if (activeRequests == 0) {
|
||||
|
|
|
@ -24,8 +24,8 @@ import java.net.URLStreamHandler;
|
|||
import java.net.URLStreamHandlerFactory;
|
||||
|
||||
import jakarta.servlet.ServletContainerInitializer;
|
||||
import org.eclipse.jetty.ee10.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
|
@ -63,7 +63,6 @@ class JasperInitializer extends AbstractLifeCycle {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void doStart() throws Exception {
|
||||
if (this.initializer == null) {
|
||||
return;
|
||||
|
@ -84,11 +83,11 @@ class JasperInitializer extends AbstractLifeCycle {
|
|||
try {
|
||||
Thread.currentThread().setContextClassLoader(this.context.getClassLoader());
|
||||
try {
|
||||
setExtendedListenerTypes(true);
|
||||
this.context.getContext().setExtendedListenerTypes(true);
|
||||
this.initializer.onStartup(null, this.context.getServletContext());
|
||||
}
|
||||
finally {
|
||||
setExtendedListenerTypes(false);
|
||||
this.context.getContext().setExtendedListenerTypes(false);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
|
@ -96,15 +95,6 @@ class JasperInitializer extends AbstractLifeCycle {
|
|||
}
|
||||
}
|
||||
|
||||
private void setExtendedListenerTypes(boolean extended) {
|
||||
try {
|
||||
this.context.getServletContext().setExtendedListenerTypes(extended);
|
||||
}
|
||||
catch (NoSuchMethodError ex) {
|
||||
// Not available on Jetty 8
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link URLStreamHandlerFactory} to support {@literal war} protocol.
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 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.
|
||||
|
@ -16,17 +16,8 @@
|
|||
|
||||
package org.springframework.boot.web.embedded.jetty;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.eclipse.jetty.ee10.servlet.ErrorPageErrorHandler;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
|
||||
|
||||
/**
|
||||
* Variation of Jetty's {@link ErrorPageErrorHandler} that supports all {@link HttpMethod
|
||||
|
@ -40,20 +31,9 @@ import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
|
|||
*/
|
||||
class JettyEmbeddedErrorHandler extends ErrorPageErrorHandler {
|
||||
|
||||
private static final Set<String> HANDLED_HTTP_METHODS = new HashSet<>(Arrays.asList("GET", "POST", "HEAD"));
|
||||
|
||||
@Override
|
||||
public boolean errorPageForMethod(String method) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
|
||||
throws IOException, ServletException {
|
||||
if (!HANDLED_HTTP_METHODS.contains(baseRequest.getMethod())) {
|
||||
baseRequest.setMethod("GET");
|
||||
}
|
||||
super.handle(target, baseRequest, request, response);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2023 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.
|
||||
|
@ -16,8 +16,9 @@
|
|||
|
||||
package org.springframework.boot.web.embedded.jetty;
|
||||
|
||||
import org.eclipse.jetty.servlet.ServletHandler;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.ee10.servlet.ServletHandler;
|
||||
import org.eclipse.jetty.ee10.webapp.ClassMatcher;
|
||||
import org.eclipse.jetty.ee10.webapp.WebAppContext;
|
||||
|
||||
/**
|
||||
* Jetty {@link WebAppContext} used by {@link JettyWebServer} to support deferred
|
||||
|
@ -27,6 +28,11 @@ import org.eclipse.jetty.webapp.WebAppContext;
|
|||
*/
|
||||
class JettyEmbeddedWebAppContext extends WebAppContext {
|
||||
|
||||
JettyEmbeddedWebAppContext() {
|
||||
setServerClassMatcher(new ClassMatcher("org.springframework.boot.loader."));
|
||||
// setTempDirectory(WebInfConfiguration.getCanonicalNameForWebAppTmpDir(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ServletHandler newServletHandler() {
|
||||
return new JettyEmbeddedServletHandler();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 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.
|
||||
|
@ -16,15 +16,13 @@
|
|||
|
||||
package org.springframework.boot.web.embedded.jetty;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.eclipse.jetty.http.HttpFields.Mutable;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.handler.HandlerWrapper;
|
||||
import org.eclipse.jetty.server.Response;
|
||||
import org.eclipse.jetty.server.handler.gzip.GzipHandler;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
|
||||
import org.springframework.boot.web.server.Compression;
|
||||
|
||||
|
@ -38,7 +36,7 @@ final class JettyHandlerWrappers {
|
|||
private JettyHandlerWrappers() {
|
||||
}
|
||||
|
||||
static HandlerWrapper createGzipHandlerWrapper(Compression compression) {
|
||||
static Handler.Wrapper createGzipHandlerWrapper(Compression compression) {
|
||||
GzipHandler handler = new GzipHandler();
|
||||
handler.setMinGzipSize((int) compression.getMinResponseSize().toBytes());
|
||||
handler.setIncludedMimeTypes(compression.getMimeTypes());
|
||||
|
@ -48,14 +46,14 @@ final class JettyHandlerWrappers {
|
|||
return handler;
|
||||
}
|
||||
|
||||
static HandlerWrapper createServerHeaderHandlerWrapper(String header) {
|
||||
static Handler.Wrapper createServerHeaderHandlerWrapper(String header) {
|
||||
return new ServerHeaderHandler(header);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link HandlerWrapper} to add a custom {@code server} header.
|
||||
* {@link Handler.Wrapper} to add a custom {@code server} header.
|
||||
*/
|
||||
private static class ServerHeaderHandler extends HandlerWrapper {
|
||||
private static class ServerHeaderHandler extends Handler.Wrapper {
|
||||
|
||||
private static final String SERVER_HEADER = "server";
|
||||
|
||||
|
@ -66,12 +64,12 @@ final class JettyHandlerWrappers {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
|
||||
throws IOException, ServletException {
|
||||
if (!response.getHeaderNames().contains(SERVER_HEADER)) {
|
||||
response.setHeader(SERVER_HEADER, this.value);
|
||||
public boolean handle(Request request, Response response, Callback callback) throws Exception {
|
||||
Mutable headers = response.getHeaders();
|
||||
if (!headers.contains(SERVER_HEADER)) {
|
||||
headers.add(SERVER_HEADER, this.value);
|
||||
}
|
||||
super.handle(target, baseRequest, request, response);
|
||||
return super.handle(request, response, callback);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,6 +26,8 @@ import java.util.Set;
|
|||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.ee10.servlet.ServletHolder;
|
||||
import org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory;
|
||||
import org.eclipse.jetty.server.AbstractConnector;
|
||||
import org.eclipse.jetty.server.ConnectionFactory;
|
||||
|
@ -35,10 +37,7 @@ import org.eclipse.jetty.server.HttpConfiguration;
|
|||
import org.eclipse.jetty.server.HttpConnectionFactory;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.ServerConnector;
|
||||
import org.eclipse.jetty.server.handler.HandlerWrapper;
|
||||
import org.eclipse.jetty.server.handler.StatisticsHandler;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.eclipse.jetty.util.thread.ThreadPool;
|
||||
|
||||
import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactory;
|
||||
|
@ -185,7 +184,7 @@ public class JettyReactiveWebServerFactory extends AbstractReactiveWebServerFact
|
|||
server.setStopTimeout(0);
|
||||
ServletHolder servletHolder = new ServletHolder(servlet);
|
||||
servletHolder.setAsyncSupported(true);
|
||||
ServletContextHandler contextHandler = new ServletContextHandler(server, "/", false, false);
|
||||
ServletContextHandler contextHandler = new ServletContextHandler("/", false, false);
|
||||
contextHandler.addServlet(servletHolder, "/");
|
||||
server.setHandler(addHandlerWrappers(contextHandler));
|
||||
JettyReactiveWebServerFactory.logger.info("Server initialized with port: " + port);
|
||||
|
@ -243,7 +242,7 @@ public class JettyReactiveWebServerFactory extends AbstractReactiveWebServerFact
|
|||
return handler;
|
||||
}
|
||||
|
||||
private Handler applyWrapper(Handler handler, HandlerWrapper wrapper) {
|
||||
private Handler applyWrapper(Handler handler, Handler.Wrapper wrapper) {
|
||||
wrapper.setHandler(handler);
|
||||
return wrapper;
|
||||
}
|
||||
|
|
|
@ -20,26 +20,43 @@ import java.io.File;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.file.Path;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.EventListener;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Set;
|
||||
import java.util.Spliterator;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.Cookie;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.servlet.http.HttpServletResponseWrapper;
|
||||
import org.eclipse.jetty.ee10.servlet.ErrorHandler;
|
||||
import org.eclipse.jetty.ee10.servlet.ErrorPageErrorHandler;
|
||||
import org.eclipse.jetty.ee10.servlet.ListenerHolder;
|
||||
import org.eclipse.jetty.ee10.servlet.ServletHandler;
|
||||
import org.eclipse.jetty.ee10.servlet.ServletHolder;
|
||||
import org.eclipse.jetty.ee10.servlet.ServletMapping;
|
||||
import org.eclipse.jetty.ee10.servlet.SessionHandler;
|
||||
import org.eclipse.jetty.ee10.servlet.Source;
|
||||
import org.eclipse.jetty.ee10.webapp.AbstractConfiguration;
|
||||
import org.eclipse.jetty.ee10.webapp.Configuration;
|
||||
import org.eclipse.jetty.ee10.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.ee10.webapp.WebInfConfiguration;
|
||||
import org.eclipse.jetty.http.HttpCookie;
|
||||
import org.eclipse.jetty.http.HttpField;
|
||||
import org.eclipse.jetty.http.HttpFields.Mutable;
|
||||
import org.eclipse.jetty.http.MimeTypes;
|
||||
import org.eclipse.jetty.http.MimeTypes.Wrapper;
|
||||
import org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory;
|
||||
import org.eclipse.jetty.server.AbstractConnector;
|
||||
import org.eclipse.jetty.server.ConnectionFactory;
|
||||
|
@ -48,28 +65,21 @@ import org.eclipse.jetty.server.Connector;
|
|||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.HttpConfiguration;
|
||||
import org.eclipse.jetty.server.HttpConnectionFactory;
|
||||
import org.eclipse.jetty.server.HttpCookieUtils;
|
||||
import org.eclipse.jetty.server.HttpStream;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.Response;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.ServerConnector;
|
||||
import org.eclipse.jetty.server.handler.ErrorHandler;
|
||||
import org.eclipse.jetty.server.handler.HandlerWrapper;
|
||||
import org.eclipse.jetty.server.handler.StatisticsHandler;
|
||||
import org.eclipse.jetty.server.session.DefaultSessionCache;
|
||||
import org.eclipse.jetty.server.session.FileSessionDataStore;
|
||||
import org.eclipse.jetty.server.session.SessionHandler;
|
||||
import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
|
||||
import org.eclipse.jetty.servlet.ListenerHolder;
|
||||
import org.eclipse.jetty.servlet.ServletHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.eclipse.jetty.servlet.ServletMapping;
|
||||
import org.eclipse.jetty.servlet.Source;
|
||||
import org.eclipse.jetty.util.resource.JarResource;
|
||||
import org.eclipse.jetty.session.DefaultSessionCache;
|
||||
import org.eclipse.jetty.session.FileSessionDataStore;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.resource.CombinedResource;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.ResourceCollection;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
import org.eclipse.jetty.util.resource.URLResourceFactory;
|
||||
import org.eclipse.jetty.util.thread.ThreadPool;
|
||||
import org.eclipse.jetty.webapp.AbstractConfiguration;
|
||||
import org.eclipse.jetty.webapp.Configuration;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
|
||||
import org.springframework.boot.web.server.Cookie.SameSite;
|
||||
import org.springframework.boot.web.server.ErrorPage;
|
||||
|
@ -161,9 +171,11 @@ public class JettyServletWebServerFactory extends AbstractServletWebServerFactor
|
|||
@Override
|
||||
public WebServer getWebServer(ServletContextInitializer... initializers) {
|
||||
JettyEmbeddedWebAppContext context = new JettyEmbeddedWebAppContext();
|
||||
context.getContext().getServletContext().setExtendedListenerTypes(true);
|
||||
int port = Math.max(getPort(), 0);
|
||||
InetSocketAddress address = new InetSocketAddress(getAddress(), port);
|
||||
Server server = createServer(address);
|
||||
context.setServer(server);
|
||||
configureWebAppContext(context, initializers);
|
||||
server.setHandler(addHandlerWrappers(context));
|
||||
this.logger.info("Server initialized with port: " + port);
|
||||
|
@ -191,12 +203,17 @@ public class JettyServletWebServerFactory extends AbstractServletWebServerFactor
|
|||
Server server = new Server(getThreadPool());
|
||||
server.setConnectors(new Connector[] { createConnector(address, server) });
|
||||
server.setStopTimeout(0);
|
||||
MimeTypes.Mutable mimeTypes = server.getMimeTypes();
|
||||
for (MimeMappings.Mapping mapping : getMimeMappings()) {
|
||||
mimeTypes.addMimeMapping(mapping.getExtension(), mapping.getMimeType());
|
||||
}
|
||||
return server;
|
||||
}
|
||||
|
||||
private AbstractConnector createConnector(InetSocketAddress address, Server server) {
|
||||
HttpConfiguration httpConfiguration = new HttpConfiguration();
|
||||
httpConfiguration.setSendServerVersion(false);
|
||||
httpConfiguration.setIdleTimeout(30000);
|
||||
List<ConnectionFactory> connectionFactories = new ArrayList<>();
|
||||
connectionFactories.add(new HttpConnectionFactory(httpConfiguration));
|
||||
if (getHttp2() != null && getHttp2().isEnabled()) {
|
||||
|
@ -222,7 +239,7 @@ public class JettyServletWebServerFactory extends AbstractServletWebServerFactor
|
|||
return handler;
|
||||
}
|
||||
|
||||
private Handler applyWrapper(Handler handler, HandlerWrapper wrapper) {
|
||||
private Handler applyWrapper(Handler handler, Handler.Wrapper wrapper) {
|
||||
wrapper.setHandler(handler);
|
||||
return wrapper;
|
||||
}
|
||||
|
@ -239,7 +256,6 @@ public class JettyServletWebServerFactory extends AbstractServletWebServerFactor
|
|||
protected final void configureWebAppContext(WebAppContext context, ServletContextInitializer... initializers) {
|
||||
Assert.notNull(context, "Context must not be null");
|
||||
context.clearAliasChecks();
|
||||
context.setTempDirectory(getTempDirectory());
|
||||
if (this.resourceLoader != null) {
|
||||
context.setClassLoader(this.resourceLoader.getClassLoader());
|
||||
}
|
||||
|
@ -260,6 +276,7 @@ public class JettyServletWebServerFactory extends AbstractServletWebServerFactor
|
|||
context.setConfigurations(configurations);
|
||||
context.setThrowUnavailableOnStartupException(true);
|
||||
configureSession(context);
|
||||
context.setTempDirectory(getTempDirectory(context));
|
||||
postProcessWebAppContext(context);
|
||||
}
|
||||
|
||||
|
@ -289,40 +306,49 @@ public class JettyServletWebServerFactory extends AbstractServletWebServerFactor
|
|||
.forEach((locale, charset) -> context.addLocaleEncoding(locale.toString(), charset.toString()));
|
||||
}
|
||||
|
||||
private File getTempDirectory() {
|
||||
private File getTempDirectory(WebAppContext context) {
|
||||
String temp = System.getProperty("java.io.tmpdir");
|
||||
return (temp != null) ? new File(temp) : null;
|
||||
return (temp != null)
|
||||
? new File(temp, WebInfConfiguration.getCanonicalNameForWebAppTmpDir(context) + UUID.randomUUID())
|
||||
: null;
|
||||
}
|
||||
|
||||
private void configureDocumentRoot(WebAppContext handler) {
|
||||
File root = getValidDocumentRoot();
|
||||
File docBase = (root != null) ? root : createTempDir("jetty-docbase");
|
||||
try {
|
||||
ResourceFactory resourceFactory = handler.getResourceFactory();
|
||||
List<Resource> resources = new ArrayList<>();
|
||||
Resource rootResource = (docBase.isDirectory() ? Resource.newResource(docBase.getCanonicalFile())
|
||||
: JarResource.newJarResource(Resource.newResource(docBase)));
|
||||
resources.add((root != null) ? new LoaderHidingResource(rootResource) : rootResource);
|
||||
Resource rootResource = (docBase.isDirectory()
|
||||
? resourceFactory.newResource(docBase.getCanonicalFile().toURI())
|
||||
: resourceFactory.newJarFileResource(docBase.toURI()));
|
||||
resources.add((root != null) ? new LoaderHidingResource(rootResource, rootResource) : rootResource);
|
||||
URLResourceFactory urlResourceFactory = new URLResourceFactory();
|
||||
for (URL resourceJarUrl : getUrlsOfJarsWithMetaInfResources()) {
|
||||
Resource resource = createResource(resourceJarUrl);
|
||||
if (resource.exists() && resource.isDirectory()) {
|
||||
Resource resource = createResource(resourceJarUrl, resourceFactory, urlResourceFactory);
|
||||
if (resource != null) {
|
||||
resources.add(resource);
|
||||
}
|
||||
}
|
||||
handler.setBaseResource(new ResourceCollection(resources.toArray(new Resource[0])));
|
||||
handler.setBaseResource(ResourceFactory.combine(resources));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private Resource createResource(URL url) throws Exception {
|
||||
private Resource createResource(URL url, ResourceFactory resourceFactory, URLResourceFactory urlResourceFactory)
|
||||
throws Exception {
|
||||
if ("file".equals(url.getProtocol())) {
|
||||
File file = new File(url.toURI());
|
||||
if (file.isFile()) {
|
||||
return Resource.newResource("jar:" + url + "!/META-INF/resources");
|
||||
return resourceFactory.newResource("jar:" + url + "!/META-INF/resources/");
|
||||
}
|
||||
if (file.isDirectory()) {
|
||||
return resourceFactory.newResource(url).resolve("META-INF/resources/");
|
||||
}
|
||||
}
|
||||
return Resource.newResource(url + "META-INF/resources");
|
||||
return urlResourceFactory.newResource(url + "META-INF/resources/");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -333,7 +359,7 @@ public class JettyServletWebServerFactory extends AbstractServletWebServerFactor
|
|||
Assert.notNull(context, "Context must not be null");
|
||||
ServletHolder holder = new ServletHolder();
|
||||
holder.setName("default");
|
||||
holder.setClassName("org.eclipse.jetty.servlet.DefaultServlet");
|
||||
holder.setClassName("org.eclipse.jetty.ee10.servlet.DefaultServlet");
|
||||
holder.setInitParameter("dirAllowed", "false");
|
||||
holder.setInitOrder(1);
|
||||
context.getServletHandler().addServletWithMapping(holder, "/");
|
||||
|
@ -382,7 +408,7 @@ public class JettyServletWebServerFactory extends AbstractServletWebServerFactor
|
|||
* @return a configuration object for adding error pages
|
||||
*/
|
||||
private Configuration getErrorPageConfiguration() {
|
||||
return new AbstractConfiguration() {
|
||||
return new AbstractConfiguration(new AbstractConfiguration.Builder()) {
|
||||
|
||||
@Override
|
||||
public void configure(WebAppContext context) throws Exception {
|
||||
|
@ -399,11 +425,12 @@ public class JettyServletWebServerFactory extends AbstractServletWebServerFactor
|
|||
* @return a configuration object for adding mime type mappings
|
||||
*/
|
||||
private Configuration getMimeTypeConfiguration() {
|
||||
return new AbstractConfiguration() {
|
||||
return new AbstractConfiguration(new AbstractConfiguration.Builder()) {
|
||||
|
||||
@Override
|
||||
public void configure(WebAppContext context) throws Exception {
|
||||
MimeTypes mimeTypes = context.getMimeTypes();
|
||||
MimeTypes.Wrapper mimeTypes = (Wrapper) context.getMimeTypes();
|
||||
mimeTypes.setWrapped(new MimeTypes(null));
|
||||
for (MimeMappings.Mapping mapping : getMimeMappings()) {
|
||||
mimeTypes.addMimeMapping(mapping.getExtension(), mapping.getMimeType());
|
||||
}
|
||||
|
@ -558,28 +585,48 @@ public class JettyServletWebServerFactory extends AbstractServletWebServerFactor
|
|||
|
||||
private static final class LoaderHidingResource extends Resource {
|
||||
|
||||
private static final String LOADER_RESOURCE_PATH_PREFIX = "/org/springframework/boot/";
|
||||
|
||||
private final Resource base;
|
||||
|
||||
private final Resource delegate;
|
||||
|
||||
private LoaderHidingResource(Resource delegate) {
|
||||
private LoaderHidingResource(Resource base, Resource delegate) {
|
||||
this.base = base;
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource addPath(String path) throws IOException {
|
||||
if (path.startsWith("/org/springframework/boot")) {
|
||||
return null;
|
||||
public void forEach(Consumer<? super Resource> action) {
|
||||
this.delegate.forEach(action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path getPath() {
|
||||
return this.delegate.getPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isContainedIn(Resource r) {
|
||||
return this.delegate.isContainedIn(r);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Resource> iterator() {
|
||||
if (this.delegate instanceof CombinedResource) {
|
||||
return list().iterator();
|
||||
}
|
||||
return this.delegate.addPath(path);
|
||||
return List.<Resource>of(this).iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isContainedIn(Resource resource) throws MalformedURLException {
|
||||
return this.delegate.isContainedIn(resource);
|
||||
public boolean equals(Object obj) {
|
||||
return this.delegate.equals(obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
this.delegate.close();
|
||||
public int hashCode() {
|
||||
return this.delegate.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -587,13 +634,23 @@ public class JettyServletWebServerFactory extends AbstractServletWebServerFactor
|
|||
return this.delegate.exists();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spliterator<Resource> spliterator() {
|
||||
return this.delegate.spliterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDirectory() {
|
||||
return this.delegate.isDirectory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long lastModified() {
|
||||
public boolean isReadable() {
|
||||
return this.delegate.isReadable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instant lastModified() {
|
||||
return this.delegate.lastModified();
|
||||
}
|
||||
|
||||
|
@ -607,39 +664,68 @@ public class JettyServletWebServerFactory extends AbstractServletWebServerFactor
|
|||
return this.delegate.getURI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getFile() throws IOException {
|
||||
return this.delegate.getFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.delegate.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream() throws IOException {
|
||||
return this.delegate.getInputStream();
|
||||
public String getFileName() {
|
||||
return this.delegate.getFileName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReadableByteChannel getReadableByteChannel() throws IOException {
|
||||
return this.delegate.getReadableByteChannel();
|
||||
public InputStream newInputStream() throws IOException {
|
||||
return this.delegate.newInputStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean delete() throws SecurityException {
|
||||
return this.delegate.delete();
|
||||
public ReadableByteChannel newReadableByteChannel() throws IOException {
|
||||
return this.delegate.newReadableByteChannel();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean renameTo(Resource dest) throws SecurityException {
|
||||
return this.delegate.renameTo(dest);
|
||||
public List<Resource> list() {
|
||||
return this.delegate.list().stream().filter(this::nonLoaderResource).toList();
|
||||
}
|
||||
|
||||
private boolean nonLoaderResource(Resource resource) {
|
||||
Path prefix = this.base.getPath().resolve(Path.of("org", "springframework", "boot"));
|
||||
return !resource.getPath().startsWith(prefix);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] list() {
|
||||
return this.delegate.list();
|
||||
public Resource resolve(String subUriPath) {
|
||||
if (subUriPath.startsWith(LOADER_RESOURCE_PATH_PREFIX)) {
|
||||
return null;
|
||||
}
|
||||
Resource resolved = this.delegate.resolve(subUriPath);
|
||||
return (resolved != null) ? new LoaderHidingResource(this.base, resolved) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAlias() {
|
||||
return this.delegate.isAlias();
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getRealURI() {
|
||||
return this.delegate.getRealURI();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyTo(Path destination) throws IOException {
|
||||
this.delegate.copyTo(destination);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Resource> getAllResources() {
|
||||
return this.delegate.getAllResources().stream().filter(this::nonLoaderResource).toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.delegate.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -652,6 +738,7 @@ public class JettyServletWebServerFactory extends AbstractServletWebServerFactor
|
|||
private final Set<String> classNames;
|
||||
|
||||
WebListenersConfiguration(Set<String> webListenerClassNames) {
|
||||
super(new AbstractConfiguration.Builder());
|
||||
this.classNames = webListenerClassNames;
|
||||
}
|
||||
|
||||
|
@ -681,10 +768,10 @@ public class JettyServletWebServerFactory extends AbstractServletWebServerFactor
|
|||
}
|
||||
|
||||
/**
|
||||
* {@link HandlerWrapper} to apply {@link CookieSameSiteSupplier supplied}
|
||||
* {@link Handler.Wrapper} to apply {@link CookieSameSiteSupplier supplied}
|
||||
* {@link SameSite} cookie values.
|
||||
*/
|
||||
private static class SuppliedSameSiteCookieHandlerWrapper extends HandlerWrapper {
|
||||
private static class SuppliedSameSiteCookieHandlerWrapper extends Handler.Wrapper {
|
||||
|
||||
private final List<CookieSameSiteSupplier> suppliers;
|
||||
|
||||
|
@ -693,41 +780,53 @@ public class JettyServletWebServerFactory extends AbstractServletWebServerFactor
|
|||
}
|
||||
|
||||
@Override
|
||||
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
|
||||
throws IOException, ServletException {
|
||||
HttpServletResponse wrappedResponse = new ResponseWrapper(response);
|
||||
super.handle(target, baseRequest, request, wrappedResponse);
|
||||
public boolean handle(Request request, Response response, Callback callback) throws Exception {
|
||||
request.addHttpStreamWrapper((stream) -> new SameSiteCookieHttpStreamWrapper(stream, request));
|
||||
return super.handle(request, response, callback);
|
||||
}
|
||||
|
||||
class ResponseWrapper extends HttpServletResponseWrapper {
|
||||
private final class SameSiteCookieHttpStreamWrapper extends HttpStream.Wrapper {
|
||||
|
||||
ResponseWrapper(HttpServletResponse response) {
|
||||
super(response);
|
||||
private final Request request;
|
||||
|
||||
private SameSiteCookieHttpStreamWrapper(HttpStream wrapped, Request request) {
|
||||
super(wrapped);
|
||||
this.request = request;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("removal")
|
||||
public void addCookie(Cookie cookie) {
|
||||
SameSite sameSite = getSameSite(cookie);
|
||||
if (sameSite != null) {
|
||||
String comment = HttpCookie.getCommentWithoutAttributes(cookie.getComment());
|
||||
String sameSiteComment = getSameSiteComment(sameSite);
|
||||
cookie.setComment((comment != null) ? comment + sameSiteComment : sameSiteComment);
|
||||
public void prepareResponse(Mutable headers) {
|
||||
super.prepareResponse(headers);
|
||||
ListIterator<HttpField> headerFields = headers.listIterator();
|
||||
while (headerFields.hasNext()) {
|
||||
HttpCookieUtils.SetCookieHttpField updatedField = applySameSiteIfNecessary(headerFields.next());
|
||||
if (updatedField != null) {
|
||||
headerFields.set(updatedField);
|
||||
}
|
||||
}
|
||||
super.addCookie(cookie);
|
||||
}
|
||||
|
||||
private String getSameSiteComment(SameSite sameSite) {
|
||||
return switch (sameSite) {
|
||||
case NONE -> HttpCookie.SAME_SITE_NONE_COMMENT;
|
||||
case LAX -> HttpCookie.SAME_SITE_LAX_COMMENT;
|
||||
case STRICT -> HttpCookie.SAME_SITE_STRICT_COMMENT;
|
||||
};
|
||||
private HttpCookieUtils.SetCookieHttpField applySameSiteIfNecessary(HttpField headerField) {
|
||||
HttpCookie cookie = HttpCookieUtils.getSetCookie(headerField);
|
||||
if (cookie == null) {
|
||||
return null;
|
||||
}
|
||||
SameSite sameSite = getSameSite(cookie);
|
||||
if (sameSite == null) {
|
||||
return null;
|
||||
}
|
||||
return new HttpCookieUtils.SetCookieHttpField(
|
||||
HttpCookie.build(cookie)
|
||||
.sameSite(org.eclipse.jetty.http.HttpCookie.SameSite.from(sameSite.name()))
|
||||
.build(),
|
||||
this.request.getConnectionMetaData().getHttpConfiguration().getResponseCookieCompliance());
|
||||
}
|
||||
|
||||
private SameSite getSameSite(Cookie cookie) {
|
||||
private SameSite getSameSite(HttpCookie cookie) {
|
||||
Cookie servletCookie = new Cookie(cookie.getName(), cookie.getValue());
|
||||
cookie.getAttributes().forEach(servletCookie::setAttribute);
|
||||
for (CookieSameSiteSupplier supplier : SuppliedSameSiteCookieHandlerWrapper.this.suppliers) {
|
||||
SameSite sameSite = supplier.getSameSite(cookie);
|
||||
SameSite sameSite = supplier.getSameSite(servletCookie);
|
||||
if (sameSite != null) {
|
||||
return sameSite;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
package org.springframework.boot.web.embedded.jetty;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -29,8 +28,6 @@ import org.eclipse.jetty.server.Handler;
|
|||
import org.eclipse.jetty.server.NetworkConnector;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.server.handler.HandlerCollection;
|
||||
import org.eclipse.jetty.server.handler.HandlerWrapper;
|
||||
import org.eclipse.jetty.server.handler.StatisticsHandler;
|
||||
|
||||
import org.springframework.boot.web.server.GracefulShutdownCallback;
|
||||
|
@ -106,7 +103,7 @@ public class JettyWebServer implements WebServer {
|
|||
if (handler instanceof StatisticsHandler statisticsHandler) {
|
||||
return statisticsHandler;
|
||||
}
|
||||
if (handler instanceof HandlerWrapper handlerWrapper) {
|
||||
if (handler instanceof Handler.Wrapper handlerWrapper) {
|
||||
return findStatisticsHandler(handlerWrapper.getHandler());
|
||||
}
|
||||
return null;
|
||||
|
@ -208,7 +205,8 @@ public class JettyWebServer implements WebServer {
|
|||
}
|
||||
|
||||
private String getContextPath() {
|
||||
return Arrays.stream(this.server.getHandlers())
|
||||
return this.server.getHandlers()
|
||||
.stream()
|
||||
.map(this::findContextHandler)
|
||||
.filter(Objects::nonNull)
|
||||
.map(ContextHandler::getContextPath)
|
||||
|
@ -216,7 +214,7 @@ public class JettyWebServer implements WebServer {
|
|||
}
|
||||
|
||||
private ContextHandler findContextHandler(Handler handler) {
|
||||
while (handler instanceof HandlerWrapper handlerWrapper) {
|
||||
while (handler instanceof Handler.Wrapper handlerWrapper) {
|
||||
if (handler instanceof ContextHandler contextHandler) {
|
||||
return contextHandler;
|
||||
}
|
||||
|
@ -225,17 +223,21 @@ public class JettyWebServer implements WebServer {
|
|||
return null;
|
||||
}
|
||||
|
||||
private void handleDeferredInitialize(Handler... handlers) throws Exception {
|
||||
private void handleDeferredInitialize(List<Handler> handlers) throws Exception {
|
||||
for (Handler handler : handlers) {
|
||||
if (handler instanceof JettyEmbeddedWebAppContext jettyEmbeddedWebAppContext) {
|
||||
jettyEmbeddedWebAppContext.deferredInitialize();
|
||||
}
|
||||
else if (handler instanceof HandlerWrapper handlerWrapper) {
|
||||
handleDeferredInitialize(handlerWrapper.getHandler());
|
||||
}
|
||||
else if (handler instanceof HandlerCollection handlerCollection) {
|
||||
handleDeferredInitialize(handlerCollection.getHandlers());
|
||||
}
|
||||
handleDeferredInitialize(handler);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleDeferredInitialize(Handler handler) throws Exception {
|
||||
if (handler instanceof JettyEmbeddedWebAppContext jettyEmbeddedWebAppContext) {
|
||||
jettyEmbeddedWebAppContext.deferredInitialize();
|
||||
}
|
||||
else if (handler instanceof Handler.Wrapper handlerWrapper) {
|
||||
handleDeferredInitialize(handlerWrapper.getHandler());
|
||||
}
|
||||
else if (handler instanceof Handler.Collection handlerCollection) {
|
||||
handleDeferredInitialize(handlerCollection.getHandlers());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 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.
|
||||
|
@ -17,9 +17,9 @@
|
|||
package org.springframework.boot.web.embedded.jetty;
|
||||
|
||||
import jakarta.servlet.ServletException;
|
||||
import org.eclipse.jetty.webapp.AbstractConfiguration;
|
||||
import org.eclipse.jetty.webapp.Configuration;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.ee10.webapp.AbstractConfiguration;
|
||||
import org.eclipse.jetty.ee10.webapp.Configuration;
|
||||
import org.eclipse.jetty.ee10.webapp.WebAppContext;
|
||||
|
||||
import org.springframework.boot.web.servlet.ServletContextInitializer;
|
||||
import org.springframework.util.Assert;
|
||||
|
@ -41,6 +41,7 @@ public class ServletContextInitializerConfiguration extends AbstractConfiguratio
|
|||
* @since 1.2.1
|
||||
*/
|
||||
public ServletContextInitializerConfiguration(ServletContextInitializer... initializers) {
|
||||
super(new AbstractConfiguration.Builder());
|
||||
Assert.notNull(initializers, "Initializers must not be null");
|
||||
this.initializers = initializers;
|
||||
}
|
||||
|
@ -59,22 +60,13 @@ public class ServletContextInitializerConfiguration extends AbstractConfiguratio
|
|||
|
||||
private void callInitializers(WebAppContext context) throws ServletException {
|
||||
try {
|
||||
setExtendedListenerTypes(context, true);
|
||||
context.getContext().setExtendedListenerTypes(true);
|
||||
for (ServletContextInitializer initializer : this.initializers) {
|
||||
initializer.onStartup(context.getServletContext());
|
||||
}
|
||||
}
|
||||
finally {
|
||||
setExtendedListenerTypes(context, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void setExtendedListenerTypes(WebAppContext context, boolean extended) {
|
||||
try {
|
||||
context.getServletContext().setExtendedListenerTypes(extended);
|
||||
}
|
||||
catch (NoSuchMethodError ex) {
|
||||
// Not available on Jetty 8
|
||||
context.getContext().setExtendedListenerTypes(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -111,19 +111,7 @@ class SslServerCustomizer implements JettyServerCustomizer {
|
|||
|
||||
private SslConnectionFactory createSslConnectionFactory(SslContextFactory.Server sslContextFactory,
|
||||
String protocol) {
|
||||
try {
|
||||
return new SslConnectionFactory(sslContextFactory, protocol);
|
||||
}
|
||||
catch (NoSuchMethodError ex) {
|
||||
// Jetty 10
|
||||
try {
|
||||
return SslConnectionFactory.class.getConstructor(SslContextFactory.Server.class, String.class)
|
||||
.newInstance(sslContextFactory, protocol);
|
||||
}
|
||||
catch (Exception ex2) {
|
||||
throw new RuntimeException(ex2);
|
||||
}
|
||||
}
|
||||
return new SslConnectionFactory(sslContextFactory, protocol);
|
||||
}
|
||||
|
||||
private boolean isJettyAlpnPresent() {
|
||||
|
|
|
@ -30,11 +30,9 @@ import org.junit.jupiter.api.Disabled;
|
|||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InOrder;
|
||||
|
||||
import org.springframework.boot.testsupport.web.servlet.Servlet5ClassPathOverrides;
|
||||
import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactoryTests;
|
||||
import org.springframework.boot.web.server.Shutdown;
|
||||
import org.springframework.http.client.reactive.JettyResourceFactory;
|
||||
import org.springframework.http.server.reactive.HttpHandler;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
|
@ -51,7 +49,6 @@ import static org.mockito.Mockito.mock;
|
|||
* @author Madhura Bhave
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
@Servlet5ClassPathOverrides
|
||||
class JettyReactiveWebServerFactoryTests extends AbstractReactiveWebServerFactoryTests {
|
||||
|
||||
@Override
|
||||
|
@ -61,7 +58,8 @@ class JettyReactiveWebServerFactoryTests extends AbstractReactiveWebServerFactor
|
|||
|
||||
@Test
|
||||
@Override
|
||||
@Disabled("Jetty 11 does not support User-Agent-based compression")
|
||||
@Disabled("Jetty 12 does not support User-Agent-based compression")
|
||||
// TODO Is this true with Jetty 12?
|
||||
protected void noCompressionForUserAgent() {
|
||||
|
||||
}
|
||||
|
@ -114,20 +112,6 @@ class JettyReactiveWebServerFactoryTests extends AbstractReactiveWebServerFactor
|
|||
assertForwardHeaderIsUsed(factory);
|
||||
}
|
||||
|
||||
@Test
|
||||
void useServerResources() throws Exception {
|
||||
JettyResourceFactory resourceFactory = new JettyResourceFactory();
|
||||
resourceFactory.afterPropertiesSet();
|
||||
JettyReactiveWebServerFactory factory = getFactory();
|
||||
factory.setResourceFactory(resourceFactory);
|
||||
JettyWebServer webServer = (JettyWebServer) factory.getWebServer(new EchoHandler());
|
||||
webServer.start();
|
||||
Connector connector = webServer.getServer().getConnectors()[0];
|
||||
assertThat(connector.getByteBufferPool()).isEqualTo(resourceFactory.getByteBufferPool());
|
||||
assertThat(connector.getExecutor()).isEqualTo(resourceFactory.getExecutor());
|
||||
assertThat(connector.getScheduler()).isEqualTo(resourceFactory.getScheduler());
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenServerIsShuttingDownGracefullyThenNewConnectionsCannotBeMade() {
|
||||
JettyReactiveWebServerFactory factory = getFactory();
|
||||
|
|
|
@ -40,29 +40,26 @@ import org.apache.hc.core5.http.Header;
|
|||
import org.apache.hc.core5.http.HttpResponse;
|
||||
import org.apache.jasper.servlet.JspServlet;
|
||||
import org.awaitility.Awaitility;
|
||||
import org.eclipse.jetty.ee10.servlet.ErrorPageErrorHandler;
|
||||
import org.eclipse.jetty.ee10.servlet.ServletHolder;
|
||||
import org.eclipse.jetty.ee10.webapp.AbstractConfiguration;
|
||||
import org.eclipse.jetty.ee10.webapp.ClassMatcher;
|
||||
import org.eclipse.jetty.ee10.webapp.Configuration;
|
||||
import org.eclipse.jetty.ee10.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.server.ConnectionLimit;
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.ServerConnector;
|
||||
import org.eclipse.jetty.server.SslConnectionFactory;
|
||||
import org.eclipse.jetty.server.handler.HandlerCollection;
|
||||
import org.eclipse.jetty.server.handler.HandlerWrapper;
|
||||
import org.eclipse.jetty.servlet.ErrorPageErrorHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.eclipse.jetty.util.ssl.SslContextFactory;
|
||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||
import org.eclipse.jetty.util.thread.ThreadPool;
|
||||
import org.eclipse.jetty.webapp.AbstractConfiguration;
|
||||
import org.eclipse.jetty.webapp.ClassMatcher;
|
||||
import org.eclipse.jetty.webapp.Configuration;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InOrder;
|
||||
|
||||
import org.springframework.boot.testsupport.system.CapturedOutput;
|
||||
import org.springframework.boot.testsupport.web.servlet.Servlet5ClassPathOverrides;
|
||||
import org.springframework.boot.web.server.Compression;
|
||||
import org.springframework.boot.web.server.GracefulShutdownResult;
|
||||
import org.springframework.boot.web.server.PortInUseException;
|
||||
|
@ -89,12 +86,20 @@ import static org.mockito.Mockito.mock;
|
|||
* @author Henri Kerola
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
@Servlet5ClassPathOverrides
|
||||
class JettyServletWebServerFactoryTests extends AbstractServletWebServerFactoryTests {
|
||||
|
||||
@Override
|
||||
protected JettyServletWebServerFactory getFactory() {
|
||||
return new JettyServletWebServerFactory(0);
|
||||
JettyServletWebServerFactory factory = new JettyServletWebServerFactory(0);
|
||||
factory.addServerCustomizers((server) -> {
|
||||
for (Connector connector : server.getConnectors()) {
|
||||
if (connector instanceof ServerConnector serverConnector) {
|
||||
// TODO Set the shutdown idle timeout in main code?
|
||||
serverConnector.setShutdownIdleTimeout(10000);
|
||||
}
|
||||
}
|
||||
});
|
||||
return factory;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -144,10 +149,17 @@ class JettyServletWebServerFactoryTests extends AbstractServletWebServerFactoryT
|
|||
|
||||
@Test
|
||||
@Override
|
||||
@Disabled("Jetty 11 does not support User-Agent-based compression")
|
||||
@Disabled("Jetty 12 does not support User-Agent-based compression")
|
||||
protected void noCompressionForUserAgent() {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Override
|
||||
@Disabled("Jetty 12 does not support SSL session tracking")
|
||||
protected void sslSessionTracking() {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void contextPathIsLoggedOnStartupWhenCompressionIsEnabled(CapturedOutput output) {
|
||||
AbstractServletWebServerFactory factory = getFactory();
|
||||
|
@ -385,11 +397,9 @@ class JettyServletWebServerFactoryTests extends AbstractServletWebServerFactoryT
|
|||
JettyServletWebServerFactory factory = getFactory();
|
||||
factory.setServerCustomizers(Collections.singletonList((server) -> {
|
||||
Handler handler = server.getHandler();
|
||||
HandlerWrapper wrapper = new HandlerWrapper();
|
||||
Handler.Wrapper wrapper = new Handler.Wrapper();
|
||||
wrapper.setHandler(handler);
|
||||
HandlerCollection collection = new HandlerCollection();
|
||||
collection.addHandler(wrapper);
|
||||
server.setHandler(collection);
|
||||
server.setHandler(wrapper);
|
||||
}));
|
||||
this.webServer = factory.getWebServer(exampleServletRegistration());
|
||||
this.webServer.start();
|
||||
|
@ -507,7 +517,7 @@ class JettyServletWebServerFactoryTests extends AbstractServletWebServerFactoryT
|
|||
@Test
|
||||
void errorHandlerCanBeOverridden() {
|
||||
JettyServletWebServerFactory factory = getFactory();
|
||||
factory.addConfigurations(new AbstractConfiguration() {
|
||||
factory.addConfigurations(new AbstractConfiguration(new AbstractConfiguration.Builder()) {
|
||||
|
||||
@Override
|
||||
public void configure(WebAppContext context) throws Exception {
|
||||
|
@ -544,7 +554,7 @@ class JettyServletWebServerFactoryTests extends AbstractServletWebServerFactoryT
|
|||
if (handler instanceof WebAppContext webAppContext) {
|
||||
return webAppContext;
|
||||
}
|
||||
if (handler instanceof HandlerWrapper wrapper) {
|
||||
if (handler instanceof Handler.Wrapper wrapper) {
|
||||
return findWebAppContext(wrapper.getHandler());
|
||||
}
|
||||
throw new IllegalStateException("No WebAppContext found");
|
||||
|
|
|
@ -41,10 +41,10 @@ import io.netty.handler.ssl.SslProvider;
|
|||
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
|
||||
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
|
||||
import org.awaitility.Awaitility;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.util.StringRequestContent;
|
||||
import org.eclipse.jetty.client.ContentResponse;
|
||||
import org.eclipse.jetty.client.StringRequestContent;
|
||||
import org.eclipse.jetty.http2.client.HTTP2Client;
|
||||
import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2;
|
||||
import org.eclipse.jetty.http2.client.transport.HttpClientTransportOverHTTP2;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2023 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.
|
||||
|
@ -38,7 +38,6 @@ import org.junit.jupiter.params.provider.MethodSource;
|
|||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.testsupport.classpath.ForkedClassPath;
|
||||
import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories;
|
||||
import org.springframework.boot.testsupport.web.servlet.Servlet5ClassPathOverrides;
|
||||
import org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer;
|
||||
import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||
|
@ -159,7 +158,6 @@ class ServletComponentScanIntegrationTests {
|
|||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Servlet5ClassPathOverrides
|
||||
static class JettyTestConfiguration extends AbstractTestConfiguration {
|
||||
|
||||
@Override
|
||||
|
|
|
@ -22,7 +22,6 @@ import org.junit.jupiter.api.AfterEach;
|
|||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories;
|
||||
import org.springframework.boot.testsupport.web.servlet.Servlet5ClassPathOverrides;
|
||||
import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
|
||||
|
@ -75,7 +74,6 @@ class ServletWebServerMvcIntegrationTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Servlet5ClassPathOverrides
|
||||
void jetty() throws Exception {
|
||||
this.context = new AnnotationConfigServletWebServerApplicationContext(JettyConfig.class);
|
||||
doTest(this.context, "/hello");
|
||||
|
@ -88,7 +86,6 @@ class ServletWebServerMvcIntegrationTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
@Servlet5ClassPathOverrides
|
||||
void advancedConfig() throws Exception {
|
||||
this.context = new AnnotationConfigServletWebServerApplicationContext(AdvancedConfig.class);
|
||||
doTest(this.context, "/example/spring/hello");
|
||||
|
|
|
@ -99,9 +99,9 @@ import org.apache.jasper.EmbeddedServletOptions;
|
|||
import org.apache.jasper.servlet.JspServlet;
|
||||
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
|
||||
import org.awaitility.Awaitility;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.ContentResponse;
|
||||
import org.eclipse.jetty.http2.client.HTTP2Client;
|
||||
import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2;
|
||||
import org.eclipse.jetty.http2.client.transport.HttpClientTransportOverHTTP2;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Assumptions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -947,6 +947,7 @@ public abstract class AbstractServletWebServerFactoryTests {
|
|||
this.webServer = factory.getWebServer();
|
||||
this.webServer.start();
|
||||
ClientHttpResponse clientResponse = getClientResponse(getLocalUrl("/"));
|
||||
assertThat(clientResponse.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
List<String> setCookieHeaders = clientResponse.getHeaders().get("Set-Cookie");
|
||||
assertThat(setCookieHeaders).satisfiesExactlyInAnyOrder(
|
||||
(header) -> assertThat(header).contains("JSESSIONID").doesNotContain("SameSite"),
|
||||
|
@ -957,7 +958,7 @@ public abstract class AbstractServletWebServerFactoryTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
void sslSessionTracking() {
|
||||
protected void sslSessionTracking() {
|
||||
AbstractServletWebServerFactory factory = getFactory();
|
||||
Ssl ssl = new Ssl();
|
||||
ssl.setEnabled(true);
|
||||
|
@ -1017,14 +1018,12 @@ public abstract class AbstractServletWebServerFactoryTests {
|
|||
void mimeMappingsAreCorrectlyConfigured() {
|
||||
AbstractServletWebServerFactory factory = getFactory();
|
||||
this.webServer = factory.getWebServer();
|
||||
Map<String, String> configuredMimeMappings = getActualMimeMappings();
|
||||
Collection<MimeMappings.Mapping> configuredMimeMappings = getActualMimeMappings().entrySet()
|
||||
.stream()
|
||||
.map((entry) -> new MimeMappings.Mapping(entry.getKey(), entry.getValue()))
|
||||
.toList();
|
||||
Collection<MimeMappings.Mapping> expectedMimeMappings = MimeMappings.DEFAULT.getAll();
|
||||
configuredMimeMappings
|
||||
.forEach((key, value) -> assertThat(expectedMimeMappings).contains(new MimeMappings.Mapping(key, value)));
|
||||
for (MimeMappings.Mapping mapping : expectedMimeMappings) {
|
||||
assertThat(configuredMimeMappings).containsEntry(mapping.getExtension(), mapping.getMimeType());
|
||||
}
|
||||
assertThat(configuredMimeMappings).hasSameSizeAs(expectedMimeMappings);
|
||||
assertThat(configuredMimeMappings).containsExactlyInAnyOrderElementsOf(expectedMimeMappings);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -41,14 +41,6 @@ configurations {
|
|||
}
|
||||
}
|
||||
|
||||
dependencyManagement {
|
||||
jetty {
|
||||
dependencies {
|
||||
dependency "jakarta.servlet:jakarta.servlet-api:5.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.register("resourcesJar", Jar) { jar ->
|
||||
def nested = project.resources.text.fromString("nested")
|
||||
from(nested) {
|
||||
|
@ -66,7 +58,7 @@ tasks.register("resourcesJar", Jar) { jar ->
|
|||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly("org.eclipse.jetty:jetty-server")
|
||||
compileOnly("org.eclipse.jetty.ee10:jetty-ee10-servlet")
|
||||
compileOnly("org.springframework:spring-web")
|
||||
|
||||
implementation("org.springframework.boot:spring-boot-starter")
|
||||
|
|
|
@ -11,10 +11,6 @@ configurations {
|
|||
}
|
||||
}
|
||||
|
||||
configurations.all {
|
||||
resolutionStrategy.force("jakarta.servlet:jakarta.servlet-api:5.0.0")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-jetty"))
|
||||
|
||||
|
@ -22,10 +18,7 @@ dependencies {
|
|||
exclude module: "spring-boot-starter-tomcat"
|
||||
}
|
||||
|
||||
providedRuntime("org.eclipse.jetty:apache-jsp") {
|
||||
exclude group: "org.eclipse.jetty.toolchain", module: "jetty-jakarta-servlet-api"
|
||||
exclude group: "org.eclipse.jetty.toolchain", module: "jetty-schemas"
|
||||
}
|
||||
providedRuntime("org.eclipse.jetty.ee10:jetty-ee10-apache-jsp")
|
||||
|
||||
runtimeOnly("org.glassfish.web:jakarta.servlet.jsp.jstl")
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
application.message: Hello Spring Boot
|
||||
server.servlet.jsp.class-name=org.eclipse.jetty.ee10.jsp.JettyJspServlet
|
||||
spring.mvc.view.prefix: /WEB-INF/jsp/
|
||||
spring.mvc.view.suffix: .jsp
|
||||
application.message: Hello Spring Boot
|
||||
|
|
|
@ -5,10 +5,6 @@ plugins {
|
|||
|
||||
description = "Spring Boot Jetty SSL smoke test"
|
||||
|
||||
configurations.all {
|
||||
resolutionStrategy.force("jakarta.servlet:jakarta.servlet-api:5.0.0")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-jetty"))
|
||||
implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-web")) {
|
||||
|
|
|
@ -5,10 +5,6 @@ plugins {
|
|||
|
||||
description = "Spring Boot Jetty smoke test"
|
||||
|
||||
configurations.all {
|
||||
resolutionStrategy.force("jakarta.servlet:jakarta.servlet-api:5.0.0")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-web")) {
|
||||
exclude module: "spring-boot-starter-tomcat"
|
||||
|
|
|
@ -2,4 +2,4 @@ server.compression.enabled: true
|
|||
server.compression.min-response-size: 1
|
||||
server.max-http-request-header-size=1000
|
||||
server.jetty.threads.acceptors=2
|
||||
server.jetty.max-http-response-header-size=1000
|
||||
server.jetty.max-http-response-header-size=4096
|
||||
|
|
|
@ -42,7 +42,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||
* @author Florian Storz
|
||||
* @author Michael Weidmann
|
||||
*/
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
|
||||
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = "logging.level.org.eclipse:trace")
|
||||
@ExtendWith(OutputCaptureExtension.class)
|
||||
class SampleJettyApplicationTests {
|
||||
|
||||
|
@ -65,9 +65,8 @@ class SampleJettyApplicationTests {
|
|||
ResponseEntity<String> entity = this.restTemplate.getForEntity("/", String.class);
|
||||
assertThat(entity.getStatusCode()).isEqualTo(HttpStatus.OK);
|
||||
assertThat(entity.getBody()).isEqualTo("Hello World");
|
||||
// Jetty HttpClient decodes gzip reponses automatically
|
||||
// Check that we received a gzip-encoded response
|
||||
assertThat(entity.getHeaders().getFirst(HttpHeaders.CONTENT_ENCODING)).isEqualTo("gzip");
|
||||
// Jetty HttpClient decodes gzip reponses automatically and removes the
|
||||
// Content-Encoding header. We have to assume that the response was gzipped.
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -5,10 +5,6 @@ plugins {
|
|||
|
||||
description = "Spring Boot WebSocket Jetty smoke test"
|
||||
|
||||
configurations.all {
|
||||
resolutionStrategy.force("jakarta.servlet:jakarta.servlet-api:5.0.0")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-jetty"))
|
||||
implementation(project(":spring-boot-project:spring-boot-starters:spring-boot-starter-websocket")) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user