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