Skip to content

Commit fea535d

Browse files
committed
Update HTTP/2 auto-configuration for Jetty
Prior to this commit, the HTTP/2 server auto-configuration for Jetty would require Conscrypt as a hard dependency. This commit updates the auto-configuration for more flexibility and now allows the following deployments: * JDK9+ with the JDK ALPN implementation * JDK8u252+ with the backported ALPN implementation * Conscrypt with no JDK requirement The auto-configuration now improves detection and guides developers in case there is a missing `jetty-alpn-*-server` dependency. The reference docs in the HOWTO section has been updated accordingly. Closes gh-22188
1 parent be32843 commit fea535d

File tree

2 files changed

+38
-17
lines changed

2 files changed

+38
-17
lines changed

spring-boot-project/spring-boot-docs/src/docs/asciidoc/howto.adoc

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ We recommend using `application.properties` to configure HTTPS, as the HTTP conn
581581
[[howto-configure-http2]]
582582
=== Configure HTTP/2
583583
You can enable HTTP/2 support in your Spring Boot application with the configprop:server.http2.enabled[] configuration property.
584-
This support depends on the chosen web server and the application environment, since that protocol is not supported out-of-the-box by JDK8.
584+
This support depends on the chosen web server and the application environment, since that protocol is not supported out-of-the-box by all JDK8 releases.
585585

586586
[NOTE]
587587
====
@@ -599,8 +599,12 @@ As of Undertow 1.4.0+, HTTP/2 is supported without any additional requirement on
599599

600600
[[howto-configure-http2-jetty]]
601601
==== HTTP/2 with Jetty
602-
As of Jetty 9.4.8, HTTP/2 is also supported with the https://www.conscrypt.org/[Conscrypt library].
603-
To enable that support, your application needs to have two additional dependencies: `org.eclipse.jetty:jetty-alpn-conscrypt-server` and `org.eclipse.jetty.http2:http2-server`.
602+
For HTTP/2 support, Jetty requires the additional `org.eclipse.jetty.http2:http2-server` dependency.
603+
Now depending on your deployment, you also need to choose other dependencies:
604+
605+
* `org.eclipse.jetty:jetty-alpn-java-server` for applications running on JDK9+
606+
* `org.eclipse.jetty:jetty-alpn-openjdk8-server` for applications running on JDK8u252+
607+
* `org.eclipse.jetty:jetty-alpn-conscrypt-server` and the https://www.conscrypt.org/[Conscrypt library] with no JDK requirement
604608

605609

606610

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/jetty/SslServerCustomizer.java

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,10 @@ private ServerConnector createServerConnector(Server server, SslContextFactory.S
9696
if (this.http2 == null || !this.http2.isEnabled()) {
9797
return createHttp11ServerConnector(server, config, sslContextFactory);
9898
}
99-
Assert.state(isAlpnPresent(),
100-
() -> "The 'org.eclipse.jetty:jetty-alpn-server' dependency is required for HTTP/2 support.");
101-
Assert.state(isConscryptPresent(), () -> "The 'org.eclipse.jetty.http2:http2-server' and Conscrypt "
102-
+ "dependencies are required for HTTP/2 support.");
99+
Assert.state(isJettyAlpnPresent(),
100+
() -> "An 'org.eclipse.jetty:jetty-alpn-*-server' dependency is required for HTTP/2 support.");
101+
Assert.state(isJettyHttp2Present(),
102+
() -> "The 'org.eclipse.jetty.http2:http2-server' dependency is required for HTTP/2 support.");
103103
return createHttp2ServerConnector(server, config, sslContextFactory);
104104
}
105105

@@ -112,23 +112,40 @@ private ServerConnector createHttp11ServerConnector(Server server, HttpConfigura
112112
connectionFactory);
113113
}
114114

115-
private boolean isAlpnPresent() {
116-
return ClassUtils.isPresent("org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory", null);
115+
private boolean isJettyAlpnPresent() {
116+
return ClassUtils.isPresent("org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory", null);
117117
}
118118

119-
private boolean isConscryptPresent() {
120-
return ClassUtils.isPresent("org.conscrypt.Conscrypt", null);
119+
private boolean isJettyHttp2Present() {
120+
return ClassUtils.isPresent("org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory", null);
121121
}
122122

123123
private ServerConnector createHttp2ServerConnector(Server server, HttpConfiguration config,
124124
SslContextFactory.Server sslContextFactory) {
125+
HttpConnectionFactory http = new HttpConnectionFactory(config);
125126
HTTP2ServerConnectionFactory h2 = new HTTP2ServerConnectionFactory(config);
126-
ALPNServerConnectionFactory alpn = new ALPNServerConnectionFactory();
127+
ALPNServerConnectionFactory alpn = createAlpnServerConnectionFactory();
127128
sslContextFactory.setCipherComparator(HTTP2Cipher.COMPARATOR);
128-
sslContextFactory.setProvider("Conscrypt");
129+
if (isConscryptPresent()) {
130+
sslContextFactory.setProvider("Conscrypt");
131+
}
129132
SslConnectionFactory ssl = new SslConnectionFactory(sslContextFactory, alpn.getProtocol());
130-
return new SslValidatingServerConnector(server, sslContextFactory, this.ssl.getKeyAlias(), ssl, alpn, h2,
131-
new HttpConnectionFactory(config));
133+
return new SslValidatingServerConnector(server, sslContextFactory, this.ssl.getKeyAlias(), ssl, alpn, h2, http);
134+
}
135+
136+
private ALPNServerConnectionFactory createAlpnServerConnectionFactory() {
137+
try {
138+
return new ALPNServerConnectionFactory();
139+
}
140+
catch (IllegalStateException ex) {
141+
throw new IllegalStateException(
142+
"An 'org.eclipse.jetty:jetty-alpn-*-server' dependency is required for HTTP/2 support.", ex);
143+
}
144+
}
145+
146+
private boolean isConscryptPresent() {
147+
return ClassUtils.isPresent("org.conscrypt.Conscrypt", null)
148+
&& ClassUtils.isPresent("org.eclipse.jetty.alpn.conscrypt.server.ConscryptServerALPNProcessor", null);
132149
}
133150

134151
/**
@@ -225,9 +242,9 @@ private void configureSslTrustStore(SslContextFactory.Server factory, Ssl ssl) {
225242
*/
226243
static class SslValidatingServerConnector extends ServerConnector {
227244

228-
private SslContextFactory sslContextFactory;
245+
private final SslContextFactory sslContextFactory;
229246

230-
private String keyAlias;
247+
private final String keyAlias;
231248

232249
SslValidatingServerConnector(Server server, SslContextFactory sslContextFactory, String keyAlias,
233250
SslConnectionFactory sslConnectionFactory, HttpConnectionFactory connectionFactory) {

0 commit comments

Comments
 (0)