diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java index 9e44dd4bfa56..9502816d9448 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,7 +26,9 @@ import org.apache.catalina.valves.RemoteIpValve; import org.apache.coyote.AbstractProtocol; import org.apache.coyote.ProtocolHandler; +import org.apache.coyote.UpgradeProtocol; import org.apache.coyote.http11.AbstractHttp11Protocol; +import org.apache.coyote.http2.Http2Protocol; import org.springframework.boot.autoconfigure.web.ErrorProperties; import org.springframework.boot.autoconfigure.web.ErrorProperties.IncludeAttribute; @@ -147,6 +149,11 @@ private void customizeProcessorCache(ConfigurableTomcatWebServerFactory factory, private void customizeKeepAliveTimeout(ConfigurableTomcatWebServerFactory factory, Duration keepAliveTimeout) { factory.addConnectorCustomizers((connector) -> { ProtocolHandler handler = connector.getProtocolHandler(); + for (UpgradeProtocol upgradeProtocol : handler.findUpgradeProtocols()) { + if (upgradeProtocol instanceof Http2Protocol) { + ((Http2Protocol) upgradeProtocol).setKeepAliveTimeout(keepAliveTimeout.toMillis()); + } + } if (handler instanceof AbstractProtocol) { AbstractProtocol protocol = (AbstractProtocol) handler; protocol.setKeepAliveTimeout((int) keepAliveTimeout.toMillis()); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java index 6a3742a17222..5e3015b81114 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/embedded/TomcatWebServerFactoryCustomizerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2021 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,6 +28,7 @@ import org.apache.coyote.AbstractProtocol; import org.apache.coyote.ajp.AbstractAjpProtocol; import org.apache.coyote.http11.AbstractHttp11Protocol; +import org.apache.coyote.http2.Http2Protocol; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -106,6 +107,22 @@ void customKeepAliveTimeout() { .isEqualTo(30)); } + @Test + void defaultKeepAliveTimeoutWithHttp2() { + bind("server.http2.enabled=true"); + customizeAndRunServer((server) -> assertThat( + ((Http2Protocol) server.getTomcat().getConnector().findUpgradeProtocols()[0]).getKeepAliveTimeout()) + .isEqualTo(20000L)); + } + + @Test + void customKeepAliveTimeoutWithHttp2() { + bind("server.tomcat.keep-alive-timeout=30s", "server.http2.enabled=true"); + customizeAndRunServer((server) -> assertThat( + ((Http2Protocol) server.getTomcat().getConnector().findUpgradeProtocols()[0]).getKeepAliveTimeout()) + .isEqualTo(30000L)); + } + @Test void customMaxKeepAliveRequests() { bind("server.tomcat.max-keep-alive-requests=-1"); @@ -514,6 +531,7 @@ private TomcatWebServer customizeAndGetServer() { private TomcatServletWebServerFactory customizeAndGetFactory() { TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(0); + factory.setHttp2(this.serverProperties.getHttp2()); this.customizer.customize(factory); return factory; }