diff options
author | Bjørn Christian Seime <bjorn.christian@seime.no> | 2021-04-12 09:47:31 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-12 09:47:31 +0200 |
commit | dcf5a1b725facbaff14ba7659254ea4b72895dbb (patch) | |
tree | 66c99c65b619df66f8a34305ac23069fdbdd48e1 /container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/ConnectorFactory.java | |
parent | 015ade7cd232f217dd964da037ab202731b37cef (diff) |
Revert "Revert "Bjorncs/jdisc http2 preps [run-systemtest]""
Diffstat (limited to 'container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/ConnectorFactory.java')
-rw-r--r-- | container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/ConnectorFactory.java | 92 |
1 files changed, 75 insertions, 17 deletions
diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/ConnectorFactory.java b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/ConnectorFactory.java index d7ad12a5c64..bc358e2fb06 100644 --- a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/ConnectorFactory.java +++ b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/ConnectorFactory.java @@ -7,6 +7,8 @@ import com.yahoo.jdisc.http.ConnectorConfig; import com.yahoo.jdisc.http.ssl.SslContextFactoryProvider; import com.yahoo.security.tls.MixedMode; import com.yahoo.security.tls.TransportSecurityUtils; +import org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory; +import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory; import org.eclipse.jetty.server.ConnectionFactory; import org.eclipse.jetty.server.DetectorConnectionFactory; import org.eclipse.jetty.server.HttpConfiguration; @@ -18,6 +20,7 @@ import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.SslConnectionFactory; import org.eclipse.jetty.util.ssl.SslContextFactory; +import java.util.Collection; import java.util.List; /** @@ -76,41 +79,72 @@ public class ConnectorFactory { } private List<ConnectionFactory> createConnectionFactories(Metric metric) { - HttpConnectionFactory httpFactory = newHttpConnectionFactory(); if (!isSslEffectivelyEnabled(connectorConfig)) { - return List.of(httpFactory); + return List.of(newHttp1ConnectionFactory()); } else if (connectorConfig.ssl().enabled()) { - return connectionFactoriesForHttps(metric, httpFactory); + return connectionFactoriesForHttps(metric); } else if (TransportSecurityUtils.isTransportSecurityEnabled()) { switch (TransportSecurityUtils.getInsecureMixedMode()) { case TLS_CLIENT_MIXED_SERVER: case PLAINTEXT_CLIENT_MIXED_SERVER: - return List.of(new DetectorConnectionFactory(newSslConnectionFactory(metric, httpFactory)), httpFactory); + return connectionFactoriesForHttpsMixedMode(metric); case DISABLED: - return connectionFactoriesForHttps(metric, httpFactory); + return connectionFactoriesForHttps(metric); default: throw new IllegalStateException(); } } else { - return List.of(httpFactory); + return List.of(newHttp1ConnectionFactory()); } } - private List<ConnectionFactory> connectionFactoriesForHttps(Metric metric, HttpConnectionFactory httpFactory) { + private List<ConnectionFactory> connectionFactoriesForHttps(Metric metric) { ConnectorConfig.ProxyProtocol proxyProtocolConfig = connectorConfig.proxyProtocol(); - SslConnectionFactory sslFactory = newSslConnectionFactory(metric, httpFactory); - if (proxyProtocolConfig.enabled()) { - if (proxyProtocolConfig.mixedMode()) { - return List.of(new DetectorConnectionFactory(sslFactory, new ProxyConnectionFactory(sslFactory.getProtocol())), sslFactory, httpFactory); + HttpConnectionFactory http1Factory = newHttp1ConnectionFactory(); + if (connectorConfig.http2Enabled()) { + HTTP2ServerConnectionFactory http2Factory = newHttp2ConnectionFactory(); + ALPNServerConnectionFactory alpnFactory = newAlpnConnectionFactory(List.of(http1Factory, http2Factory), http1Factory); + SslConnectionFactory sslFactory = newSslConnectionFactory(metric, alpnFactory); + if (proxyProtocolConfig.enabled()) { + if (proxyProtocolConfig.mixedMode()) { + ProxyConnectionFactory proxyProtocolFactory = newProxyProtocolConnectionFactory(alpnFactory); + DetectorConnectionFactory detectorFactory = newDetectorConnectionFactory(sslFactory, proxyProtocolFactory); + return List.of(detectorFactory, proxyProtocolFactory, sslFactory, alpnFactory, http1Factory, http2Factory); + } else { + ProxyConnectionFactory proxyProtocolFactory = newProxyProtocolConnectionFactory(alpnFactory); + return List.of(proxyProtocolFactory, sslFactory, alpnFactory, http1Factory, http2Factory); + } } else { - return List.of(new ProxyConnectionFactory(sslFactory.getProtocol()), sslFactory, httpFactory); + return List.of(sslFactory, alpnFactory, http1Factory, http2Factory); } } else { - return List.of(sslFactory, httpFactory); + SslConnectionFactory sslFactory = newSslConnectionFactory(metric, http1Factory); + if (proxyProtocolConfig.enabled()) { + if (proxyProtocolConfig.mixedMode()) { + ProxyConnectionFactory proxyProtocolFactory = newProxyProtocolConnectionFactory(sslFactory); + DetectorConnectionFactory detectorFactory = newDetectorConnectionFactory(sslFactory, proxyProtocolFactory); + return List.of(detectorFactory, proxyProtocolFactory, sslFactory, http1Factory); + } else { + ProxyConnectionFactory proxyProtocolFactory = newProxyProtocolConnectionFactory(sslFactory); + return List.of(proxyProtocolFactory, sslFactory, http1Factory); + } + } else { + return List.of(sslFactory, http1Factory); + } } } - private HttpConnectionFactory newHttpConnectionFactory() { + private List<ConnectionFactory> connectionFactoriesForHttpsMixedMode(Metric metric) { + // No support for proxy-protocol/http2 when using HTTP with TLS mixed mode + HttpConnectionFactory httpFactory = newHttp1ConnectionFactory(); + SslConnectionFactory sslFactory = newSslConnectionFactory(metric, httpFactory); + // Detector connection factory with single alternative will fallback to next protocol in list (httpFactory in this case) + // Cannot specify HttpConnectionFactory as alternative it does not implement ConnectionFactory.Detecting + DetectorConnectionFactory detectorFactory = newDetectorConnectionFactory(sslFactory); + return List.of(detectorFactory, httpFactory, sslFactory); + } + + private HttpConfiguration newHttpConfiguration() { HttpConfiguration httpConfig = new HttpConfiguration(); httpConfig.setSendDateHeader(true); httpConfig.setSendServerVersion(false); @@ -122,16 +156,40 @@ public class ConnectorFactory { if (isSslEffectivelyEnabled(connectorConfig)) { httpConfig.addCustomizer(new SecureRequestCustomizer()); } - return new HttpConnectionFactory(httpConfig); + return httpConfig; + } + + private HttpConnectionFactory newHttp1ConnectionFactory() { + return new HttpConnectionFactory(newHttpConfiguration()); } - private SslConnectionFactory newSslConnectionFactory(Metric metric, HttpConnectionFactory httpFactory) { + private HTTP2ServerConnectionFactory newHttp2ConnectionFactory() { + return new HTTP2ServerConnectionFactory(newHttpConfiguration()); + } + + private SslConnectionFactory newSslConnectionFactory(Metric metric, ConnectionFactory wrappedFactory) { SslContextFactory ctxFactory = sslContextFactoryProvider.getInstance(connectorConfig.name(), connectorConfig.listenPort()); - SslConnectionFactory connectionFactory = new SslConnectionFactory(ctxFactory, httpFactory.getProtocol()); + SslConnectionFactory connectionFactory = new SslConnectionFactory(ctxFactory, wrappedFactory.getProtocol()); connectionFactory.addBean(new SslHandshakeFailedListener(metric, connectorConfig.name(), connectorConfig.listenPort())); return connectionFactory; } + private ALPNServerConnectionFactory newAlpnConnectionFactory(Collection<ConnectionFactory> alternatives, + ConnectionFactory defaultFactory) { + String[] protocols = alternatives.stream().map(ConnectionFactory::getProtocol).toArray(String[]::new); + ALPNServerConnectionFactory factory = new ALPNServerConnectionFactory(protocols); + factory.setDefaultProtocol(defaultFactory.getProtocol()); + return factory; + } + + private DetectorConnectionFactory newDetectorConnectionFactory(ConnectionFactory.Detecting... alternatives) { + return new DetectorConnectionFactory(alternatives); + } + + private ProxyConnectionFactory newProxyProtocolConnectionFactory(ConnectionFactory wrappedFactory) { + return new ProxyConnectionFactory(wrappedFactory.getProtocol()); + } + private static boolean isSslEffectivelyEnabled(ConnectorConfig config) { return config.ssl().enabled() || (config.implicitTlsEnabled() && TransportSecurityUtils.isTransportSecurityEnabled()); |