Add KMP networking backends

This commit is contained in:
sergeych committed 2026-04-02 19:23:46 +03:00
1 parent d409a4bb8b
commit 5346d15a9f
25 files changed
+1744 -75

No files matched your search

@@ -332,7 +332,7 @@ private class ObjHttpResponse(
fun from(response: LyngHttpResponse): ObjHttpResponse {
val single = linkedMapOf<String, String>()
response.headers.forEach { (name, values) ->
if (values.isNotEmpty()) single.putIfAbsent(name, values.first())
if (values.isNotEmpty() && name !in single) single[name] = values.first()
}
return ObjHttpResponse(
status = response.status.toLong(),
@@ -17,17 +17,6 @@
package net.sergeych.lyngio.http
import io.ktor.client.HttpClient
import io.ktor.client.call.body
import io.ktor.client.engine.cio.CIO
import io.ktor.client.plugins.timeout
import io.ktor.client.request.HttpRequestBuilder
import io.ktor.client.request.request
import io.ktor.client.request.setBody
import io.ktor.http.HttpMethod
import io.ktor.http.headers
import io.ktor.http.takeFrom
data class LyngHttpRequest(
val method: String,
val url: String,
@@ -49,7 +38,7 @@ interface LyngHttpEngine {
suspend fun request(request: LyngHttpRequest): LyngHttpResponse
}
private object UnsupportedHttpEngine : LyngHttpEngine {
internal object UnsupportedHttpEngine : LyngHttpEngine {
override val isSupported: Boolean = false
override suspend fun request(request: LyngHttpRequest): LyngHttpResponse {
@@ -57,48 +46,4 @@ private object UnsupportedHttpEngine : LyngHttpEngine {
}
}
private object KtorLyngHttpEngine : LyngHttpEngine {
private val clientResult by lazy {
runCatching {
HttpClient(CIO) {
expectSuccess = false
}
}
}
override val isSupported: Boolean
get() = clientResult.isSuccess
override suspend fun request(request: LyngHttpRequest): LyngHttpResponse {
val httpClient = clientResult.getOrElse {
throw UnsupportedOperationException(it.message ?: "HTTP client is not supported")
}
val response = httpClient.request {
applyRequest(request)
}
return LyngHttpResponse(
status = response.status.value,
statusText = response.status.description,
headers = response.headers.entries().associate { it.key to it.value.toList() },
bodyBytes = response.body<ByteArray>(),
)
}
private fun HttpRequestBuilder.applyRequest(request: LyngHttpRequest) {
method = HttpMethod.parse(request.method.uppercase())
url.takeFrom(request.url)
headers {
request.headers.forEach { (name, value) -> append(name, value) }
}
request.timeoutMillis?.let { timeout { requestTimeoutMillis = it } }
when {
request.bodyBytes != null && request.bodyText != null ->
throw IllegalArgumentException("Only one of bodyText or bodyBytes may be set")
request.bodyBytes != null -> setBody(request.bodyBytes)
request.bodyText != null -> setBody(request.bodyText)
}
}
}
fun getSystemHttpEngine(): LyngHttpEngine = KtorLyngHttpEngine
expect fun getSystemHttpEngine(): LyngHttpEngine