Repository: square/okhttp
File: okhttp-dnsoverhttps/src/main/kotlin/okhttp3/dnsoverhttps/DnsOverHttps.kt (Kotlin)

Code before:
 * [doh_spec]: https://tools.ietf.org/html/draft-ietf-doh-dns-over-https-13
 */
class DnsOverHttps internal constructor(
  @get:JvmName("client") val client: OkHttpClient,
  @get:JvmName("url") val url: HttpUrl,
  @get:JvmName("includeIPv6") val includeIPv6: Boolean,
  @get:JvmName("post") val post: Boolean,
  @get:JvmName("resolvePrivateAddresses") val resolvePrivateAddresses: Boolean,
  @get:JvmName("resolvePublicAddresses") val resolvePublicAddresses: Boolean
) : Dns {
  @Throws(UnknownHostException::class)
  override fun lookup(hostname: String): List<InetAddress> {
    if (!resolvePrivateAddresses || !resolvePublicAddresses) {
      val privateHost = isPrivateHost(hostname)

      if (privateHost && !resolvePrivateAddresses) {
        throw UnknownHostException("private hosts not resolved")
      }

      if (!privateHost && !resolvePublicAddresses) {
        throw UnknownHostException("public hosts not resolved")
      }
    }

    return try {
      listOf(InetAddressUtil.forString(hostname))
    } catch (e: UnknownHostException) {
      lookupHttps(hostname)
    }
  }

  @Throws(UnknownHostException::class)
  private fun lookupHttps(hostname: String): List<InetAddress> {
    val networkRequests = ArrayList<Call>(2)
    val failures = ArrayList<Exception>(2)
    val results = ArrayList<InetAddress>(5)

    buildRequest(hostname, networkRequests, results, failures, DnsRecordCodec.TYPE_A)

    if (includeIPv6) {
      buildRequest(hostname, networkRequests, results, failures, DnsRecordCodec.TYPE_AAAA)
    }

    executeRequests(hostname, networkRequests, results, failures)

    return results.ifEmpty {
      throwBestFailure(hostname, failures)
    }
  }

  private fun buildRequest(

Review comment (suggestion):
Can you add a test?  

We need to avoid an exception in most calls here.  Maybe reverse this logic (try hostname first) and in the normal case call lookupHttps, and catch and exception, check if it's a ip address and then return forString.

Code after:
 * [doh_spec]: https://tools.ietf.org/html/draft-ietf-doh-dns-over-https-13
 */
class DnsOverHttps internal constructor(
  @get:JvmName("client") val client: OkHttpClient,
  @get:JvmName("url") val url: HttpUrl,
  @get:JvmName("includeIPv6") val includeIPv6: Boolean,
  @get:JvmName("post") val post: Boolean,
  @get:JvmName("resolvePrivateAddresses") val resolvePrivateAddresses: Boolean,
  @get:JvmName("resolvePublicAddresses") val resolvePublicAddresses: Boolean
) : Dns {
  @Throws(UnknownHostException::class)
  override fun lookup(hostname: String): List<InetAddress> {
    if (!resolvePrivateAddresses || !resolvePublicAddresses) {
      val privateHost = isPrivateHost(hostname)

      if (privateHost && !resolvePrivateAddresses) {
        throw UnknownHostException("private hosts not resolved")
      }

      if (!privateHost && !resolvePublicAddresses) {
        throw UnknownHostException("public hosts not resolved")
      }
    }

    return lookupHttps(hostname)
  }

  @Throws(UnknownHostException::class)
  private fun lookupHttps(hostname: String): List<InetAddress> {
    val networkRequests = ArrayList<Call>(2)
    val failures = ArrayList<Exception>(2)
    val results = ArrayList<InetAddress>(5)

    buildRequest(hostname, networkRequests, results, failures, DnsRecordCodec.TYPE_A)

    if (includeIPv6) {
      buildRequest(hostname, networkRequests, results, failures, DnsRecordCodec.TYPE_AAAA)
    }

    executeRequests(hostname, networkRequests, results, failures)

    return results.ifEmpty {
      throwBestFailure(hostname, failures)
    }
  }

  private fun buildRequest(
    hostname: String,
    networkRequests: MutableList<Call>,
    results: MutableList<InetAddress>,
    failures: MutableList<Exception>,