diff --git a/spring-cloud-gateway-integration-tests/http2/pom.xml b/spring-cloud-gateway-integration-tests/http2/pom.xml
new file mode 100644
index 00000000..5b31be14
--- /dev/null
+++ b/spring-cloud-gateway-integration-tests/http2/pom.xml
@@ -0,0 +1,67 @@
+
+
+ 4.0.0
+
+ http2
+ jar
+
+ Spring Cloud Gateway HTTP2 Integration Test
+ Spring Cloud Gateway HTTP2 Integration Test
+
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-gateway-integration-tests
+ 3.1.0-SNAPSHOT
+ ..
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-webflux
+
+
+ org.springframework.cloud
+ spring-cloud-starter-gateway
+
+
+ org.springframework.cloud
+ spring-cloud-starter-loadbalancer
+
+
+ io.netty
+ netty-tcnative-boringssl-static
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ io.projectreactor
+ reactor-test
+ test
+
+
+ org.assertj
+ assertj-core
+ test
+
+
+
+
+
+ maven-deploy-plugin
+
+ true
+
+
+
+
+
+
diff --git a/spring-cloud-gateway-integration-tests/http2/src/main/java/org/springframework/cloud/gateway/tests/http2/Http2Application.java b/spring-cloud-gateway-integration-tests/http2/src/main/java/org/springframework/cloud/gateway/tests/http2/Http2Application.java
new file mode 100644
index 00000000..cb68162e
--- /dev/null
+++ b/spring-cloud-gateway-integration-tests/http2/src/main/java/org/springframework/cloud/gateway/tests/http2/Http2Application.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2013-2021 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.cloud.gateway.tests.http2;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.SpringBootConfiguration;
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.cloud.client.DefaultServiceInstance;
+import org.springframework.cloud.gateway.route.RouteLocator;
+import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
+import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient;
+import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClients;
+import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
+import org.springframework.cloud.loadbalancer.support.ServiceInstanceListSuppliers;
+import org.springframework.context.annotation.Bean;
+import org.springframework.core.env.Environment;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author Spencer Gibb
+ */
+// curl -i --insecure https://localhost:8443/hello
+@SpringBootConfiguration
+@EnableAutoConfiguration
+@RestController
+@LoadBalancerClients({
+ @LoadBalancerClient(name = "myservice", configuration = Http2Application.MyServiceConf.class),
+ @LoadBalancerClient(name = "nossl", configuration = Http2Application.NosslServiceConf.class)
+})
+public class Http2Application {
+
+ @GetMapping("hello")
+ public String hello() {
+ return "Hello";
+ }
+
+ @Bean
+ public RouteLocator myRouteLocator(RouteLocatorBuilder builder) {
+ return builder.routes().route(r -> r.path("/myprefix/**").filters(f -> f.stripPrefix(1)).uri("lb://myservice"))
+ .route(r -> r.path("/nossl/**").filters(f -> f.stripPrefix(1)).uri("lb://nossl"))
+ .route(r -> r.path("/neverssl/**").filters(f -> f.stripPrefix(1)).uri("http://neverssl.com"))
+ .route(r -> r.path("/httpbin/**").uri("https://nghttp2.org")).build();
+ }
+
+ public static void main(String[] args) {
+ SpringApplication.run(Http2Application.class, args);
+ }
+
+ static class MyServiceConf {
+
+ @Bean
+ public ServiceInstanceListSupplier staticServiceInstanceListSupplier(Environment env) {
+ Integer port = env.getProperty("local.server.port", Integer.class, 8443);
+ return ServiceInstanceListSuppliers.from("myservice",
+ new DefaultServiceInstance("myservice-1", "myservice", "localhost", port, true));
+ }
+
+ }
+
+ static class NosslServiceConf {
+
+ @Bean
+ public ServiceInstanceListSupplier noSslStaticServiceInstanceListSupplier() {
+ int port = Integer.parseInt(System.getProperty("nossl.port", "8080"));
+ return ServiceInstanceListSuppliers.from("nossl",
+ new DefaultServiceInstance("nossl-1", "nossl", "localhost", port, false));
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/spring-cloud-gateway-integration-tests/http2/src/main/resources/application.yml b/spring-cloud-gateway-integration-tests/http2/src/main/resources/application.yml
new file mode 100644
index 00000000..8438b1d5
--- /dev/null
+++ b/spring-cloud-gateway-integration-tests/http2/src/main/resources/application.yml
@@ -0,0 +1,22 @@
+logging:
+ level:
+ org.springframework.cloud.gateway: TRACE
+ reactor.netty.http.client: DEBUG
+
+server:
+ ssl:
+ key-store: classpath:sample.jks
+ key-store-password: secret
+ key-password: password
+ http2:
+ enabled: true
+
+spring:
+ cloud:
+ gateway:
+# httpserver:
+# wiretap: true
+ httpclient:
+ wiretap: true
+ ssl:
+ use-insecure-trust-manager: true
\ No newline at end of file
diff --git a/spring-cloud-gateway-integration-tests/http2/src/main/resources/sample.jks b/spring-cloud-gateway-integration-tests/http2/src/main/resources/sample.jks
new file mode 100644
index 00000000..6aa9a280
Binary files /dev/null and b/spring-cloud-gateway-integration-tests/http2/src/main/resources/sample.jks differ
diff --git a/spring-cloud-gateway-integration-tests/http2/src/test/java/org/springframework/cloud/gateway/tests/http2/Http2ApplicationTests.java b/spring-cloud-gateway-integration-tests/http2/src/test/java/org/springframework/cloud/gateway/tests/http2/Http2ApplicationTests.java
new file mode 100644
index 00000000..b690adbc
--- /dev/null
+++ b/spring-cloud-gateway-integration-tests/http2/src/test/java/org/springframework/cloud/gateway/tests/http2/Http2ApplicationTests.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2013-2021 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.cloud.gateway.tests.http2;
+
+import java.nio.charset.StandardCharsets;
+import java.time.Duration;
+
+import io.netty.buffer.ByteBufAllocator;
+import io.netty.handler.codec.http.HttpMethod;
+import io.netty.handler.codec.http.HttpResponseStatus;
+import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import reactor.core.publisher.Flux;
+import reactor.core.publisher.Mono;
+import reactor.netty.http.Http2SslContextSpec;
+import reactor.netty.http.HttpProtocol;
+import reactor.netty.http.client.HttpClient;
+import reactor.netty.http.client.HttpClientResponse;
+import reactor.netty.resources.ConnectionProvider;
+import reactor.test.StepVerifier;
+
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.system.CapturedOutput;
+import org.springframework.boot.test.system.OutputCaptureExtension;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.core.io.buffer.DataBufferUtils;
+import org.springframework.core.io.buffer.NettyDataBufferFactory;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+
+/**
+ * @author Spencer Gibb
+ */
+@ExtendWith(OutputCaptureExtension.class)
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
+public class Http2ApplicationTests {
+
+ @LocalServerPort
+ int port;
+
+ @Test
+ public void http2Works(CapturedOutput output) {
+ String uri = "https://localhost:" + port + "/myprefix/hello";
+ String expected = "Hello";
+ assertResponse(uri, expected);
+ Assertions.assertThat(output).contains("Negotiated application-level protocol [h2]", "PRI * HTTP/2.0");
+ }
+
+ public static void assertResponse(String uri, String expected ) {
+ Flux responseFlux = getHttpClient().request(HttpMethod.GET)
+ .uri(uri)
+ .send(Mono.empty())
+ .response((res, byteBufFlux) -> {
+ assertThat(res.status()).isEqualTo(HttpResponseStatus.OK);
+ NettyDataBufferFactory bufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);
+ return DataBufferUtils.join(byteBufFlux.map(bufferFactory::wrap))
+ .map(dataBuffer -> dataBuffer.toString(StandardCharsets.UTF_8))
+ .map(s -> {
+ assertThat(s).isEqualTo(expected);
+ return res;
+ });
+ });
+
+ StepVerifier.create(responseFlux).expectNextCount(1).expectComplete().verify();
+ }
+
+ static HttpClient getHttpClient() {
+ return HttpClient.create(ConnectionProvider.builder("test").maxConnections(100)
+ .pendingAcquireTimeout(Duration.ofMillis(0))
+ .pendingAcquireMaxCount(-1).build())
+ .protocol(HttpProtocol.HTTP11, HttpProtocol.H2)
+ .secure(sslContextSpec -> {
+ Http2SslContextSpec clientSslCtxt =
+ Http2SslContextSpec.forClient()
+ .configure(builder -> builder.trustManager(InsecureTrustManagerFactory.INSTANCE));
+ sslContextSpec.sslContext(clientSslCtxt);
+ });
+ }
+
+}
diff --git a/spring-cloud-gateway-integration-tests/http2/src/test/java/org/springframework/cloud/gateway/tests/http2/config/NosslConfiguration.java b/spring-cloud-gateway-integration-tests/http2/src/test/java/org/springframework/cloud/gateway/tests/http2/config/NosslConfiguration.java
new file mode 100644
index 00000000..f303049d
--- /dev/null
+++ b/spring-cloud-gateway-integration-tests/http2/src/test/java/org/springframework/cloud/gateway/tests/http2/config/NosslConfiguration.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2013-2021 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.cloud.gateway.tests.http2.config;
+
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@Configuration
+@EnableAutoConfiguration
+public class NosslConfiguration {
+
+ @GetMapping
+ public String home() {
+ return "nossl";
+ }
+}
diff --git a/spring-cloud-gateway-integration-tests/http2/src/test/java/org/springframework/cloud/gateway/tests/http2/config/NosslTests.java b/spring-cloud-gateway-integration-tests/http2/src/test/java/org/springframework/cloud/gateway/tests/http2/config/NosslTests.java
new file mode 100644
index 00000000..0f4d5c5a
--- /dev/null
+++ b/spring-cloud-gateway-integration-tests/http2/src/test/java/org/springframework/cloud/gateway/tests/http2/config/NosslTests.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2013-2021 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.cloud.gateway.tests.http2.config;
+
+import org.assertj.core.api.Assertions;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.system.CapturedOutput;
+import org.springframework.boot.test.system.OutputCaptureExtension;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.cloud.gateway.tests.http2.Http2Application;
+import org.springframework.util.SocketUtils;
+
+import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import static org.springframework.cloud.gateway.tests.http2.Http2ApplicationTests.assertResponse;
+
+/**
+ * @author Spencer Gibb
+ */
+@ExtendWith(OutputCaptureExtension.class)
+@SpringBootTest(classes = Http2Application.class, webEnvironment = WebEnvironment.RANDOM_PORT)
+public class NosslTests {
+
+ @LocalServerPort
+ int port;
+
+ @BeforeAll
+ static void beforeAll() {
+ int noSslPort = SocketUtils.findAvailableTcpPort();
+ System.setProperty("nossl.port", String.valueOf(noSslPort));
+ }
+
+ @AfterAll
+ static void afterAll() {
+ System.clearProperty("nossl.port");
+ }
+
+ @Test
+ public void http2Works(CapturedOutput output) {
+ String uri = "https://localhost:" + port + "/myprefix/hello";
+ String expected = "Hello";
+ assertResponse(uri, expected);
+ Assertions.assertThat(output).contains("Negotiated application-level protocol [h2]", "PRI * HTTP/2.0");
+ }
+
+
+}
diff --git a/spring-cloud-gateway-integration-tests/http2/src/test/resources/application-nossl.yml b/spring-cloud-gateway-integration-tests/http2/src/test/resources/application-nossl.yml
new file mode 100644
index 00000000..6143bf9d
--- /dev/null
+++ b/spring-cloud-gateway-integration-tests/http2/src/test/resources/application-nossl.yml
@@ -0,0 +1,13 @@
+server:
+ ssl:
+ enabled: false
+ key-store: ~
+ key-store-password: ~
+ key-password: ~
+ http2:
+ enabled: false
+
+spring:
+ cloud:
+ gateway:
+ enabled: false
\ No newline at end of file
diff --git a/spring-cloud-gateway-integration-tests/pom.xml b/spring-cloud-gateway-integration-tests/pom.xml
index 6e396521..f0197462 100644
--- a/spring-cloud-gateway-integration-tests/pom.xml
+++ b/spring-cloud-gateway-integration-tests/pom.xml
@@ -21,6 +21,7 @@
+ http2
mvc-failure-analyzer
diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java
index e51e0fc8..60c9634b 100644
--- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java
+++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/GatewayAutoConfiguration.java
@@ -23,15 +23,18 @@ import java.util.Set;
import java.util.function.Supplier;
import io.netty.channel.ChannelOption;
-import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import reactor.core.publisher.Flux;
+import reactor.netty.http.Http11SslContextSpec;
+import reactor.netty.http.Http2SslContextSpec;
+import reactor.netty.http.HttpProtocol;
import reactor.netty.http.client.HttpClient;
import reactor.netty.http.client.WebsocketClientSpec;
import reactor.netty.http.server.WebsocketServerSpec;
import reactor.netty.resources.ConnectionProvider;
+import reactor.netty.tcp.SslProvider.ProtocolSslContextSpec;
import reactor.netty.transport.ProxyProvider;
import org.springframework.beans.factory.BeanFactory;
@@ -641,7 +644,8 @@ public class GatewayAutoConfiguration {
@Bean
@ConditionalOnMissingBean
- public HttpClient gatewayHttpClient(HttpClientProperties properties, List customizers) {
+ public HttpClient gatewayHttpClient(HttpClientProperties properties, ServerProperties serverProperties,
+ List customizers) {
// configure pool resources
ConnectionProvider connectionProvider = buildConnectionProvider(properties);
@@ -658,57 +662,66 @@ public class GatewayAutoConfiguration {
spec.maxInitialLineLength((int) properties.getMaxInitialLineLength().toBytes());
}
return spec;
- }).tcpConfiguration(tcpClient -> {
-
- if (properties.getConnectTimeout() != null) {
- tcpClient = tcpClient.option(ChannelOption.CONNECT_TIMEOUT_MILLIS,
- properties.getConnectTimeout());
- }
-
- // configure proxy if proxy host is set.
- HttpClientProperties.Proxy proxy = properties.getProxy();
-
- if (StringUtils.hasText(proxy.getHost())) {
-
- tcpClient = tcpClient.proxy(proxySpec -> {
- ProxyProvider.Builder builder = proxySpec.type(proxy.getType()).host(proxy.getHost());
-
- PropertyMapper map = PropertyMapper.get();
-
- map.from(proxy::getPort).whenNonNull().to(builder::port);
- map.from(proxy::getUsername).whenHasText().to(builder::username);
- map.from(proxy::getPassword).whenHasText()
- .to(password -> builder.password(s -> password));
- map.from(proxy::getNonProxyHostsPattern).whenHasText().to(builder::nonProxyHosts);
- });
- }
- return tcpClient;
});
+ if (serverProperties.getHttp2().isEnabled()) {
+ httpClient = httpClient.protocol(HttpProtocol.HTTP11, HttpProtocol.H2);
+ }
+
+ if (properties.getConnectTimeout() != null) {
+ httpClient = httpClient.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, properties.getConnectTimeout());
+ }
+
+ // configure proxy if proxy host is set.
+ if (StringUtils.hasText(properties.getProxy().getHost())) {
+ HttpClientProperties.Proxy proxy = properties.getProxy();
+
+ httpClient = httpClient.proxy(proxySpec -> {
+ ProxyProvider.Builder builder = proxySpec.type(proxy.getType()).host(proxy.getHost());
+
+ PropertyMapper map = PropertyMapper.get();
+
+ map.from(proxy::getPort).whenNonNull().to(builder::port);
+ map.from(proxy::getUsername).whenHasText().to(builder::username);
+ map.from(proxy::getPassword).whenHasText().to(password -> builder.password(s -> password));
+ map.from(proxy::getNonProxyHostsPattern).whenHasText().to(builder::nonProxyHosts);
+ });
+ }
+
HttpClientProperties.Ssl ssl = properties.getSsl();
if ((ssl.getKeyStore() != null && ssl.getKeyStore().length() > 0)
|| ssl.getTrustedX509CertificatesForTrustManager().length > 0 || ssl.isUseInsecureTrustManager()) {
httpClient = httpClient.secure(sslContextSpec -> {
// configure ssl
- SslContextBuilder sslContextBuilder = SslContextBuilder.forClient();
+ ProtocolSslContextSpec clientSslContext = (serverProperties.getHttp2().isEnabled())
+ ? Http2SslContextSpec.forClient() : Http11SslContextSpec.forClient();
+ clientSslContext.configure(sslContextBuilder -> {
+ X509Certificate[] trustedX509Certificates = ssl.getTrustedX509CertificatesForTrustManager();
+ if (trustedX509Certificates.length > 0) {
+ sslContextBuilder.trustManager(trustedX509Certificates);
+ }
+ else if (ssl.isUseInsecureTrustManager()) {
+ sslContextBuilder.trustManager(InsecureTrustManagerFactory.INSTANCE);
+ }
- X509Certificate[] trustedX509Certificates = ssl.getTrustedX509CertificatesForTrustManager();
- if (trustedX509Certificates.length > 0) {
- sslContextBuilder = sslContextBuilder.trustManager(trustedX509Certificates);
- }
- else if (ssl.isUseInsecureTrustManager()) {
- sslContextBuilder = sslContextBuilder.trustManager(InsecureTrustManagerFactory.INSTANCE);
- }
+ try {
+ sslContextBuilder.keyManager(ssl.getKeyManagerFactory());
+ }
+ catch (Exception e) {
+ logger.error(e);
+ }
+ });
- try {
- sslContextBuilder = sslContextBuilder.keyManager(ssl.getKeyManagerFactory());
- }
- catch (Exception e) {
- logger.error(e);
- }
-
- sslContextSpec.sslContext(sslContextBuilder).defaultConfiguration(ssl.getDefaultConfigurationType())
- .handshakeTimeout(ssl.getHandshakeTimeout())
+ sslContextSpec.sslContext(clientSslContext).handshakeTimeout(ssl.getHandshakeTimeout())
+ .closeNotifyFlushTimeout(ssl.getCloseNotifyFlushTimeout())
+ .closeNotifyReadTimeout(ssl.getCloseNotifyReadTimeout());
+ });
+ }
+ else if (serverProperties.getHttp2().isEnabled()) {
+ httpClient = httpClient.secure(sslContextSpec -> {
+ Http2SslContextSpec clientSslCtxt = Http2SslContextSpec.forClient()
+ .configure(builder -> builder.trustManager(InsecureTrustManagerFactory.INSTANCE));
+ sslContextSpec.sslContext(clientSslCtxt).handshakeTimeout(ssl.getHandshakeTimeout())
.closeNotifyFlushTimeout(ssl.getCloseNotifyFlushTimeout())
.closeNotifyReadTimeout(ssl.getCloseNotifyReadTimeout());
});
diff --git a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientProperties.java b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientProperties.java
index a7054cd4..59295613 100644
--- a/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientProperties.java
+++ b/spring-cloud-gateway-server/src/main/java/org/springframework/cloud/gateway/config/HttpClientProperties.java
@@ -403,6 +403,7 @@ public class HttpClientProperties {
private Duration closeNotifyReadTimeout = Duration.ZERO;
/** The default ssl configuration type. Defaults to TCP. */
+ @Deprecated
private SslProvider.DefaultConfigurationType defaultConfigurationType = SslProvider.DefaultConfigurationType.TCP;
/** Keystore path for Netty HttpClient. */
@@ -568,10 +569,12 @@ public class HttpClientProperties {
this.closeNotifyReadTimeout = closeNotifyReadTimeout;
}
+ @Deprecated
public SslProvider.DefaultConfigurationType getDefaultConfigurationType() {
return defaultConfigurationType;
}
+ @Deprecated
public void setDefaultConfigurationType(SslProvider.DefaultConfigurationType defaultConfigurationType) {
this.defaultConfigurationType = defaultConfigurationType;
}
diff --git a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/config/GatewayAutoConfigurationTests.java b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/config/GatewayAutoConfigurationTests.java
index a39c91b9..cbff76b2 100644
--- a/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/config/GatewayAutoConfigurationTests.java
+++ b/spring-cloud-gateway-server/src/test/java/org/springframework/cloud/gateway/config/GatewayAutoConfigurationTests.java
@@ -33,7 +33,9 @@ import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration;
import org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration;
+import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
import org.springframework.cloud.gateway.actuate.GatewayControllerEndpoint;
import org.springframework.cloud.gateway.actuate.GatewayLegacyControllerEndpoint;
@@ -68,7 +70,8 @@ public class GatewayAutoConfigurationTests {
public void nettyHttpClientDefaults() {
new ReactiveWebApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(WebFluxAutoConfiguration.class, MetricsAutoConfiguration.class,
- SimpleMetricsExportAutoConfiguration.class, GatewayAutoConfiguration.class))
+ SimpleMetricsExportAutoConfiguration.class, GatewayAutoConfiguration.class,
+ ServerPropertiesConfig.class))
.withPropertyValues("debug=true").run(context -> {
assertThat(context).hasSingleBean(HttpClient.class);
assertThat(context).hasBean("gatewayHttpClient");
@@ -94,7 +97,7 @@ public class GatewayAutoConfigurationTests {
new ReactiveWebApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(WebFluxAutoConfiguration.class, MetricsAutoConfiguration.class,
SimpleMetricsExportAutoConfiguration.class, GatewayAutoConfiguration.class,
- HttpClientCustomizedConfig.class))
+ HttpClientCustomizedConfig.class, ServerPropertiesConfig.class))
.withPropertyValues("spring.cloud.gateway.httpclient.ssl.use-insecure-trust-manager=true",
"spring.cloud.gateway.httpclient.connect-timeout=10",
"spring.cloud.gateway.httpclient.response-timeout=10s",
@@ -228,6 +231,12 @@ public class GatewayAutoConfigurationTests {
assertThat(spec2.protocols()).isNull();
}
+ @Configuration
+ @EnableConfigurationProperties(ServerProperties.class)
+ protected static class ServerPropertiesConfig {
+
+ }
+
@EnableAutoConfiguration
@SpringBootConfiguration
protected static class Config {