OkHttp & Interceptors Flashcards
DATA › Networking
- What is the difference between an application interceptor and a network interceptor in OkHttp?
- An application interceptor (addInterceptor) runs once per call, sees the original request without OkHttp-injected headers, and does not see redirects/retries or cache hits. A network interceptor (addNetworkInterceptor) runs once per actual network request, so it fires again on each redirect/retry, sees OkHttp's headers (e.g. Accept-Encoding), and has access to the Connection.
- You need to add an Authorization header to every request. Where do you put it and why?
- Add it in an application interceptor: build a new request from chain.request() with the header via newBuilder(), then return chain.proceed(newRequest). It runs once per call regardless of redirects/retries, which is what you want for app-level auth.
- Why is HttpLoggingInterceptor usually added as an application interceptor rather than a network interceptor?
- As an application interceptor it logs the logical request/response once, showing your original headers and the final body without per-redirect noise. As a network interceptor it logs every hop and the raw, possibly gzipped/encoded bytes. Use BODY level only in debug; never log bodies (tokens) in release.
- An interceptor calls chain.proceed() but never returns the response to the caller. What can go wrong?
- Response bodies are a one-shot stream that must be consumed or closed exactly once. If you call proceed multiple times or drop a response without closing it, you leak the connection from the pool. Close previous responses before re-proceeding.
- How do connection pooling and keep-alive work in OkHttp, and how do you configure them?
- OkHttpClient keeps a ConnectionPool that reuses warm HTTP/1.1 keep-alive and HTTP/2 connections to the same host, cutting latency. Defaults are roughly 5 idle connections kept for 5 minutes. You tune it via OkHttpClient.Builder().connectionPool(ConnectionPool(...)). Share one OkHttpClient so the pool (and cache/threads) is reused.
- How do you enable response caching in OkHttp and what controls whether a response is served from cache?
- Set a Cache(directory, maxSize) on the OkHttpClient.Builder via .cache(...). OkHttp then honors HTTP caching headers (Cache-Control, ETag, Last-Modified) per RFC 9111. You can rewrite Cache-Control in an interceptor to force caching or, with onlyIfCached / a network-availability interceptor, serve stale data offline.
- What is certificate pinning in OkHttp and how do you set it up?
- CertificatePinner ties a hostname to expected certificate public-key SHA-256 hashes, so a connection fails if a CA issues a rogue cert. Configure it via CertificatePinner.Builder().add("host", "sha256/...").build() on OkHttpClient. Pin a backup key and have a rotation plan, since a wrong/expired pin bricks the app's networking.
- How does gzip work in OkHttp by default, and when must you handle it manually?
- If you do not set Accept-Encoding yourself, OkHttp transparently adds gzip, decompresses the response, and strips Content-Encoding/Content-Length so it is invisible to your code. If you set Accept-Encoding manually, transparent gzip is disabled and you must decompress yourself. Request-body gzip is never automatic; you add a Content-Encoding: gzip interceptor.
- What timeouts can OkHttp configure, and what does each cover?
- connectTimeout (TCP/TLS handshake), readTimeout (idle gap waiting for bytes), writeTimeout (idle gap sending bytes), and callTimeout (entire call incl. redirects, default 0 = none). Set them on OkHttpClient.Builder; an interceptor can override per-request via chain.withReadTimeout/withWriteTimeout/withConnectTimeout.