Skip to content

Instantly share code, notes, and snippets.

@alwarren
Created March 21, 2018 03:07
Show Gist options
  • Save alwarren/aaebd57634a8086a3ab7db5bee7bb773 to your computer and use it in GitHub Desktop.
Save alwarren/aaebd57634a8086a3ab7db5bee7bb773 to your computer and use it in GitHub Desktop.
import okhttp3.*
import retrofit2.Call
import retrofit2.Retrofit
import retrofit2.converter.scalars.ScalarsConverterFactory
import retrofit2.http.GET
import java.io.File
import java.io.IOException
import java.security.cert.X509Certificate
import javax.net.ssl.SSLContext
import javax.net.ssl.SSLSocketFactory
import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManager
import javax.security.cert.CertificateException
/**
* Retrofit offline caching example refactored for Kotlin
*
* see https://stackoverflow.com/a/48058557
*/
class OkHttpTestCachedRequest {
companion object {
private var isConnected = false
interface TestService {
@get:GET("/cache/60")
val testDate: Call<String>
}
@Throws(IOException::class)
@JvmStatic
fun main(args: Array<String>) {
val clientBuilder = OkHttpClient.Builder()
.cache(Cache(File("/tmp/http"), (10 * 1024 * 1024).toLong()))
// workaround for untrusted example host
clientBuilder.sslSocketFactory(MockTrust.sslSocketFactory(), MockTrust.trustManager())
clientBuilder.addInterceptor(OfflineInterceptor())
val builder = Retrofit.Builder()
.addConverterFactory(ScalarsConverterFactory.create())
.baseUrl("https://httpbin.org/")
.client(clientBuilder.build())
.build()
val service = builder.create(TestService::class.java)
isConnected = true
val online = service.testDate.execute().body()
println(online)
isConnected = false
val offline = service.testDate.execute().body()
println(offline)
}
}
private class OfflineInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
var request = chain.request()
request = if (isConnected)
request.newBuilder().cacheControl(CacheControl.FORCE_NETWORK).build()
else
request.newBuilder().cacheControl(CacheControl.FORCE_CACHE).build()
val response = chain.proceed(request)
println("network: " + response.networkResponse())
println("cache: " + response.cacheResponse())
return response
}
}
/**
* BEGIN workaround for untrusted example host
* see https://stackoverflow.com/q/25509296
*/
private class MockTrust {
companion object {
val managers = arrayOf<TrustManager>(object : X509TrustManager, TrustManager {
@Throws(CertificateException::class)
override fun checkClientTrusted(chain: Array<X509Certificate>, authType: String) {
}
@Throws(CertificateException::class)
override fun checkServerTrusted(chain: Array<X509Certificate>, authType: String) {
}
override fun getAcceptedIssuers(): Array<X509Certificate> {
return arrayOf()
}
})
fun trustManager() = object : X509TrustManager {
override fun getAcceptedIssuers(): Array<X509Certificate> {
return arrayOf()
}
@Throws(CertificateException::class)
override fun checkClientTrusted(chain: Array<java.security.cert.X509Certificate>, authType: String) {
}
@Throws(CertificateException::class)
override fun checkServerTrusted(chain: Array<java.security.cert.X509Certificate>, authType: String) {
}
}
fun sslSocketFactory(): SSLSocketFactory {
val context = SSLContext.getInstance("SSL")
context.init(null, MockTrust.managers, java.security.SecureRandom())
return context.socketFactory
}
}
}
/**
* END workaround for untrusted example host
*/
}
network: Response{protocol=http/1.1, code=200, message=OK, url=https://httpbin.org/cache/60}
cache: null
{
"args": {},
"headers": {
"Accept-Encoding": "gzip",
"Cache-Control": "no-cache",
"Connection": "close",
"Host": "httpbin.org",
"User-Agent": "okhttp/3.9.1"
},
"origin": "128.0.0.1",
"url": "https://httpbin.org/cache/60"
}
network: null
cache: Response{protocol=http/1.1, code=200, message=OK, url=https://httpbin.org/cache/60}
{
"args": {},
"headers": {
"Accept-Encoding": "gzip",
"Cache-Control": "no-cache",
"Connection": "close",
"Host": "httpbin.org",
"User-Agent": "okhttp/3.9.1"
},
"origin": "128.0.0.1",
"url": "https://httpbin.org/cache/60"
}
Process finished with exit code 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment