All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.shoothzj.http.client.facade.OkhttpClient Maven / Gradle / Ivy

Go to download

Http client abstracts multiple underlying HTTP clients, such as Jdk and OkHttp, and provides a unified API

The newest version!
package io.github.shoothzj.http.client.facade;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.ConnectionSpec;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.IOException;
import java.util.Collections;
import java.util.concurrent.CompletableFuture;

public class OkhttpClient extends BaseHttpClient {

    private final OkHttpClient client;

    public OkhttpClient(HttpClientConfig config) {
        super(config);
        OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder()
                .connectTimeout(config.connectTimeout())
                .readTimeout(config.timeout())
                .writeTimeout(config.timeout());

        if (config.tlsConfig() != null) {
            TlsConfig tlsConfig = config.tlsConfig();

            // set tls version and cipher suits
            ConnectionSpec connectionSpec = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS).tlsVersions(
                    tlsConfig.versions()).cipherSuites(tlsConfig.cipherSuites()).build();
            okHttpClientBuilder.connectionSpecs(Collections.singletonList(connectionSpec));

            // create ssl context from keystore and truststore
            OkHttpSslContextFactory.OkHttpSslContext sslContext = OkHttpSslContextFactory.createOkHttpSslContext(
                    tlsConfig);
            okHttpClientBuilder.sslSocketFactory(sslContext.sslSocketFactory, sslContext.x509TrustManager);

            // override hostnameVerifier to make it always success when hostname verification has been disabled
            if (tlsConfig.hostnameVerifyDisabled()) {
                okHttpClientBuilder.hostnameVerifier((s, sslSession) -> true);
            }
        }

        this.client = okHttpClientBuilder.build();
    }

    @Override
    public CompletableFuture send(HttpRequest request) throws HttpClientException {
        Request okHttpRequest = buildOkHttpRequest(request);
        CompletableFuture future = new CompletableFuture<>();

        client.newCall(okHttpRequest).enqueue(new Callback() {
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {
                future.completeExceptionally(new HttpClientException("Async request failed", e));
            }

            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
                future.complete(buildHttpResponse(response));
            }
        });

        return future;
    }

    @Override
    public void close() {
        client.dispatcher().executorService().shutdown();
        client.connectionPool().evictAll();
    }

    private Request buildOkHttpRequest(HttpRequest request) {
        Request.Builder builder = new Request.Builder()
                .url(request.url())
                .method(request.method().name(), request.getBody() != null ? RequestBody.create(request.getBody()) : null);

        request.headers().forEach((name, values) -> {
            for (String value : values) {
                builder.addHeader(name, value);
            }
        });

        return builder.build();
    }

    private @NotNull HttpResponse buildHttpResponse(@NotNull Response response) throws IOException {
        byte[] body = getBody(response.body());
        return new HttpResponse(
                response.code(),
                body,
                response.headers().toMultimap()
        );
    }

    @Nullable
    private static byte[] getBody(@Nullable ResponseBody responseBody) throws IOException {
        byte[] body = null;
        if (responseBody != null) {
            body = responseBody.bytes();
        }
        return body;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy