Repackage web server classes
Issue: 44286 Issue: 44067
This commit is contained in:
committed by
Phillip Webb
parent
778f58c9e1
commit
96785b6980
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -28,8 +28,8 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.server.servlet.tomcat.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
@@ -82,7 +82,7 @@ class PulsarAutoConfigurationIntegrationTests {
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ImportAutoConfiguration({ DispatcherServletAutoConfiguration.class, ServletWebServerFactoryAutoConfiguration.class,
|
||||
@ImportAutoConfiguration({ DispatcherServletAutoConfiguration.class, TomcatServletWebServerAutoConfiguration.class,
|
||||
WebMvcAutoConfiguration.class, HttpMessageConvertersAutoConfiguration.class, JacksonAutoConfiguration.class,
|
||||
PulsarAutoConfiguration.class, PulsarReactiveAutoConfiguration.class })
|
||||
@Import(TestWebController.class)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -27,8 +27,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.annotation.ImportCandidates;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.servlet.ServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.servlet.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
@@ -56,8 +56,8 @@ import org.springframework.util.unit.DataSize;
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for RSocket servers. In the case of
|
||||
* {@link org.springframework.boot.WebApplicationType#REACTIVE}, the RSocket server is
|
||||
* added as a WebSocket endpoint on the existing
|
||||
* {@link org.springframework.boot.web.embedded.netty.NettyWebServer}. If a specific
|
||||
* server port is configured, a new standalone RSocket server is created.
|
||||
* {@link org.springframework.boot.web.server.reactive.netty.NettyWebServer}. If a
|
||||
* specific server port is configured, a new standalone RSocket server is created.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Scott Frederick
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -29,7 +29,7 @@ import reactor.netty.http.server.WebsocketServerSpec;
|
||||
import reactor.netty.http.server.WebsocketServerSpec.Builder;
|
||||
|
||||
import org.springframework.boot.rsocket.server.RSocketServerCustomizer;
|
||||
import org.springframework.boot.web.embedded.netty.NettyRouteProvider;
|
||||
import org.springframework.boot.web.server.reactive.netty.NettyRouteProvider;
|
||||
|
||||
/**
|
||||
* {@link NettyRouteProvider} that configures an RSocket Websocket endpoint.
|
||||
|
||||
@@ -41,8 +41,8 @@ import org.springframework.boot.web.server.Http2;
|
||||
import org.springframework.boot.web.server.MimeMappings;
|
||||
import org.springframework.boot.web.server.Shutdown;
|
||||
import org.springframework.boot.web.server.Ssl;
|
||||
import org.springframework.boot.web.servlet.server.Jsp;
|
||||
import org.springframework.boot.web.servlet.server.Session;
|
||||
import org.springframework.boot.web.server.servlet.Jsp;
|
||||
import org.springframework.boot.web.server.servlet.Session;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.unit.DataSize;
|
||||
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2024 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.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.xnio.SslClientAuthMode;
|
||||
import reactor.netty.http.server.HttpServer;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnNotWarDeployment;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnThreading;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.thread.Threading;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.web.embedded.undertow.UndertowDeploymentInfoCustomizer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.task.VirtualThreadTaskExecutor;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for embedded servlet and reactive
|
||||
* web servers customizations.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Moritz Halbritter
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@ConditionalOnNotWarDeployment
|
||||
@ConditionalOnWebApplication
|
||||
@EnableConfigurationProperties(ServerProperties.class)
|
||||
public class EmbeddedWebServerFactoryCustomizerAutoConfiguration {
|
||||
|
||||
/**
|
||||
* Nested configuration if Tomcat is being used.
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass({ Tomcat.class, UpgradeProtocol.class })
|
||||
public static class TomcatWebServerFactoryCustomizerConfiguration {
|
||||
|
||||
@Bean
|
||||
public TomcatWebServerFactoryCustomizer tomcatWebServerFactoryCustomizer(Environment environment,
|
||||
ServerProperties serverProperties) {
|
||||
return new TomcatWebServerFactoryCustomizer(environment, serverProperties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnThreading(Threading.VIRTUAL)
|
||||
TomcatVirtualThreadsWebServerFactoryCustomizer tomcatVirtualThreadsProtocolHandlerCustomizer() {
|
||||
return new TomcatVirtualThreadsWebServerFactoryCustomizer();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Nested configuration if Jetty is being used.
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass({ Server.class, Loader.class, WebAppContext.class })
|
||||
public static class JettyWebServerFactoryCustomizerConfiguration {
|
||||
|
||||
@Bean
|
||||
public JettyWebServerFactoryCustomizer jettyWebServerFactoryCustomizer(Environment environment,
|
||||
ServerProperties serverProperties) {
|
||||
return new JettyWebServerFactoryCustomizer(environment, serverProperties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnThreading(Threading.VIRTUAL)
|
||||
JettyVirtualThreadsWebServerFactoryCustomizer jettyVirtualThreadsWebServerFactoryCustomizer(
|
||||
ServerProperties serverProperties) {
|
||||
return new JettyVirtualThreadsWebServerFactoryCustomizer(serverProperties);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Nested configuration if Undertow is being used.
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass({ Undertow.class, SslClientAuthMode.class })
|
||||
public static class UndertowWebServerFactoryCustomizerConfiguration {
|
||||
|
||||
@Bean
|
||||
public UndertowWebServerFactoryCustomizer undertowWebServerFactoryCustomizer(Environment environment,
|
||||
ServerProperties serverProperties) {
|
||||
return new UndertowWebServerFactoryCustomizer(environment, serverProperties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnThreading(Threading.VIRTUAL)
|
||||
UndertowDeploymentInfoCustomizer virtualThreadsUndertowDeploymentInfoCustomizer() {
|
||||
return (deploymentInfo) -> deploymentInfo.setExecutor(new VirtualThreadTaskExecutor("undertow-"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Nested configuration if Netty is being used.
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(HttpServer.class)
|
||||
public static class NettyWebServerFactoryCustomizerConfiguration {
|
||||
|
||||
@Bean
|
||||
public NettyWebServerFactoryCustomizer nettyWebServerFactoryCustomizer(Environment environment,
|
||||
ServerProperties serverProperties) {
|
||||
return new NettyWebServerFactoryCustomizer(environment, serverProperties);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,123 +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;
|
||||
|
||||
import io.undertow.Undertow;
|
||||
import org.eclipse.jetty.ee10.servlet.ServletHolder;
|
||||
import reactor.netty.http.server.HttpServer;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.reactor.netty.ReactorNettyConfigurations;
|
||||
import org.springframework.boot.web.embedded.jetty.JettyReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer;
|
||||
import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.netty.NettyRouteProvider;
|
||||
import org.springframework.boot.web.embedded.netty.NettyServerCustomizer;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.undertow.UndertowBuilderCustomizer;
|
||||
import org.springframework.boot.web.embedded.undertow.UndertowReactiveWebServerFactory;
|
||||
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.ReactorResourceFactory;
|
||||
|
||||
/**
|
||||
* Configuration classes for reactive web servers
|
||||
* <p>
|
||||
* Those should be {@code @Import} in a regular auto-configuration class to guarantee
|
||||
* their order of execution.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Raheela Aslam
|
||||
* @author Sergey Serdyuk
|
||||
*/
|
||||
abstract class ReactiveWebServerFactoryConfiguration {
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnMissingBean(ReactiveWebServerFactory.class)
|
||||
@ConditionalOnClass({ HttpServer.class })
|
||||
@Import(ReactorNettyConfigurations.ReactorResourceFactoryConfiguration.class)
|
||||
static class EmbeddedNetty {
|
||||
|
||||
@Bean
|
||||
NettyReactiveWebServerFactory nettyReactiveWebServerFactory(ReactorResourceFactory resourceFactory,
|
||||
ObjectProvider<NettyRouteProvider> routes, ObjectProvider<NettyServerCustomizer> serverCustomizers) {
|
||||
NettyReactiveWebServerFactory serverFactory = new NettyReactiveWebServerFactory();
|
||||
serverFactory.setResourceFactory(resourceFactory);
|
||||
routes.orderedStream().forEach(serverFactory::addRouteProviders);
|
||||
serverFactory.getServerCustomizers().addAll(serverCustomizers.orderedStream().toList());
|
||||
return serverFactory;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnMissingBean(ReactiveWebServerFactory.class)
|
||||
@ConditionalOnClass({ org.apache.catalina.startup.Tomcat.class })
|
||||
static class EmbeddedTomcat {
|
||||
|
||||
@Bean
|
||||
TomcatReactiveWebServerFactory tomcatReactiveWebServerFactory(
|
||||
ObjectProvider<TomcatConnectorCustomizer> connectorCustomizers,
|
||||
ObjectProvider<TomcatContextCustomizer> contextCustomizers,
|
||||
ObjectProvider<TomcatProtocolHandlerCustomizer<?>> protocolHandlerCustomizers) {
|
||||
TomcatReactiveWebServerFactory factory = new TomcatReactiveWebServerFactory();
|
||||
factory.getTomcatConnectorCustomizers().addAll(connectorCustomizers.orderedStream().toList());
|
||||
factory.getTomcatContextCustomizers().addAll(contextCustomizers.orderedStream().toList());
|
||||
factory.getTomcatProtocolHandlerCustomizers().addAll(protocolHandlerCustomizers.orderedStream().toList());
|
||||
return factory;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnMissingBean(ReactiveWebServerFactory.class)
|
||||
@ConditionalOnClass({ org.eclipse.jetty.server.Server.class, ServletHolder.class })
|
||||
static class EmbeddedJetty {
|
||||
|
||||
@Bean
|
||||
JettyReactiveWebServerFactory jettyReactiveWebServerFactory(
|
||||
ObjectProvider<JettyServerCustomizer> serverCustomizers) {
|
||||
JettyReactiveWebServerFactory serverFactory = new JettyReactiveWebServerFactory();
|
||||
serverFactory.getServerCustomizers().addAll(serverCustomizers.orderedStream().toList());
|
||||
return serverFactory;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnMissingBean(ReactiveWebServerFactory.class)
|
||||
@ConditionalOnClass({ Undertow.class })
|
||||
static class EmbeddedUndertow {
|
||||
|
||||
@Bean
|
||||
UndertowReactiveWebServerFactory undertowReactiveWebServerFactory(
|
||||
ObjectProvider<UndertowBuilderCustomizer> builderCustomizers) {
|
||||
UndertowReactiveWebServerFactory factory = new UndertowReactiveWebServerFactory();
|
||||
factory.getBuilderCustomizers().addAll(builderCustomizers.orderedStream().toList());
|
||||
return factory;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -106,9 +106,8 @@ import org.springframework.web.server.session.WebSessionManager;
|
||||
* @author Weix Sun
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@AutoConfiguration(after = { ReactiveWebServerFactoryAutoConfiguration.class, CodecsAutoConfiguration.class,
|
||||
ReactiveMultipartAutoConfiguration.class, ValidationAutoConfiguration.class,
|
||||
WebSessionIdResolverAutoConfiguration.class })
|
||||
@AutoConfiguration(after = { CodecsAutoConfiguration.class, ReactiveMultipartAutoConfiguration.class,
|
||||
ValidationAutoConfiguration.class, WebSessionIdResolverAutoConfiguration.class })
|
||||
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
|
||||
@ConditionalOnClass(WebFluxConfigurer.class)
|
||||
@ConditionalOnMissingBean({ WebFluxConfigurationSupport.class })
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.web.embedded;
|
||||
package org.springframework.boot.autoconfigure.web.server.jetty;
|
||||
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.SynchronousQueue;
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -14,14 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.web.embedded;
|
||||
package org.springframework.boot.autoconfigure.web.server.jetty;
|
||||
|
||||
import org.eclipse.jetty.util.VirtualThreads;
|
||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.web.embedded.jetty.ConfigurableJettyWebServerFactory;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.boot.web.server.jetty.ConfigurableJettyWebServerFactory;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
@@ -29,7 +29,7 @@ import org.springframework.util.Assert;
|
||||
* Activates virtual threads on the {@link ConfigurableJettyWebServerFactory}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @since 3.2.0
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public class JettyVirtualThreadsWebServerFactoryCustomizer
|
||||
implements WebServerFactoryCustomizer<ConfigurableJettyWebServerFactory>, Ordered {
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.server.jetty;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnNotWarDeployment;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnThreading;
|
||||
import org.springframework.boot.autoconfigure.thread.Threading;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.autoconfigure.web.server.reactive.jetty.JettyReactiveWebServerAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.server.servlet.jetty.JettyServletWebServerAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
/**
|
||||
* {@link Configuration Configuration} for a Jetty-based reactive or servlet web server.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 4.0.0
|
||||
* @see JettyReactiveWebServerAutoConfiguration
|
||||
* @see JettyServletWebServerAutoConfiguration
|
||||
*/
|
||||
@ConditionalOnNotWarDeployment
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public class JettyWebServerConfiguration {
|
||||
|
||||
@Bean
|
||||
JettyWebServerFactoryCustomizer jettyWebServerFactoryCustomizer(Environment environment,
|
||||
ServerProperties serverProperties) {
|
||||
return new JettyWebServerFactoryCustomizer(environment, serverProperties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnThreading(Threading.VIRTUAL)
|
||||
JettyVirtualThreadsWebServerFactoryCustomizer jettyVirtualThreadsWebServerFactoryCustomizer(
|
||||
ServerProperties serverProperties) {
|
||||
return new JettyVirtualThreadsWebServerFactoryCustomizer(serverProperties);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.web.embedded;
|
||||
package org.springframework.boot.autoconfigure.web.server.jetty;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
@@ -36,8 +36,8 @@ import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties.Jetty.Accesslog.Format;
|
||||
import org.springframework.boot.cloud.CloudPlatform;
|
||||
import org.springframework.boot.context.properties.PropertyMapper;
|
||||
import org.springframework.boot.web.embedded.jetty.ConfigurableJettyWebServerFactory;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.boot.web.server.jetty.ConfigurableJettyWebServerFactory;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
@@ -52,7 +52,7 @@ import org.springframework.util.unit.DataSize;
|
||||
* @author Rafiullah Hamedy
|
||||
* @author Florian Storz
|
||||
* @author Michael Weidmann
|
||||
* @since 2.0.0
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public class JettyWebServerFactoryCustomizer
|
||||
implements WebServerFactoryCustomizer<ConfigurableJettyWebServerFactory>, Ordered {
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Classes related to the auto-configuration of a servlet or reactive web server using
|
||||
* Jetty.
|
||||
*/
|
||||
package org.springframework.boot.autoconfigure.web.server.jetty;
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.web.reactive;
|
||||
package org.springframework.boot.autoconfigure.web.server.reactive;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
@@ -23,44 +23,31 @@ import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.ssl.SslBundles;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.http.ReactiveHttpInputMessage;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.web.server.adapter.ForwardedHeaderTransformer;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for a reactive web server.
|
||||
* {@link Configuration Configuration} for a reactive web server.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Scott Frederick
|
||||
* @since 2.0.0
|
||||
* @since 4.0.0
|
||||
*/
|
||||
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
|
||||
@AutoConfiguration
|
||||
@ConditionalOnClass(ReactiveHttpInputMessage.class)
|
||||
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableConfigurationProperties(ServerProperties.class)
|
||||
@Import({ ReactiveWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,
|
||||
ReactiveWebServerFactoryConfiguration.EmbeddedTomcat.class,
|
||||
ReactiveWebServerFactoryConfiguration.EmbeddedJetty.class,
|
||||
ReactiveWebServerFactoryConfiguration.EmbeddedUndertow.class,
|
||||
ReactiveWebServerFactoryConfiguration.EmbeddedNetty.class })
|
||||
public class ReactiveWebServerFactoryAutoConfiguration {
|
||||
@Import(ReactiveWebServerConfiguration.BeanPostProcessorsRegistrar.class)
|
||||
public class ReactiveWebServerConfiguration {
|
||||
|
||||
@Bean
|
||||
public ReactiveWebServerFactoryCustomizer reactiveWebServerFactoryCustomizer(ServerProperties serverProperties,
|
||||
@@ -68,13 +55,6 @@ public class ReactiveWebServerFactoryAutoConfiguration {
|
||||
return new ReactiveWebServerFactoryCustomizer(serverProperties, sslBundles.getIfAvailable());
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnClass(name = "org.apache.catalina.startup.Tomcat")
|
||||
public TomcatReactiveWebServerFactoryCustomizer tomcatReactiveWebServerFactoryCustomizer(
|
||||
ServerProperties serverProperties) {
|
||||
return new TomcatReactiveWebServerFactoryCustomizer(serverProperties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnProperty(name = "server.forward-headers-strategy", havingValue = "framework")
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -14,13 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.web.reactive;
|
||||
package org.springframework.boot.autoconfigure.web.server.reactive;
|
||||
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.context.properties.PropertyMapper;
|
||||
import org.springframework.boot.ssl.SslBundles;
|
||||
import org.springframework.boot.web.reactive.server.ConfigurableReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.boot.web.server.reactive.ConfigurableReactiveWebServerFactory;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
/**
|
||||
@@ -30,7 +30,7 @@ import org.springframework.core.Ordered;
|
||||
* @author Brian Clozel
|
||||
* @author Yunkun Huang
|
||||
* @author Scott Frederick
|
||||
* @since 2.0.0
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public class ReactiveWebServerFactoryCustomizer
|
||||
implements WebServerFactoryCustomizer<ConfigurableReactiveWebServerFactory>, Ordered {
|
||||
@@ -51,7 +51,7 @@ public class ReactiveWebServerFactoryCustomizer
|
||||
* Create a new {@link ReactiveWebServerFactoryCustomizer} instance.
|
||||
* @param serverProperties the server properties
|
||||
* @param sslBundles the SSL bundles
|
||||
* @since 3.1.0
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public ReactiveWebServerFactoryCustomizer(ServerProperties serverProperties, SslBundles sslBundles) {
|
||||
this.serverProperties = serverProperties;
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.server.reactive.jetty;
|
||||
|
||||
import org.eclipse.jetty.ee10.servlet.ServletHolder;
|
||||
import org.eclipse.jetty.ee10.websocket.jakarta.server.config.JakartaWebSocketServletContainerInitializer;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.web.server.jetty.JettyWebServerConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.server.reactive.ReactiveWebServerConfiguration;
|
||||
import org.springframework.boot.web.server.jetty.JettyServerCustomizer;
|
||||
import org.springframework.boot.web.server.reactive.ReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.server.reactive.jetty.JettyReactiveWebServerFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.ReactiveHttpInputMessage;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for a Jetty-based reactive web
|
||||
* server.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 4.0.0
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@ConditionalOnClass({ Server.class, ServletHolder.class, ReactiveHttpInputMessage.class })
|
||||
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
|
||||
@Import({ JettyWebServerConfiguration.class, ReactiveWebServerConfiguration.class })
|
||||
public class JettyReactiveWebServerAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(ReactiveWebServerFactory.class)
|
||||
JettyReactiveWebServerFactory jettyReactiveWebServerFactory(
|
||||
ObjectProvider<JettyServerCustomizer> serverCustomizers) {
|
||||
JettyReactiveWebServerFactory serverFactory = new JettyReactiveWebServerFactory();
|
||||
serverFactory.getServerCustomizers().addAll(serverCustomizers.orderedStream().toList());
|
||||
return serverFactory;
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(JakartaWebSocketServletContainerInitializer.class)
|
||||
static class JettyWebSocketConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = "websocketReactiveWebServerCustomizer")
|
||||
WebSocketJettyReactiveWebServerFactoryCustomizer websocketServletWebServerCustomizer() {
|
||||
return new WebSocketJettyReactiveWebServerFactoryCustomizer();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.websocket.reactive;
|
||||
package org.springframework.boot.autoconfigure.web.server.reactive.jetty;
|
||||
|
||||
import jakarta.servlet.ServletContext;
|
||||
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
|
||||
@@ -25,17 +25,17 @@ import org.eclipse.jetty.server.Handler;
|
||||
import org.eclipse.jetty.websocket.core.server.WebSocketMappings;
|
||||
import org.eclipse.jetty.websocket.core.server.WebSocketServerComponents;
|
||||
|
||||
import org.springframework.boot.web.embedded.jetty.JettyReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.boot.web.server.reactive.jetty.JettyReactiveWebServerFactory;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
/**
|
||||
* WebSocket customizer for {@link JettyReactiveWebServerFactory}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 3.0.8
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public class JettyWebSocketReactiveWebServerCustomizer
|
||||
public class WebSocketJettyReactiveWebServerFactoryCustomizer
|
||||
implements WebServerFactoryCustomizer<JettyReactiveWebServerFactory>, Ordered {
|
||||
|
||||
@Override
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Classes related to the auto-configuration of a reactive web server using Jetty.
|
||||
*/
|
||||
package org.springframework.boot.autoconfigure.web.server.reactive.jetty;
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.server.reactive.netty;
|
||||
|
||||
import reactor.netty.http.server.HttpServer;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.reactor.netty.ReactorNettyConfigurations.ReactorResourceFactoryConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.autoconfigure.web.server.reactive.ReactiveWebServerConfiguration;
|
||||
import org.springframework.boot.web.server.reactive.ReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.server.reactive.netty.NettyReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.server.reactive.netty.NettyRouteProvider;
|
||||
import org.springframework.boot.web.server.reactive.netty.NettyServerCustomizer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.http.ReactiveHttpInputMessage;
|
||||
import org.springframework.http.client.ReactorResourceFactory;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for a Netty-based reactive web
|
||||
* server.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 4.0.0
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@ConditionalOnClass({ ReactiveHttpInputMessage.class, HttpServer.class })
|
||||
@Import({ ReactiveWebServerConfiguration.class, ReactorResourceFactoryConfiguration.class })
|
||||
public class NettyReactiveWebServerAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(ReactiveWebServerFactory.class)
|
||||
NettyReactiveWebServerFactory nettyReactiveWebServerFactory(ReactorResourceFactory resourceFactory,
|
||||
ObjectProvider<NettyRouteProvider> routes, ObjectProvider<NettyServerCustomizer> serverCustomizers) {
|
||||
NettyReactiveWebServerFactory serverFactory = new NettyReactiveWebServerFactory();
|
||||
serverFactory.setResourceFactory(resourceFactory);
|
||||
routes.orderedStream().forEach(serverFactory::addRouteProviders);
|
||||
serverFactory.getServerCustomizers().addAll(serverCustomizers.orderedStream().toList());
|
||||
return serverFactory;
|
||||
}
|
||||
|
||||
@Bean
|
||||
NettyReactiveWebServerFactoryCustomizer nettyWebServerFactoryCustomizer(Environment environment,
|
||||
ServerProperties serverProperties) {
|
||||
return new NettyReactiveWebServerFactoryCustomizer(environment, serverProperties);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.web.embedded;
|
||||
package org.springframework.boot.autoconfigure.web.server.reactive.netty;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
@@ -23,8 +23,8 @@ import io.netty.channel.ChannelOption;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.cloud.CloudPlatform;
|
||||
import org.springframework.boot.context.properties.PropertyMapper;
|
||||
import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.boot.web.server.reactive.netty.NettyReactiveWebServerFactory;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
@@ -34,16 +34,16 @@ import org.springframework.core.env.Environment;
|
||||
* @author Brian Clozel
|
||||
* @author Chentao Qu
|
||||
* @author Artsiom Yudovin
|
||||
* @since 2.1.0
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public class NettyWebServerFactoryCustomizer
|
||||
public class NettyReactiveWebServerFactoryCustomizer
|
||||
implements WebServerFactoryCustomizer<NettyReactiveWebServerFactory>, Ordered {
|
||||
|
||||
private final Environment environment;
|
||||
|
||||
private final ServerProperties serverProperties;
|
||||
|
||||
public NettyWebServerFactoryCustomizer(Environment environment, ServerProperties serverProperties) {
|
||||
public NettyReactiveWebServerFactoryCustomizer(Environment environment, ServerProperties serverProperties) {
|
||||
this.environment = environment;
|
||||
this.serverProperties = serverProperties;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Classes related to the auto-configuration of a reactive web server using Netty.
|
||||
*/
|
||||
package org.springframework.boot.autoconfigure.web.server.reactive.netty;
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -15,6 +15,6 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Configuration for embedded reactive and servlet web servers.
|
||||
* Classes related to the auto-configuration of a reactive web server.
|
||||
*/
|
||||
package org.springframework.boot.autoconfigure.web.embedded;
|
||||
package org.springframework.boot.autoconfigure.web.server.reactive;
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.server.reactive.tomcat;
|
||||
|
||||
import org.apache.catalina.startup.Tomcat;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.autoconfigure.web.server.reactive.ReactiveWebServerConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.server.tomcat.TomcatWebServerConfiguration;
|
||||
import org.springframework.boot.web.server.reactive.ReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.server.reactive.tomcat.TomcatReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.server.tomcat.TomcatConnectorCustomizer;
|
||||
import org.springframework.boot.web.server.tomcat.TomcatContextCustomizer;
|
||||
import org.springframework.boot.web.server.tomcat.TomcatProtocolHandlerCustomizer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.ReactiveHttpInputMessage;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for a Tomcat-based reactive web
|
||||
* server.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 4.0.0
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@ConditionalOnClass({ ReactiveHttpInputMessage.class, Tomcat.class })
|
||||
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
|
||||
@Import({ TomcatWebServerConfiguration.class, ReactiveWebServerConfiguration.class })
|
||||
public class TomcatReactiveWebServerAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
TomcatReactiveWebServerFactoryCustomizer tomcatReactiveWebServerFactoryCustomizer(
|
||||
ServerProperties serverProperties) {
|
||||
return new TomcatReactiveWebServerFactoryCustomizer(serverProperties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(ReactiveWebServerFactory.class)
|
||||
TomcatReactiveWebServerFactory tomcatReactiveWebServerFactory(
|
||||
ObjectProvider<TomcatConnectorCustomizer> connectorCustomizers,
|
||||
ObjectProvider<TomcatContextCustomizer> contextCustomizers,
|
||||
ObjectProvider<TomcatProtocolHandlerCustomizer<?>> protocolHandlerCustomizers) {
|
||||
TomcatReactiveWebServerFactory factory = new TomcatReactiveWebServerFactory();
|
||||
factory.getConnectorCustomizers().addAll(connectorCustomizers.orderedStream().toList());
|
||||
factory.getContextCustomizers().addAll(contextCustomizers.orderedStream().toList());
|
||||
factory.getProtocolHandlerCustomizers().addAll(protocolHandlerCustomizers.orderedStream().toList());
|
||||
return factory;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,15 +14,15 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.web.reactive;
|
||||
package org.springframework.boot.autoconfigure.web.server.reactive.tomcat;
|
||||
|
||||
import org.apache.catalina.core.AprLifecycleListener;
|
||||
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties.Tomcat;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties.Tomcat.UseApr;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.boot.web.server.reactive.tomcat.TomcatReactiveWebServerFactory;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -30,7 +30,7 @@ import org.springframework.util.Assert;
|
||||
* web servers.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 2.2.0
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public class TomcatReactiveWebServerFactoryCustomizer
|
||||
implements WebServerFactoryCustomizer<TomcatReactiveWebServerFactory> {
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Classes related to the auto-configuration of a reactive web server using Tomcat.
|
||||
*/
|
||||
package org.springframework.boot.autoconfigure.web.server.reactive.tomcat;
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.server.reactive.undertow;
|
||||
|
||||
import io.undertow.Undertow;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.web.server.reactive.ReactiveWebServerConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.server.undertow.UndertowWebServerConfiguration;
|
||||
import org.springframework.boot.web.server.reactive.ReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.server.reactive.undertow.UndertowReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.server.undertow.UndertowBuilderCustomizer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.ReactiveHttpInputMessage;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for an Undertow-based reactive web
|
||||
* server.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 4.0.0
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@ConditionalOnClass({ ReactiveHttpInputMessage.class, Undertow.class })
|
||||
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
|
||||
@Import({ UndertowWebServerConfiguration.class, ReactiveWebServerConfiguration.class })
|
||||
public class UndertowReactiveWebServerAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(ReactiveWebServerFactory.class)
|
||||
UndertowReactiveWebServerFactory undertowReactiveWebServerFactory(
|
||||
ObjectProvider<UndertowBuilderCustomizer> builderCustomizers) {
|
||||
UndertowReactiveWebServerFactory factory = new UndertowReactiveWebServerFactory();
|
||||
factory.getBuilderCustomizers().addAll(builderCustomizers.orderedStream().toList());
|
||||
return factory;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Classes related to the auto-configuration of a reactive web server using Undertow.
|
||||
*/
|
||||
package org.springframework.boot.autoconfigure.web.server.reactive.undertow;
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.server.servlet;
|
||||
|
||||
import org.springframework.web.filter.ForwardedHeaderFilter;
|
||||
|
||||
/**
|
||||
* Customizer for the auto-configured {@link ForwardedHeaderFilter}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public interface ForwardedHeaderFilterCustomizer {
|
||||
|
||||
/**
|
||||
* Customizes the given {@code filter}.
|
||||
* @param filter the filter to customize
|
||||
*/
|
||||
void customize(ForwardedHeaderFilter filter);
|
||||
|
||||
}
|
||||
@@ -14,10 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.web.servlet;
|
||||
package org.springframework.boot.autoconfigure.web.server.servlet;
|
||||
|
||||
import jakarta.servlet.DispatcherType;
|
||||
import jakarta.servlet.ServletRequest;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
@@ -26,22 +25,16 @@ import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
|
||||
import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ConditionalOnMissingFilterBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.ssl.SslBundles;
|
||||
import org.springframework.boot.web.server.ErrorPageRegistrarBeanPostProcessor;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor;
|
||||
import org.springframework.boot.web.server.servlet.CookieSameSiteSupplier;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.boot.web.servlet.WebListenerRegistrar;
|
||||
import org.springframework.boot.web.servlet.server.CookieSameSiteSupplier;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
@@ -52,7 +45,7 @@ import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.web.filter.ForwardedHeaderFilter;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for servlet web servers.
|
||||
* {@link Configuration Configuration} for a servlet web server.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Dave Syer
|
||||
@@ -60,21 +53,15 @@ import org.springframework.web.filter.ForwardedHeaderFilter;
|
||||
* @author Brian Clozel
|
||||
* @author Stephane Nicoll
|
||||
* @author Scott Frederick
|
||||
* @since 2.0.0
|
||||
* @since 4.0.0
|
||||
*/
|
||||
@AutoConfiguration(after = SslAutoConfiguration.class)
|
||||
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
|
||||
@ConditionalOnClass(ServletRequest.class)
|
||||
@ConditionalOnWebApplication(type = Type.SERVLET)
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableConfigurationProperties(ServerProperties.class)
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,
|
||||
ServletWebServerFactoryConfiguration.EmbeddedTomcat.class,
|
||||
ServletWebServerFactoryConfiguration.EmbeddedJetty.class,
|
||||
ServletWebServerFactoryConfiguration.EmbeddedUndertow.class })
|
||||
public class ServletWebServerFactoryAutoConfiguration {
|
||||
@Import(ServletWebServerConfiguration.BeanPostProcessorsRegistrar.class)
|
||||
public class ServletWebServerConfiguration {
|
||||
|
||||
@Bean
|
||||
public ServletWebServerFactoryCustomizer servletWebServerFactoryCustomizer(ServerProperties serverProperties,
|
||||
ServletWebServerFactoryCustomizer servletWebServerFactoryCustomizer(ServerProperties serverProperties,
|
||||
ObjectProvider<WebListenerRegistrar> webListenerRegistrars,
|
||||
ObjectProvider<CookieSameSiteSupplier> cookieSameSiteSuppliers, ObjectProvider<SslBundles> sslBundles) {
|
||||
return new ServletWebServerFactoryCustomizer(serverProperties, webListenerRegistrars.orderedStream().toList(),
|
||||
@@ -82,47 +69,23 @@ public class ServletWebServerFactoryAutoConfiguration {
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnClass(name = "org.apache.catalina.startup.Tomcat")
|
||||
public TomcatServletWebServerFactoryCustomizer tomcatServletWebServerFactoryCustomizer(
|
||||
ServerProperties serverProperties) {
|
||||
return new TomcatServletWebServerFactoryCustomizer(serverProperties);
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnProperty(name = "server.forward-headers-strategy", havingValue = "framework")
|
||||
@ConditionalOnMissingFilterBean(ForwardedHeaderFilter.class)
|
||||
static class ForwardedHeaderFilterConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnClass(name = "org.apache.catalina.startup.Tomcat")
|
||||
ForwardedHeaderFilterCustomizer tomcatForwardedHeaderFilterCustomizer(ServerProperties serverProperties) {
|
||||
return (filter) -> filter.setRelativeRedirects(serverProperties.getTomcat().isUseRelativeRedirects());
|
||||
}
|
||||
|
||||
@Bean
|
||||
FilterRegistrationBean<ForwardedHeaderFilter> forwardedHeaderFilter(
|
||||
ObjectProvider<ForwardedHeaderFilterCustomizer> customizerProvider) {
|
||||
ForwardedHeaderFilter filter = new ForwardedHeaderFilter();
|
||||
customizerProvider.ifAvailable((customizer) -> customizer.customize(filter));
|
||||
FilterRegistrationBean<ForwardedHeaderFilter> registration = new FilterRegistrationBean<>(filter);
|
||||
registration.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ASYNC, DispatcherType.ERROR);
|
||||
registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
|
||||
return registration;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
interface ForwardedHeaderFilterCustomizer {
|
||||
|
||||
void customize(ForwardedHeaderFilter filter);
|
||||
|
||||
FilterRegistrationBean<ForwardedHeaderFilter> forwardedHeaderFilter(
|
||||
ObjectProvider<ForwardedHeaderFilterCustomizer> customizerProvider) {
|
||||
ForwardedHeaderFilter filter = new ForwardedHeaderFilter();
|
||||
customizerProvider.ifAvailable((customizer) -> customizer.customize(filter));
|
||||
FilterRegistrationBean<ForwardedHeaderFilter> registration = new FilterRegistrationBean<>(filter);
|
||||
registration.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ASYNC, DispatcherType.ERROR);
|
||||
registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
|
||||
return registration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a {@link WebServerFactoryCustomizerBeanPostProcessor}. Registered via
|
||||
* {@link ImportBeanDefinitionRegistrar} for early registration.
|
||||
*/
|
||||
public static class BeanPostProcessorsRegistrar implements ImportBeanDefinitionRegistrar, BeanFactoryAware {
|
||||
static class BeanPostProcessorsRegistrar implements ImportBeanDefinitionRegistrar, BeanFactoryAware {
|
||||
|
||||
private ConfigurableListableBeanFactory beanFactory;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.web.servlet;
|
||||
package org.springframework.boot.autoconfigure.web.server.servlet;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -23,9 +23,9 @@ import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.context.properties.PropertyMapper;
|
||||
import org.springframework.boot.ssl.SslBundles;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.boot.web.server.servlet.ConfigurableServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.servlet.CookieSameSiteSupplier;
|
||||
import org.springframework.boot.web.servlet.WebListenerRegistrar;
|
||||
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
|
||||
import org.springframework.boot.web.servlet.server.CookieSameSiteSupplier;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
@@ -39,7 +39,7 @@ import org.springframework.util.CollectionUtils;
|
||||
* @author Yunkun Huang
|
||||
* @author Scott Frederick
|
||||
* @author Lasse Wulff
|
||||
* @since 2.0.0
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public class ServletWebServerFactoryCustomizer
|
||||
implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>, Ordered {
|
||||
@@ -53,15 +53,10 @@ public class ServletWebServerFactoryCustomizer
|
||||
private final SslBundles sslBundles;
|
||||
|
||||
public ServletWebServerFactoryCustomizer(ServerProperties serverProperties) {
|
||||
this(serverProperties, Collections.emptyList());
|
||||
this(serverProperties, Collections.emptyList(), Collections.emptyList(), null);
|
||||
}
|
||||
|
||||
public ServletWebServerFactoryCustomizer(ServerProperties serverProperties,
|
||||
List<WebListenerRegistrar> webListenerRegistrars) {
|
||||
this(serverProperties, webListenerRegistrars, null, null);
|
||||
}
|
||||
|
||||
ServletWebServerFactoryCustomizer(ServerProperties serverProperties,
|
||||
List<WebListenerRegistrar> webListenerRegistrars, List<CookieSameSiteSupplier> cookieSameSiteSuppliers,
|
||||
SslBundles sslBundles) {
|
||||
this.serverProperties = serverProperties;
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -14,69 +14,59 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.websocket.servlet;
|
||||
package org.springframework.boot.autoconfigure.web.server.servlet.jetty;
|
||||
|
||||
import java.util.EnumSet;
|
||||
|
||||
import jakarta.servlet.DispatcherType;
|
||||
import jakarta.servlet.FilterRegistration.Dynamic;
|
||||
import jakarta.servlet.Servlet;
|
||||
import jakarta.websocket.server.ServerContainer;
|
||||
import org.apache.catalina.startup.Tomcat;
|
||||
import org.apache.tomcat.websocket.server.WsSci;
|
||||
import jakarta.servlet.ServletRequest;
|
||||
import org.eclipse.jetty.ee10.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.ee10.websocket.jakarta.server.config.JakartaWebSocketServletContainerInitializer;
|
||||
import org.eclipse.jetty.ee10.websocket.servlet.WebSocketUpgradeFilter;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.util.Loader;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnNotWarDeployment;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
|
||||
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
|
||||
import org.springframework.boot.autoconfigure.web.server.jetty.JettyWebServerConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.server.servlet.ServletWebServerConfiguration;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.boot.web.server.jetty.JettyServerCustomizer;
|
||||
import org.springframework.boot.web.server.servlet.ServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.servlet.jetty.JettyServletWebServerFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
|
||||
/**
|
||||
* Auto configuration for WebSocket servlet server in embedded Tomcat, Jetty or Undertow.
|
||||
* Requires the appropriate WebSocket modules to be on the classpath.
|
||||
* <p>
|
||||
* If Tomcat's WebSocket support is detected on the classpath we add a customizer that
|
||||
* installs the Tomcat WebSocket initializer. In a non-embedded server it should already
|
||||
* be there.
|
||||
* <p>
|
||||
* If Jetty's WebSocket support is detected on the classpath we add a configuration that
|
||||
* configures the context with WebSocket support. In a non-embedded server it should
|
||||
* already be there.
|
||||
* <p>
|
||||
* If Undertow's WebSocket support is detected on the classpath we add a customizer that
|
||||
* installs the Undertow WebSocket DeploymentInfo Customizer. In a non-embedded server it
|
||||
* should already be there.
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for a Jetty-based servlet web
|
||||
* server.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
* @since 1.0.0
|
||||
* @since 4.0.0
|
||||
*/
|
||||
@AutoConfiguration(before = ServletWebServerFactoryAutoConfiguration.class)
|
||||
@ConditionalOnClass({ Servlet.class, ServerContainer.class })
|
||||
@AutoConfiguration
|
||||
@ConditionalOnClass({ ServletRequest.class, Server.class, Loader.class, WebAppContext.class })
|
||||
@ConditionalOnWebApplication(type = Type.SERVLET)
|
||||
public class WebSocketServletAutoConfiguration {
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass({ Tomcat.class, WsSci.class })
|
||||
static class TomcatWebSocketConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = "websocketServletWebServerCustomizer")
|
||||
TomcatWebSocketServletWebServerCustomizer websocketServletWebServerCustomizer() {
|
||||
return new TomcatWebSocketServletWebServerCustomizer();
|
||||
}
|
||||
@Import({ JettyWebServerConfiguration.class, ServletWebServerConfiguration.class })
|
||||
public class JettyServletWebServerAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT)
|
||||
JettyServletWebServerFactory jettyServletWebServerFactory(ObjectProvider<JettyServerCustomizer> serverCustomizers) {
|
||||
JettyServletWebServerFactory factory = new JettyServletWebServerFactory();
|
||||
factory.getServerCustomizers().addAll(serverCustomizers.orderedStream().toList());
|
||||
return factory;
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@@ -85,8 +75,8 @@ public class WebSocketServletAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = "websocketServletWebServerCustomizer")
|
||||
JettyWebSocketServletWebServerCustomizer websocketServletWebServerCustomizer() {
|
||||
return new JettyWebSocketServletWebServerCustomizer();
|
||||
WebSocketJettyServletWebServerFactoryCustomizer websocketServletWebServerCustomizer() {
|
||||
return new WebSocketJettyServletWebServerFactoryCustomizer();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -106,16 +96,4 @@ public class WebSocketServletAutoConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(io.undertow.websockets.jsr.Bootstrap.class)
|
||||
static class UndertowWebSocketConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = "websocketServletWebServerCustomizer")
|
||||
UndertowWebSocketServletWebServerCustomizer websocketServletWebServerCustomizer() {
|
||||
return new UndertowWebSocketServletWebServerCustomizer();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.websocket.servlet;
|
||||
package org.springframework.boot.autoconfigure.web.server.servlet.jetty;
|
||||
|
||||
import org.eclipse.jetty.ee10.webapp.AbstractConfiguration;
|
||||
import org.eclipse.jetty.ee10.webapp.WebAppContext;
|
||||
@@ -24,8 +24,8 @@ 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.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.boot.web.server.servlet.jetty.JettyServletWebServerFactory;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
/**
|
||||
@@ -34,9 +34,9 @@ import org.springframework.core.Ordered;
|
||||
* @author Dave Syer
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
* @since 2.0.0
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public class JettyWebSocketServletWebServerCustomizer
|
||||
public class WebSocketJettyServletWebServerFactoryCustomizer
|
||||
implements WebServerFactoryCustomizer<JettyServletWebServerFactory>, Ordered {
|
||||
|
||||
@Override
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Classes related to the auto-configuration of a servlet web server using Jetty.
|
||||
*/
|
||||
package org.springframework.boot.autoconfigure.web.server.servlet.jetty;
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -15,6 +15,6 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Auto-configuration for WebSocket support in reactive web servers.
|
||||
* Classes related to the auto-configuration of a servlet web server.
|
||||
*/
|
||||
package org.springframework.boot.autoconfigure.websocket.reactive;
|
||||
package org.springframework.boot.autoconfigure.web.server.servlet;
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.server.servlet.tomcat;
|
||||
|
||||
import jakarta.servlet.ServletRequest;
|
||||
import org.apache.catalina.startup.Tomcat;
|
||||
import org.apache.coyote.UpgradeProtocol;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
|
||||
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.autoconfigure.web.server.servlet.ForwardedHeaderFilterCustomizer;
|
||||
import org.springframework.boot.autoconfigure.web.server.servlet.ServletWebServerConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.server.tomcat.TomcatWebServerConfiguration;
|
||||
import org.springframework.boot.web.server.servlet.ServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.servlet.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.tomcat.TomcatConnectorCustomizer;
|
||||
import org.springframework.boot.web.server.tomcat.TomcatContextCustomizer;
|
||||
import org.springframework.boot.web.server.tomcat.TomcatProtocolHandlerCustomizer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for a Tomcat-based servlet web
|
||||
* server.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 4.0.0
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@ConditionalOnClass({ ServletRequest.class, Tomcat.class, UpgradeProtocol.class })
|
||||
@ConditionalOnWebApplication(type = Type.SERVLET)
|
||||
@Import({ ServletWebServerConfiguration.class, TomcatWebServerConfiguration.class })
|
||||
public class TomcatServletWebServerAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT)
|
||||
TomcatServletWebServerFactory tomcatServletWebServerFactory(
|
||||
ObjectProvider<TomcatConnectorCustomizer> connectorCustomizers,
|
||||
ObjectProvider<TomcatContextCustomizer> contextCustomizers,
|
||||
ObjectProvider<TomcatProtocolHandlerCustomizer<?>> protocolHandlerCustomizers) {
|
||||
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
|
||||
factory.getConnectorCustomizers().addAll(connectorCustomizers.orderedStream().toList());
|
||||
factory.getContextCustomizers().addAll(contextCustomizers.orderedStream().toList());
|
||||
factory.getProtocolHandlerCustomizers().addAll(protocolHandlerCustomizers.orderedStream().toList());
|
||||
return factory;
|
||||
}
|
||||
|
||||
@Bean
|
||||
TomcatServletWebServerFactoryCustomizer tomcatServletWebServerFactoryCustomizer(ServerProperties serverProperties) {
|
||||
return new TomcatServletWebServerFactoryCustomizer(serverProperties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(name = "server.forward-headers-strategy", havingValue = "framework")
|
||||
ForwardedHeaderFilterCustomizer tomcatForwardedHeaderFilterCustomizer(ServerProperties serverProperties) {
|
||||
return (filter) -> filter.setRelativeRedirects(serverProperties.getTomcat().isUseRelativeRedirects());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,17 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.web.servlet;
|
||||
|
||||
import org.apache.catalina.core.AprLifecycleListener;
|
||||
package org.springframework.boot.autoconfigure.web.server.servlet.tomcat;
|
||||
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties.Tomcat.UseApr;
|
||||
import org.springframework.boot.web.embedded.tomcat.ConfigurableTomcatWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.boot.web.server.servlet.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.tomcat.ConfigurableTomcatWebServerFactory;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
@@ -33,14 +29,13 @@ import org.springframework.util.ObjectUtils;
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Phillip Webb
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class TomcatServletWebServerFactoryCustomizer
|
||||
class TomcatServletWebServerFactoryCustomizer
|
||||
implements WebServerFactoryCustomizer<TomcatServletWebServerFactory>, Ordered {
|
||||
|
||||
private final ServerProperties serverProperties;
|
||||
|
||||
public TomcatServletWebServerFactoryCustomizer(ServerProperties serverProperties) {
|
||||
TomcatServletWebServerFactoryCustomizer(ServerProperties serverProperties) {
|
||||
this.serverProperties = serverProperties;
|
||||
}
|
||||
|
||||
@@ -60,7 +55,6 @@ public class TomcatServletWebServerFactoryCustomizer
|
||||
}
|
||||
customizeUseRelativeRedirects(factory, tomcatProperties.isUseRelativeRedirects());
|
||||
factory.setDisableMBeanRegistry(!tomcatProperties.getMbeanregistry().isEnabled());
|
||||
factory.setUseApr(getUseApr(tomcatProperties.getUseApr()));
|
||||
}
|
||||
|
||||
private void customizeRedirectContextRoot(ConfigurableTomcatWebServerFactory factory, boolean redirectContextRoot) {
|
||||
@@ -72,22 +66,4 @@ public class TomcatServletWebServerFactoryCustomizer
|
||||
factory.addContextCustomizers((context) -> context.setUseRelativeRedirects(useRelativeRedirects));
|
||||
}
|
||||
|
||||
private boolean getUseApr(UseApr useApr) {
|
||||
return switch (useApr) {
|
||||
case ALWAYS -> {
|
||||
Assert.state(isAprAvailable(), "APR has been configured to 'ALWAYS', but it's not available");
|
||||
yield true;
|
||||
}
|
||||
case WHEN_AVAILABLE -> isAprAvailable();
|
||||
case NEVER -> false;
|
||||
};
|
||||
}
|
||||
|
||||
private boolean isAprAvailable() {
|
||||
// At least one instance of AprLifecycleListener has to be created for
|
||||
// isAprAvailable() to work
|
||||
new AprLifecycleListener();
|
||||
return AprLifecycleListener.isAprAvailable();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Classes related to the auto-configuration of a servlet web server using Tomcat.
|
||||
*/
|
||||
package org.springframework.boot.autoconfigure.web.server.servlet.tomcat;
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.server.servlet.undertow;
|
||||
|
||||
import io.undertow.Undertow;
|
||||
import io.undertow.websockets.jsr.Bootstrap;
|
||||
import jakarta.servlet.ServletRequest;
|
||||
import org.xnio.SslClientAuthMode;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
|
||||
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.autoconfigure.web.server.servlet.ServletWebServerConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.server.undertow.UndertowWebServerConfiguration;
|
||||
import org.springframework.boot.web.server.servlet.ServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.servlet.undertow.UndertowDeploymentInfoCustomizer;
|
||||
import org.springframework.boot.web.server.servlet.undertow.UndertowServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.undertow.UndertowBuilderCustomizer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for an Undertow-based servlet web
|
||||
* server.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 4.0.0
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@ConditionalOnClass({ ServletRequest.class, Undertow.class, SslClientAuthMode.class })
|
||||
@ConditionalOnWebApplication(type = Type.SERVLET)
|
||||
@Import({ UndertowWebServerConfiguration.class, ServletWebServerConfiguration.class })
|
||||
public class UndertowServletWebServerAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT)
|
||||
UndertowServletWebServerFactory undertowServletWebServerFactory(
|
||||
ObjectProvider<UndertowDeploymentInfoCustomizer> deploymentInfoCustomizers,
|
||||
ObjectProvider<UndertowBuilderCustomizer> builderCustomizers) {
|
||||
UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory();
|
||||
factory.getDeploymentInfoCustomizers().addAll(deploymentInfoCustomizers.orderedStream().toList());
|
||||
factory.getBuilderCustomizers().addAll(builderCustomizers.orderedStream().toList());
|
||||
return factory;
|
||||
}
|
||||
|
||||
@Bean
|
||||
UndertowServletWebServerFactoryCustomizer undertowServletWebServerFactoryCustomizer(
|
||||
ServerProperties serverProperties) {
|
||||
return new UndertowServletWebServerFactoryCustomizer(serverProperties);
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(Bootstrap.class)
|
||||
static class UndertowWebSocketConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = "websocketServletWebServerCustomizer")
|
||||
WebSocketUndertowServletWebServerFactoryCustomizer websocketServletWebServerCustomizer() {
|
||||
return new WebSocketUndertowServletWebServerFactoryCustomizer();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -14,25 +14,23 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.web.servlet;
|
||||
package org.springframework.boot.autoconfigure.web.server.servlet.undertow;
|
||||
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.boot.web.server.servlet.undertow.UndertowServletWebServerFactory;
|
||||
|
||||
/**
|
||||
* {@link WebServerFactoryCustomizer} to apply {@link ServerProperties} to Undertow
|
||||
* Servlet web servers.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 2.1.7
|
||||
*/
|
||||
public class UndertowServletWebServerFactoryCustomizer
|
||||
implements WebServerFactoryCustomizer<UndertowServletWebServerFactory> {
|
||||
class UndertowServletWebServerFactoryCustomizer implements WebServerFactoryCustomizer<UndertowServletWebServerFactory> {
|
||||
|
||||
private final ServerProperties serverProperties;
|
||||
|
||||
public UndertowServletWebServerFactoryCustomizer(ServerProperties serverProperties) {
|
||||
UndertowServletWebServerFactoryCustomizer(ServerProperties serverProperties) {
|
||||
this.serverProperties = serverProperties;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -14,14 +14,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.websocket.servlet;
|
||||
package org.springframework.boot.autoconfigure.web.server.servlet.undertow;
|
||||
|
||||
import io.undertow.servlet.api.DeploymentInfo;
|
||||
import io.undertow.websockets.jsr.WebSocketDeploymentInfo;
|
||||
|
||||
import org.springframework.boot.web.embedded.undertow.UndertowDeploymentInfoCustomizer;
|
||||
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.boot.web.server.servlet.undertow.UndertowDeploymentInfoCustomizer;
|
||||
import org.springframework.boot.web.server.servlet.undertow.UndertowServletWebServerFactory;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
/**
|
||||
@@ -30,7 +30,7 @@ import org.springframework.core.Ordered;
|
||||
* @author Phillip Webb
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class UndertowWebSocketServletWebServerCustomizer
|
||||
public class WebSocketUndertowServletWebServerFactoryCustomizer
|
||||
implements WebServerFactoryCustomizer<UndertowServletWebServerFactory>, Ordered {
|
||||
|
||||
@Override
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Classes related to the auto-configuration of a servlet web server using Undertow.
|
||||
*/
|
||||
package org.springframework.boot.autoconfigure.web.server.servlet.undertow;
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -14,13 +14,13 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.web.embedded;
|
||||
package org.springframework.boot.autoconfigure.web.server.tomcat;
|
||||
|
||||
import org.apache.coyote.ProtocolHandler;
|
||||
import org.apache.tomcat.util.threads.VirtualThreadExecutor;
|
||||
|
||||
import org.springframework.boot.web.embedded.tomcat.ConfigurableTomcatWebServerFactory;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.boot.web.server.tomcat.ConfigurableTomcatWebServerFactory;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
/**
|
||||
@@ -28,7 +28,7 @@ import org.springframework.core.Ordered;
|
||||
* handler}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
* @since 3.2.0
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public class TomcatVirtualThreadsWebServerFactoryCustomizer
|
||||
implements WebServerFactoryCustomizer<ConfigurableTomcatWebServerFactory>, Ordered {
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.server.tomcat;
|
||||
|
||||
import org.apache.tomcat.websocket.server.WsSci;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnNotWarDeployment;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnThreading;
|
||||
import org.springframework.boot.autoconfigure.thread.Threading;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.autoconfigure.web.server.reactive.tomcat.TomcatReactiveWebServerAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.server.servlet.tomcat.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
/**
|
||||
* {@link Configuration Configuration} for a Tomcat-based reactive or servlet web server.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 4.0.0
|
||||
* @see TomcatReactiveWebServerAutoConfiguration
|
||||
* @see TomcatServletWebServerAutoConfiguration
|
||||
*/
|
||||
@ConditionalOnNotWarDeployment
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public class TomcatWebServerConfiguration {
|
||||
|
||||
@Bean
|
||||
TomcatWebServerFactoryCustomizer tomcatWebServerFactoryCustomizer(Environment environment,
|
||||
ServerProperties serverProperties) {
|
||||
return new TomcatWebServerFactoryCustomizer(environment, serverProperties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnThreading(Threading.VIRTUAL)
|
||||
TomcatVirtualThreadsWebServerFactoryCustomizer tomcatVirtualThreadsProtocolHandlerCustomizer() {
|
||||
return new TomcatVirtualThreadsWebServerFactoryCustomizer();
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(WsSci.class)
|
||||
static class TomcatWebSocketConfiguration {
|
||||
|
||||
@Bean
|
||||
WebSocketTomcatWebServerFactoryCustomizer webSocketWebServerCustomizer() {
|
||||
return new WebSocketTomcatWebServerFactoryCustomizer();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.web.embedded;
|
||||
package org.springframework.boot.autoconfigure.web.server.tomcat;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
@@ -22,6 +22,7 @@ import java.util.function.ObjIntConsumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.catalina.Lifecycle;
|
||||
import org.apache.catalina.core.AprLifecycleListener;
|
||||
import org.apache.catalina.valves.AccessLogValve;
|
||||
import org.apache.catalina.valves.ErrorReportValve;
|
||||
import org.apache.catalina.valves.RemoteIpValve;
|
||||
@@ -36,18 +37,19 @@ import org.springframework.boot.autoconfigure.web.ErrorProperties.IncludeAttribu
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties.Tomcat.Accesslog;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties.Tomcat.Remoteip;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties.Tomcat.UseApr;
|
||||
import org.springframework.boot.cloud.CloudPlatform;
|
||||
import org.springframework.boot.context.properties.PropertyMapper;
|
||||
import org.springframework.boot.web.embedded.tomcat.ConfigurableTomcatWebServerFactory;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.boot.web.server.tomcat.ConfigurableTomcatWebServerFactory;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.unit.DataSize;
|
||||
|
||||
/**
|
||||
* Customization for Tomcat-specific features common for both Servlet and Reactive
|
||||
* servers.
|
||||
* Customization for Tomcat-specific features common to both Servlet and Reactive servers.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Yulin Qin
|
||||
@@ -62,7 +64,7 @@ import org.springframework.util.unit.DataSize;
|
||||
* @author Parviz Rozikov
|
||||
* @author Florian Storz
|
||||
* @author Michael Weidmann
|
||||
* @since 2.0.0
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public class TomcatWebServerFactoryCustomizer
|
||||
implements WebServerFactoryCustomizer<ConfigurableTomcatWebServerFactory>, Ordered {
|
||||
@@ -149,6 +151,25 @@ public class TomcatWebServerFactoryCustomizer
|
||||
.to((relaxedChars) -> customizeRelaxedQueryChars(factory, relaxedChars));
|
||||
customizeStaticResources(factory);
|
||||
customizeErrorReportValve(this.serverProperties.getError(), factory);
|
||||
factory.setUseApr(getUseApr(this.serverProperties.getTomcat().getUseApr()));
|
||||
}
|
||||
|
||||
private boolean getUseApr(UseApr useApr) {
|
||||
return switch (useApr) {
|
||||
case ALWAYS -> {
|
||||
Assert.state(isAprAvailable(), "APR has been configured to 'ALWAYS', but it's not available");
|
||||
yield true;
|
||||
}
|
||||
case WHEN_AVAILABLE -> isAprAvailable();
|
||||
case NEVER -> false;
|
||||
};
|
||||
}
|
||||
|
||||
private boolean isAprAvailable() {
|
||||
// At least one instance of AprLifecycleListener has to be created for
|
||||
// isAprAvailable() to work
|
||||
new AprLifecycleListener();
|
||||
return AprLifecycleListener.isAprAvailable();
|
||||
}
|
||||
|
||||
private boolean isPositive(int value) {
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -14,33 +14,25 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.websocket.servlet;
|
||||
package org.springframework.boot.autoconfigure.web.server.tomcat;
|
||||
|
||||
import org.apache.tomcat.websocket.server.WsSci;
|
||||
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.boot.web.server.tomcat.ConfigurableTomcatWebServerFactory;
|
||||
|
||||
/**
|
||||
* WebSocket customizer for {@link TomcatServletWebServerFactory}.
|
||||
* {@link WebServerFactoryCustomizer} that configures Tomcat's WebSocket support.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
* @since 2.0.0
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public class TomcatWebSocketServletWebServerCustomizer
|
||||
implements WebServerFactoryCustomizer<TomcatServletWebServerFactory>, Ordered {
|
||||
public class WebSocketTomcatWebServerFactoryCustomizer
|
||||
implements WebServerFactoryCustomizer<ConfigurableTomcatWebServerFactory> {
|
||||
|
||||
@Override
|
||||
public void customize(TomcatServletWebServerFactory factory) {
|
||||
public void customize(ConfigurableTomcatWebServerFactory factory) {
|
||||
factory.addContextCustomizers((context) -> context.addServletContainerInitializer(new WsSci(), null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Classes related to the auto-configuration of a servlet or reactive web server using
|
||||
* Tomcat.
|
||||
*/
|
||||
package org.springframework.boot.autoconfigure.web.server.tomcat;
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.server.undertow;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnNotWarDeployment;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnThreading;
|
||||
import org.springframework.boot.autoconfigure.thread.Threading;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.web.server.servlet.undertow.UndertowDeploymentInfoCustomizer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.task.VirtualThreadTaskExecutor;
|
||||
|
||||
/**
|
||||
* {@link Configuration Configuration} for an Undertow-based reactive or servlet web
|
||||
* server.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 4.0.0
|
||||
*/
|
||||
@ConditionalOnNotWarDeployment
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public class UndertowWebServerConfiguration {
|
||||
|
||||
@Bean
|
||||
UndertowWebServerFactoryCustomizer undertowWebServerFactoryCustomizer(Environment environment,
|
||||
ServerProperties serverProperties) {
|
||||
return new UndertowWebServerFactoryCustomizer(environment, serverProperties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnThreading(Threading.VIRTUAL)
|
||||
UndertowDeploymentInfoCustomizer virtualThreadsUndertowDeploymentInfoCustomizer() {
|
||||
return (deploymentInfo) -> deploymentInfo.setExecutor(new VirtualThreadTaskExecutor("undertow-"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.web.embedded;
|
||||
package org.springframework.boot.autoconfigure.web.server.undertow;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.nio.charset.Charset;
|
||||
@@ -34,8 +34,8 @@ import org.springframework.boot.autoconfigure.web.ServerProperties.Undertow;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties.Undertow.Accesslog;
|
||||
import org.springframework.boot.cloud.CloudPlatform;
|
||||
import org.springframework.boot.context.properties.PropertyMapper;
|
||||
import org.springframework.boot.web.embedded.undertow.ConfigurableUndertowWebServerFactory;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.boot.web.server.undertow.ConfigurableUndertowWebServerFactory;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -54,7 +54,7 @@ import org.springframework.util.unit.DataSize;
|
||||
* @author Arstiom Yudovin
|
||||
* @author Rafiullah Hamedy
|
||||
* @author HaiTao Zhang
|
||||
* @since 2.0.0
|
||||
* @since 4.0.0
|
||||
*/
|
||||
public class UndertowWebServerFactoryCustomizer
|
||||
implements WebServerFactoryCustomizer<ConfigurableUndertowWebServerFactory>, Ordered {
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Classes related to the auto-configuration of a servlet or reactive web server using
|
||||
* Undertow.
|
||||
*/
|
||||
package org.springframework.boot.autoconfigure.web.server.undertow;
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -63,7 +63,7 @@ import org.springframework.web.servlet.DispatcherServlet;
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
|
||||
@AutoConfiguration(after = ServletWebServerFactoryAutoConfiguration.class)
|
||||
@AutoConfiguration
|
||||
@ConditionalOnWebApplication(type = Type.SERVLET)
|
||||
@ConditionalOnClass(DispatcherServlet.class)
|
||||
public class DispatcherServletAutoConfiguration {
|
||||
|
||||
@@ -1,126 +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.servlet;
|
||||
|
||||
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.xnio.SslClientAuthMode;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer;
|
||||
import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.undertow.UndertowBuilderCustomizer;
|
||||
import org.springframework.boot.web.embedded.undertow.UndertowDeploymentInfoCustomizer;
|
||||
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
|
||||
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Configuration classes for servlet web servers
|
||||
* <p>
|
||||
* Those should be {@code @Import} in a regular auto-configuration class to guarantee
|
||||
* their order of execution.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Dave Syer
|
||||
* @author Ivan Sopov
|
||||
* @author Brian Clozel
|
||||
* @author Stephane Nicoll
|
||||
* @author Raheela Asalm
|
||||
* @author Sergey Serdyuk
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
class ServletWebServerFactoryConfiguration {
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass({ Servlet.class, Tomcat.class, UpgradeProtocol.class })
|
||||
@ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT)
|
||||
static class EmbeddedTomcat {
|
||||
|
||||
@Bean
|
||||
TomcatServletWebServerFactory tomcatServletWebServerFactory(
|
||||
ObjectProvider<TomcatConnectorCustomizer> connectorCustomizers,
|
||||
ObjectProvider<TomcatContextCustomizer> contextCustomizers,
|
||||
ObjectProvider<TomcatProtocolHandlerCustomizer<?>> protocolHandlerCustomizers) {
|
||||
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
|
||||
factory.getTomcatConnectorCustomizers().addAll(connectorCustomizers.orderedStream().toList());
|
||||
factory.getTomcatContextCustomizers().addAll(contextCustomizers.orderedStream().toList());
|
||||
factory.getTomcatProtocolHandlerCustomizers().addAll(protocolHandlerCustomizers.orderedStream().toList());
|
||||
return factory;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Nested configuration if Jetty is being used.
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass({ Servlet.class, Server.class, Loader.class, WebAppContext.class })
|
||||
@ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT)
|
||||
static class EmbeddedJetty {
|
||||
|
||||
@Bean
|
||||
JettyServletWebServerFactory jettyServletWebServerFactory(
|
||||
ObjectProvider<JettyServerCustomizer> serverCustomizers) {
|
||||
JettyServletWebServerFactory factory = new JettyServletWebServerFactory();
|
||||
factory.getServerCustomizers().addAll(serverCustomizers.orderedStream().toList());
|
||||
return factory;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Nested configuration if Undertow is being used.
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass({ Servlet.class, Undertow.class, SslClientAuthMode.class })
|
||||
@ConditionalOnMissingBean(value = ServletWebServerFactory.class, search = SearchStrategy.CURRENT)
|
||||
static class EmbeddedUndertow {
|
||||
|
||||
@Bean
|
||||
UndertowServletWebServerFactory undertowServletWebServerFactory(
|
||||
ObjectProvider<UndertowDeploymentInfoCustomizer> deploymentInfoCustomizers,
|
||||
ObjectProvider<UndertowBuilderCustomizer> builderCustomizers) {
|
||||
UndertowServletWebServerFactory factory = new UndertowServletWebServerFactory();
|
||||
factory.getDeploymentInfoCustomizers().addAll(deploymentInfoCustomizers.orderedStream().toList());
|
||||
factory.getBuilderCustomizers().addAll(builderCustomizers.orderedStream().toList());
|
||||
return factory;
|
||||
}
|
||||
|
||||
@Bean
|
||||
UndertowServletWebServerFactoryCustomizer undertowServletWebServerFactoryCustomizer(
|
||||
ServerProperties serverProperties) {
|
||||
return new UndertowServletWebServerFactoryCustomizer(serverProperties);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,8 +26,8 @@ import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.boot.autoconfigure.web.ErrorProperties;
|
||||
import org.springframework.boot.web.error.ErrorAttributeOptions;
|
||||
import org.springframework.boot.web.error.ErrorAttributeOptions.Include;
|
||||
import org.springframework.boot.web.server.servlet.ConfigurableServletWebServerFactory;
|
||||
import org.springframework.boot.web.servlet.error.ErrorAttributes;
|
||||
import org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
@@ -42,7 +42,7 @@ import org.springframework.web.servlet.ModelAndView;
|
||||
* Basic global error {@link Controller @Controller}, rendering {@link ErrorAttributes}.
|
||||
* More specific errors can be handled either using Spring MVC abstractions (e.g.
|
||||
* {@code @ExceptionHandler}) or by adding servlet
|
||||
* {@link AbstractServletWebServerFactory#setErrorPages server error pages}.
|
||||
* {@link ConfigurableServletWebServerFactory#setErrorPages server error pages}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Phillip Webb
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -33,7 +33,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.boot.context.properties.bind.Bindable;
|
||||
import org.springframework.boot.context.properties.bind.Binder;
|
||||
@@ -59,7 +58,7 @@ import org.springframework.xml.xsd.SimpleXsdSchema;
|
||||
* @author Stephane Nicoll
|
||||
* @since 1.4.0
|
||||
*/
|
||||
@AutoConfiguration(after = ServletWebServerFactoryAutoConfiguration.class)
|
||||
@AutoConfiguration
|
||||
@ConditionalOnWebApplication(type = Type.SERVLET)
|
||||
@ConditionalOnClass(MessageDispatcherServlet.class)
|
||||
@ConditionalOnMissingBean(WsConfigurationSupport.class)
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* 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.websocket.reactive;
|
||||
|
||||
import org.apache.tomcat.websocket.server.WsSci;
|
||||
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
/**
|
||||
* WebSocket customizer for {@link TomcatReactiveWebServerFactory}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class TomcatWebSocketReactiveWebServerCustomizer
|
||||
implements WebServerFactoryCustomizer<TomcatReactiveWebServerFactory>, Ordered {
|
||||
|
||||
@Override
|
||||
public void customize(TomcatReactiveWebServerFactory factory) {
|
||||
factory.addContextCustomizers((context) -> context.addServletContainerInitializer(new WsSci(), null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,73 +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.websocket.reactive;
|
||||
|
||||
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.ee10.websocket.jakarta.server.config.JakartaWebSocketServletContainerInitializer;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
|
||||
import org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Auto-configuration for WebSocket reactive server in Tomcat, Jetty or Undertow. Requires
|
||||
* the appropriate WebSocket modules to be on the classpath.
|
||||
* <p>
|
||||
* If Tomcat's WebSocket support is detected on the classpath we add a customizer that
|
||||
* installs the Tomcat WebSocket initializer.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@AutoConfiguration(before = ReactiveWebServerFactoryAutoConfiguration.class)
|
||||
@ConditionalOnClass({ Servlet.class, ServerContainer.class })
|
||||
@ConditionalOnWebApplication(type = Type.REACTIVE)
|
||||
public class WebSocketReactiveAutoConfiguration {
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass({ Tomcat.class, WsSci.class })
|
||||
static class TomcatWebSocketConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = "websocketReactiveWebServerCustomizer")
|
||||
TomcatWebSocketReactiveWebServerCustomizer websocketReactiveWebServerCustomizer() {
|
||||
return new TomcatWebSocketReactiveWebServerCustomizer();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass(JakartaWebSocketServletContainerInitializer.class)
|
||||
static class JettyWebSocketConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = "websocketReactiveWebServerCustomizer")
|
||||
JettyWebSocketReactiveWebServerCustomizer websocketServletWebServerCustomizer() {
|
||||
return new JettyWebSocketReactiveWebServerCustomizer();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -136,23 +136,26 @@ org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.web.reactive.ReactiveMultipartAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.web.reactive.WebSessionIdResolverAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.web.server.reactive.jetty.JettyReactiveWebServerAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.web.server.reactive.netty.NettyReactiveWebServerAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.web.server.reactive.tomcat.TomcatReactiveWebServerAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.web.server.reactive.undertow.UndertowReactiveWebServerAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.web.server.servlet.jetty.JettyServletWebServerAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.web.server.servlet.tomcat.TomcatServletWebServerAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.web.server.servlet.undertow.UndertowServletWebServerAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration
|
||||
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -31,8 +31,8 @@ import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.admin.SpringApplicationAdminMXBeanRegistrar;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.web.server.servlet.tomcat.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext;
|
||||
@@ -111,7 +111,7 @@ class SpringApplicationAdminJmxAutoConfigurationTests {
|
||||
@Test
|
||||
void registerWithSimpleWebApp() throws Exception {
|
||||
try (ConfigurableApplicationContext context = new SpringApplicationBuilder()
|
||||
.sources(ServletWebServerFactoryAutoConfiguration.class, DispatcherServletAutoConfiguration.class,
|
||||
.sources(TomcatServletWebServerAutoConfiguration.class, DispatcherServletAutoConfiguration.class,
|
||||
MultipleMBeanExportersConfiguration.class, SpringApplicationAdminJmxAutoConfiguration.class)
|
||||
.run("--" + ENABLE_ADMIN_PROP, "--server.port=0")) {
|
||||
assertThat(context).isInstanceOf(ServletWebServerApplicationContext.class);
|
||||
|
||||
@@ -22,8 +22,8 @@ import reactor.core.publisher.Mono;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.boot.web.reactive.server.MockReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.server.reactive.MockReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.server.reactive.ReactiveWebServerFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.server.reactive.HttpHandler;
|
||||
|
||||
@@ -22,8 +22,8 @@ import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
|
||||
import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebApplicationContext;
|
||||
import org.springframework.boot.web.reactive.server.MockReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.server.reactive.MockReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.server.reactive.ReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
|
||||
@@ -38,9 +38,9 @@ import org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContex
|
||||
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
|
||||
import org.springframework.boot.testsupport.classpath.resources.WithResource;
|
||||
import org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer;
|
||||
import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.netty.NettyRouteProvider;
|
||||
import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext;
|
||||
import org.springframework.boot.web.server.reactive.netty.NettyReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.server.reactive.netty.NettyRouteProvider;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.graphql.client.RSocketGraphQlClient;
|
||||
|
||||
@@ -30,7 +30,7 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.server.servlet.tomcat.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.context.properties.ConfigurationPropertiesBindException;
|
||||
import org.springframework.boot.context.properties.bind.BindException;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
@@ -185,7 +185,7 @@ class H2ConsoleAutoConfigurationTests {
|
||||
void dataSourceIsNotInitializedEarly(CapturedOutput output) {
|
||||
new WebApplicationContextRunner(AnnotationConfigServletWebServerApplicationContext::new)
|
||||
.withConfiguration(AutoConfigurations.of(H2ConsoleAutoConfiguration.class,
|
||||
ServletWebServerFactoryAutoConfiguration.class))
|
||||
TomcatServletWebServerAutoConfiguration.class))
|
||||
.withUserConfiguration(EarlyInitializationConfiguration.class)
|
||||
.withPropertyValues("spring.h2.console.enabled=true", "server.port=0")
|
||||
.run((context) -> {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -25,7 +25,7 @@ import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.server.servlet.tomcat.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
@@ -72,7 +72,7 @@ class JerseyAutoConfigurationCustomApplicationTests {
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
@Import({ TomcatServletWebServerAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
static class TestConfiguration {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -32,7 +32,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.server.servlet.tomcat.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
@@ -91,7 +91,7 @@ class JerseyAutoConfigurationCustomFilterContextPathTests {
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Configuration
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
@Import({ TomcatServletWebServerAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -32,7 +32,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.server.servlet.tomcat.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
@@ -90,7 +90,7 @@ class JerseyAutoConfigurationCustomFilterPathTests {
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Configuration
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
@Import({ TomcatServletWebServerAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -27,7 +27,7 @@ import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.server.servlet.tomcat.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
@@ -67,7 +67,7 @@ class JerseyAutoConfigurationCustomLoadOnStartupTests {
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Configuration
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
@Import({ JerseyAutoConfiguration.class, TomcatServletWebServerAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -32,7 +32,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.server.servlet.tomcat.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
@@ -117,7 +117,7 @@ class JerseyAutoConfigurationCustomObjectMapperProviderTests {
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Configuration
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JacksonAutoConfiguration.class,
|
||||
@Import({ TomcatServletWebServerAutoConfiguration.class, JacksonAutoConfiguration.class,
|
||||
JerseyAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -32,7 +32,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.server.servlet.tomcat.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
@@ -89,7 +89,7 @@ class JerseyAutoConfigurationCustomServletContextPathTests {
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Configuration
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
@Import({ TomcatServletWebServerAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -32,7 +32,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.server.servlet.tomcat.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
@@ -89,7 +89,7 @@ class JerseyAutoConfigurationCustomServletPathTests {
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Configuration
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
@Import({ TomcatServletWebServerAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -31,7 +31,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.server.servlet.tomcat.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
@@ -88,7 +88,7 @@ class JerseyAutoConfigurationDefaultFilterPathTests {
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Configuration
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
@Import({ TomcatServletWebServerAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -31,7 +31,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.server.servlet.tomcat.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
@@ -87,7 +87,7 @@ class JerseyAutoConfigurationDefaultServletPathTests {
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Configuration
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
@Import({ TomcatServletWebServerAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -33,7 +33,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.server.servlet.tomcat.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
@@ -127,7 +127,7 @@ class JerseyAutoConfigurationObjectMapperProviderTests {
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Configuration
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JacksonAutoConfiguration.class,
|
||||
@Import({ TomcatServletWebServerAutoConfiguration.class, JacksonAutoConfiguration.class,
|
||||
JerseyAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -32,12 +32,12 @@ import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jersey.JerseyAutoConfigurationServletContainerTests.Application;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.server.servlet.tomcat.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.system.CapturedOutput;
|
||||
import org.springframework.boot.test.system.OutputCaptureExtension;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.servlet.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
@@ -62,7 +62,7 @@ class JerseyAutoConfigurationServletContainerTests {
|
||||
assertThat(output).contains("Servlet " + Application.class.getName() + " was not registered");
|
||||
}
|
||||
|
||||
@ImportAutoConfiguration({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
@ImportAutoConfiguration({ TomcatServletWebServerAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
@Import(ContainerConfiguration.class)
|
||||
@Path("/hello")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2022 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -31,7 +31,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.server.servlet.tomcat.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
@@ -87,7 +87,7 @@ class JerseyAutoConfigurationWithoutApplicationPathTests {
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Configuration
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
@Import({ TomcatServletWebServerAutoConfiguration.class, JerseyAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
|
||||
@@ -26,8 +26,8 @@ import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.WebApplicationType;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.server.reactive.netty.NettyReactiveWebServerAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.web.reactive.result.view.MustacheView;
|
||||
@@ -81,7 +81,7 @@ class MustacheAutoConfigurationReactiveIntegrationTests {
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@Import({ ReactiveWebServerFactoryAutoConfiguration.class, WebFluxAutoConfiguration.class,
|
||||
@Import({ NettyReactiveWebServerAutoConfiguration.class, WebFluxAutoConfiguration.class,
|
||||
HttpHandlerAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class })
|
||||
@Controller
|
||||
static class Application {
|
||||
|
||||
@@ -33,8 +33,8 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.server.servlet.tomcat.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
@@ -132,7 +132,7 @@ class MustacheAutoConfigurationServletIntegrationTests {
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Import({ ServletWebServerFactoryAutoConfiguration.class, DispatcherServletAutoConfiguration.class,
|
||||
@Import({ TomcatServletWebServerAutoConfiguration.class, DispatcherServletAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class })
|
||||
protected @interface MinimalWebConfiguration {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -29,10 +29,10 @@ import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfig
|
||||
import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration;
|
||||
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
|
||||
import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext;
|
||||
import org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext;
|
||||
import org.springframework.boot.web.server.WebServer;
|
||||
import org.springframework.boot.web.server.reactive.netty.NettyReactiveWebServerFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@@ -27,7 +27,7 @@ import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguratio
|
||||
import org.springframework.boot.test.context.FilteredClassLoader;
|
||||
import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.servlet.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -39,7 +39,7 @@ import org.springframework.boot.test.util.TestPropertyValues;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.boot.testsupport.classpath.ClassPathExclusions;
|
||||
import org.springframework.boot.testsupport.web.servlet.DirtiesUrlFactories;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.servlet.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplic
|
||||
import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext;
|
||||
import org.springframework.boot.test.context.runner.ContextConsumer;
|
||||
import org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext;
|
||||
import org.springframework.boot.web.reactive.server.MockReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.server.reactive.MockReactiveWebServerFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
|
||||
|
||||
@@ -21,7 +21,7 @@ import java.util.LinkedHashMap;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.server.servlet.tomcat.TomcatServletWebServerAutoConfiguration;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
@@ -52,7 +52,7 @@ class SessionAutoConfigurationEarlyInitializationIntegrationTests {
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableSpringHttpSession
|
||||
@ImportAutoConfiguration({ ServletWebServerFactoryAutoConfiguration.class, SessionAutoConfiguration.class })
|
||||
@ImportAutoConfiguration({ TomcatServletWebServerAutoConfiguration.class, SessionAutoConfiguration.class })
|
||||
static class TestConfiguration {
|
||||
|
||||
@Bean
|
||||
|
||||
@@ -44,11 +44,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.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.server.MimeMappings;
|
||||
import org.springframework.boot.web.server.MimeMappings.Mapping;
|
||||
import org.springframework.boot.web.server.jetty.JettyWebServer;
|
||||
import org.springframework.boot.web.server.servlet.jetty.JettyServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.servlet.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import org.springframework.util.unit.DataSize;
|
||||
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2024 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.embedded;
|
||||
|
||||
import io.undertow.servlet.api.DeploymentInfo;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.EnabledForJreRange;
|
||||
import org.junit.jupiter.api.condition.JRE;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration.UndertowWebServerFactoryCustomizerConfiguration;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.boot.web.embedded.undertow.UndertowDeploymentInfoCustomizer;
|
||||
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebApplicationContext;
|
||||
import org.springframework.core.task.VirtualThreadTaskExecutor;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link UndertowWebServerFactoryCustomizerConfiguration}.
|
||||
*
|
||||
* @author Moritz Halbritter
|
||||
*/
|
||||
class UndertowWebServerFactoryCustomizerConfigurationTests {
|
||||
|
||||
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner(
|
||||
AnnotationConfigServletWebApplicationContext::new)
|
||||
.withConfiguration(AutoConfigurations.of(EmbeddedWebServerFactoryCustomizerAutoConfiguration.class));
|
||||
|
||||
@EnabledForJreRange(min = JRE.JAVA_21)
|
||||
@Test
|
||||
void shouldUseVirtualThreadsIfEnabled() {
|
||||
this.contextRunner.withPropertyValues("spring.threads.virtual.enabled=true").run((context) -> {
|
||||
assertThat(context).hasSingleBean(UndertowDeploymentInfoCustomizer.class);
|
||||
assertThat(context).hasBean("virtualThreadsUndertowDeploymentInfoCustomizer");
|
||||
UndertowDeploymentInfoCustomizer customizer = context.getBean(UndertowDeploymentInfoCustomizer.class);
|
||||
DeploymentInfo deploymentInfo = new DeploymentInfo();
|
||||
customizer.customize(deploymentInfo);
|
||||
assertThat(deploymentInfo.getExecutor()).isInstanceOf(VirtualThreadTaskExecutor.class);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,569 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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;
|
||||
|
||||
import io.undertow.Undertow;
|
||||
import io.undertow.Undertow.Builder;
|
||||
import org.apache.catalina.Context;
|
||||
import org.apache.catalina.connector.Connector;
|
||||
import org.apache.catalina.startup.Tomcat;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import reactor.netty.http.server.HttpServer;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.ssl.SslAutoConfiguration;
|
||||
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.web.embedded.jetty.JettyReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer;
|
||||
import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.netty.NettyServerCustomizer;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.undertow.UndertowBuilderCustomizer;
|
||||
import org.springframework.boot.web.embedded.undertow.UndertowDeploymentInfoCustomizer;
|
||||
import org.springframework.boot.web.embedded.undertow.UndertowReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebApplicationContext;
|
||||
import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext;
|
||||
import org.springframework.boot.web.reactive.server.ConfigurableReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.reactive.server.MockReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.context.ApplicationContextException;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.server.reactive.HttpHandler;
|
||||
import org.springframework.web.server.adapter.ForwardedHeaderTransformer;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.BDDMockito.then;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link ReactiveWebServerFactoryAutoConfiguration}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Raheela Aslam
|
||||
* @author Madhura Bhave
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
@DirtiesUrlFactories
|
||||
class ReactiveWebServerFactoryAutoConfigurationTests {
|
||||
|
||||
private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner(
|
||||
AnnotationConfigReactiveWebServerApplicationContext::new)
|
||||
.withConfiguration(
|
||||
AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class, SslAutoConfiguration.class));
|
||||
|
||||
@Test
|
||||
void createFromConfigClass() {
|
||||
this.contextRunner.withUserConfiguration(MockWebServerConfiguration.class, HttpHandlerConfiguration.class)
|
||||
.run((context) -> {
|
||||
assertThat(context.getBeansOfType(ReactiveWebServerFactory.class)).hasSize(1);
|
||||
assertThat(context.getBeansOfType(WebServerFactoryCustomizer.class)).hasSize(2);
|
||||
assertThat(context.getBeansOfType(ReactiveWebServerFactoryCustomizer.class)).hasSize(1);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void missingHttpHandler() {
|
||||
this.contextRunner.withUserConfiguration(MockWebServerConfiguration.class)
|
||||
.run((context) -> assertThat(context.getStartupFailure()).isInstanceOf(ApplicationContextException.class)
|
||||
.rootCause()
|
||||
.hasMessageContaining("missing HttpHandler bean"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void multipleHttpHandler() {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(MockWebServerConfiguration.class, HttpHandlerConfiguration.class,
|
||||
TooManyHttpHandlers.class)
|
||||
.run((context) -> assertThat(context.getStartupFailure()).isInstanceOf(ApplicationContextException.class)
|
||||
.rootCause()
|
||||
.hasMessageContaining("multiple HttpHandler beans : httpHandler,additionalHttpHandler"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void customizeReactiveWebServer() {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(MockWebServerConfiguration.class, HttpHandlerConfiguration.class,
|
||||
ReactiveWebServerCustomization.class)
|
||||
.run((context) -> assertThat(context.getBean(MockReactiveWebServerFactory.class).getPort())
|
||||
.isEqualTo(9000));
|
||||
}
|
||||
|
||||
@Test
|
||||
void defaultWebServerIsTomcat() {
|
||||
// Tomcat should be chosen over Netty if the Tomcat library is present.
|
||||
this.contextRunner.withUserConfiguration(HttpHandlerConfiguration.class)
|
||||
.withPropertyValues("server.port=0")
|
||||
.run((context) -> assertThat(context.getBean(ReactiveWebServerFactory.class))
|
||||
.isInstanceOf(TomcatReactiveWebServerFactory.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void webServerFailsWithInvalidSslBundle() {
|
||||
this.contextRunner.withUserConfiguration(HttpHandlerConfiguration.class)
|
||||
.withPropertyValues("server.port=0", "server.ssl.bundle=test-bundle")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasFailed();
|
||||
assertThat(context.getStartupFailure().getCause()).isInstanceOf(NoSuchSslBundleException.class)
|
||||
.withFailMessage("test");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void tomcatConnectorCustomizerBeanIsAddedToFactory() {
|
||||
ReactiveWebApplicationContextRunner runner = new ReactiveWebApplicationContextRunner(
|
||||
AnnotationConfigReactiveWebServerApplicationContext::new)
|
||||
.withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class))
|
||||
.withUserConfiguration(HttpHandlerConfiguration.class, TomcatConnectorCustomizerConfiguration.class)
|
||||
.withPropertyValues("server.port: 0");
|
||||
runner.run((context) -> {
|
||||
TomcatReactiveWebServerFactory factory = context.getBean(TomcatReactiveWebServerFactory.class);
|
||||
TomcatConnectorCustomizer customizer = context.getBean("connectorCustomizer",
|
||||
TomcatConnectorCustomizer.class);
|
||||
assertThat(factory.getTomcatConnectorCustomizers()).contains(customizer);
|
||||
then(customizer).should().customize(any(Connector.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void tomcatConnectorCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() {
|
||||
ReactiveWebApplicationContextRunner runner = new ReactiveWebApplicationContextRunner(
|
||||
AnnotationConfigReactiveWebServerApplicationContext::new)
|
||||
.withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class))
|
||||
.withUserConfiguration(HttpHandlerConfiguration.class,
|
||||
DoubleRegistrationTomcatConnectorCustomizerConfiguration.class)
|
||||
.withPropertyValues("server.port: 0");
|
||||
runner.run((context) -> {
|
||||
TomcatReactiveWebServerFactory factory = context.getBean(TomcatReactiveWebServerFactory.class);
|
||||
TomcatConnectorCustomizer customizer = context.getBean("connectorCustomizer",
|
||||
TomcatConnectorCustomizer.class);
|
||||
assertThat(factory.getTomcatConnectorCustomizers()).contains(customizer);
|
||||
then(customizer).should().customize(any(Connector.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void tomcatContextCustomizerBeanIsAddedToFactory() {
|
||||
ReactiveWebApplicationContextRunner runner = new ReactiveWebApplicationContextRunner(
|
||||
AnnotationConfigReactiveWebServerApplicationContext::new)
|
||||
.withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class))
|
||||
.withUserConfiguration(HttpHandlerConfiguration.class, TomcatContextCustomizerConfiguration.class)
|
||||
.withPropertyValues("server.port: 0");
|
||||
runner.run((context) -> {
|
||||
TomcatReactiveWebServerFactory factory = context.getBean(TomcatReactiveWebServerFactory.class);
|
||||
TomcatContextCustomizer customizer = context.getBean("contextCustomizer", TomcatContextCustomizer.class);
|
||||
assertThat(factory.getTomcatContextCustomizers()).contains(customizer);
|
||||
then(customizer).should().customize(any(Context.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void tomcatContextCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() {
|
||||
ReactiveWebApplicationContextRunner runner = new ReactiveWebApplicationContextRunner(
|
||||
AnnotationConfigReactiveWebServerApplicationContext::new)
|
||||
.withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class))
|
||||
.withUserConfiguration(HttpHandlerConfiguration.class,
|
||||
DoubleRegistrationTomcatContextCustomizerConfiguration.class)
|
||||
.withPropertyValues("server.port: 0");
|
||||
runner.run((context) -> {
|
||||
TomcatReactiveWebServerFactory factory = context.getBean(TomcatReactiveWebServerFactory.class);
|
||||
TomcatContextCustomizer customizer = context.getBean("contextCustomizer", TomcatContextCustomizer.class);
|
||||
assertThat(factory.getTomcatContextCustomizers()).contains(customizer);
|
||||
then(customizer).should().customize(any(Context.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void tomcatProtocolHandlerCustomizerBeanIsAddedToFactory() {
|
||||
ReactiveWebApplicationContextRunner runner = new ReactiveWebApplicationContextRunner(
|
||||
AnnotationConfigReactiveWebServerApplicationContext::new)
|
||||
.withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class))
|
||||
.withUserConfiguration(HttpHandlerConfiguration.class, TomcatProtocolHandlerCustomizerConfiguration.class)
|
||||
.withPropertyValues("server.port: 0");
|
||||
runner.run((context) -> {
|
||||
TomcatReactiveWebServerFactory factory = context.getBean(TomcatReactiveWebServerFactory.class);
|
||||
TomcatProtocolHandlerCustomizer<?> customizer = context.getBean("protocolHandlerCustomizer",
|
||||
TomcatProtocolHandlerCustomizer.class);
|
||||
assertThat(factory.getTomcatProtocolHandlerCustomizers()).contains(customizer);
|
||||
then(customizer).should().customize(any());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void tomcatProtocolHandlerCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() {
|
||||
ReactiveWebApplicationContextRunner runner = new ReactiveWebApplicationContextRunner(
|
||||
AnnotationConfigReactiveWebServerApplicationContext::new)
|
||||
.withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class))
|
||||
.withUserConfiguration(HttpHandlerConfiguration.class,
|
||||
DoubleRegistrationTomcatProtocolHandlerCustomizerConfiguration.class)
|
||||
.withPropertyValues("server.port: 0");
|
||||
runner.run((context) -> {
|
||||
TomcatReactiveWebServerFactory factory = context.getBean(TomcatReactiveWebServerFactory.class);
|
||||
TomcatProtocolHandlerCustomizer<?> customizer = context.getBean("protocolHandlerCustomizer",
|
||||
TomcatProtocolHandlerCustomizer.class);
|
||||
assertThat(factory.getTomcatProtocolHandlerCustomizers()).contains(customizer);
|
||||
then(customizer).should().customize(any());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void jettyServerCustomizerBeanIsAddedToFactory() {
|
||||
new ReactiveWebApplicationContextRunner(AnnotationConfigReactiveWebApplicationContext::new)
|
||||
.withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class))
|
||||
.withClassLoader(new FilteredClassLoader(Tomcat.class, HttpServer.class))
|
||||
.withUserConfiguration(JettyServerCustomizerConfiguration.class, HttpHandlerConfiguration.class)
|
||||
.run((context) -> {
|
||||
JettyReactiveWebServerFactory factory = context.getBean(JettyReactiveWebServerFactory.class);
|
||||
assertThat(factory.getServerCustomizers()).hasSize(1);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void jettyServerCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() {
|
||||
new ReactiveWebApplicationContextRunner(AnnotationConfigReactiveWebServerApplicationContext::new)
|
||||
.withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class))
|
||||
.withClassLoader(new FilteredClassLoader(Tomcat.class, HttpServer.class))
|
||||
.withUserConfiguration(DoubleRegistrationJettyServerCustomizerConfiguration.class,
|
||||
HttpHandlerConfiguration.class)
|
||||
.withPropertyValues("server.port=0")
|
||||
.run((context) -> {
|
||||
JettyReactiveWebServerFactory factory = context.getBean(JettyReactiveWebServerFactory.class);
|
||||
JettyServerCustomizer customizer = context.getBean("serverCustomizer", JettyServerCustomizer.class);
|
||||
assertThat(factory.getServerCustomizers()).contains(customizer);
|
||||
then(customizer).should().customize(any(Server.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void undertowBuilderCustomizerBeanIsAddedToFactory() {
|
||||
new ReactiveWebApplicationContextRunner(AnnotationConfigReactiveWebApplicationContext::new)
|
||||
.withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class))
|
||||
.withClassLoader(new FilteredClassLoader(Tomcat.class, HttpServer.class, Server.class))
|
||||
.withUserConfiguration(UndertowBuilderCustomizerConfiguration.class, HttpHandlerConfiguration.class)
|
||||
.run((context) -> {
|
||||
UndertowReactiveWebServerFactory factory = context.getBean(UndertowReactiveWebServerFactory.class);
|
||||
assertThat(factory.getBuilderCustomizers()).hasSize(1);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void undertowBuilderCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() {
|
||||
new ReactiveWebApplicationContextRunner(AnnotationConfigReactiveWebServerApplicationContext::new)
|
||||
.withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class))
|
||||
.withClassLoader(new FilteredClassLoader(Tomcat.class, HttpServer.class, Server.class))
|
||||
.withUserConfiguration(DoubleRegistrationUndertowBuilderCustomizerConfiguration.class,
|
||||
HttpHandlerConfiguration.class)
|
||||
.withPropertyValues("server.port: 0")
|
||||
.run((context) -> {
|
||||
UndertowReactiveWebServerFactory factory = context.getBean(UndertowReactiveWebServerFactory.class);
|
||||
UndertowBuilderCustomizer customizer = context.getBean("builderCustomizer",
|
||||
UndertowBuilderCustomizer.class);
|
||||
assertThat(factory.getBuilderCustomizers()).contains(customizer);
|
||||
then(customizer).should().customize(any(Builder.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void nettyServerCustomizerBeanIsAddedToFactory() {
|
||||
new ReactiveWebApplicationContextRunner(AnnotationConfigReactiveWebApplicationContext::new)
|
||||
.withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class))
|
||||
.withClassLoader(new FilteredClassLoader(Tomcat.class, Server.class, Undertow.class))
|
||||
.withUserConfiguration(NettyServerCustomizerConfiguration.class, HttpHandlerConfiguration.class)
|
||||
.run((context) -> {
|
||||
NettyReactiveWebServerFactory factory = context.getBean(NettyReactiveWebServerFactory.class);
|
||||
assertThat(factory.getServerCustomizers()).hasSize(1);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void nettyServerCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() {
|
||||
new ReactiveWebApplicationContextRunner(AnnotationConfigReactiveWebServerApplicationContext::new)
|
||||
.withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class))
|
||||
.withClassLoader(new FilteredClassLoader(Tomcat.class, Server.class, Undertow.class))
|
||||
.withUserConfiguration(DoubleRegistrationNettyServerCustomizerConfiguration.class,
|
||||
HttpHandlerConfiguration.class)
|
||||
.withPropertyValues("server.port: 0")
|
||||
.run((context) -> {
|
||||
NettyReactiveWebServerFactory factory = context.getBean(NettyReactiveWebServerFactory.class);
|
||||
NettyServerCustomizer customizer = context.getBean("serverCustomizer", NettyServerCustomizer.class);
|
||||
assertThat(factory.getServerCustomizers()).contains(customizer);
|
||||
then(customizer).should().apply(any(HttpServer.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void forwardedHeaderTransformerShouldBeConfigured() {
|
||||
this.contextRunner.withUserConfiguration(HttpHandlerConfiguration.class)
|
||||
.withPropertyValues("server.forward-headers-strategy=framework", "server.port=0")
|
||||
.run((context) -> assertThat(context).hasSingleBean(ForwardedHeaderTransformer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void forwardedHeaderTransformerWhenStrategyNotFilterShouldNotBeConfigured() {
|
||||
this.contextRunner.withUserConfiguration(HttpHandlerConfiguration.class)
|
||||
.withPropertyValues("server.forward-headers-strategy=native", "server.port=0")
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(ForwardedHeaderTransformer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void forwardedHeaderTransformerWhenAlreadyRegisteredShouldBackOff() {
|
||||
this.contextRunner
|
||||
.withUserConfiguration(ForwardedHeaderTransformerConfiguration.class, HttpHandlerConfiguration.class)
|
||||
.withPropertyValues("server.forward-headers-strategy=framework", "server.port=0")
|
||||
.run((context) -> assertThat(context).hasSingleBean(ForwardedHeaderTransformer.class));
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class HttpHandlerConfiguration {
|
||||
|
||||
@Bean
|
||||
HttpHandler httpHandler() {
|
||||
return mock(HttpHandler.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class TooManyHttpHandlers {
|
||||
|
||||
@Bean
|
||||
HttpHandler additionalHttpHandler() {
|
||||
return mock(HttpHandler.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class ReactiveWebServerCustomization {
|
||||
|
||||
@Bean
|
||||
WebServerFactoryCustomizer<ConfigurableReactiveWebServerFactory> reactiveWebServerCustomizer() {
|
||||
return (factory) -> factory.setPort(9000);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class MockWebServerConfiguration {
|
||||
|
||||
@Bean
|
||||
MockReactiveWebServerFactory mockReactiveWebServerFactory() {
|
||||
return new MockReactiveWebServerFactory();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class TomcatConnectorCustomizerConfiguration {
|
||||
|
||||
@Bean
|
||||
TomcatConnectorCustomizer connectorCustomizer() {
|
||||
return mock(TomcatConnectorCustomizer.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class DoubleRegistrationTomcatConnectorCustomizerConfiguration {
|
||||
|
||||
private final TomcatConnectorCustomizer customizer = mock(TomcatConnectorCustomizer.class);
|
||||
|
||||
@Bean
|
||||
TomcatConnectorCustomizer connectorCustomizer() {
|
||||
return this.customizer;
|
||||
}
|
||||
|
||||
@Bean
|
||||
WebServerFactoryCustomizer<TomcatReactiveWebServerFactory> tomcatCustomizer() {
|
||||
return (tomcat) -> tomcat.addConnectorCustomizers(this.customizer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class TomcatContextCustomizerConfiguration {
|
||||
|
||||
@Bean
|
||||
TomcatContextCustomizer contextCustomizer() {
|
||||
return mock(TomcatContextCustomizer.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class DoubleRegistrationTomcatContextCustomizerConfiguration {
|
||||
|
||||
private final TomcatContextCustomizer customizer = mock(TomcatContextCustomizer.class);
|
||||
|
||||
@Bean
|
||||
TomcatContextCustomizer contextCustomizer() {
|
||||
return this.customizer;
|
||||
}
|
||||
|
||||
@Bean
|
||||
WebServerFactoryCustomizer<TomcatReactiveWebServerFactory> tomcatCustomizer() {
|
||||
return (tomcat) -> tomcat.addContextCustomizers(this.customizer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class TomcatProtocolHandlerCustomizerConfiguration {
|
||||
|
||||
@Bean
|
||||
TomcatProtocolHandlerCustomizer<?> protocolHandlerCustomizer() {
|
||||
return mock(TomcatProtocolHandlerCustomizer.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class DoubleRegistrationTomcatProtocolHandlerCustomizerConfiguration {
|
||||
|
||||
private final TomcatProtocolHandlerCustomizer<?> customizer = mock(TomcatProtocolHandlerCustomizer.class);
|
||||
|
||||
@Bean
|
||||
TomcatProtocolHandlerCustomizer<?> protocolHandlerCustomizer() {
|
||||
return this.customizer;
|
||||
}
|
||||
|
||||
@Bean
|
||||
WebServerFactoryCustomizer<TomcatReactiveWebServerFactory> tomcatCustomizer() {
|
||||
return (tomcat) -> tomcat.addProtocolHandlerCustomizers(this.customizer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class JettyServerCustomizerConfiguration {
|
||||
|
||||
@Bean
|
||||
JettyServerCustomizer serverCustomizer() {
|
||||
return (server) -> {
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class DoubleRegistrationJettyServerCustomizerConfiguration {
|
||||
|
||||
private final JettyServerCustomizer customizer = mock(JettyServerCustomizer.class);
|
||||
|
||||
@Bean
|
||||
JettyServerCustomizer serverCustomizer() {
|
||||
return this.customizer;
|
||||
}
|
||||
|
||||
@Bean
|
||||
WebServerFactoryCustomizer<JettyReactiveWebServerFactory> jettyCustomizer() {
|
||||
return (jetty) -> jetty.addServerCustomizers(this.customizer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class UndertowBuilderCustomizerConfiguration {
|
||||
|
||||
@Bean
|
||||
UndertowBuilderCustomizer builderCustomizer() {
|
||||
return (builder) -> {
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class DoubleRegistrationUndertowBuilderCustomizerConfiguration {
|
||||
|
||||
private final UndertowBuilderCustomizer customizer = mock(UndertowBuilderCustomizer.class);
|
||||
|
||||
@Bean
|
||||
UndertowBuilderCustomizer builderCustomizer() {
|
||||
return this.customizer;
|
||||
}
|
||||
|
||||
@Bean
|
||||
WebServerFactoryCustomizer<UndertowReactiveWebServerFactory> undertowCustomizer() {
|
||||
return (undertow) -> undertow.addBuilderCustomizers(this.customizer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class UndertowDeploymentInfoCustomizerConfiguration {
|
||||
|
||||
@Bean
|
||||
UndertowDeploymentInfoCustomizer deploymentInfoCustomizer() {
|
||||
return (deploymentInfo) -> {
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class NettyServerCustomizerConfiguration {
|
||||
|
||||
@Bean
|
||||
NettyServerCustomizer serverCustomizer() {
|
||||
return (server) -> server;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class DoubleRegistrationNettyServerCustomizerConfiguration {
|
||||
|
||||
private final NettyServerCustomizer customizer = mock(NettyServerCustomizer.class);
|
||||
|
||||
DoubleRegistrationNettyServerCustomizerConfiguration() {
|
||||
given(this.customizer.apply(any(HttpServer.class))).willAnswer((invocation) -> invocation.getArgument(0));
|
||||
}
|
||||
|
||||
@Bean
|
||||
NettyServerCustomizer serverCustomizer() {
|
||||
return this.customizer;
|
||||
}
|
||||
|
||||
@Bean
|
||||
WebServerFactoryCustomizer<NettyReactiveWebServerFactory> nettyCustomizer() {
|
||||
return (netty) -> netty.addServerCustomizers(this.customizer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class ForwardedHeaderTransformerConfiguration {
|
||||
|
||||
@Bean
|
||||
ForwardedHeaderTransformer testForwardedHeaderTransformer() {
|
||||
return new ForwardedHeaderTransformer();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -61,7 +61,7 @@ import org.springframework.boot.testsupport.classpath.resources.WithResource;
|
||||
import org.springframework.boot.web.codec.CodecCustomizer;
|
||||
import org.springframework.boot.web.reactive.context.ReactiveWebApplicationContext;
|
||||
import org.springframework.boot.web.reactive.filter.OrderedHiddenHttpMethodFilter;
|
||||
import org.springframework.boot.web.reactive.server.MockReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.server.reactive.MockReactiveWebServerFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@@ -36,8 +36,8 @@ import org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.autoconfigure.web.WebProperties;
|
||||
import org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.server.reactive.netty.NettyReactiveWebServerAutoConfiguration;
|
||||
import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext;
|
||||
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
|
||||
import org.springframework.boot.test.system.CapturedOutput;
|
||||
@@ -86,7 +86,7 @@ class DefaultErrorWebExceptionHandlerIntegrationTests {
|
||||
private final LogIdFilter logIdFilter = new LogIdFilter();
|
||||
|
||||
private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(ReactiveWebServerFactoryAutoConfiguration.class,
|
||||
.withConfiguration(AutoConfigurations.of(NettyReactiveWebServerAutoConfiguration.class,
|
||||
HttpHandlerAutoConfiguration.class, WebFluxAutoConfiguration.class, ErrorWebFluxAutoConfiguration.class,
|
||||
PropertyPlaceholderAutoConfiguration.class, MustacheAutoConfiguration.class))
|
||||
.withPropertyValues("spring.main.web-application-type=reactive", "server.port=0")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.web.embedded;
|
||||
package org.springframework.boot.autoconfigure.web.server.jetty;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.Executor;
|
||||
@@ -28,7 +28,7 @@ import org.junit.jupiter.api.condition.EnabledForJreRange;
|
||||
import org.junit.jupiter.api.condition.JRE;
|
||||
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.web.embedded.jetty.ConfigurableJettyWebServerFactory;
|
||||
import org.springframework.boot.web.server.jetty.ConfigurableJettyWebServerFactory;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.assertArg;
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.web.embedded;
|
||||
package org.springframework.boot.autoconfigure.web.server.jetty;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -48,9 +48,9 @@ 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.web.embedded.jetty.ConfigurableJettyWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.jetty.JettyWebServer;
|
||||
import org.springframework.boot.web.server.jetty.ConfigurableJettyWebServerFactory;
|
||||
import org.springframework.boot.web.server.jetty.JettyWebServer;
|
||||
import org.springframework.boot.web.server.servlet.jetty.JettyServletWebServerFactory;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
import org.springframework.test.context.support.TestPropertySourceUtils;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.server.reactive;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.ssl.DefaultSslBundleRegistry;
|
||||
import org.springframework.boot.ssl.NoSuchSslBundleException;
|
||||
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
|
||||
import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext;
|
||||
import org.springframework.boot.web.server.ConfigurableWebServerFactory;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.boot.web.server.reactive.ConfigurableReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.server.reactive.MockReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.server.reactive.ReactiveWebServerFactory;
|
||||
import org.springframework.context.ApplicationContextException;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.server.reactive.HttpHandler;
|
||||
import org.springframework.web.server.adapter.ForwardedHeaderTransformer;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Base class for testing sub-classes of {@link ReactiveWebServerConfiguration}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Raheela Aslam
|
||||
* @author Madhura Bhave
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
// @DirtiesUrlFactories
|
||||
public abstract class AbstractReactiveWebServerAutoConfigurationTests {
|
||||
|
||||
private final ReactiveWebApplicationContextRunner mockServerRunner;
|
||||
|
||||
protected final ReactiveWebApplicationContextRunner serverRunner;
|
||||
|
||||
protected AbstractReactiveWebServerAutoConfigurationTests(Class<?> serverAutoConfiguration) {
|
||||
ReactiveWebApplicationContextRunner common = new ReactiveWebApplicationContextRunner(
|
||||
AnnotationConfigReactiveWebServerApplicationContext::new)
|
||||
.withConfiguration(AutoConfigurations.of(serverAutoConfiguration));
|
||||
this.serverRunner = common.withPropertyValues("server.port=0")
|
||||
.withUserConfiguration(HttpHandlerConfiguration.class);
|
||||
this.mockServerRunner = common.withUserConfiguration(MockWebServerConfiguration.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void createFromConfigClass() {
|
||||
this.mockServerRunner.withUserConfiguration(MockWebServerConfiguration.class, HttpHandlerConfiguration.class)
|
||||
.run((context) -> {
|
||||
assertThat(context.getBeansOfType(ReactiveWebServerFactory.class)).hasSize(1);
|
||||
assertThat(context.getBeansOfType(WebServerFactoryCustomizer.class)).hasSizeGreaterThanOrEqualTo(1);
|
||||
assertThat(context.getBeansOfType(ReactiveWebServerFactoryCustomizer.class)).hasSize(1);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void missingHttpHandler() {
|
||||
this.mockServerRunner.withUserConfiguration(MockWebServerConfiguration.class)
|
||||
.run((context) -> assertThat(context.getStartupFailure()).isInstanceOf(ApplicationContextException.class)
|
||||
.rootCause()
|
||||
.hasMessageContaining("missing HttpHandler bean"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void multipleHttpHandler() {
|
||||
this.mockServerRunner
|
||||
.withUserConfiguration(MockWebServerConfiguration.class, HttpHandlerConfiguration.class,
|
||||
TooManyHttpHandlers.class)
|
||||
.run((context) -> assertThat(context.getStartupFailure()).isInstanceOf(ApplicationContextException.class)
|
||||
.rootCause()
|
||||
.hasMessageContaining("multiple HttpHandler beans : httpHandler,additionalHttpHandler"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void customizeReactiveWebServer() {
|
||||
this.mockServerRunner
|
||||
.withUserConfiguration(MockWebServerConfiguration.class, HttpHandlerConfiguration.class,
|
||||
ReactiveWebServerCustomization.class)
|
||||
.run((context) -> assertThat(context.getBean(MockReactiveWebServerFactory.class).getPort())
|
||||
.isEqualTo(9000));
|
||||
}
|
||||
|
||||
@Test
|
||||
void webServerFailsWithInvalidSslBundle() {
|
||||
this.serverRunner.withUserConfiguration(HttpHandlerConfiguration.class)
|
||||
.withBean(WebServerFactoryCustomizer.class,
|
||||
() -> (WebServerFactoryCustomizer<ConfigurableWebServerFactory>) (factory) -> factory
|
||||
.setSslBundles(new DefaultSslBundleRegistry()))
|
||||
.withPropertyValues("server.ssl.bundle=test-bundle")
|
||||
.run((context) -> {
|
||||
assertThat(context).hasFailed();
|
||||
assertThat(context.getStartupFailure().getCause()).isInstanceOf(NoSuchSslBundleException.class)
|
||||
.withFailMessage("test");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void forwardedHeaderTransformerShouldBeConfigured() {
|
||||
this.mockServerRunner.withUserConfiguration(HttpHandlerConfiguration.class)
|
||||
.withPropertyValues("server.forward-headers-strategy=framework", "server.port=0")
|
||||
.run((context) -> assertThat(context).hasSingleBean(ForwardedHeaderTransformer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void forwardedHeaderTransformerWhenStrategyNotFilterShouldNotBeConfigured() {
|
||||
this.mockServerRunner.withUserConfiguration(HttpHandlerConfiguration.class)
|
||||
.withPropertyValues("server.forward-headers-strategy=native", "server.port=0")
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(ForwardedHeaderTransformer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void forwardedHeaderTransformerWhenAlreadyRegisteredShouldBackOff() {
|
||||
this.mockServerRunner
|
||||
.withUserConfiguration(ForwardedHeaderTransformerConfiguration.class, HttpHandlerConfiguration.class)
|
||||
.withPropertyValues("server.forward-headers-strategy=framework", "server.port=0")
|
||||
.run((context) -> assertThat(context).hasSingleBean(ForwardedHeaderTransformer.class));
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class HttpHandlerConfiguration {
|
||||
|
||||
@Bean
|
||||
HttpHandler httpHandler() {
|
||||
return mock(HttpHandler.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class TooManyHttpHandlers {
|
||||
|
||||
@Bean
|
||||
HttpHandler additionalHttpHandler() {
|
||||
return mock(HttpHandler.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class ReactiveWebServerCustomization {
|
||||
|
||||
@Bean
|
||||
WebServerFactoryCustomizer<ConfigurableReactiveWebServerFactory> reactiveWebServerCustomizer() {
|
||||
return (factory) -> factory.setPort(9000);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class MockWebServerConfiguration {
|
||||
|
||||
@Bean
|
||||
MockReactiveWebServerFactory mockReactiveWebServerFactory() {
|
||||
return new MockReactiveWebServerFactory();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class ForwardedHeaderTransformerConfiguration {
|
||||
|
||||
@Bean
|
||||
ForwardedHeaderTransformer testForwardedHeaderTransformer() {
|
||||
return new ForwardedHeaderTransformer();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.web.reactive;
|
||||
package org.springframework.boot.autoconfigure.web.server.reactive;
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
||||
@@ -24,9 +24,9 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.ssl.DefaultSslBundleRegistry;
|
||||
import org.springframework.boot.ssl.SslBundles;
|
||||
import org.springframework.boot.web.reactive.server.ConfigurableReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.server.Shutdown;
|
||||
import org.springframework.boot.web.server.Ssl;
|
||||
import org.springframework.boot.web.server.reactive.ConfigurableReactiveWebServerFactory;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.assertArg;
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.server.reactive.jetty;
|
||||
|
||||
import jakarta.websocket.server.ServerContainer;
|
||||
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.StatisticsHandler;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.web.server.reactive.AbstractReactiveWebServerAutoConfigurationTests;
|
||||
import org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext;
|
||||
import org.springframework.boot.web.server.WebServer;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.boot.web.server.jetty.JettyServerCustomizer;
|
||||
import org.springframework.boot.web.server.jetty.JettyWebServer;
|
||||
import org.springframework.boot.web.server.reactive.jetty.JettyReactiveWebServerFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.BDDMockito.then;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link JettyReactiveWebServerAutoConfiguration}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Raheela Aslam
|
||||
* @author Madhura Bhave
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
class JettyReactiveWebServerAutoConfigurationTests extends AbstractReactiveWebServerAutoConfigurationTests {
|
||||
|
||||
JettyReactiveWebServerAutoConfigurationTests() {
|
||||
super(JettyReactiveWebServerAutoConfiguration.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void jettyServerCustomizerBeanIsAddedToFactory() {
|
||||
this.serverRunner.withUserConfiguration(JettyServerCustomizerConfiguration.class).run((context) -> {
|
||||
JettyReactiveWebServerFactory factory = context.getBean(JettyReactiveWebServerFactory.class);
|
||||
assertThat(factory.getServerCustomizers())
|
||||
.contains(context.getBean("serverCustomizer", JettyServerCustomizer.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void jettyServerCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() {
|
||||
this.serverRunner.withUserConfiguration(DoubleRegistrationJettyServerCustomizerConfiguration.class)
|
||||
.run((context) -> {
|
||||
JettyReactiveWebServerFactory factory = context.getBean(JettyReactiveWebServerFactory.class);
|
||||
JettyServerCustomizer customizer = context.getBean("serverCustomizer", JettyServerCustomizer.class);
|
||||
assertThat(factory.getServerCustomizers()).contains(customizer);
|
||||
then(customizer).should().customize(any(Server.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void webSocketServerContainerIsAvailableFromServletContext() {
|
||||
this.serverRunner.run((context) -> {
|
||||
WebServer webServer = ((ReactiveWebServerApplicationContext) context.getSourceApplicationContext())
|
||||
.getWebServer();
|
||||
ServletContextHandler servletContextHandler = (ServletContextHandler) ((StatisticsHandler) ((JettyWebServer) webServer)
|
||||
.getServer()
|
||||
.getHandler()).getHandler();
|
||||
Object serverContainer = servletContextHandler.getContext()
|
||||
.getAttribute("jakarta.websocket.server.ServerContainer");
|
||||
assertThat(serverContainer).isInstanceOf(ServerContainer.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class JettyServerCustomizerConfiguration {
|
||||
|
||||
@Bean
|
||||
JettyServerCustomizer serverCustomizer() {
|
||||
return (server) -> {
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class DoubleRegistrationJettyServerCustomizerConfiguration {
|
||||
|
||||
private final JettyServerCustomizer customizer = mock(JettyServerCustomizer.class);
|
||||
|
||||
@Bean
|
||||
JettyServerCustomizer serverCustomizer() {
|
||||
return this.customizer;
|
||||
}
|
||||
|
||||
@Bean
|
||||
WebServerFactoryCustomizer<JettyReactiveWebServerFactory> jettyCustomizer() {
|
||||
return (jetty) -> jetty.addServerCustomizers(this.customizer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.server.reactive.netty;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import reactor.netty.http.server.HttpServer;
|
||||
|
||||
import org.springframework.boot.autoconfigure.web.server.reactive.AbstractReactiveWebServerAutoConfigurationTests;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.boot.web.server.reactive.netty.NettyReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.server.reactive.netty.NettyServerCustomizer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.BDDMockito.then;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link NettyReactiveWebServerAutoConfiguration}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Raheela Aslam
|
||||
* @author Madhura Bhave
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
// @DirtiesUrlFactories
|
||||
class NettyReactiveWebServerAutoConfigurationTests extends AbstractReactiveWebServerAutoConfigurationTests {
|
||||
|
||||
NettyReactiveWebServerAutoConfigurationTests() {
|
||||
super(NettyReactiveWebServerAutoConfiguration.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void nettyServerCustomizerBeanIsAddedToFactory() {
|
||||
this.serverRunner.withUserConfiguration(NettyServerCustomizerConfiguration.class).run((context) -> {
|
||||
NettyReactiveWebServerFactory factory = context.getBean(NettyReactiveWebServerFactory.class);
|
||||
assertThat(factory.getServerCustomizers())
|
||||
.contains(context.getBean("serverCustomizer", NettyServerCustomizer.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void nettyServerCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() {
|
||||
this.serverRunner.withUserConfiguration(DoubleRegistrationNettyServerCustomizerConfiguration.class)
|
||||
.run((context) -> {
|
||||
NettyReactiveWebServerFactory factory = context.getBean(NettyReactiveWebServerFactory.class);
|
||||
NettyServerCustomizer customizer = context.getBean("serverCustomizer", NettyServerCustomizer.class);
|
||||
assertThat(factory.getServerCustomizers()).contains(customizer);
|
||||
then(customizer).should().apply(any(HttpServer.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class NettyServerCustomizerConfiguration {
|
||||
|
||||
@Bean
|
||||
NettyServerCustomizer serverCustomizer() {
|
||||
return (server) -> server;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class DoubleRegistrationNettyServerCustomizerConfiguration {
|
||||
|
||||
private final NettyServerCustomizer customizer = mock(NettyServerCustomizer.class);
|
||||
|
||||
DoubleRegistrationNettyServerCustomizerConfiguration() {
|
||||
given(this.customizer.apply(any(HttpServer.class))).willAnswer((invocation) -> invocation.getArgument(0));
|
||||
}
|
||||
|
||||
@Bean
|
||||
NettyServerCustomizer serverCustomizer() {
|
||||
return this.customizer;
|
||||
}
|
||||
|
||||
@Bean
|
||||
WebServerFactoryCustomizer<NettyReactiveWebServerFactory> nettyCustomizer() {
|
||||
return (netty) -> netty.addServerCustomizers(this.customizer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.web.embedded;
|
||||
package org.springframework.boot.autoconfigure.web.server.reactive.netty;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Map;
|
||||
@@ -32,8 +32,8 @@ import reactor.netty.http.server.HttpServer;
|
||||
|
||||
import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
|
||||
import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.netty.NettyServerCustomizer;
|
||||
import org.springframework.boot.web.server.reactive.netty.NettyReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.server.reactive.netty.NettyServerCustomizer;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
import org.springframework.util.unit.DataSize;
|
||||
|
||||
@@ -45,20 +45,20 @@ import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
|
||||
/**
|
||||
* Tests for {@link NettyWebServerFactoryCustomizer}.
|
||||
* Tests for {@link NettyReactiveWebServerFactoryCustomizer}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Artsiom Yudovin
|
||||
* @author Leo Li
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class NettyWebServerFactoryCustomizerTests {
|
||||
class NettyReactiveWebServerFactoryCustomizerTests {
|
||||
|
||||
private MockEnvironment environment;
|
||||
|
||||
private ServerProperties serverProperties;
|
||||
|
||||
private NettyWebServerFactoryCustomizer customizer;
|
||||
private NettyReactiveWebServerFactoryCustomizer customizer;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<NettyServerCustomizer> customizerCaptor;
|
||||
@@ -68,7 +68,7 @@ class NettyWebServerFactoryCustomizerTests {
|
||||
this.environment = new MockEnvironment();
|
||||
this.serverProperties = new ServerProperties();
|
||||
ConfigurationPropertySources.attach(this.environment);
|
||||
this.customizer = new NettyWebServerFactoryCustomizer(this.environment, this.serverProperties);
|
||||
this.customizer = new NettyReactiveWebServerFactoryCustomizer(this.environment, this.serverProperties);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.server.reactive.tomcat;
|
||||
|
||||
import jakarta.servlet.ServletContext;
|
||||
import jakarta.websocket.server.ServerContainer;
|
||||
import org.apache.catalina.Container;
|
||||
import org.apache.catalina.Context;
|
||||
import org.apache.catalina.connector.Connector;
|
||||
import org.apache.catalina.startup.Tomcat;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.web.server.reactive.AbstractReactiveWebServerAutoConfigurationTests;
|
||||
import org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext;
|
||||
import org.springframework.boot.web.server.WebServer;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.boot.web.server.reactive.tomcat.TomcatReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.server.tomcat.TomcatConnectorCustomizer;
|
||||
import org.springframework.boot.web.server.tomcat.TomcatContextCustomizer;
|
||||
import org.springframework.boot.web.server.tomcat.TomcatProtocolHandlerCustomizer;
|
||||
import org.springframework.boot.web.server.tomcat.TomcatWebServer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.BDDMockito.then;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link TomcatReactiveWebServerAutoConfiguration}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Raheela Aslam
|
||||
* @author Madhura Bhave
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
class TomcatReactiveWebServerAutoConfigurationTests extends AbstractReactiveWebServerAutoConfigurationTests {
|
||||
|
||||
TomcatReactiveWebServerAutoConfigurationTests() {
|
||||
super(TomcatReactiveWebServerAutoConfiguration.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void tomcatConnectorCustomizerBeanIsAddedToFactory() {
|
||||
this.serverRunner.withUserConfiguration(TomcatConnectorCustomizerConfiguration.class).run((context) -> {
|
||||
TomcatReactiveWebServerFactory factory = context.getBean(TomcatReactiveWebServerFactory.class);
|
||||
TomcatConnectorCustomizer customizer = context.getBean("connectorCustomizer",
|
||||
TomcatConnectorCustomizer.class);
|
||||
assertThat(factory.getConnectorCustomizers()).contains(customizer);
|
||||
then(customizer).should().customize(any(Connector.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void tomcatConnectorCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() {
|
||||
this.serverRunner.withUserConfiguration(DoubleRegistrationTomcatConnectorCustomizerConfiguration.class)
|
||||
.run((context) -> {
|
||||
TomcatReactiveWebServerFactory factory = context.getBean(TomcatReactiveWebServerFactory.class);
|
||||
TomcatConnectorCustomizer customizer = context.getBean("connectorCustomizer",
|
||||
TomcatConnectorCustomizer.class);
|
||||
assertThat(factory.getConnectorCustomizers()).contains(customizer);
|
||||
then(customizer).should().customize(any(Connector.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void tomcatContextCustomizerBeanIsAddedToFactory() {
|
||||
this.serverRunner.withUserConfiguration(TomcatContextCustomizerConfiguration.class).run((context) -> {
|
||||
TomcatReactiveWebServerFactory factory = context.getBean(TomcatReactiveWebServerFactory.class);
|
||||
TomcatContextCustomizer customizer = context.getBean("contextCustomizer", TomcatContextCustomizer.class);
|
||||
assertThat(factory.getContextCustomizers()).contains(customizer);
|
||||
then(customizer).should().customize(any(Context.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void tomcatContextCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() {
|
||||
this.serverRunner.withUserConfiguration(DoubleRegistrationTomcatContextCustomizerConfiguration.class)
|
||||
.run((context) -> {
|
||||
TomcatReactiveWebServerFactory factory = context.getBean(TomcatReactiveWebServerFactory.class);
|
||||
TomcatContextCustomizer customizer = context.getBean("contextCustomizer",
|
||||
TomcatContextCustomizer.class);
|
||||
assertThat(factory.getContextCustomizers()).contains(customizer);
|
||||
then(customizer).should().customize(any(Context.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void tomcatProtocolHandlerCustomizerBeanIsAddedToFactory() {
|
||||
this.serverRunner.withUserConfiguration(TomcatProtocolHandlerCustomizerConfiguration.class).run((context) -> {
|
||||
TomcatReactiveWebServerFactory factory = context.getBean(TomcatReactiveWebServerFactory.class);
|
||||
TomcatProtocolHandlerCustomizer<?> customizer = context.getBean("protocolHandlerCustomizer",
|
||||
TomcatProtocolHandlerCustomizer.class);
|
||||
assertThat(factory.getProtocolHandlerCustomizers()).contains(customizer);
|
||||
then(customizer).should().customize(any());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void tomcatProtocolHandlerCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() {
|
||||
this.serverRunner.withUserConfiguration(DoubleRegistrationTomcatProtocolHandlerCustomizerConfiguration.class)
|
||||
.run((context) -> {
|
||||
TomcatReactiveWebServerFactory factory = context.getBean(TomcatReactiveWebServerFactory.class);
|
||||
TomcatProtocolHandlerCustomizer<?> customizer = context.getBean("protocolHandlerCustomizer",
|
||||
TomcatProtocolHandlerCustomizer.class);
|
||||
assertThat(factory.getProtocolHandlerCustomizers()).contains(customizer);
|
||||
then(customizer).should().customize(any());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void webSocketServerContainerIsAvailableFromServletContext() {
|
||||
this.serverRunner.run((context) -> {
|
||||
WebServer webServer = ((ReactiveWebServerApplicationContext) context.getSourceApplicationContext())
|
||||
.getWebServer();
|
||||
ServletContext servletContext = findContext(((TomcatWebServer) webServer).getTomcat()).getServletContext();
|
||||
Object serverContainer = servletContext.getAttribute("jakarta.websocket.server.ServerContainer");
|
||||
assertThat(serverContainer).isInstanceOf(ServerContainer.class);
|
||||
});
|
||||
}
|
||||
|
||||
private static Context findContext(Tomcat tomcat) {
|
||||
for (Container child : tomcat.getHost().findChildren()) {
|
||||
if (child instanceof Context context) {
|
||||
return context;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("The Host does not contain a Context");
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class TomcatConnectorCustomizerConfiguration {
|
||||
|
||||
@Bean
|
||||
TomcatConnectorCustomizer connectorCustomizer() {
|
||||
return mock(TomcatConnectorCustomizer.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class DoubleRegistrationTomcatConnectorCustomizerConfiguration {
|
||||
|
||||
private final TomcatConnectorCustomizer customizer = mock(TomcatConnectorCustomizer.class);
|
||||
|
||||
@Bean
|
||||
TomcatConnectorCustomizer connectorCustomizer() {
|
||||
return this.customizer;
|
||||
}
|
||||
|
||||
@Bean
|
||||
WebServerFactoryCustomizer<TomcatReactiveWebServerFactory> tomcatCustomizer() {
|
||||
return (tomcat) -> tomcat.addConnectorCustomizers(this.customizer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class TomcatContextCustomizerConfiguration {
|
||||
|
||||
@Bean
|
||||
TomcatContextCustomizer contextCustomizer() {
|
||||
return mock(TomcatContextCustomizer.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class DoubleRegistrationTomcatContextCustomizerConfiguration {
|
||||
|
||||
private final TomcatContextCustomizer customizer = mock(TomcatContextCustomizer.class);
|
||||
|
||||
@Bean
|
||||
TomcatContextCustomizer contextCustomizer() {
|
||||
return this.customizer;
|
||||
}
|
||||
|
||||
@Bean
|
||||
WebServerFactoryCustomizer<TomcatReactiveWebServerFactory> tomcatCustomizer() {
|
||||
return (tomcat) -> tomcat.addContextCustomizers(this.customizer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class TomcatProtocolHandlerCustomizerConfiguration {
|
||||
|
||||
@Bean
|
||||
TomcatProtocolHandlerCustomizer<?> protocolHandlerCustomizer() {
|
||||
return mock(TomcatProtocolHandlerCustomizer.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class DoubleRegistrationTomcatProtocolHandlerCustomizerConfiguration {
|
||||
|
||||
private final TomcatProtocolHandlerCustomizer<?> customizer = mock(TomcatProtocolHandlerCustomizer.class);
|
||||
|
||||
@Bean
|
||||
TomcatProtocolHandlerCustomizer<?> protocolHandlerCustomizer() {
|
||||
return this.customizer;
|
||||
}
|
||||
|
||||
@Bean
|
||||
WebServerFactoryCustomizer<TomcatReactiveWebServerFactory> tomcatCustomizer() {
|
||||
return (tomcat) -> tomcat.addProtocolHandlerCustomizers(this.customizer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.server.reactive.undertow;
|
||||
|
||||
import io.undertow.Undertow.Builder;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.web.server.reactive.AbstractReactiveWebServerAutoConfigurationTests;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.boot.web.server.reactive.undertow.UndertowReactiveWebServerFactory;
|
||||
import org.springframework.boot.web.server.servlet.undertow.UndertowDeploymentInfoCustomizer;
|
||||
import org.springframework.boot.web.server.undertow.UndertowBuilderCustomizer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.BDDMockito.then;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link UndertowReactiveWebServerAutoConfiguration}.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Raheela Aslam
|
||||
* @author Madhura Bhave
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
class UndertowReactiveWebServerAutoConfigurationTests extends AbstractReactiveWebServerAutoConfigurationTests {
|
||||
|
||||
UndertowReactiveWebServerAutoConfigurationTests() {
|
||||
super(UndertowReactiveWebServerAutoConfiguration.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void undertowBuilderCustomizerBeanIsAddedToFactory() {
|
||||
this.serverRunner.withUserConfiguration(UndertowBuilderCustomizerConfiguration.class).run((context) -> {
|
||||
UndertowReactiveWebServerFactory factory = context.getBean(UndertowReactiveWebServerFactory.class);
|
||||
assertThat(factory.getBuilderCustomizers())
|
||||
.contains(context.getBean("builderCustomizer", UndertowBuilderCustomizer.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void undertowBuilderCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() {
|
||||
this.serverRunner.withUserConfiguration(DoubleRegistrationUndertowBuilderCustomizerConfiguration.class)
|
||||
.run((context) -> {
|
||||
UndertowReactiveWebServerFactory factory = context.getBean(UndertowReactiveWebServerFactory.class);
|
||||
UndertowBuilderCustomizer customizer = context.getBean("builderCustomizer",
|
||||
UndertowBuilderCustomizer.class);
|
||||
assertThat(factory.getBuilderCustomizers()).contains(customizer);
|
||||
then(customizer).should().customize(any(Builder.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class UndertowBuilderCustomizerConfiguration {
|
||||
|
||||
@Bean
|
||||
UndertowBuilderCustomizer builderCustomizer() {
|
||||
return (builder) -> {
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class DoubleRegistrationUndertowBuilderCustomizerConfiguration {
|
||||
|
||||
private final UndertowBuilderCustomizer customizer = mock(UndertowBuilderCustomizer.class);
|
||||
|
||||
@Bean
|
||||
UndertowBuilderCustomizer builderCustomizer() {
|
||||
return this.customizer;
|
||||
}
|
||||
|
||||
@Bean
|
||||
WebServerFactoryCustomizer<UndertowReactiveWebServerFactory> undertowCustomizer() {
|
||||
return (undertow) -> undertow.addBuilderCustomizers(this.customizer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class UndertowDeploymentInfoCustomizerConfiguration {
|
||||
|
||||
@Bean
|
||||
UndertowDeploymentInfoCustomizer deploymentInfoCustomizer() {
|
||||
return (deploymentInfo) -> {
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.server.servlet;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import jakarta.servlet.DispatcherType;
|
||||
import jakarta.servlet.Filter;
|
||||
import jakarta.servlet.FilterChain;
|
||||
import jakarta.servlet.ServletContext;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.ServletRequest;
|
||||
import jakarta.servlet.ServletResponse;
|
||||
import jakarta.servlet.http.HttpServlet;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.websocket.server.ServerContainer;
|
||||
import jakarta.websocket.server.ServerEndpoint;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.boot.web.context.WebServerApplicationContext;
|
||||
import org.springframework.boot.web.server.WebServer;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.boot.web.server.servlet.ConfigurableServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.servlet.CookieSameSiteSupplier;
|
||||
import org.springframework.boot.web.server.servlet.MockServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.servlet.ServletContextInitializer;
|
||||
import org.springframework.boot.web.server.servlet.ServletWebServerFactory;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
||||
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.RequestEntity;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.filter.ForwardedHeaderFilter;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Base class for testing sub-classes of {@link ServletWebServerConfiguration}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Phillip Webb
|
||||
* @author Stephane Nicoll
|
||||
* @author Raheela Aslam
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
public abstract class AbstractServletWebServerAutoConfigurationTests {
|
||||
|
||||
private final WebApplicationContextRunner mockServerRunner;
|
||||
|
||||
protected final WebApplicationContextRunner serverRunner;
|
||||
|
||||
protected AbstractServletWebServerAutoConfigurationTests(Class<?> serverAutoConfiguration) {
|
||||
WebApplicationContextRunner common = new WebApplicationContextRunner(
|
||||
AnnotationConfigServletWebServerApplicationContext::new)
|
||||
.withConfiguration(AutoConfigurations.of(serverAutoConfiguration));
|
||||
this.serverRunner = common.withPropertyValues("server.port=0");
|
||||
this.mockServerRunner = common.withUserConfiguration(MockWebServerConfiguration.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void createFromConfigClass() {
|
||||
this.mockServerRunner
|
||||
.run((context) -> assertThat(context).hasSingleBean(ServletWebServerFactoryCustomizer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void webServerHasNoServletContext() {
|
||||
this.mockServerRunner.withUserConfiguration(EnsureWebServerHasNoServletContext.class)
|
||||
.run((context) -> assertThat(context).hasNotFailed());
|
||||
}
|
||||
|
||||
@Test
|
||||
void webServerFactoryCustomizerBeansAreCalledToCustomizeWebServerFactory() {
|
||||
this.mockServerRunner
|
||||
.withBean(WebServerFactoryCustomizer.class,
|
||||
() -> (WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>) (factory) -> factory
|
||||
.setPort(9000))
|
||||
.run((context) -> assertThat(context.getBean(MockServletWebServerFactory.class).getPort()).isEqualTo(9000));
|
||||
}
|
||||
|
||||
@Test
|
||||
void initParametersAreConfiguredOnTheServletContext() {
|
||||
this.mockServerRunner
|
||||
.withPropertyValues("server.servlet.context-parameters.a:alpha",
|
||||
"server.servlet.context-parameters.b:bravo")
|
||||
.run((context) -> {
|
||||
ServletContext servletContext = context.getServletContext();
|
||||
assertThat(servletContext.getInitParameter("a")).isEqualTo("alpha");
|
||||
assertThat(servletContext.getInitParameter("b")).isEqualTo("bravo");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void forwardedHeaderFilterShouldBeConfigured() {
|
||||
this.mockServerRunner.withPropertyValues("server.forward-headers-strategy=framework").run((context) -> {
|
||||
assertThat(context).hasSingleBean(FilterRegistrationBean.class);
|
||||
Filter filter = context.getBean(FilterRegistrationBean.class).getFilter();
|
||||
assertThat(filter).isInstanceOf(ForwardedHeaderFilter.class);
|
||||
assertThat(filter).extracting("relativeRedirects").isEqualTo(false);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void forwardedHeaderFilterWhenStrategyNotFilterShouldNotBeConfigured() {
|
||||
this.mockServerRunner.withPropertyValues("server.forward-headers-strategy=native")
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(FilterRegistrationBean.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void forwardedHeaderFilterWhenFilterAlreadyRegisteredShouldBackOff() {
|
||||
this.mockServerRunner.withUserConfiguration(ForwardedHeaderFilterConfiguration.class)
|
||||
.withPropertyValues("server.forward-headers-strategy=framework")
|
||||
.run((context) -> assertThat(context).hasSingleBean(FilterRegistrationBean.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void cookieSameSiteSuppliersAreApplied() {
|
||||
this.mockServerRunner.withUserConfiguration(CookieSameSiteSupplierConfiguration.class).run((context) -> {
|
||||
ConfigurableServletWebServerFactory webServerFactory = context
|
||||
.getBean(ConfigurableServletWebServerFactory.class);
|
||||
assertThat(webServerFactory.getSettings().getCookieSameSiteSuppliers()).hasSize(2);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void webSocketServerContainerIsAvailableFromServletContext() {
|
||||
this.serverRunner.run((context) -> {
|
||||
Object serverContainer = context.getServletContext()
|
||||
.getAttribute("jakarta.websocket.server.ServerContainer");
|
||||
assertThat(serverContainer).isInstanceOf(ServerContainer.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void webSocketUpgradeDoesNotPreventAFilterFromRejectingTheRequest() {
|
||||
this.serverRunner
|
||||
.withBean("testEndpointRegistrar", ServletContextInitializer.class, () -> TestEndpoint::register)
|
||||
.withUserConfiguration(UnauthorizedFilterConfiguration.class)
|
||||
.run((context) -> {
|
||||
TestEndpoint.register(context.getServletContext());
|
||||
WebServer webServer = ((WebServerApplicationContext) context.getSourceApplicationContext())
|
||||
.getWebServer();
|
||||
int port = webServer.getPort();
|
||||
TestRestTemplate rest = new TestRestTemplate();
|
||||
RequestEntity<Void> request = RequestEntity.get("http://localhost:" + port)
|
||||
.header("Upgrade", "websocket")
|
||||
.header("Connection", "upgrade")
|
||||
.header("Sec-WebSocket-Version", "13")
|
||||
.header("Sec-WebSocket-Key", "key")
|
||||
.build();
|
||||
ResponseEntity<Void> response = rest.exchange(request, Void.class);
|
||||
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnExpression("true")
|
||||
static class MockWebServerConfiguration {
|
||||
|
||||
@Bean
|
||||
ServletWebServerFactory webServerFactory() {
|
||||
return new MockServletWebServerFactory();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Component
|
||||
static class EnsureWebServerHasNoServletContext implements BeanPostProcessor {
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) {
|
||||
if (bean instanceof ConfigurableServletWebServerFactory) {
|
||||
MockServletWebServerFactory webServerFactory = (MockServletWebServerFactory) bean;
|
||||
assertThat(webServerFactory.getServletContext()).isNull();
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) {
|
||||
return bean;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class ForwardedHeaderFilterConfiguration {
|
||||
|
||||
@Bean
|
||||
FilterRegistrationBean<ForwardedHeaderFilter> testForwardedHeaderFilter() {
|
||||
ForwardedHeaderFilter filter = new ForwardedHeaderFilter();
|
||||
return new FilterRegistrationBean<>(filter);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class CookieSameSiteSupplierConfiguration {
|
||||
|
||||
@Bean
|
||||
CookieSameSiteSupplier cookieSameSiteSupplier1() {
|
||||
return CookieSameSiteSupplier.ofLax().whenHasName("test1");
|
||||
}
|
||||
|
||||
@Bean
|
||||
CookieSameSiteSupplier cookieSameSiteSupplier2() {
|
||||
return CookieSameSiteSupplier.ofNone().whenHasName("test2");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ServerEndpoint("/")
|
||||
public static class TestEndpoint {
|
||||
|
||||
static void register(ServletContext context) {
|
||||
try {
|
||||
ServerContainer serverContainer = (ServerContainer) context
|
||||
.getAttribute("jakarta.websocket.server.ServerContainer");
|
||||
if (serverContainer != null) {
|
||||
serverContainer.addEndpoint(TestEndpoint.class);
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
// Continue
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class UnauthorizedFilterConfiguration {
|
||||
|
||||
@Bean
|
||||
FilterRegistrationBean<Filter> unauthorizedFilter() {
|
||||
FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>(new Filter() {
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException {
|
||||
((HttpServletResponse) response).sendError(HttpStatus.UNAUTHORIZED.value());
|
||||
}
|
||||
|
||||
});
|
||||
registration.setOrder(Ordered.HIGHEST_PRECEDENCE);
|
||||
registration.addUrlPatterns("/*");
|
||||
registration.setDispatcherTypes(DispatcherType.REQUEST);
|
||||
return registration;
|
||||
}
|
||||
|
||||
@Bean
|
||||
ServletRegistrationBean<HttpServlet> basicServlet() {
|
||||
ServletRegistrationBean<HttpServlet> registration = new ServletRegistrationBean<>(new HttpServlet() {
|
||||
});
|
||||
registration.addUrlMappings("/");
|
||||
return registration;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2024 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.web.servlet;
|
||||
package org.springframework.boot.autoconfigure.web.server.servlet;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@@ -35,8 +35,8 @@ import org.springframework.boot.web.server.Cookie;
|
||||
import org.springframework.boot.web.server.MimeMappings;
|
||||
import org.springframework.boot.web.server.Shutdown;
|
||||
import org.springframework.boot.web.server.Ssl;
|
||||
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
|
||||
import org.springframework.boot.web.servlet.server.Jsp;
|
||||
import org.springframework.boot.web.server.servlet.ConfigurableServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.servlet.Jsp;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2023 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.web.servlet;
|
||||
package org.springframework.boot.autoconfigure.web.server.servlet;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@@ -26,13 +26,13 @@ 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.web.embedded.jetty.JettyServletWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.WebServer;
|
||||
import org.springframework.boot.web.server.servlet.ServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.servlet.jetty.JettyServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.servlet.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.servlet.undertow.UndertowServletWebServerFactory;
|
||||
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
|
||||
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
|
||||
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.server.servlet.jetty;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import jakarta.servlet.Filter;
|
||||
import org.eclipse.jetty.ee10.websocket.servlet.WebSocketUpgradeFilter;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.boot.autoconfigure.web.server.servlet.AbstractServletWebServerAutoConfigurationTests;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.boot.web.server.jetty.JettyServerCustomizer;
|
||||
import org.springframework.boot.web.server.servlet.ServletContextInitializer;
|
||||
import org.springframework.boot.web.server.servlet.jetty.JettyServletWebServerFactory;
|
||||
import org.springframework.boot.web.servlet.AbstractFilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.BDDMockito.then;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Base class for testing sub-classes of {@link JettyServletWebServerAutoConfiguration}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Phillip Webb
|
||||
* @author Stephane Nicoll
|
||||
* @author Raheela Aslam
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
class JettyServletWebServerAutoConfigurationTests extends AbstractServletWebServerAutoConfigurationTests {
|
||||
|
||||
protected JettyServletWebServerAutoConfigurationTests() {
|
||||
super(JettyServletWebServerAutoConfiguration.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void jettyServerCustomizerBeanIsAddedToFactory() {
|
||||
this.serverRunner.withUserConfiguration(JettyServerCustomizerConfiguration.class).run((context) -> {
|
||||
JettyServletWebServerFactory factory = context.getBean(JettyServletWebServerFactory.class);
|
||||
assertThat(factory.getServerCustomizers())
|
||||
.contains(context.getBean("serverCustomizer", JettyServerCustomizer.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void jettyServerCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() {
|
||||
this.serverRunner.withUserConfiguration(DoubleRegistrationJettyServerCustomizerConfiguration.class)
|
||||
.run((context) -> {
|
||||
JettyServletWebServerFactory factory = context.getBean(JettyServletWebServerFactory.class);
|
||||
JettyServerCustomizer customizer = context.getBean("serverCustomizer", JettyServerCustomizer.class);
|
||||
assertThat(factory.getServerCustomizers()).contains(customizer);
|
||||
then(customizer).should().customize(any(Server.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void jettyWebSocketUpgradeFilterIsAddedToServletContex() {
|
||||
this.serverRunner.run((context) -> assertThat(
|
||||
context.getServletContext().getFilterRegistration(WebSocketUpgradeFilter.class.getName()))
|
||||
.isNotNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("rawtypes")
|
||||
void jettyWebSocketUpgradeFilterIsNotExposedAsABean() {
|
||||
this.serverRunner.run((context) -> {
|
||||
Map<String, Filter> filters = context.getBeansOfType(Filter.class);
|
||||
assertThat(filters.values()).noneMatch(WebSocketUpgradeFilter.class::isInstance);
|
||||
Map<String, AbstractFilterRegistrationBean> filterRegistrations = context
|
||||
.getBeansOfType(AbstractFilterRegistrationBean.class);
|
||||
assertThat(filterRegistrations.values()).extracting(AbstractFilterRegistrationBean::getFilter)
|
||||
.noneMatch(WebSocketUpgradeFilter.class::isInstance);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void jettyWebSocketUpgradeFilterServletContextInitializerBacksOffWhenBeanWithSameNameIsDefined() {
|
||||
this.serverRunner
|
||||
.withUserConfiguration(CustomWebSocketUpgradeFilterServletContextInitializerConfiguration.class)
|
||||
.run((context) -> {
|
||||
BeanDefinition definition = context.getBeanFactory()
|
||||
.getBeanDefinition("websocketUpgradeFilterServletContextInitializer");
|
||||
assertThat(definition.getFactoryBeanName())
|
||||
.contains("CustomWebSocketUpgradeFilterServletContextInitializerConfiguration");
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class JettyServerCustomizerConfiguration {
|
||||
|
||||
@Bean
|
||||
JettyServerCustomizer serverCustomizer() {
|
||||
return (server) -> {
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class DoubleRegistrationJettyServerCustomizerConfiguration {
|
||||
|
||||
private final JettyServerCustomizer customizer = mock(JettyServerCustomizer.class);
|
||||
|
||||
@Bean
|
||||
JettyServerCustomizer serverCustomizer() {
|
||||
return this.customizer;
|
||||
}
|
||||
|
||||
@Bean
|
||||
WebServerFactoryCustomizer<JettyServletWebServerFactory> jettyCustomizer() {
|
||||
return (jetty) -> jetty.addServerCustomizers(this.customizer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class CustomWebSocketUpgradeFilterServletContextInitializerConfiguration {
|
||||
|
||||
@Bean
|
||||
ServletContextInitializer websocketUpgradeFilterServletContextInitializer() {
|
||||
return (servletContext) -> {
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,228 @@
|
||||
/*
|
||||
* Copyright 2012-2025 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.server.servlet.tomcat;
|
||||
|
||||
import jakarta.servlet.Filter;
|
||||
import org.apache.catalina.Context;
|
||||
import org.apache.catalina.connector.Connector;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.autoconfigure.web.server.servlet.AbstractServletWebServerAutoConfigurationTests;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
|
||||
import org.springframework.boot.web.server.servlet.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.tomcat.TomcatConnectorCustomizer;
|
||||
import org.springframework.boot.web.server.tomcat.TomcatContextCustomizer;
|
||||
import org.springframework.boot.web.server.tomcat.TomcatProtocolHandlerCustomizer;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.filter.ForwardedHeaderFilter;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.BDDMockito.then;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link TomcatServletWebServerAutoConfiguration}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Phillip Webb
|
||||
* @author Stephane Nicoll
|
||||
* @author Raheela Aslam
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
class TomcatServletWebServerAutoConfigurationTests extends AbstractServletWebServerAutoConfigurationTests {
|
||||
|
||||
TomcatServletWebServerAutoConfigurationTests() {
|
||||
super(TomcatServletWebServerAutoConfiguration.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void tomcatConnectorCustomizerBeanIsAddedToFactory() {
|
||||
this.serverRunner.withUserConfiguration(TomcatConnectorCustomizerConfiguration.class).run((context) -> {
|
||||
TomcatServletWebServerFactory factory = context.getBean(TomcatServletWebServerFactory.class);
|
||||
TomcatConnectorCustomizer customizer = context.getBean("connectorCustomizer",
|
||||
TomcatConnectorCustomizer.class);
|
||||
assertThat(factory.getConnectorCustomizers()).contains(customizer);
|
||||
then(customizer).should().customize(any(Connector.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void tomcatConnectorCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() {
|
||||
this.serverRunner.withUserConfiguration(DoubleRegistrationTomcatConnectorCustomizerConfiguration.class)
|
||||
.run((context) -> {
|
||||
TomcatServletWebServerFactory factory = context.getBean(TomcatServletWebServerFactory.class);
|
||||
TomcatConnectorCustomizer customizer = context.getBean("connectorCustomizer",
|
||||
TomcatConnectorCustomizer.class);
|
||||
assertThat(factory.getConnectorCustomizers()).contains(customizer);
|
||||
then(customizer).should().customize(any(Connector.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void tomcatContextCustomizerBeanIsAddedToFactory() {
|
||||
this.serverRunner.withUserConfiguration(TomcatContextCustomizerConfiguration.class).run((context) -> {
|
||||
TomcatServletWebServerFactory factory = context.getBean(TomcatServletWebServerFactory.class);
|
||||
TomcatContextCustomizer customizer = context.getBean("contextCustomizer", TomcatContextCustomizer.class);
|
||||
assertThat(factory.getContextCustomizers()).contains(customizer);
|
||||
then(customizer).should().customize(any(Context.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void tomcatContextCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() {
|
||||
this.serverRunner.withUserConfiguration(DoubleRegistrationTomcatContextCustomizerConfiguration.class)
|
||||
.run((context) -> {
|
||||
TomcatServletWebServerFactory factory = context.getBean(TomcatServletWebServerFactory.class);
|
||||
TomcatContextCustomizer customizer = context.getBean("contextCustomizer",
|
||||
TomcatContextCustomizer.class);
|
||||
assertThat(factory.getContextCustomizers()).contains(customizer);
|
||||
then(customizer).should().customize(any(Context.class));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void tomcatProtocolHandlerCustomizerBeanIsAddedToFactory() {
|
||||
this.serverRunner.withUserConfiguration(TomcatProtocolHandlerCustomizerConfiguration.class).run((context) -> {
|
||||
TomcatServletWebServerFactory factory = context.getBean(TomcatServletWebServerFactory.class);
|
||||
TomcatProtocolHandlerCustomizer<?> customizer = context.getBean("protocolHandlerCustomizer",
|
||||
TomcatProtocolHandlerCustomizer.class);
|
||||
assertThat(factory.getProtocolHandlerCustomizers()).contains(customizer);
|
||||
then(customizer).should().customize(any());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void tomcatProtocolHandlerCustomizerRegisteredAsBeanAndViaFactoryIsOnlyCalledOnce() {
|
||||
this.serverRunner.withUserConfiguration(DoubleRegistrationTomcatProtocolHandlerCustomizerConfiguration.class)
|
||||
.run((context) -> {
|
||||
TomcatServletWebServerFactory factory = context.getBean(TomcatServletWebServerFactory.class);
|
||||
TomcatProtocolHandlerCustomizer<?> customizer = context.getBean("protocolHandlerCustomizer",
|
||||
TomcatProtocolHandlerCustomizer.class);
|
||||
assertThat(factory.getProtocolHandlerCustomizers()).contains(customizer);
|
||||
then(customizer).should().customize(any());
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingFrameworkForwardHeadersStrategyAndRelativeRedirectsAreEnabledThenFilterIsConfiguredToUseRelativeRedirects() {
|
||||
this.serverRunner
|
||||
.withPropertyValues("server.forward-headers-strategy=framework",
|
||||
"server.tomcat.use-relative-redirects=true", "server.port=0")
|
||||
.run((context) -> {
|
||||
Filter filter = context.getBean(FilterRegistrationBean.class).getFilter();
|
||||
assertThat(filter).isInstanceOf(ForwardedHeaderFilter.class);
|
||||
assertThat(filter).extracting("relativeRedirects").isEqualTo(true);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingFrameworkForwardHeadersStrategyAndNotUsingRelativeRedirectsThenFilterIsNotConfiguredToUseRelativeRedirects() {
|
||||
this.serverRunner
|
||||
.withPropertyValues("server.forward-headers-strategy=framework",
|
||||
"server.tomcat.use-relative-redirects=false", "server.port=0")
|
||||
.run((context) -> {
|
||||
Filter filter = context.getBean(FilterRegistrationBean.class).getFilter();
|
||||
assertThat(filter).isInstanceOf(ForwardedHeaderFilter.class);
|
||||
assertThat(filter).extracting("relativeRedirects").isEqualTo(false);
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class TomcatConnectorCustomizerConfiguration {
|
||||
|
||||
@Bean
|
||||
TomcatConnectorCustomizer connectorCustomizer() {
|
||||
return mock(TomcatConnectorCustomizer.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class DoubleRegistrationTomcatConnectorCustomizerConfiguration {
|
||||
|
||||
private final TomcatConnectorCustomizer customizer = mock(TomcatConnectorCustomizer.class);
|
||||
|
||||
@Bean
|
||||
TomcatConnectorCustomizer connectorCustomizer() {
|
||||
return this.customizer;
|
||||
}
|
||||
|
||||
@Bean
|
||||
WebServerFactoryCustomizer<TomcatServletWebServerFactory> tomcatCustomizer() {
|
||||
return (tomcat) -> tomcat.addConnectorCustomizers(this.customizer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class TomcatContextCustomizerConfiguration {
|
||||
|
||||
@Bean
|
||||
TomcatContextCustomizer contextCustomizer() {
|
||||
return mock(TomcatContextCustomizer.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class DoubleRegistrationTomcatContextCustomizerConfiguration {
|
||||
|
||||
private final TomcatContextCustomizer customizer = mock(TomcatContextCustomizer.class);
|
||||
|
||||
@Bean
|
||||
TomcatContextCustomizer contextCustomizer() {
|
||||
return this.customizer;
|
||||
}
|
||||
|
||||
@Bean
|
||||
WebServerFactoryCustomizer<TomcatServletWebServerFactory> tomcatCustomizer() {
|
||||
return (tomcat) -> tomcat.addContextCustomizers(this.customizer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class TomcatProtocolHandlerCustomizerConfiguration {
|
||||
|
||||
@Bean
|
||||
TomcatProtocolHandlerCustomizer<?> protocolHandlerCustomizer() {
|
||||
return mock(TomcatProtocolHandlerCustomizer.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class DoubleRegistrationTomcatProtocolHandlerCustomizerConfiguration {
|
||||
|
||||
private final TomcatProtocolHandlerCustomizer<?> customizer = mock(TomcatProtocolHandlerCustomizer.class);
|
||||
|
||||
@Bean
|
||||
TomcatProtocolHandlerCustomizer<?> protocolHandlerCustomizer() {
|
||||
return this.customizer;
|
||||
}
|
||||
|
||||
@Bean
|
||||
WebServerFactoryCustomizer<TomcatServletWebServerFactory> tomcatCustomizer() {
|
||||
return (tomcat) -> tomcat.addProtocolHandlerCustomizers(this.customizer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
* Copyright 2012-2025 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.
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.autoconfigure.web.servlet;
|
||||
package org.springframework.boot.autoconfigure.web.server.servlet.tomcat;
|
||||
|
||||
import org.apache.catalina.Context;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -24,8 +24,8 @@ import org.springframework.boot.autoconfigure.web.ServerProperties;
|
||||
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.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatWebServer;
|
||||
import org.springframework.boot.web.server.servlet.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.tomcat.TomcatWebServer;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
import org.springframework.test.context.support.TestPropertySourceUtils;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user