diff --git a/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/authenticator/JavaNetAuthenticator.kt b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/authenticator/JavaNetAuthenticator.kt index e31b6afc4798..0330e5d043fc 100644 --- a/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/authenticator/JavaNetAuthenticator.kt +++ b/okhttp/src/commonJvmAndroid/kotlin/okhttp3/internal/authenticator/JavaNetAuthenticator.kt @@ -53,17 +53,21 @@ class JavaNetAuthenticator( val dns = route?.address?.dns ?: defaultDns val auth = if (proxyAuthorization) { - val proxyAddress = proxy.address() as InetSocketAddress - Authenticator.requestPasswordAuthentication( - proxyAddress.hostName, - proxy.connectToInetAddress(url, dns), - proxyAddress.port, - url.scheme, - challenge.realm, - challenge.scheme, - url.toUrl(), - Authenticator.RequestorType.PROXY, - ) + if (proxy.type() == Proxy.Type.HTTP) { + val proxyAddress = proxy.address() as InetSocketAddress + Authenticator.requestPasswordAuthentication( + proxyAddress.hostName, + proxy.connectToInetAddress(url, dns), + proxyAddress.port, + url.scheme, + challenge.realm, + challenge.scheme, + url.toUrl(), + Authenticator.RequestorType.PROXY, + ) + } else { + null + } } else { Authenticator.requestPasswordAuthentication( url.host, @@ -102,6 +106,13 @@ class JavaNetAuthenticator( ): InetAddress = when (type()) { Proxy.Type.DIRECT -> dns.lookup(url.host).first() - else -> (address() as InetSocketAddress).address + else -> { + val socketAddress = address() as InetSocketAddress + if (socketAddress.isUnresolved) { + dns.lookup(socketAddress.hostString).first() + } else { + socketAddress.address + } + } } } diff --git a/okhttp/src/jvmTest/kotlin/okhttp3/internal/authenticator/JavaNetAuthenticatorTest.kt b/okhttp/src/jvmTest/kotlin/okhttp3/internal/authenticator/JavaNetAuthenticatorTest.kt index bbf4ecf74be2..e0ae707ecaff 100644 --- a/okhttp/src/jvmTest/kotlin/okhttp3/internal/authenticator/JavaNetAuthenticatorTest.kt +++ b/okhttp/src/jvmTest/kotlin/okhttp3/internal/authenticator/JavaNetAuthenticatorTest.kt @@ -17,7 +17,8 @@ package okhttp3.internal.authenticator import java.net.Authenticator import java.net.InetAddress -import junit.framework.TestCase.assertNull +import java.net.InetSocketAddress +import java.net.Proxy import okhttp3.FakeDns import okhttp3.Protocol.HTTP_2 import okhttp3.Request @@ -26,6 +27,7 @@ import okhttp3.TestValueFactory import okhttp3.internal.RecordingAuthenticator import org.junit.jupiter.api.AfterEach import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNull import org.junit.jupiter.api.BeforeEach import org.junit.jupiter.api.Test @@ -100,4 +102,60 @@ class JavaNetAuthenticatorTest { val authRequest = authenticator.authenticate(null, response) assertNull(authRequest) } + + @Test + fun testProxyAuthDirect() { + fakeDns["server"] = listOf(InetAddress.getLocalHost()) + + val route = factory.newRoute() + + val request = + Request + .Builder() + .url("https://server/robots.txt") + .build() + val response = + Response + .Builder() + .request(request) + .code(407) + .header("Proxy-Authenticate", "Basic realm=\"User Visible Realm\"") + .protocol(HTTP_2) + .message("Unauthorized") + .build() + val authRequest = authenticator.authenticate(route, response) + + assertNull(authRequest) + } + + @Test + fun testProxyAuthUnresolvedAddress() { + fakeDns["server"] = listOf(InetAddress.getLocalHost()) + fakeDns["127.0.0.1"] = listOf(InetAddress.getLocalHost()) + + // ProxySelector's default implementation, sun.net.spi.DefaultProxySelector, returns unresolved addresses + val proxy = Proxy(Proxy.Type.HTTP, InetSocketAddress.createUnresolved("127.0.0.1", 3128)) + val route = factory.newRoute(proxy = proxy) + + val request = + Request + .Builder() + .url("https://server/robots.txt") + .build() + val response = + Response + .Builder() + .request(request) + .code(407) + .header("Proxy-Authenticate", "Basic realm=\"User Visible Realm\"") + .protocol(HTTP_2) + .message("Unauthorized") + .build() + val authRequest = authenticator.authenticate(route, response) + + assertEquals( + "Basic ${RecordingAuthenticator.BASE_64_CREDENTIALS}", + authRequest!!.header("Proxy-Authorization"), + ) + } }