001package io.freefair.spring.okhttp.autoconfigure; 002 003import io.freefair.spring.okhttp.ApplicationInterceptor; 004import io.freefair.spring.okhttp.NetworkInterceptor; 005import io.freefair.spring.okhttp.OkHttp3Configurer; 006import okhttp3.*; 007import org.springframework.beans.factory.ObjectProvider; 008import org.springframework.beans.factory.annotation.Autowired; 009import org.springframework.boot.autoconfigure.AutoConfiguration; 010import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 011import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 012import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 013import org.springframework.boot.context.properties.EnableConfigurationProperties; 014import org.springframework.context.annotation.Bean; 015 016import javax.net.ssl.HostnameVerifier; 017import java.io.File; 018import java.io.IOException; 019import java.nio.file.Files; 020import java.time.Duration; 021import java.util.concurrent.TimeUnit; 022 023/** 024 * @author Lars Grefer 025 */ 026@SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection") 027@AutoConfiguration 028@ConditionalOnClass(OkHttpClient.class) 029@EnableConfigurationProperties(OkHttpProperties.class) 030public class OkHttp3AutoConfiguration { 031 032 @Autowired 033 private OkHttpProperties okHttpProperties; 034 035 @Autowired 036 private ObjectProvider<OkHttp3Configurer> configurers; 037 038 @Autowired 039 @ApplicationInterceptor 040 private ObjectProvider<Interceptor> applicationInterceptors; 041 042 @Autowired 043 @NetworkInterceptor 044 private ObjectProvider<Interceptor> networkInterceptors; 045 046 @Bean 047 @ConditionalOnMissingBean 048 public OkHttpClient okHttp3Client( 049 ObjectProvider<Cache> cache, 050 ObjectProvider<CookieJar> cookieJar, 051 ObjectProvider<Dns> dns, 052 ObjectProvider<HostnameVerifier> hostnameVerifier, 053 ObjectProvider<CertificatePinner> certificatePinner, 054 ConnectionPool connectionPool, 055 ObjectProvider<EventListener> eventListener 056 ) { 057 OkHttpClient.Builder builder = new OkHttpClient.Builder(); 058 059 cache.ifUnique(builder::cache); 060 061 eventListener.ifUnique(builder::eventListener); 062 063 builder.connectTimeout(okHttpProperties.getConnectTimeout()); 064 builder.readTimeout(okHttpProperties.getReadTimeout()); 065 builder.writeTimeout(okHttpProperties.getWriteTimeout()); 066 builder.pingInterval(okHttpProperties.getPingInterval()); 067 068 cookieJar.ifUnique(builder::cookieJar); 069 070 dns.ifUnique(builder::dns); 071 072 hostnameVerifier.ifUnique(builder::hostnameVerifier); 073 certificatePinner.ifUnique(builder::certificatePinner); 074 075 builder.connectionPool(connectionPool); 076 077 builder.followRedirects(okHttpProperties.isFollowRedirects()); 078 builder.followSslRedirects(okHttpProperties.isFollowSslRedirects()); 079 builder.retryOnConnectionFailure(okHttpProperties.isRetryOnConnectionFailure()); 080 081 applicationInterceptors.forEach(builder::addInterceptor); 082 083 networkInterceptors.forEach(builder::addNetworkInterceptor); 084 085 configurers.forEach(configurer -> configurer.configure(builder)); 086 087 return builder.build(); 088 } 089 090 @Bean 091 @ConditionalOnMissingBean 092 public ConnectionPool okHttp3ConnectionPool() { 093 int maxIdleConnections = okHttpProperties.getConnectionPool().getMaxIdleConnections(); 094 Duration keepAliveDuration = okHttpProperties.getConnectionPool().getKeepAliveDuration(); 095 return new ConnectionPool(maxIdleConnections, keepAliveDuration.toNanos(), TimeUnit.NANOSECONDS); 096 } 097 098 @Bean 099 @ConditionalOnMissingBean 100 @ConditionalOnProperty(value = "okhttp.cache.enabled", havingValue = "true", matchIfMissing = true) 101 public Cache okHttp3Cache() throws IOException { 102 File directory = okHttpProperties.getCache().getDirectory(); 103 if (directory == null) { 104 directory = Files.createTempDirectory("okhttp-cache").toFile(); 105 } 106 return new Cache(directory, okHttpProperties.getCache().getMaxSize().toBytes()); 107 } 108}