or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

client-configuration.mdcookie-management.mdengine-configuration.mdform-handling.mdhttp-caching.mdindex.mdplugin-system.mdrequest-building.mdresponse-handling.mdwebsocket-support.md
tile.json

tessl/maven-io-ktor--ktor-client-core-iosx64

Ktor HTTP client core library - asynchronous framework for creating HTTP clients in Kotlin multiplatform

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
mavenpkg:maven/io.ktor/ktor-client-core-iosx64@2.3.x

To install, run

npx @tessl/cli install tessl/maven-io-ktor--ktor-client-core-iosx64@2.3.0

index.mddocs/

Ktor HTTP Client Core

Ktor HTTP Client Core is a multiplatform asynchronous HTTP client library for Kotlin that enables developers to make HTTP requests and handle responses across JVM, JavaScript, and Native platforms. The library features a plugin-based architecture, type-safe request building through DSL syntax, full coroutine support, and extensive configuration options for timeouts, redirects, cookies, caching, and WebSocket connections.

Package Information

  • Package Name: io.ktor:ktor-client-core-iosx64
  • Package Type: Maven
  • Language: Kotlin Multiplatform
  • Installation: Add dependency to your build.gradle.kts:
dependencies {
    implementation("io.ktor:ktor-client-core:2.3.13")
    // Also add a specific engine implementation
    implementation("io.ktor:ktor-client-cio:2.3.13") // For JVM
}

Core Imports

import io.ktor.client.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.client.engine.cio.*

Basic Usage

import io.ktor.client.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.client.engine.cio.*

// Create HTTP client
val client = HttpClient(CIO) {
    // Optional configuration
}

// Make GET request
val response: HttpResponse = client.get("https://api.example.com/users")
val content: String = response.bodyAsText()

// Make POST request with JSON
val postResponse = client.post("https://api.example.com/users") {
    contentType(ContentType.Application.Json)
    setBody("""{"name": "John", "email": "john@example.com"}""")
}

// Clean up
client.close()

Architecture

Ktor HTTP Client Core is built around several key components:

  • HttpClient: Main client class implementing CoroutineScope for structured concurrency
  • HttpClientEngine: Platform-specific engine abstraction for actual HTTP operations
  • Request Pipeline: Configurable pipeline for processing outgoing requests
  • Response Pipeline: Configurable pipeline for processing incoming responses
  • Plugin System: Extensible architecture for adding functionality like authentication, caching, and logging
  • Type-Safe DSL: Kotlin DSL for building requests with compile-time safety
  • Multiplatform Design: Common API with platform-specific optimizations

Capabilities

HTTP Client Creation and Configuration

Core functionality for creating and configuring HTTP clients with engine selection and plugin installation.

// Primary client factory function (platform-specific)
expect fun HttpClient(
    block: HttpClientConfig<*>.() -> Unit = {}
): HttpClient

// Client factory with engine
fun <T : HttpClientEngineConfig> HttpClient(
    engineFactory: HttpClientEngineFactory<T>,
    block: HttpClientConfig<T>.() -> Unit = {}
): HttpClient

// Client with existing engine
fun HttpClient(
    engine: HttpClientEngine,
    block: HttpClientConfig<*>.() -> Unit
): HttpClient

class HttpClient(
    val engine: HttpClientEngine,
    private val userConfig: HttpClientConfig<out HttpClientEngineConfig> = HttpClientConfig()
) : CoroutineScope, Closeable {
    val requestPipeline: HttpRequestPipeline
    val responsePipeline: HttpResponsePipeline
    val sendPipeline: HttpSendPipeline
    val receivePipeline: HttpReceivePipeline
    val attributes: Attributes
    val engineConfig: HttpClientEngineConfig
    val monitor: Events
    
    fun isSupported(capability: HttpClientEngineCapability<*>): Boolean
    fun config(block: HttpClientConfig<*>.() -> Unit): HttpClient
    override fun close()
}

Client Configuration

HTTP Request Building and Execution

Type-safe DSL for building and executing HTTP requests with all standard HTTP methods.

// Generic request functions
suspend fun HttpClient.request(
    builder: HttpRequestBuilder = HttpRequestBuilder()
): HttpResponse

suspend fun HttpClient.request(
    block: HttpRequestBuilder.() -> Unit
): HttpResponse

suspend fun HttpClient.request(
    urlString: String,
    block: HttpRequestBuilder.() -> Unit = {}
): HttpResponse

// HTTP method convenience functions
suspend fun HttpClient.get(urlString: String, block: HttpRequestBuilder.() -> Unit = {}): HttpResponse
suspend fun HttpClient.post(urlString: String, block: HttpRequestBuilder.() -> Unit = {}): HttpResponse
suspend fun HttpClient.put(urlString: String, block: HttpRequestBuilder.() -> Unit = {}): HttpResponse
suspend fun HttpClient.delete(urlString: String, block: HttpRequestBuilder.() -> Unit = {}): HttpResponse
suspend fun HttpClient.patch(urlString: String, block: HttpRequestBuilder.() -> Unit = {}): HttpResponse
suspend fun HttpClient.head(urlString: String, block: HttpRequestBuilder.() -> Unit = {}): HttpResponse
suspend fun HttpClient.options(urlString: String, block: HttpRequestBuilder.() -> Unit = {}): HttpResponse

class HttpRequestBuilder {
    var url: URLBuilder
    var method: HttpMethod
    var headers: HeadersBuilder
    var body: Any
    var attributes: Attributes
    
    fun url(block: URLBuilder.() -> Unit)
    fun build(): HttpRequestData
    fun takeFrom(builder: HttpRequestBuilder): HttpRequestBuilder
}

// Progress tracking extensions
typealias ProgressListener = suspend (bytesSentTotal: Long, contentLength: Long) -> Unit
fun HttpRequestBuilder.onUpload(listener: ProgressListener?)
fun HttpRequestBuilder.onDownload(listener: ProgressListener?)

// Timeout configuration extension
fun HttpRequestBuilder.timeout(block: HttpTimeout.HttpTimeoutCapabilityConfiguration.() -> Unit)

// Retry configuration extension  
fun HttpRequestBuilder.retry(block: HttpRequestRetry.Configuration.() -> Unit)

Request Building

HTTP Response Handling

Comprehensive response handling with typed body access and streaming capabilities.

// Response classes
abstract class HttpResponse : HttpMessage, CoroutineScope {
    abstract val call: HttpClientCall
    abstract val status: HttpStatusCode
    abstract val version: HttpProtocolVersion
    abstract val requestTime: GMTDate
    abstract val responseTime: GMTDate
    abstract val content: ByteReadChannel
}

// Response body access
suspend fun HttpResponse.bodyAsText(fallbackCharset: Charset = Charsets.UTF_8): String
suspend fun HttpResponse.bodyAsChannel(): ByteReadChannel
suspend inline fun <reified T> HttpResponse.body(): T

// Prepared statements
class HttpStatement(
    private val builder: HttpRequestBuilder,
    private val client: HttpClient
) {
    suspend fun <T> execute(block: suspend (response: HttpResponse) -> T): T
    suspend fun execute(): HttpResponse
    suspend inline fun <reified T> body(): T
}

// Client call representation
class HttpClientCall(
    val client: HttpClient
) : CoroutineScope {
    val attributes: Attributes
    val request: HttpRequest
    val response: HttpResponse
    
    suspend inline fun <reified T> body(): T
    suspend fun bodyNullable(info: TypeInfo): Any?
}

Response Handling

Plugin System

Extensible plugin architecture for adding cross-cutting concerns like authentication, caching, and logging.

interface HttpClientPlugin<out TConfig : Any, TPlugin : Any> {
    val key: AttributeKey<TPlugin>
    
    fun prepare(block: TConfig.() -> Unit = {}): TPlugin
    fun install(plugin: TPlugin, scope: HttpClient)
}

// Plugin access
fun <B : Any, F : Any> HttpClient.pluginOrNull(plugin: HttpClientPlugin<B, F>): F?
fun <B : Any, F : Any> HttpClient.plugin(plugin: HttpClientPlugin<B, F>): F

// Configuration in client
class HttpClientConfig<T : HttpClientEngineConfig> {
    fun <TBuilder : Any, TPlugin : Any> install(
        plugin: HttpClientPlugin<TBuilder, TPlugin>,
        configure: TBuilder.() -> Unit = {}
    )
    fun install(key: String, block: HttpClient.() -> Unit)
}

Plugin System

Engine Abstraction

Platform-specific engine abstraction providing the underlying HTTP implementation.

interface HttpClientEngine : CoroutineScope, Closeable {
    val dispatcher: CoroutineDispatcher
    val config: HttpClientEngineConfig
    val supportedCapabilities: Set<HttpClientEngineCapability<*>>
}

interface HttpClientEngineFactory<out T : HttpClientEngineConfig> {
    fun create(block: T.() -> Unit = {}): HttpClientEngine
}

open class HttpClientEngineConfig {
    var threadsCount: Int = 4 // Deprecated
    var pipelining: Boolean = false
    var proxy: ProxyConfig? = null
}

Engine Configuration

WebSocket Support

Full-duplex WebSocket communication with extensions support and content conversion.

object WebSockets : HttpClientPlugin<WebSockets.Config, WebSockets> {
    class Config {
        var pingInterval: Long = -1L
        var maxFrameSize: Long = Long.MAX_VALUE
        var contentConverter: WebsocketContentConverter? = null
        
        fun extensions(block: WebSocketExtensionsConfig.() -> Unit)
    }
}

// WebSocket connection functions
suspend fun HttpClient.webSocketSession(
    block: HttpRequestBuilder.() -> Unit
): DefaultClientWebSocketSession

suspend fun HttpClient.webSocket(
    urlString: String,
    request: HttpRequestBuilder.() -> Unit = {},
    block: suspend DefaultClientWebSocketSession.() -> Unit
)

suspend fun HttpClient.ws(
    urlString: String,
    request: HttpRequestBuilder.() -> Unit = {},
    block: suspend DefaultClientWebSocketSession.() -> Unit
)

WebSocket Support

Form Handling

Support for URL-encoded forms and multipart form data with file uploads.

// Form content classes
class FormDataContent(val formData: Parameters) : OutgoingContent.ByteArrayContent() {
    override val contentLength: Long
    override val contentType: ContentType
    override fun bytes(): ByteArray
}

class MultiPartFormDataContent(
    parts: List<PartData>,
    boundary: String,
    contentType: ContentType = ContentType.MultiPart.FormData.withParameter("boundary", boundary)
) : OutgoingContent.WriteChannelContent() {
    val boundary: String
    override val contentType: ContentType
    override val contentLength: Long?
}

// Form submission functions
suspend fun HttpClient.submitForm(
    formParameters: Parameters,
    encodeInQuery: Boolean = false,
    block: HttpRequestBuilder.() -> Unit = {}
): HttpResponse

suspend fun HttpClient.submitFormWithBinaryData(
    formData: List<PartData>,
    block: HttpRequestBuilder.() -> Unit = {}
): HttpResponse

Form Handling

Cookie Management

Cookie storage and management with configurable storage backends.

class HttpCookies private constructor(
    private val storage: CookiesStorage
) : Closeable {
    class Config {
        var storage: CookiesStorage = AcceptAllCookiesStorage()
        
        fun default(block: suspend CookiesStorage.() -> Unit)
    }
    
    companion object : HttpClientPlugin<Config, HttpCookies> {
        override val key: AttributeKey<HttpCookies> = AttributeKey("HttpCookies")
    }
    
    suspend fun get(requestUrl: Url): List<Cookie>
}

interface CookiesStorage : Closeable {
    suspend fun get(requestUrl: Url): List<Cookie>
    suspend fun addCookie(requestUrl: Url, cookie: Cookie)
}

class AcceptAllCookiesStorage : CookiesStorage
class ConstantCookiesStorage(cookies: List<Cookie>) : CookiesStorage

Cookie Management

HTTP Caching

Response caching with configurable storage backends and cache control support.

class HttpCache internal constructor(
    private val publicStorage: CacheStorage,
    private val privateStorage: CacheStorage,
    private val isSharedClient: Boolean
) {
    class Config {
        var isShared: Boolean = false
        
        fun publicStorage(storage: CacheStorage)
        fun privateStorage(storage: CacheStorage)
    }
    
    companion object : HttpClientPlugin<Config, HttpCache> {
        override val key: AttributeKey<HttpCache> = AttributeKey("HttpCache")
        val HttpResponseFromCache: EventDefinition<HttpResponse>
    }
}

interface CacheStorage {
    suspend fun store(url: Url, data: CachedResponseData)
    suspend fun find(url: Url, varyKeys: Map<String, String>): CachedResponseData?
    suspend fun findAll(url: Url): Set<CachedResponseData>
    
    companion object {
        fun Unlimited(): CacheStorage
        val Disabled: CacheStorage
    }
}

data class CachedResponseData(
    val url: Url,
    val statusCode: HttpStatusCode,
    val requestTime: GMTDate,
    val responseTime: GMTDate,
    val version: HttpProtocolVersion,
    val expires: GMTDate,
    val headers: Headers,
    val varyKeys: Map<String, String>,
    val body: ByteArray
)

HTTP Caching

Types

Core Types

// Request types
interface HttpRequest : HttpMessage {
    val call: HttpClientCall
    val method: HttpMethod
    val url: Url
    val attributes: Attributes
    val content: OutgoingContent
}

data class HttpRequestData(
    val url: Url,
    val method: HttpMethod,
    val headers: Headers,
    val body: OutgoingContent,
    val executionContext: Job,
    val attributes: Attributes
)

data class HttpResponseData(
    val statusCode: HttpStatusCode,
    val requestTime: GMTDate,
    val headers: Headers,
    val version: HttpProtocolVersion,
    val body: ByteReadChannel,
    val callContext: CoroutineContext
)

// Pipeline types
class HttpRequestPipeline(developmentMode: Boolean = false)
class HttpResponsePipeline(developmentMode: Boolean = false)  
class HttpSendPipeline(developmentMode: Boolean = false)
class HttpReceivePipeline(developmentMode: Boolean = false)

// Engine capability
interface HttpClientEngineCapability<T>

// Proxy configuration
expect class ProxyConfig

enum class ProxyType {
    SOCKS, HTTP, UNKNOWN
}

expect object ProxyBuilder {
    fun http(url: Url): ProxyConfig
    fun http(urlString: String): ProxyConfig  
    fun socks(host: String, port: Int): ProxyConfig
}

Exception Classes

// Request/Response exceptions
class DoubleReceiveException(message: String) : IllegalStateException(message)
class ReceivePipelineException(message: String, cause: Throwable) : IllegalStateException(message, cause)
class NoTransformationFoundException(from: KType, to: KType) : UnsupportedOperationException()

// Timeout exceptions  
class HttpRequestTimeoutException(url: String, timeoutMillis: Long?) : IOException()
fun ConnectTimeoutException(request: HttpRequestData, cause: Throwable? = null): ConnectTimeoutException
fun ConnectTimeoutException(url: String, timeout: Long?, cause: Throwable? = null): ConnectTimeoutException
fun SocketTimeoutException(request: HttpRequestData, cause: Throwable? = null): SocketTimeoutException

// Plugin validation exceptions
class ResponseException(response: HttpResponse, cachedResponseText: String) : IllegalStateException()
class RedirectResponseException(response: HttpResponse, message: String) : ResponseException(response, message)
class ClientRequestException(response: HttpResponse, message: String) : ResponseException(response, message)  
class ServerResponseException(response: HttpResponse, message: String) : ResponseException(response, message)

// Retry exceptions
class SendCountExceedException(message: String) : IllegalStateException(message)

// WebSocket exceptions
open class WebSocketException(message: String) : IllegalStateException(message)

// Cache exceptions
class InvalidCacheStateException(message: String) : IllegalStateException(message)

Event Definitions

val HttpRequestCreated: EventDefinition<HttpRequestBuilder>
val HttpRequestIsReadyForSending: EventDefinition<HttpRequestBuilder>
val HttpResponseReceived: EventDefinition<HttpResponse>
val HttpResponseReceiveFailed: EventDefinition<HttpResponseReceiveFail>
val HttpResponseCancelled: EventDefinition<HttpResponse>
val HttpRequestRetryEvent: EventDefinition<HttpRequestRetry.RetryEventData>

data class HttpResponseReceiveFail(
    val response: HttpResponse,
    val cause: Throwable
)