Skip to content

Commit 631a29e

Browse files
authored
fix DoH error when using ip address as hostname (#7073)
* fix DoH error when using ip address as hostname * lookup hostname first and try to parse as IP address only when lookup failed * add unit test in DnsOverHttpsTest for the case that Doing DNS lookup with an IP address hostname * use simpler ipAddress check instead of complex support functions * add test case for some special ipv6 addresses * use existing ipAddress check functions instead of adding a new similar function * avoid to do dns lookup when the hostname is already an IP address * code style update * add test case * use loopback address instead of localhost
1 parent d88e29a commit 631a29e

File tree

2 files changed

+34
-6
lines changed

2 files changed

+34
-6
lines changed

okhttp/src/jvmMain/kotlin/okhttp3/internal/connection/RouteSelector.kt

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package okhttp3.internal.connection
1717

1818
import java.io.IOException
19+
import java.net.InetAddress
1920
import java.net.InetSocketAddress
2021
import java.net.Proxy
2122
import java.net.SocketException
@@ -26,6 +27,7 @@ import okhttp3.Call
2627
import okhttp3.EventListener
2728
import okhttp3.HttpUrl
2829
import okhttp3.Route
30+
import okhttp3.internal.canParseAsIpAddress
2931
import okhttp3.internal.immutableListOf
3032
import okhttp3.internal.toImmutableList
3133

@@ -159,15 +161,20 @@ class RouteSelector(
159161
if (proxy.type() == Proxy.Type.SOCKS) {
160162
mutableInetSocketAddresses += InetSocketAddress.createUnresolved(socketHost, socketPort)
161163
} else {
162-
eventListener.dnsStart(call, socketHost)
164+
val addresses = if (socketHost.canParseAsIpAddress()) {
165+
listOf(InetAddress.getByName(socketHost))
166+
} else {
167+
eventListener.dnsStart(call, socketHost)
168+
169+
val result = address.dns.lookup(socketHost)
170+
if (result.isEmpty()) {
171+
throw UnknownHostException("${address.dns} returned no addresses for $socketHost")
172+
}
163173

164-
val addresses = address.dns.lookup(socketHost)
165-
if (addresses.isEmpty()) {
166-
throw UnknownHostException("${address.dns} returned no addresses for $socketHost")
174+
eventListener.dnsEnd(call, socketHost, result)
175+
result
167176
}
168177

169-
eventListener.dnsEnd(call, socketHost, addresses)
170-
171178
// Try each address for best behavior in mixed IPv4/IPv6 environments.
172179
val orderedAddresses = when {
173180
fastFallback -> reorderForHappyEyeballs(addresses)

okhttp/src/jvmTest/java/okhttp3/EventListenerTest.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,27 @@ public final class EventListenerTest {
139139
"ResponseBodyEnd", "ConnectionReleased", "CallEnd");
140140
}
141141

142+
@Test public void successfulCallEventSequenceForIpAddress() throws IOException {
143+
server.enqueue(new MockResponse()
144+
.setBody("abc"));
145+
146+
String ipAddress = InetAddress.getLoopbackAddress().getHostAddress();
147+
148+
Call call = client.newCall(new Request.Builder()
149+
.url(server.url("/").newBuilder().host(ipAddress).build())
150+
.build());
151+
Response response = call.execute();
152+
assertThat(response.code()).isEqualTo(200);
153+
assertThat(response.body().string()).isEqualTo("abc");
154+
response.body().close();
155+
156+
assertThat(listener.recordedEventTypes()).containsExactly("CallStart",
157+
"ProxySelectStart", "ProxySelectEnd",
158+
"ConnectStart", "ConnectEnd", "ConnectionAcquired", "RequestHeadersStart",
159+
"RequestHeadersEnd", "ResponseHeadersStart", "ResponseHeadersEnd", "ResponseBodyStart",
160+
"ResponseBodyEnd", "ConnectionReleased", "CallEnd");
161+
}
162+
142163
@Test public void successfulCallEventSequenceForEnqueue() throws Exception {
143164
server.enqueue(new MockResponse()
144165
.setBody("abc"));

0 commit comments

Comments
 (0)