Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I configure the engine for KTOR HTTPclient Multiplatform Kotlin projects? Addition of SSL certificate is also required

Below is the code that I have tried. I am trying the following code in the commonMain block.

suspend fun callHttpFunction(){

val clientEngine = HttpClient{

        engine {
            pipelining = true
            threadsCount = 4
        }

    }

    clientEngine.post<String>("https","m2.testing.com",8080,
        "/TokenServiceEncrypt/api/base/TokenUpdated",requestBlock
    ) {
        headers.append("Content-Type", "application/json")
        headers.append("Accept", "application/json")
        headers.append("SessionToken", "seesfssfsf")
    }
    clientEngine.close()
}

//HttpClient(Apache) fails and so does HttpClient(OkHttp)
like image 932
Ganesh Hegde Avatar asked Oct 21 '25 18:10

Ganesh Hegde


2 Answers

I've managed to use expect/actual classes which return a HttpClient and each platform uses its dedicated engine.

expect class HttpClientProvider() {
    fun getHttpClient(host: String, sslPin: String): HttpClient
}
actual class HttpClientProvider {
    actual fun getHttpClient(host: String, sslPin: String): HttpClient {
        val okHttpClient = OkHttpClient.Builder().apply {
            certificatePinner(
                CertificatePinner.Builder()
                    .add(host, sslPin)
                    .build()
            )
        }.build()

        return HttpClient(OkHttp) {
            engine {
                preconfigured = okHttpClient
            }
        }
    }
}

As you see, you can pass a OkHttpClient to preconfigured and in there, you can use all features of OkHttp (I use certificatePinner(), socketFactory() and sslSocketFactory).

This should work for iOS as well (had no time to test yet).

private val client = HttpClientProvider().getHttpClient(stage.host, stage.sslPin).config {
    requestTimeout?.let {
        install(HttpTimeout) {
            requestTimeoutMillis = it.toLongMilliseconds()
        }
    }

    logLevel?.let {
        install(Logging) {
            logger = Logger.SIMPLE
            level = it
        }
    }
}

And you can use the normal config { }-block as well.

like image 175
hardysim Avatar answered Oct 23 '25 07:10

hardysim


Not possible to add Apache, OkHttp or CIO engines in the common block - these three are specific to JVM (although CIO is also available for Windows). Add them to your JVM/Android source sets. Also,

"in the case of the JVM, the default engine is resolved with a ServiceLoader, getting the first one available sorted in alphabetical order. This depends on the artifacts you have included."

(Link at the bottom).

List of engines by platform

This means that unless you need to customize your engine config, you don't have to explicitly initialize, as long as you put them in the right order (for JVM), and for iOS there are really no options, just one built in option that will be picked up automatically and uses NSUrlSession internally.

Ktor Engines and where they belong:

like image 32
Dmitri Avatar answered Oct 23 '25 08:10

Dmitri



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!