CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-squareup-okhttp3--okhttp

Square's meticulous HTTP client for Java and Kotlin

Pending
Overview
Eval results
Files

interceptors.mddocs/

Interceptors

Pluggable request and response transformation framework for monitoring, rewriting, and retry logic.

Interceptor Interface

interface Interceptor {
    fun intercept(chain: Chain): Response
    
    interface Chain {
        fun request(): Request
        fun proceed(request: Request): Response
        fun connection(): Connection?
        fun call(): Call
        fun connectTimeoutMillis(): Int
        fun withConnectTimeout(timeout: Int, unit: TimeUnit): Chain
        fun readTimeoutMillis(): Int
        fun withReadTimeout(timeout: Int, unit: TimeUnit): Chain
        fun writeTimeoutMillis(): Int
        fun withWriteTimeout(timeout: Int, unit: TimeUnit): Chain
    }
}

Application vs Network Interceptors

  • Application Interceptors: Called once per request, see final redirected response
  • Network Interceptors: Called for each network request, including redirects and retries
val client = OkHttpClient.Builder()
    .addInterceptor(applicationInterceptor)  // Application-level
    .addNetworkInterceptor(networkInterceptor)  // Network-level
    .build()

Common Interceptor Patterns

Logging Interceptor

class LoggingInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()
        
        val t1 = System.nanoTime()
        println("Sending request ${request.url}")
        
        val response = chain.proceed(request)
        
        val t2 = System.nanoTime()
        println("Received response for ${response.request.url} in ${(t2 - t1) / 1e6} ms")
        
        return response
    }
}

Authentication Interceptor

class AuthInterceptor(private val token: String) : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request().newBuilder()
            .addHeader("Authorization", "Bearer $token")
            .build()
        return chain.proceed(request)
    }
}

Retry Interceptor

class RetryInterceptor(private val maxRetries: Int = 3) : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        var request = chain.request()
        var response = chain.proceed(request)
        var retryCount = 0
        
        while (!response.isSuccessful && retryCount < maxRetries) {
            retryCount++
            response.close()
            response = chain.proceed(request)
        }
        
        return response
    }
}

Cache Override Interceptor

class CacheInterceptor : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()
        
        // Modify request based on network availability
        val cacheControl = if (isNetworkAvailable()) {
            CacheControl.Builder()
                .maxAge(5, TimeUnit.MINUTES)
                .build()
        } else {
            CacheControl.Builder()
                .onlyIfCached()
                .maxStale(7, TimeUnit.DAYS)
                .build()
        }
        
        val cacheRequest = request.newBuilder()
            .cacheControl(cacheControl)
            .build()
            
        return chain.proceed(cacheRequest)
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-com-squareup-okhttp3--okhttp

docs

caching.md

cookies.md

forms-multipart.md

http-client.md

index.md

interceptors.md

networking.md

requests-responses.md

security.md

urls.md

websockets.md

tile.json