get rid of HttpClientTransportOverQuic and IClientConnector
Signed-off-by: Ludovic Orban <lorban@bitronix.be>
This commit is contained in:
parent
c70f49c773
commit
b8f39b5b2c
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<ContentDecoder.Factory> 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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<String> 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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<String> 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<String, Object> 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<String, Object> context)
|
||||
{
|
||||
HttpDestination destination = (HttpDestination)context.get(HTTP_DESTINATION_CONTEXT_KEY);
|
||||
context.put(ClientConnector.CLIENT_CONNECTION_FACTORY_CONTEXT_KEY, destination.getClientConnectionFactory());
|
||||
@SuppressWarnings("unchecked")
|
||||
Promise<org.eclipse.jetty.client.api.Connection> promise = (Promise<org.eclipse.jetty.client.api.Connection>)context.get(HTTP_CONNECTION_PROMISE_CONTEXT_KEY);
|
||||
context.put(ClientConnector.CONNECTION_PROMISE_CONTEXT_KEY, Promise.from(ioConnection -> {}, promise::failed));
|
||||
connector.connect(address, context);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ import org.slf4j.LoggerFactory;
|
|||
* </pre>
|
||||
*/
|
||||
@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())
|
||||
|
|
|
@ -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);
|
||||
}
|
Loading…
Reference in New Issue