001package io.freefair.spring.okhttp.autoconfigure; 002 003import io.freefair.spring.okhttp.client.OkHttpClientRequestFactory; 004import okhttp3.ConnectionSpec; 005import okhttp3.OkHttpClient; 006import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder; 007import org.springframework.boot.http.client.ClientHttpRequestFactorySettings; 008import org.springframework.boot.ssl.SslBundle; 009import org.springframework.boot.ssl.SslOptions; 010import org.springframework.lang.Nullable; 011import org.springframework.util.Assert; 012import javax.net.ssl.SSLContext; 013import javax.net.ssl.SSLSocketFactory; 014import javax.net.ssl.TrustManager; 015import javax.net.ssl.X509TrustManager; 016import java.time.Duration; 017import java.util.List; 018 019/** 020 * @author Lars Grefer 021 */ 022public class OkHttpClientRequestFactoryBuilder implements ClientHttpRequestFactoryBuilder<OkHttpClientRequestFactory> { 023 private final OkHttpClient okHttpClient; 024 025 @Override 026 public OkHttpClientRequestFactory build() { 027 return this.build(null); 028 } 029 030 @Override 031 public OkHttpClientRequestFactory build(@Nullable ClientHttpRequestFactorySettings settings) { 032 OkHttpClient.Builder builder = okHttpClient.newBuilder(); 033 if (settings == null) { 034 return new OkHttpClientRequestFactory(builder.build()); 035 } 036 Duration connectTimeout = settings.connectTimeout(); 037 if (connectTimeout != null) { 038 builder.connectTimeout(connectTimeout); 039 } 040 Duration readTimeout = settings.readTimeout(); 041 if (readTimeout != null) { 042 builder.readTimeout(readTimeout); 043 } 044 SslBundle sslBundle = settings.sslBundle(); 045 if (sslBundle != null) { 046 SslOptions sslOptions = sslBundle.getOptions(); 047 if (sslOptions.isSpecified()) { 048 ConnectionSpec connectionSpec = new ConnectionSpec.Builder(true).cipherSuites(sslOptions.getCiphers()).tlsVersions(sslOptions.getEnabledProtocols()).build(); 049 builder.connectionSpecs(List.of(connectionSpec)); 050 } 051 SSLContext sslContext = sslBundle.createSslContext(); 052 SSLSocketFactory socketFactory = sslContext.getSocketFactory(); 053 TrustManager[] trustManagers = sslBundle.getManagers().getTrustManagers(); 054 Assert.state(trustManagers.length == 1, "Trust material must be provided in the SSL bundle for OkHttp3ClientHttpRequestFactory"); 055 builder.sslSocketFactory(socketFactory, (X509TrustManager) trustManagers[0]); 056 } 057 ClientHttpRequestFactorySettings.Redirects redirects = settings.redirects(); 058 if (redirects != null) { 059 switch (redirects) { 060 case FOLLOW_WHEN_POSSIBLE, FOLLOW -> { 061 builder.followRedirects(true); 062 builder.followSslRedirects(true); 063 } 064 case DONT_FOLLOW -> { 065 builder.followRedirects(false); 066 builder.followSslRedirects(true); 067 } 068 default -> { 069 } 070 } 071 } 072 return new OkHttpClientRequestFactory(builder.build()); 073 } 074 075 public OkHttpClientRequestFactoryBuilder(final OkHttpClient okHttpClient) { 076 this.okHttpClient = okHttpClient; 077 } 078}