Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package okhttp3.internal.connection

import java.io.IOException
import java.net.InetAddress
import java.net.InetSocketAddress
import java.net.Proxy
import java.net.SocketException
Expand All @@ -26,6 +27,7 @@ import okhttp3.Call
import okhttp3.EventListener
import okhttp3.HttpUrl
import okhttp3.Route
import okhttp3.internal.canParseAsIpAddress
import okhttp3.internal.immutableListOf
import okhttp3.internal.toImmutableList

Expand Down Expand Up @@ -159,15 +161,20 @@ class RouteSelector(
if (proxy.type() == Proxy.Type.SOCKS) {
mutableInetSocketAddresses += InetSocketAddress.createUnresolved(socketHost, socketPort)
} else {
eventListener.dnsStart(call, socketHost)
val addresses = if (socketHost.canParseAsIpAddress()) {
listOf(InetAddress.getByName(socketHost))
} else {
eventListener.dnsStart(call, socketHost)
Copy link
Collaborator

@yschimke yschimke Feb 16, 2022

Choose a reason for hiding this comment

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

This seems like a nice benefit of this change. that DNS start event isn't emitted for an IP address.


val result = address.dns.lookup(socketHost)
if (result.isEmpty()) {
throw UnknownHostException("${address.dns} returned no addresses for $socketHost")
}

val addresses = address.dns.lookup(socketHost)
if (addresses.isEmpty()) {
throw UnknownHostException("${address.dns} returned no addresses for $socketHost")
eventListener.dnsEnd(call, socketHost, result)
result
}

eventListener.dnsEnd(call, socketHost, addresses)

// Try each address for best behavior in mixed IPv4/IPv6 environments.
val orderedAddresses = when {
fastFallback -> reorderForHappyEyeballs(addresses)
Expand Down
21 changes: 21 additions & 0 deletions okhttp/src/jvmTest/java/okhttp3/EventListenerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,27 @@ public final class EventListenerTest {
"ResponseBodyEnd", "ConnectionReleased", "CallEnd");
}

@Test public void successfulCallEventSequenceForIpAddress() throws IOException {
server.enqueue(new MockResponse()
.setBody("abc"));

String ipAddress = InetAddress.getLoopbackAddress().getHostAddress();

Call call = client.newCall(new Request.Builder()
.url(server.url("/").newBuilder().host(ipAddress).build())
.build());
Response response = call.execute();
assertThat(response.code()).isEqualTo(200);
assertThat(response.body().string()).isEqualTo("abc");
response.body().close();

assertThat(listener.recordedEventTypes()).containsExactly("CallStart",
"ProxySelectStart", "ProxySelectEnd",
"ConnectStart", "ConnectEnd", "ConnectionAcquired", "RequestHeadersStart",
"RequestHeadersEnd", "ResponseHeadersStart", "ResponseHeadersEnd", "ResponseBodyStart",
"ResponseBodyEnd", "ConnectionReleased", "CallEnd");
}

@Test public void successfulCallEventSequenceForEnqueue() throws Exception {
server.enqueue(new MockResponse()
.setBody("abc"));
Expand Down