
jvmMain.io.ktor.client.engine.okhttp.OkUtils.kt Maven / Gradle / Ivy
/*
* Copyright 2014-2019 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/
package io.ktor.client.engine.okhttp
import io.ktor.client.plugins.*
import io.ktor.client.request.*
import io.ktor.http.*
import kotlinx.coroutines.*
import okhttp3.*
import java.io.*
import java.net.*
import kotlin.coroutines.*
import okhttp3.Headers as OkHttpHeaders
internal suspend fun OkHttpClient.execute(
request: Request,
requestData: HttpRequestData
): Response = suspendCancellableCoroutine { continuation ->
val call = newCall(request)
call.enqueue(OkHttpCallback(requestData, continuation))
continuation.invokeOnCancellation {
call.cancel()
}
}
private class OkHttpCallback(
private val requestData: HttpRequestData,
private val continuation: CancellableContinuation
) : Callback {
override fun onFailure(call: Call, e: IOException) {
if (continuation.isCancelled) {
return
}
continuation.resumeWithException(mapOkHttpException(requestData, e))
}
override fun onResponse(call: Call, response: Response) {
if (!call.isCanceled()) {
continuation.resume(response)
}
}
}
internal fun OkHttpHeaders.fromOkHttp(): Headers = object : Headers {
override val caseInsensitiveName: Boolean = true
override fun getAll(name: String): List? = [email protected](name).takeIf { it.isNotEmpty() }
override fun names(): Set = [email protected]()
override fun entries(): Set>> = [email protected]().entries
override fun isEmpty(): Boolean = [email protected] == 0
}
@Suppress("DEPRECATION")
internal fun Protocol.fromOkHttp(): HttpProtocolVersion = when (this) {
Protocol.HTTP_1_0 -> HttpProtocolVersion.HTTP_1_0
Protocol.HTTP_1_1 -> HttpProtocolVersion.HTTP_1_1
Protocol.SPDY_3 -> HttpProtocolVersion.SPDY_3
Protocol.HTTP_2 -> HttpProtocolVersion.HTTP_2_0
Protocol.H2_PRIOR_KNOWLEDGE -> HttpProtocolVersion.HTTP_2_0
Protocol.QUIC -> HttpProtocolVersion.QUIC
}
private fun mapOkHttpException(
requestData: HttpRequestData,
origin: IOException
): Throwable = when (origin) {
is StreamAdapterIOException -> origin.cause ?: origin
is SocketTimeoutException ->
if (origin.isConnectException()) {
ConnectTimeoutException(requestData, origin)
} else {
SocketTimeoutException(requestData, origin)
}
else -> origin
}
private fun IOException.isConnectException() =
message?.contains("connect", ignoreCase = true) == true
© 2015 - 2025 Weber Informatics LLC | Privacy Policy