Skip to content

Conversation

@yschimke
Copy link
Collaborator

@yschimke yschimke commented Oct 5, 2025

This pull request introduces significant enhancements to the Interceptor.Chain API in OkHttp, allowing much more fine-grained and dynamic control over the HTTP client's configuration on a per-call basis.

Let's delve into it;

API Extensions for Interceptor.Chain

  • Added numerous getter and setter methods to the Interceptor.Chain interface for properties such as DNS, proxy, cache, authenticators, SSL factories, certificate pinners, connection pool, cookie jar, hostname verifier, and retry settings. These methods allow interceptors and clients to override or access the OkHttpClient's configuration dynamically within the interceptor chain.

Internal Refactoring to Use Chain Properties

  • Refactored BridgeInterceptor and CacheInterceptor to use the new properties from Interceptor.Chain instead of being directly constructed with dependencies like CookieJar or Cache. This makes interceptors more decoupled and flexible.

Extensive test of overrides

  • InterceptorOverridesTest exhaustively tests that overrides can be applied by an application interceptor and observed from a network interceptor. That they can't be set in a network interceptor. And finally that bad defaults on OkHttpClient, can be saved by good overrides.

@yschimke yschimke requested a review from squarejesse October 5, 2025 09:06
# Conflicts:
#	okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/connection/RealCall.kt
#	okhttp/src/jvmTest/kotlin/okhttp3/internal/connection/RouteSelectorTest.kt
Copy link
Collaborator

@swankjesse swankjesse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is pretty rad actually. The most difficult part is gonna be making the tests?

@yschimke
Copy link
Collaborator Author

yschimke commented Nov 9, 2025

@swankjesse I'll follow up with more specific samples, such as Android Network Pinning.

@yschimke yschimke requested a review from swankjesse November 10, 2025 08:48
Copy link
Collaborator

@swankjesse swankjesse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love it

I would like more confidence that the override value is actually used, different from whether it’s reflected in the chain’s own properties. That’s necessary but not sufficient.

@yschimke yschimke marked this pull request as draft December 9, 2025 08:56
@yschimke yschimke marked this pull request as ready for review December 11, 2025 07:57
@yschimke
Copy link
Collaborator Author

@swankjesse still have a few tests to fix, but ready for review

@yschimke yschimke requested a review from swankjesse December 13, 2025 12:00
if (sink
.timeout()
.timeoutNanos()
.nanoseconds.inWholeMilliseconds == 10L
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@swankjesse I tried to implement this using

            .socketFactory(
              DelayingSocketFactory(onWrite = {
                Thread.sleep(100L)
              }),

But if I break point at Thread.sleep, then socket.sink().timeout().timeoutNanos() is always cleared (0).

I suspect a bug with write timeout, but this replicates a timeout just by checking if we have the bad timeout value.

interceptors += RetryAndFollowUpInterceptor(client)
interceptors += BridgeInterceptor(client.cookieJar)
interceptors += CacheInterceptor(this, client.cache)
interceptors += RetryAndFollowUpInterceptor()
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@swankjesse this seems like a nice win.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants