Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to configure HTTPClient to support HTTP/1.1, HTTP/2 and HTTP/3 simultaneously? #10882

Closed
cowwoc opened this issue Nov 10, 2023 · 4 comments
Labels

Comments

@cowwoc
Copy link
Contributor

cowwoc commented Nov 10, 2023

Jetty Version
12.0.3

Java Version
openjdk version "21.0.1" 2023-10-17 LTS
OpenJDK Runtime Environment Zulu21.30+15-CA (build 21.0.1+12-LTS)
OpenJDK 64-Bit Server VM Zulu21.30+15-CA (build 21.0.1+12-LTS, mixed mode, sharing)

Question
When I configure HttpClient as follows:

SslContextFactory.Client sslContextFactory = new SslContextFactory.Client();
sslContextFactory.setKeyStorePath("keystore/keystore.p12");
sslContextFactory.setKeyStorePassword("changeit");
Security.addProvider(new OpenSSLProvider());
sslContextFactory.setProvider("Conscrypt");

sslContextFactory.setTrustAll(true);
sslContextFactory.setHostnameVerifier((hostName, _) -> hostName.endsWith("localhost"));

ClientConnectionFactory.Info http11 = HttpClientConnectionFactory.HTTP11;

HTTP2Client http2Client = new HTTP2Client();
http2Client.getClientConnector().setSslContextFactory(sslContextFactory);
ClientConnectionFactory.Info http2 = new ClientConnectionFactoryOverHTTP2.HTTP2(http2Client);

HTTP3Client http3Client = new HTTP3Client();
http3Client.getClientConnector().setSslContextFactory(sslContextFactory);
clientConnectionFactory.Info http3 = new ClientConnectionFactoryOverHTTP3.HTTP3(http3Client);

ttpClientTransport transport = new HttpClientTransportDynamic(http3, http2, http11);
HttpClient client = new HttpClient(transport);
client.setSslContextFactory(sslContextFactory);

and try hitting a server endpoint that supports HTTP/1.1, HTTP/2 and HTTP/3, I get:

java.lang.ClassCastException: class org.eclipse.jetty.http2.client.HTTP2ClientConnectionFactory$HTTP2ClientConnection cannot be cast to class org.eclipse.jetty.http3.HTTP3StreamConnection (org.eclipse.jetty.http2.client.HTTP2ClientConnectionFactory$HTTP2ClientConnection is in module org.eclipse.jetty.http2.client@12.0.3 of loader 'app'; org.eclipse.jetty.http3.HTTP3StreamConnection is in module org.eclipse.jetty.http3.common@12.0.3 of loader 'app')

	at org.eclipse.jetty.http3.common@12.0.3/org.eclipse.jetty.http3.HTTP3Session.newHTTP3Stream(HTTP3Session.java:303)
	at org.eclipse.jetty.http3.common@12.0.3/org.eclipse.jetty.http3.HTTP3Session.lambda$createStream$3(HTTP3Session.java:278)
	at java.base/java.util.concurrent.ConcurrentHashMap.compute(ConcurrentHashMap.java:1916)
	at org.eclipse.jetty.http3.common@12.0.3/org.eclipse.jetty.http3.HTTP3Session.createStream(HTTP3Session.java:274)
	at org.eclipse.jetty.http3.client@12.0.3/org.eclipse.jetty.http3.client.HTTP3SessionClient.newRequest(HTTP3SessionClient.java:114)
	at org.eclipse.jetty.http3.client@12.0.3/org.eclipse.jetty.http3.client.HTTP3SessionClient.newRequest(HTTP3SessionClient.java:97)
	at org.eclipse.jetty.http3.client.transport@12.0.3/org.eclipse.jetty.http3.client.transport.internal.HttpSenderOverHTTP3.sendHeaders(HttpSenderOverHTTP3.java:131)
	at org.eclipse.jetty.client@12.0.3/org.eclipse.jetty.client.transport.HttpSender$ContentSender.process(HttpSender.java:515)
	at org.eclipse.jetty.util@12.0.3/org.eclipse.jetty.util.IteratingCallback.processing(IteratingCallback.java:243)
	at org.eclipse.jetty.util@12.0.3/org.eclipse.jetty.util.IteratingCallback.iterate(IteratingCallback.java:224)
	at org.eclipse.jetty.client@12.0.3/org.eclipse.jetty.client.transport.HttpSender.send(HttpSender.java:85)
	at org.eclipse.jetty.http3.client.transport@12.0.3/org.eclipse.jetty.http3.client.transport.internal.HttpChannelOverHTTP3.send(HttpChannelOverHTTP3.java:82)
	at org.eclipse.jetty.client@12.0.3/org.eclipse.jetty.client.transport.HttpChannel.send(HttpChannel.java:137)
	at org.eclipse.jetty.client@12.0.3/org.eclipse.jetty.client.transport.HttpConnection.send(HttpConnection.java:112)
	at org.eclipse.jetty.http3.client.transport@12.0.3/org.eclipse.jetty.http3.client.transport.internal.HttpConnectionOverHTTP3.send(HttpConnectionOverHTTP3.java:85)
	at org.eclipse.jetty.client@12.0.3/org.eclipse.jetty.client.transport.HttpDestination.send(HttpDestination.java:422)
	at org.eclipse.jetty.client@12.0.3/org.eclipse.jetty.client.transport.HttpDestination.process(HttpDestination.java:398)
	at org.eclipse.jetty.client@12.0.3/org.eclipse.jetty.client.transport.HttpDestination.process(HttpDestination.java:353)
	at org.eclipse.jetty.client@12.0.3/org.eclipse.jetty.client.transport.HttpDestination.send(HttpDestination.java:336)
	at org.eclipse.jetty.client@12.0.3/org.eclipse.jetty.client.transport.HttpDestination.succeeded(HttpDestination.java:269)
	at org.eclipse.jetty.client@12.0.3/org.eclipse.jetty.client.AbstractConnectionPool.proceed(AbstractConnectionPool.java:315)
	at org.eclipse.jetty.client@12.0.3/org.eclipse.jetty.client.AbstractConnectionPool$FutureConnection.succeeded(AbstractConnectionPool.java:576)
	at org.eclipse.jetty.client@12.0.3/org.eclipse.jetty.client.AbstractConnectionPool$FutureConnection.succeeded(AbstractConnectionPool.java:554)
	at org.eclipse.jetty.util@12.0.3/org.eclipse.jetty.util.Promise$Wrapper.succeeded(Promise.java:195)
	at org.eclipse.jetty.http3.client.transport@12.0.3/org.eclipse.jetty.http3.client.transport.internal.SessionClientListener.onSettings(SessionClientListener.java:53)
	at org.eclipse.jetty.http3.common@12.0.3/org.eclipse.jetty.http3.HTTP3Session.notifySettings(HTTP3Session.java:382)
	at org.eclipse.jetty.http3.common@12.0.3/org.eclipse.jetty.http3.HTTP3Session.onSettings(HTTP3Session.java:375)
	at org.eclipse.jetty.http3.client@12.0.3/org.eclipse.jetty.http3.client.HTTP3SessionClient.onSettings(HTTP3SessionClient.java:90)
	at org.eclipse.jetty.http3.common@12.0.3/org.eclipse.jetty.http3.parser.BodyParser.notifySettings(BodyParser.java:106)
	at org.eclipse.jetty.http3.common@12.0.3/org.eclipse.jetty.http3.parser.SettingsBodyParser.onSettings(SettingsBodyParser.java:138)
	at org.eclipse.jetty.http3.common@12.0.3/org.eclipse.jetty.http3.parser.SettingsBodyParser.parse(SettingsBodyParser.java:114)
	at org.eclipse.jetty.http3.common@12.0.3/org.eclipse.jetty.http3.parser.ControlParser.parse(ControlParser.java:116)
	at org.eclipse.jetty.http3.common@12.0.3/org.eclipse.jetty.http3.internal.ControlStreamConnection.onFillable(ControlStreamConnection.java:89)
	at org.eclipse.jetty.io@12.0.3/org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:322)
	at org.eclipse.jetty.io@12.0.3/org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100)
	at org.eclipse.jetty.quic.common@12.0.3/org.eclipse.jetty.quic.common.QuicStreamEndPoint.onReadable(QuicStreamEndPoint.java:252)
	at org.eclipse.jetty.http3.client@12.0.3/org.eclipse.jetty.http3.client.ClientHTTP3Session.onReadable(ClientHTTP3Session.java:244)
	at org.eclipse.jetty.quic.common@12.0.3/org.eclipse.jetty.quic.common.ProtocolSession.processReadableStreams(ProtocolSession.java:130)
	at org.eclipse.jetty.quic.common@12.0.3/org.eclipse.jetty.quic.common.ProtocolSession$StreamsProducer.produce(ProtocolSession.java:222)
	at org.eclipse.jetty.util@12.0.3/org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.produceTask(AdaptiveExecutionStrategy.java:512)
	at org.eclipse.jetty.util@12.0.3/org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:258)
	at org.eclipse.jetty.util@12.0.3/org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.produce(AdaptiveExecutionStrategy.java:195)
	at org.eclipse.jetty.quic.common@12.0.3/org.eclipse.jetty.quic.common.ProtocolSession.produce(ProtocolSession.java:78)
	at org.eclipse.jetty.quic.client@12.0.3/org.eclipse.jetty.quic.client.ClientProtocolSession.lambda$new$0(ClientProtocolSession.java:31)
	at org.eclipse.jetty.util@12.0.3/org.eclipse.jetty.util.thread.Invocable$ReadyTask.run(Invocable.java:105)
	at org.eclipse.jetty.util@12.0.3/org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask(AdaptiveExecutionStrategy.java:478)
	at org.eclipse.jetty.util@12.0.3/org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask(AdaptiveExecutionStrategy.java:426)
	at org.eclipse.jetty.util@12.0.3/org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:293)
	at org.eclipse.jetty.util@12.0.3/org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.produce(AdaptiveExecutionStrategy.java:195)
	at org.eclipse.jetty.quic.common@12.0.3/org.eclipse.jetty.quic.common.QuicConnection.onFillable(QuicConnection.java:165)
	at org.eclipse.jetty.quic.client@12.0.3/org.eclipse.jetty.quic.client.ClientQuicConnection.onFillable(ClientQuicConnection.java:127)
	at org.eclipse.jetty.quic.common@12.0.3/org.eclipse.jetty.quic.common.QuicConnection$FillableCallback.succeeded(QuicConnection.java:426)
	at org.eclipse.jetty.io@12.0.3/org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100)
	at org.eclipse.jetty.io@12.0.3/org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53)
	at org.eclipse.jetty.util@12.0.3/org.eclipse.jetty.util.thread.Invocable.invokeNonBlocking(Invocable.java:156)
	at org.eclipse.jetty.util@12.0.3/org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.invokeAsNonBlocking(AdaptiveExecutionStrategy.java:495)
	at org.eclipse.jetty.util@12.0.3/org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask(AdaptiveExecutionStrategy.java:431)
	at org.eclipse.jetty.util@12.0.3/org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:293)
	at org.eclipse.jetty.util@12.0.3/org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.produce(AdaptiveExecutionStrategy.java:195)
	at org.eclipse.jetty.util@12.0.3/org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:971)
	at org.eclipse.jetty.util@12.0.3/org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob(QueuedThreadPool.java:1196)
	at org.eclipse.jetty.util@12.0.3/org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1151)

Is this a bug or a configuration error on my part?

@cowwoc cowwoc changed the title Is it possible to configure HTTPClient to support HTTP/1.1, HTTP/2 and HTTP/3? Is it possible to configure HTTPClient to support HTTP/1.1, HTTP/2 and HTTP/3 simultaneously? Nov 10, 2023
@cowwoc
Copy link
Contributor Author

cowwoc commented Nov 10, 2023

It looks like this issue is blocked by #8979

If you agree, please close this issue and I will wait for the aforementioned issue to get fixed.

@sbordet
Copy link
Contributor

sbordet commented Jan 3, 2024

Yes, it's currently not possible to support TCP-based transports with UDP-based transports.

@sbordet sbordet closed this as completed Jan 3, 2024
@sbordet
Copy link
Contributor

sbordet commented Jan 31, 2024

It will be possible to perform TCP-based requests with UDP-based requests in the same HttpClient when #8979 is fixed.

@sbordet
Copy link
Contributor

sbordet commented Feb 4, 2024

@cowwoc can you please try #11368 and see if you can now use the same HttpClient for all HTTP versions?
We have a test for that case, but would be great if you can confirm. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants