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