From 8eddd1d6b89801641f6820a0ed0b745055221cdb Mon Sep 17 00:00:00 2001 From: Yuri Schimke Date: Wed, 18 Jan 2023 18:59:42 +0000 Subject: [PATCH] [4.x] Cherry pick: fix DoH error when using ip address as hostname (#7648) * Cherrypick: fix DoH error when using ip address as hostname (#7073) (cherry picked from commit 631a29eb7a3bd5bedb2fdf25515df93413bccd8e) Co-authored-by: Tao.Zang --- .../internal/connection/RouteSelector.kt | 21 ++++++++++++------- .../test/java/okhttp3/EventListenerTest.java | 21 +++++++++++++++++++ 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/okhttp/src/main/kotlin/okhttp3/internal/connection/RouteSelector.kt b/okhttp/src/main/kotlin/okhttp3/internal/connection/RouteSelector.kt index 9fd8b1fbc784..c4389743d6cf 100644 --- a/okhttp/src/main/kotlin/okhttp3/internal/connection/RouteSelector.kt +++ b/okhttp/src/main/kotlin/okhttp3/internal/connection/RouteSelector.kt @@ -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 @@ -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 @@ -158,16 +160,21 @@ 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) + + // Try each address for best behavior in mixed IPv4/IPv6 environments. + val result = address.dns.lookup(socketHost) + if (result.isEmpty()) { + throw UnknownHostException("${address.dns} returned no addresses for $socketHost") + } - // Try each address for best behavior in mixed IPv4/IPv6 environments. - 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) - for (inetAddress in addresses) { mutableInetSocketAddresses += InetSocketAddress(inetAddress, socketPort) } diff --git a/okhttp/src/test/java/okhttp3/EventListenerTest.java b/okhttp/src/test/java/okhttp3/EventListenerTest.java index 72472012bded..ea598ebddd05 100644 --- a/okhttp/src/test/java/okhttp3/EventListenerTest.java +++ b/okhttp/src/test/java/okhttp3/EventListenerTest.java @@ -135,6 +135,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"));