From b8f39b5b2c1ba4aecaf9d05d57dabfc21090a830 Mon Sep 17 00:00:00 2001 From: Ludovic Orban Date: Fri, 26 Mar 2021 17:43:20 +0100 Subject: [PATCH] get rid of HttpClientTransportOverQuic and IClientConnector Signed-off-by: Ludovic Orban --- .../jetty/client/DuplexHttpDestination.java | 7 +- .../org/eclipse/jetty/client/HttpClient.java | 5 +- .../http/HttpClientTransportOverHTTP.java | 2 +- .../http3/client/ClientQuicConnection.java | 9 + .../http3/client/ClientQuicConnector.java | 12 +- .../client/HttpClientTransportOverQuic.java | 154 ------------------ .../jetty/http3/client/End2EndClientTest.java | 3 +- .../org/eclipse/jetty/io/ClientConnector.java | 7 +- .../eclipse/jetty/io/IClientConnector.java | 54 ------ 9 files changed, 33 insertions(+), 220 deletions(-) delete mode 100644 jetty-http3/http3-client/src/main/java/org/eclipse/jetty/http3/client/HttpClientTransportOverQuic.java delete mode 100644 jetty-io/src/main/java/org/eclipse/jetty/io/IClientConnector.java diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/DuplexHttpDestination.java b/jetty-client/src/main/java/org/eclipse/jetty/client/DuplexHttpDestination.java index 1a20940912f..70337e73bd7 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/DuplexHttpDestination.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/DuplexHttpDestination.java @@ -22,6 +22,11 @@ public class DuplexHttpDestination extends HttpDestination { public DuplexHttpDestination(HttpClient client, Origin origin) { - super(client, origin, false); + this(client, origin, false); + } + + public DuplexHttpDestination(HttpClient client, Origin origin, boolean intrinsicallySecure) + { + super(client, origin, intrinsicallySecure); } } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java index 72844d6fbc0..8eb987c3494 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpClient.java @@ -58,7 +58,6 @@ import org.eclipse.jetty.io.ArrayRetainableByteBufferPool; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.ClientConnectionFactory; import org.eclipse.jetty.io.ClientConnector; -import org.eclipse.jetty.io.IClientConnector; import org.eclipse.jetty.io.MappedByteBufferPool; import org.eclipse.jetty.io.RetainableByteBufferPool; import org.eclipse.jetty.io.ssl.SslClientConnectionFactory; @@ -127,7 +126,7 @@ public class HttpClient extends ContainerLifeCycle private final Set decoderFactories = new ContentDecoderFactorySet(); private final ProxyConfiguration proxyConfig = new ProxyConfiguration(); private final HttpClientTransport transport; - private final IClientConnector connector; + private final ClientConnector connector; private AuthenticationStore authenticationStore = new HttpAuthenticationStore(); private CookieManager cookieManager; private CookieStore cookieStore; @@ -162,7 +161,7 @@ public class HttpClient extends ContainerLifeCycle { this.transport = Objects.requireNonNull(transport); addBean(transport); - this.connector = ((AbstractHttpClientTransport)transport).getContainedBeans(IClientConnector.class).stream().findFirst().orElseThrow(); + this.connector = ((AbstractHttpClientTransport)transport).getContainedBeans(ClientConnector.class).stream().findFirst().orElseThrow(); addBean(handlers); addBean(decoderFactories); } diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpClientTransportOverHTTP.java b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpClientTransportOverHTTP.java index 0eb54ef3502..818a901ed0b 100644 --- a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpClientTransportOverHTTP.java +++ b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpClientTransportOverHTTP.java @@ -68,7 +68,7 @@ public class HttpClientTransportOverHTTP extends AbstractConnectorHttpClientTran @Override public HttpDestination newHttpDestination(Origin origin) { - return new DuplexHttpDestination(getHttpClient(), origin); + return new DuplexHttpDestination(getHttpClient(), origin, getClientConnector().isIntrinsicallySecure()); } @Override diff --git a/jetty-http3/http3-client/src/main/java/org/eclipse/jetty/http3/client/ClientQuicConnection.java b/jetty-http3/http3-client/src/main/java/org/eclipse/jetty/http3/client/ClientQuicConnection.java index 2ad6a52523b..2257977a40a 100644 --- a/jetty-http3/http3-client/src/main/java/org/eclipse/jetty/http3/client/ClientQuicConnection.java +++ b/jetty-http3/http3-client/src/main/java/org/eclipse/jetty/http3/client/ClientQuicConnection.java @@ -16,10 +16,13 @@ package org.eclipse.jetty.http3.client; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; +import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; +import org.eclipse.jetty.client.HttpClientTransport; +import org.eclipse.jetty.client.HttpDestination; import org.eclipse.jetty.http3.common.QuicConnection; import org.eclipse.jetty.http3.common.QuicSession; import org.eclipse.jetty.http3.quiche.QuicheConfig; @@ -57,6 +60,12 @@ public class ClientQuicConnection extends QuicConnection try { InetSocketAddress remoteAddress = (InetSocketAddress)context.get(ClientConnector.REMOTE_SOCKET_ADDRESS_CONTEXT_KEY); + HttpDestination destination = (HttpDestination)context.get(HttpClientTransport.HTTP_DESTINATION_CONTEXT_KEY); + List protocols = destination.getOrigin().getProtocol().getProtocols(); + + // TODO: create quiche config here, pulling the config from somewhere else TBD (context?) + quicheConfig.setApplicationProtos(protocols.toArray(new String[0])); + QuicheConnection quicheConnection = QuicheConnection.connect(quicheConfig, remoteAddress); QuicSession session = new ClientQuicSession(getExecutor(), getScheduler(), getByteBufferPool(), quicheConnection, this, remoteAddress, context); pendingSessions.put(remoteAddress, session); diff --git a/jetty-http3/http3-client/src/main/java/org/eclipse/jetty/http3/client/ClientQuicConnector.java b/jetty-http3/http3-client/src/main/java/org/eclipse/jetty/http3/client/ClientQuicConnector.java index 2b0ff8c775e..d048ae3c604 100644 --- a/jetty-http3/http3-client/src/main/java/org/eclipse/jetty/http3/client/ClientQuicConnector.java +++ b/jetty-http3/http3-client/src/main/java/org/eclipse/jetty/http3/client/ClientQuicConnector.java @@ -56,14 +56,16 @@ public class ClientQuicConnector extends ClientConnector { } + @Override + public boolean isIntrinsicallySecure() + { + return true; + } + @Override protected void doStart() throws Exception { - //TODO: what is the best place to create the quiche config? - - // TODO detect the ALPN protos - quicheConfig.setApplicationProtos("http/1.1"); -// quicheConfig.setApplicationProtos(protocolNames.toArray(new String[0])); + // TODO: move the creation of quiche config to ClientQuicConnection.onOpen() // TODO make these QuicheConfig settings configurable quicheConfig.setDisableActiveMigration(true); diff --git a/jetty-http3/http3-client/src/main/java/org/eclipse/jetty/http3/client/HttpClientTransportOverQuic.java b/jetty-http3/http3-client/src/main/java/org/eclipse/jetty/http3/client/HttpClientTransportOverQuic.java deleted file mode 100644 index 58cf9bd3228..00000000000 --- a/jetty-http3/http3-client/src/main/java/org/eclipse/jetty/http3/client/HttpClientTransportOverQuic.java +++ /dev/null @@ -1,154 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2021 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.http3.client; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; - -import org.eclipse.jetty.client.AbstractHttpClientTransport; -import org.eclipse.jetty.client.HttpClient; -import org.eclipse.jetty.client.HttpDestination; -import org.eclipse.jetty.client.HttpRequest; -import org.eclipse.jetty.client.MultiplexConnectionPool; -import org.eclipse.jetty.client.MultiplexHttpDestination; -import org.eclipse.jetty.client.Origin; -import org.eclipse.jetty.client.http.HttpClientConnectionFactory; -import org.eclipse.jetty.http3.quiche.QuicheConfig; -import org.eclipse.jetty.io.ClientConnectionFactory; -import org.eclipse.jetty.io.ClientConnector; -import org.eclipse.jetty.io.Connection; -import org.eclipse.jetty.io.EndPoint; -import org.eclipse.jetty.util.Promise; -import org.eclipse.jetty.util.annotation.ManagedAttribute; -import org.eclipse.jetty.util.annotation.ManagedObject; - -//TODO: get rid of this class, it should not be needed -@ManagedObject("The QUIC client transport") -public class HttpClientTransportOverQuic extends AbstractHttpClientTransport -{ - private final ClientConnectionFactory connectionFactory = new HttpClientConnectionFactory(); - private final ClientQuicConnector connector; - private final Origin.Protocol protocol; - private final QuicheConfig quicheConfig; - private int initialSessionRecvWindow = 16 * 1024 * 1024; - private int initialStreamRecvWindow = 8 * 1024 * 1024; - private int maxConcurrentPushedStreams = 32; - - public HttpClientTransportOverQuic() - { - this(HttpClientConnectionFactory.HTTP11); - } - - public HttpClientTransportOverQuic(ClientConnectionFactory.Info... factoryInfos) - { - List protocolNames = Arrays.stream(factoryInfos).flatMap(info -> info.getProtocols(true).stream()).collect(Collectors.toList()); - quicheConfig = new QuicheConfig(); - quicheConfig.setApplicationProtos(protocolNames.toArray(new String[0])); - - protocol = new Origin.Protocol(protocolNames, false); - connector = new ClientQuicConnector(); - addBean(connector); - setConnectionPoolFactory(destination -> - { - HttpClient httpClient = getHttpClient(); - int maxConnections = httpClient.getMaxConnectionsPerDestination(); - return new MultiplexConnectionPool(destination, maxConnections, destination, 1); - }); - } - - @ManagedAttribute("The initial size of session's flow control receive window") - public int getInitialSessionRecvWindow() - { - return initialSessionRecvWindow; - } - - public void setInitialSessionRecvWindow(int initialSessionRecvWindow) - { - this.initialSessionRecvWindow = initialSessionRecvWindow; - } - - @ManagedAttribute("The initial size of stream's flow control receive window") - public int getInitialStreamRecvWindow() - { - return initialStreamRecvWindow; - } - - public void setInitialStreamRecvWindow(int initialStreamRecvWindow) - { - this.initialStreamRecvWindow = initialStreamRecvWindow; - } - - @ManagedAttribute("The max number of concurrent pushed streams") - public int getMaxConcurrentPushedStreams() - { - return maxConcurrentPushedStreams; - } - - public void setMaxConcurrentPushedStreams(int maxConcurrentPushedStreams) - { - this.maxConcurrentPushedStreams = maxConcurrentPushedStreams; - } - - @Override - protected void doStart() throws Exception - { - // TODO make these QuicheConfig settings configurable - quicheConfig.setDisableActiveMigration(true); - quicheConfig.setVerifyPeer(false); - - // TODO review the meaning of those QuicheConfig settings and see if they match their HTTP2 equivalents - quicheConfig.setMaxIdleTimeout(getHttpClient().getIdleTimeout()); - quicheConfig.setInitialMaxData((long)getInitialSessionRecvWindow()); - quicheConfig.setInitialMaxStreamDataBidiLocal((long)getInitialStreamRecvWindow()); - quicheConfig.setInitialMaxStreamDataUni((long)getInitialStreamRecvWindow()); - quicheConfig.setInitialMaxStreamsBidi((long)getMaxConcurrentPushedStreams()); - quicheConfig.setInitialMaxStreamsUni((long)getMaxConcurrentPushedStreams()); - - super.doStart(); - } - - @Override - public Connection newConnection(EndPoint endPoint, Map context) throws IOException - { - endPoint.setIdleTimeout(getHttpClient().getIdleTimeout()); - return connectionFactory.newConnection(endPoint, context); - } - - @Override - public Origin newOrigin(HttpRequest request) - { - return getHttpClient().createOrigin(request, protocol); - } - - @Override - public HttpDestination newHttpDestination(Origin origin) - { - return new MultiplexHttpDestination(getHttpClient(), origin, true); - } - - @Override - public void connect(InetSocketAddress address, Map context) - { - HttpDestination destination = (HttpDestination)context.get(HTTP_DESTINATION_CONTEXT_KEY); - context.put(ClientConnector.CLIENT_CONNECTION_FACTORY_CONTEXT_KEY, destination.getClientConnectionFactory()); - @SuppressWarnings("unchecked") - Promise promise = (Promise)context.get(HTTP_CONNECTION_PROMISE_CONTEXT_KEY); - context.put(ClientConnector.CONNECTION_PROMISE_CONTEXT_KEY, Promise.from(ioConnection -> {}, promise::failed)); - connector.connect(address, context); - } -} diff --git a/jetty-http3/http3-client/src/test/java/org/eclipse/jetty/http3/client/End2EndClientTest.java b/jetty-http3/http3-client/src/test/java/org/eclipse/jetty/http3/client/End2EndClientTest.java index 79ce32bcd28..6c7cea78620 100644 --- a/jetty-http3/http3-client/src/test/java/org/eclipse/jetty/http3/client/End2EndClientTest.java +++ b/jetty-http3/http3-client/src/test/java/org/eclipse/jetty/http3/client/End2EndClientTest.java @@ -25,6 +25,7 @@ import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.api.ContentResponse; +import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP; import org.eclipse.jetty.http.HttpCompliance; import org.eclipse.jetty.http3.server.ServerQuicConnector; import org.eclipse.jetty.server.HttpConfiguration; @@ -74,7 +75,7 @@ public class End2EndClientTest server.start(); - HttpClientTransportOverQuic transport = new HttpClientTransportOverQuic(); + HttpClientTransportOverHTTP transport = new HttpClientTransportOverHTTP(new ClientQuicConnector()); client = new HttpClient(transport); client.start(); } diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/ClientConnector.java b/jetty-io/src/main/java/org/eclipse/jetty/io/ClientConnector.java index 7cbfb2cda41..b42c5da1db4 100644 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/ClientConnector.java +++ b/jetty-io/src/main/java/org/eclipse/jetty/io/ClientConnector.java @@ -71,7 +71,7 @@ import org.slf4j.LoggerFactory; * */ @ManagedObject -public class ClientConnector extends ContainerLifeCycle implements IClientConnector +public class ClientConnector extends ContainerLifeCycle { public static final String CLIENT_CONNECTOR_CONTEXT_KEY = "org.eclipse.jetty.client.connector"; public static final String REMOTE_SOCKET_ADDRESS_CONTEXT_KEY = CLIENT_CONNECTOR_CONTEXT_KEY + ".remoteSocketAddress"; @@ -134,6 +134,11 @@ public class ClientConnector extends ContainerLifeCycle implements IClientConnec return executor; } + public boolean isIntrinsicallySecure() + { + return false; + } + public void setExecutor(Executor executor) { if (isStarted()) diff --git a/jetty-io/src/main/java/org/eclipse/jetty/io/IClientConnector.java b/jetty-io/src/main/java/org/eclipse/jetty/io/IClientConnector.java deleted file mode 100644 index a6421eda085..00000000000 --- a/jetty-io/src/main/java/org/eclipse/jetty/io/IClientConnector.java +++ /dev/null @@ -1,54 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2021 Mort Bay Consulting Pty Ltd and others. -// -// This program and the accompanying materials are made available under the -// terms of the Eclipse Public License v. 2.0 which is available at -// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 -// which is available at https://www.apache.org/licenses/LICENSE-2.0. -// -// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 -// ======================================================================== -// - -package org.eclipse.jetty.io; - -import java.net.SocketAddress; -import java.time.Duration; -import java.util.concurrent.Executor; - -import org.eclipse.jetty.util.ssl.SslContextFactory; -import org.eclipse.jetty.util.thread.Scheduler; - -public interface IClientConnector -{ - SocketAddress getBindAddress(); - - void setBindAddress(SocketAddress bindAddress); - - ByteBufferPool getByteBufferPool(); - - void setByteBufferPool(ByteBufferPool byteBufferPool); - - Duration getConnectTimeout(); - - void setConnectTimeout(Duration connectTimeout); - - Executor getExecutor(); - - void setExecutor(Executor executor); - - Duration getIdleTimeout(); - - void setIdleTimeout(Duration idleTimeout); - - Scheduler getScheduler(); - - void setScheduler(Scheduler scheduler); - - SslContextFactory.Client getSslContextFactory(); - - boolean isConnectBlocking(); - - void setConnectBlocking(boolean connectBlocking); -}