Search code examples
ktorktor-client

ktor httpclient: how to send request to specific ip address?


I have DNS address which contains several ip addresses. It's possible to send request for each address using ktor http-client?

For classic curl it can be made usin --resolve option:

    curl https://host  --resolve "host:443:127.0.0.1"
    curl https://host  --resolve "host:443:127.0.0.2"

Solution

  • You can use Ktor's OkHttp engine to configure an underlying OkHttpClient to use a DNS service that resolves a specified host to a custom IP address. Unfortunately, if you want to provide multiple IP addresses for the same host you have to create a separate client instance for each IP address. Here is an example:

    import io.ktor.client.HttpClient
    import io.ktor.client.engine.okhttp.OkHttp
    import io.ktor.client.request.get
    import okhttp3.Dns
    import okhttp3.OkHttpClient
    import java.net.Inet4Address
    import java.net.InetAddress
    
    suspend fun main() {
        val okHttpClient = OkHttpClient.Builder()
            .dns(HostsDns(mapOf("example.com" to "127.0.0.1")))
            .build()
    
        val client = HttpClient(OkHttp) {
            engine {
                preconfigured = okHttpClient
            }
        }
    
        client.get("http://example.com")
    }
    
    class HostsDns(private val map: Map<String, String>) : Dns {
        override fun lookup(hostname: String): List<InetAddress> {
            val ip = map[hostname]
            return if (ip != null) listOf(Inet4Address.getByName(ip)) else Dns.Companion.SYSTEM.lookup(hostname)
        }
    }