Also promote RealConnectPlan to a top-level type, ConnectPlan.
Each RealConnection is now created only once its ready to be used
to carry exchanges. We do the actual connect work in ConnectPlan.
* EquipPlan, a class to describe what happens between TLS and HTTP
After a successful TCP socket is acquired we may need a CONNECT tunnel
and/or TLS handshake. I'm using the word 'equip' to mean 'equipping a TCP
socket with state to carry HTTP' though I'm not attached to this name.
This is a step towards splitting the TCP and equip phases so that happy
eyeballs can do TCP in parallel but equipping in serial order.
* Added tests for TLS fallback
* Tests for FastFallbackExchangeFinder
This needed more test facets in TaskFaker.
I'm pretty happy with how the tests read.
* More tests for FastFallbackExchangeFinder.
In order to deterministically test FastFallbackExchangeFinder I need
a test facet that supports several test coordinating:
- the call thread is waiting for either a connection to connect
or for the next-connection timeout (250 ms) to elapse
- the in-flight connection needs to connect
TaskFaker wasn't up to the task for this because it assumed at most
two threads, the test thread and the task thread.
With this change TaskFaker can coordinate multiple task threads
that each run sequentially, as directed by a test thread.
This doesn't yet introduce any mechanism to enable or disable
happy eyeballs.
It also doesn't sort IP addresses to alternate IPv6, IPv4
for best success.
It also doesn't limit how many connections are attempted
simultaneously.
It also lacks an appropriate number of tests.
This is bad because it moves test logic out of tests. But it's also
good because it lowers the cost of writing unit tests with common
types like RealConnection and Route.
This introduces a new RoutePlanner interface that I'm intending
to use to make it possible to unit test all the interesting races
in happy eyeballs.
ExchangeFinder is the current sequential algorithm, and I think
I just need to create a new thing, HappyEyeballsExchangeFinder,
that implements a parallel search.
This commit is intended as a pure refactor with no behavior
changes.
Previously we did all IOException recovery in RetryAndFollowUpInterceptor.
With this PR we move recovering from connect failures into ExchangeFinder.
This allows us to delete the RouteException class as it's no longer
necessary.
The user-visible consequence of this change is we now segregate
suppressed exceptions into TCP layer and HTTP layer.
This also introduces a new Plan sealed class to represent the
two different ways a connection is found: reuse and connect.
One behavior change here is we won't fire connectionAcquired()
followed by connectionReleased() if we take an connection from the
pool only to immediately find it's unhealthy.
I'm working towards moving the loop over connect attempts and
fails from RetryAndFollowUpInterceptor and into ExchangeFinder.
(We'll still need some recovery in RetryAndFollowUpInterceptor,
but not connection recovery.)
Each exchange has 3 places for a connection
- the connection on the call (from a previous redirect, auth challenge, etc.)
- a connection from the pool
- a fresh connection
We query the pool after each blocking step to give ourselves the maximum
chance or connection reuse.
This changes code structure without changing behavior.
This is the only behavior change in the PR. The rest is converting
a test from Java to Kotlin (so it can see this internal member) and
getting a TaskRunner instance into the ExchangeFinder, hopefully
useful for implementing Happy Eyeballs.
Also fix up some formatting problems.
Also migrate some tests that use these Util functions from Java to Kotlin.
If we're going to make OkHttp multiplatform, our tests need to be Kotlin
so we can run them on all supported platforms.
* Move basic enum types to common and use expect/actual for IOException
* Move basic enum types to common and use expect/actual for IOException
* Move basic enum types to common and use expect/actual for IOException
* Cleanup gradle
Gradle 7.3.2 adds dependency constraints to the _build_ classpath to reject known-bad versions of log4j.
There is no log4j dependency in OkHttp for clients, but it's possible that some build plugins use log4j which could affect CI.
See also https://blog.gradle.org/log4j-vulnerability.