Ktor HTTP Client Core for tvOS ARM64 - multiplatform asynchronous HTTP client library with coroutines support
—
The HTTP engine abstraction layer provides pluggable HTTP implementations across platforms with comprehensive configuration options for connection management, proxies, and platform-specific settings.
interface HttpClientEngine : CoroutineScope, Closeable {
val config: HttpClientEngineConfig
val dispatcher: CoroutineDispatcher
val supportedCapabilities: Set<HttpClientEngineCapability<*>>
suspend fun execute(data: HttpRequestData): HttpResponseData
override fun close()
}
interface HttpClientEngineFactory<T : HttpClientEngineConfig> {
fun create(block: T.() -> Unit = {}): HttpClientEngine
}
abstract class HttpClientEngineBase(
engineName: String
) : HttpClientEngine {
protected val engine: String = engineName
protected abstract suspend fun execute(data: HttpRequestData): HttpResponseData
// Utility methods for subclasses
protected fun HttpRequestData.isUpgradeRequest(): Boolean
protected fun HttpRequestData.requiresDuplexConnection(): Boolean
}open class HttpClientEngineConfig {
var threadsCount: Int = 4
var pipelining: Boolean = false
var proxy: ProxyConfig? = null
// Connection settings
val requestsJob: CompletableJob = Job()
internal val clientConfig: HttpClientConfig<*>? = null
}
data class ProxyConfig(
val type: Type,
val address: SocketAddress
) {
enum class Type { HTTP, SOCKS }
companion object {
fun http(host: String, port: Int): ProxyConfig
fun socks(host: String, port: Int): ProxyConfig
}
}// Uses platform-appropriate default engine
val client = HttpClient()
// Platform defaults:
// - JVM: CIO or OkHttp (if available)
// - JavaScript: Js (Fetch API)
// - Native: Curl// Using specific engine factory
val client = HttpClient(engineFactory) {
// Engine-specific configuration
threadsCount = 8
pipelining = true
}val client = HttpClient {
engine(engineFactory) {
// Engine configuration
threadsCount = 4
pipelining = false
// Proxy configuration
proxy = ProxyConfig.http("proxy.example.com", 8080)
}
}val client = HttpClient {
engine(CIO) {
proxy = ProxyConfig.http("proxy.example.com", 8080)
}
}val client = HttpClient {
engine(CIO) {
proxy = ProxyConfig.socks("socks.example.com", 1080)
}
}val client = HttpClient {
engine(CIO) {
proxy = null // Disable proxy
}
}interface HttpClientEngineCapability<T> {
val key: String
}
// Built-in capabilities
object HttpTimeoutCapability : HttpClientEngineCapability<HttpTimeoutConfig>
object WebSocketCapability : HttpClientEngineCapability<Unit>
object HttpRedirectCapability : HttpClientEngineCapability<HttpRedirect.Config>val engine = client.engine
if (WebSocketCapability in engine.supportedCapabilities) {
println("Engine supports WebSockets")
}
if (HttpTimeoutCapability in engine.supportedCapabilities) {
println("Engine supports timeouts")
}val client = HttpClient {
engine(CIO) {
// Set number of threads for connection pool
threadsCount = 8
// Enable HTTP pipelining
pipelining = true
}
}Engine-specific timeout configuration:
val client = HttpClient {
engine(CIO) {
// CIO-specific timeouts
connectTimeout = 10000 // 10 seconds
requestTimeout = 30000 // 30 seconds
}
}val client = HttpClient(CIO) {
threadsCount = 4
pipelining = false
// CIO-specific settings
maxConnectionsCount = 1000
endpoint {
maxConnectionsPerRoute = 100
pipelineMaxSize = 20
keepAliveTime = 5000
connectTimeout = 5000
connectAttempts = 5
}
}val client = HttpClient(OkHttp) {
// OkHttp-specific configuration
config {
// Configure OkHttpClient
followRedirects(true)
connectTimeout(30, TimeUnit.SECONDS)
readTimeout(30, TimeUnit.SECONDS)
}
}val client = HttpClient(Js) {
// JS engine uses browser's fetch API
// Limited configuration options
}val client = HttpClient(Curl) {
// Curl-specific configuration
sslOptions {
// SSL/TLS configuration
}
}val engine = engineFactory.create {
threadsCount = 4
pipelining = true
}
val client = HttpClient(engine)
// Manual cleanup
client.close()
engine.close()val sharedEngine = CIO.create {
threadsCount = 8
}
// Multiple clients can share the same engine
val client1 = HttpClient(sharedEngine)
val client2 = HttpClient(sharedEngine)
// Only close engine after all clients are closed
client1.close()
client2.close()
sharedEngine.close()// Engine utility functions
fun HttpClientEngineConfig.proxy(type: ProxyConfig.Type, host: String, port: Int)
// Request data utilities
fun HttpRequestData.isWebSocketRequest(): Boolean
fun HttpRequestData.isUpgradeRequest(): Boolean
// Response data utilities
class HttpResponseData(
val statusCode: HttpStatusCode,
val requestTime: GMTDate,
val headers: Headers,
val version: HttpProtocolVersion,
val body: ByteReadChannel,
val callContext: CoroutineContext
)class MyCustomEngine(
override val config: MyCustomEngineConfig
) : HttpClientEngineBase("MyCustomEngine") {
override val dispatcher: CoroutineDispatcher = Dispatchers.IO
override suspend fun execute(data: HttpRequestData): HttpResponseData {
// Custom HTTP implementation
return HttpResponseData(
statusCode = HttpStatusCode.OK,
requestTime = GMTDate(),
headers = Headers.Empty,
version = HttpProtocolVersion.HTTP_1_1,
body = ByteReadChannel.Empty,
callContext = coroutineContext
)
}
override fun close() {
// Cleanup resources
}
}
class MyCustomEngineConfig : HttpClientEngineConfig() {
// Custom configuration properties
var customProperty: String = "default"
}
object MyCustomEngineFactory : HttpClientEngineFactory<MyCustomEngineConfig> {
override fun create(block: MyCustomEngineConfig.() -> Unit): HttpClientEngine {
val config = MyCustomEngineConfig().apply(block)
return MyCustomEngine(config)
}
}val client = HttpClient(MyCustomEngineFactory) {
customProperty = "custom value"
threadsCount = 2
}val mockEngine = MockEngine { request ->
respond(
content = """{"id": 1, "name": "John"}""",
status = HttpStatusCode.OK,
headers = headersOf(HttpHeaders.ContentType, "application/json")
)
}
val client = HttpClient(mockEngine)
val response = client.get("http://test.com/users/1")
// Response will be the mocked datatry {
val response = client.get("https://example.com")
} catch (e: ConnectTimeoutException) {
println("Connection timeout")
} catch (e: SocketTimeoutException) {
println("Read timeout")
} catch (e: UnresolvedAddressException) {
println("DNS resolution failed")
} catch (e: ConnectException) {
println("Connection failed")
}try {
client.webSocket("wss://example.com/ws") {
// WebSocket code
}
} catch (e: UnsupportedOperationException) {
println("Current engine doesn't support WebSockets")
}Install with Tessl CLI
npx tessl i tessl/maven-io-ktor--ktor-client-core-tvosarm64