net.luminis.http3.Http3Client Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of flupke Show documentation
Show all versions of flupke Show documentation
Java implementation of HTTP3 (RFC 9114): generic client / client library and HTTP3 server plugin for Kwik.
/*
* Copyright © 2019, 2020, 2021, 2022, 2023 Peter Doornbosch
*
* This file is part of Flupke, a HTTP3 client Java library
*
* Flupke is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your option)
* any later version.
*
* Flupke is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
* more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*/
package net.luminis.http3;
import net.luminis.http3.core.Http3ClientConnection;
import net.luminis.http3.impl.Http3ClientConnectionImpl;
import net.luminis.http3.impl.Http3ConnectionFactory;
import net.luminis.http3.server.HttpError;
import net.luminis.quic.Statistics;
import net.luminis.quic.concurrent.DaemonThreadFactory;
import net.luminis.quic.log.Logger;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLParameters;
import java.io.IOException;
import java.net.Authenticator;
import java.net.CookieHandler;
import java.net.ProxySelector;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.Duration;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Http3Client extends HttpClient {
private final Duration connectTimeout;
private final Long receiveBufferSize;
private final boolean disableCertificateCheck;
private final Logger logger;
private Http3ClientConnection http3Connection;
protected Http3ConnectionFactory http3ConnectionFactory;
private final ExecutorService executorService;
Http3Client(Duration connectTimeout, Long receiveBufferSize, boolean disableCertificateCheck, Logger logger) {
this.connectTimeout = connectTimeout;
this.receiveBufferSize = receiveBufferSize;
this.disableCertificateCheck = disableCertificateCheck;
this.logger = logger;
this.http3ConnectionFactory = new Http3ConnectionFactory(this);
executorService = Executors.newCachedThreadPool(new DaemonThreadFactory("http3"));
}
public static HttpClient newHttpClient() {
return new Http3ClientBuilder().build();
}
public static Http3ClientBuilder newBuilder() {
return new Http3ClientBuilder();
}
public Optional receiveBufferSize() {
return Optional.ofNullable(receiveBufferSize);
}
@Override
public Optional cookieHandler() {
return Optional.empty();
}
@Override
public Optional connectTimeout() {
return Optional.ofNullable(connectTimeout);
}
@Override
public Redirect followRedirects() {
return Redirect.NEVER;
}
@Override
public Optional proxy() {
return Optional.empty();
}
@Override
public SSLContext sslContext() {
return null;
}
@Override
public SSLParameters sslParameters() {
return null;
}
@Override
public Optional authenticator() {
return Optional.empty();
}
@Override
public Version version() {
return null;
}
@Override
public Optional executor() {
return Optional.empty();
}
public boolean isDisableCertificateCheck() {
return disableCertificateCheck;
}
public Logger getLogger() {
return logger;
}
@Override
public HttpResponse send(HttpRequest request, HttpResponse.BodyHandler responseBodyHandler) throws IOException {
http3Connection = http3ConnectionFactory.getConnection(request);
http3Connection.connect();
return http3Connection.send(request, responseBodyHandler);
}
@Override
public CompletableFuture> sendAsync(HttpRequest request, HttpResponse.BodyHandler responseBodyHandler) {
CompletableFuture> future = new CompletableFuture<>();
executorService.submit(() -> {
try {
future.complete(send(request, responseBodyHandler));
}
catch (IOException ex) {
future.completeExceptionally(ex);
}
catch (RuntimeException ex) {
future.completeExceptionally(ex);
}
});
return future;
}
@Override
public CompletableFuture> sendAsync(HttpRequest request, HttpResponse.BodyHandler responseBodyHandler, HttpResponse.PushPromiseHandler pushPromiseHandler) {
throw new UnsupportedOperationException("server push is not (yet) supported");
}
/**
* Sends a CONNECT request (that creates a tunnel to a remote host) and returns a HttpStream object that can be used
* to send/receive data to/from remote host.
*
* https://www.rfc-editor.org/rfc/rfc9114.html#name-the-connect-method:
* "In HTTP/2 and HTTP/3, the CONNECT method is used to establish a tunnel over a single stream."
*
* @param request
* @return
* @throws IOException
* @throws HttpError
*/
public Http3ClientConnectionImpl.HttpStreamImpl sendConnect(HttpRequest request) throws IOException, HttpError {
http3Connection = http3ConnectionFactory.getConnection(request);
http3Connection.connect();
return http3Connection.sendConnect(request);
}
/**
* Sends an Extended CONNECT request (that can be used for tunneling other protocols like websocket and webtransport).
* See https://www.rfc-editor.org/rfc/rfc9220.html and https://www.rfc-editor.org/rfc/rfc8441.html.
*
* @param request
* @param protocol
* @param scheme
* @return
* @throws IOException
* @throws HttpError
* @throws InterruptedException
*/
public Http3ClientConnection.HttpStream sendExtendedConnect(HttpRequest request, String protocol, String scheme) throws IOException, HttpError, InterruptedException {
http3Connection = http3ConnectionFactory.getConnection(request);
http3Connection.connect();
return http3Connection.sendExtendedConnect(request, protocol, scheme, Duration.ofSeconds(10));
}
public Statistics getConnectionStatistics() {
if (http3Connection != null) {
return http3Connection.getConnectionStats();
}
else {
return null;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy