Ktor HTTP client core library providing asynchronous HTTP client functionality for multiplatform applications with macOS ARM64 support.
npx @tessl/cli install tessl/maven-io-ktor--ktor-client-core-macosarm64@3.2.0Ktor Client Core is a multiplatform asynchronous HTTP client library that provides comprehensive HTTP client functionality for Kotlin applications. It offers coroutine-based HTTP operations, request/response handling, authentication, content negotiation, and WebSocket support with multiplatform compatibility across JVM, Android, iOS, JavaScript, and native platforms including macOS ARM64.
implementation("io.ktor:ktor-client-core:3.2.0")import io.ktor.client.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.client.call.*
import io.ktor.client.engine.*
import io.ktor.client.plugins.*import io.ktor.client.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
// Create a client
val client = HttpClient()
try {
// Make a GET request
val response: HttpResponse = client.get("https://ktor.io/")
val content: String = response.bodyAsText()
println(content)
// Make a POST request with JSON
val postResponse = client.post("https://api.example.com/data") {
setBody("""{"name": "value"}""")
headers {
append("Content-Type", "application/json")
}
}
} finally {
// Always close the client
client.close()
}Ktor Client Core is built around several key architectural components:
Core HTTP client functionality for making requests, handling responses, and managing client lifecycle. Provides coroutine-based API with full multiplatform support.
class HttpClient(
engine: HttpClientEngine,
userConfig: HttpClientConfig<out HttpClientEngineConfig> = HttpClientConfig()
) : CoroutineScope, Closeable {
val engine: HttpClientEngine
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()
}
expect fun HttpClient(
block: HttpClientConfig<*>.() -> Unit = {}
): HttpClientRequest building DSL for constructing HTTP requests with headers, parameters, body content, and various configuration options.
class HttpRequestBuilder {
var method: HttpMethod
val url: URLBuilder
val headers: HeadersBuilder
var body: Any
val attributes: Attributes
var executionContext: Job?
fun header(key: String, value: String)
fun headers(block: HeadersBuilder.() -> Unit)
fun parameter(key: String, value: Any?)
fun accept(contentType: ContentType)
fun contentType(contentType: ContentType)
fun userAgent(agent: String)
fun basicAuth(username: String, password: String)
fun bearerAuth(token: String)
fun timeout(block: HttpTimeoutCapabilityConfiguration.() -> Unit)
fun build(): HttpRequestData
}
suspend fun HttpClient.request(block: HttpRequestBuilder.() -> Unit): HttpResponse
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: block: HttpRequestBuilder.() -> Unit = {}): HttpResponseResponse processing capabilities for extracting data from HTTP responses, handling different content types, and streaming response data.
interface HttpResponse {
val call: HttpClientCall
val status: HttpStatusCode
val version: HttpProtocolVersion
val requestTime: GMTDate
val responseTime: GMTDate
val headers: Headers
override val coroutineContext: CoroutineContext
}
class HttpStatement(
private val builder: HttpRequestBuilder,
private val client: HttpClient
) {
suspend fun execute(block: suspend (response: HttpResponse) -> T): T
suspend inline fun <reified T> body(): T
suspend fun bodyAsText(fallbackCharset: Charset = Charsets.UTF_8): String
suspend fun bodyAsChannel(): ByteReadChannel
suspend fun bodyAsBytes(): ByteArray
}
suspend inline fun <reified T> HttpResponse.body(): T
suspend fun HttpResponse.bodyAsText(fallbackCharset: Charset = Charsets.UTF_8): String
suspend fun HttpResponse.bodyAsChannel(): ByteReadChannel
suspend fun HttpResponse.bodyAsBytes(): ByteArrayHTTP engine abstraction providing platform-specific implementations and configuration options for connection management, timeouts, and networking behavior.
interface HttpClientEngine : CoroutineScope, Closeable {
val config: HttpClientEngineConfig
val dispatcher: CoroutineDispatcher
val supportedCapabilities: Set<HttpClientEngineCapability<*>>
suspend fun execute(data: HttpRequestData): HttpResponseData
fun install(client: HttpClient)
}
open class HttpClientEngineConfig {
var dispatcher: CoroutineDispatcher?
var pipelining: Boolean
var proxy: ProxyConfig?
var localAddress: SocketAddress?
fun proxy(url: String)
}
interface HttpClientEngineFactory<out T : HttpClientEngineConfig> {
fun create(block: T.() -> Unit = {}): HttpClientEngine
}Plugin framework for extending client functionality with authentication, logging, content negotiation, caching, and custom middleware.
interface HttpClientPlugin<TConfig : Any, TPlugin : Any> {
val key: AttributeKey<TPlugin>
fun prepare(block: TConfig.() -> Unit): TPlugin
fun install(plugin: TPlugin, scope: HttpClient)
}
class ClientPluginBuilder<TConfig : Any>(
private val name: String
) {
fun on(event: ClientHook<*>, block: suspend ClientHookHandler<*>.() -> Unit)
fun onRequest(block: suspend OnRequestContext.() -> Unit)
fun onResponse(block: suspend OnResponseContext.() -> Unit)
fun transformRequestBody(block: suspend TransformRequestBodyContext.() -> Unit)
fun transformResponseBody(block: suspend TransformResponseBodyContext.() -> Unit)
}
fun <TConfig : Any> createClientPlugin(
name: String,
createConfiguration: () -> TConfig,
body: ClientPluginBuilder<TConfig>.() -> Unit
): HttpClientPlugin<TConfig, *>Comprehensive set of built-in plugins providing essential HTTP client features including authentication, cookies, redirects, timeouts, content negotiation, and WebSocket support.
object HttpRequestLifecycle : HttpClientPlugin<Unit, Unit>
object BodyProgress : HttpClientPlugin<Unit, Unit>
object SaveBody : HttpClientPlugin<Unit, Unit>
object HttpSend : HttpClientPlugin<Unit, Unit>
object HttpPlainText : HttpClientPlugin<Unit, Unit>
object HttpCallValidator : HttpClientPlugin<Unit, Unit>
object HttpRedirect : HttpClientPlugin<Unit, Unit>
object HttpCookies : HttpClientPlugin<HttpCookiesConfig, HttpCookies>
object HttpCache : HttpClientPlugin<Unit, Unit>
object HttpTimeout : HttpClientPlugin<HttpTimeoutCapabilityConfiguration, Unit>
object Auth : HttpClientPlugin<AuthConfig, Auth>
object WebSockets : HttpClientPlugin<WebSocketConfig, Unit>
object SSE : HttpClientPlugin<Unit, Unit>Content handling for form data, multipart uploads, file uploads, and various content types with proper encoding and streaming support.
class FormDataContent(formData: Parameters) : OutgoingContent.ByteArrayContent()
class MultiPartFormDataContent(
private val formData: List<PartData>,
override val contentType: ContentType = ContentType.MultiPart.FormData.withParameter("boundary", boundary),
override val contentLength: Long? = null
) : OutgoingContent.WriteChannelContent()
class ParametersBuilder(size: Int = 8) : StringValuesBuilder {
fun append(name: String, value: String)
fun appendAll(stringValues: StringValues)
fun appendAll(name: String, values: Iterable<String>)
fun appendMissing(stringValues: StringValues)
fun appendMissing(name: String, values: Iterable<String>)
fun build(): Parameters
}
suspend fun HttpClient.submitForm(
url: String,
formParameters: Parameters = Parameters.Empty,
encodeInQuery: Boolean = false,
block: HttpRequestBuilder.() -> Unit = {}
): HttpResponse
suspend fun HttpClient.submitFormWithBinaryData(
url: String,
formData: List<PartData>,
block: HttpRequestBuilder.() -> Unit = {}
): HttpResponseclass HttpClientCall(
val client: HttpClient,
val request: HttpRequest,
val response: HttpResponse,
val attributes: Attributes
) {
suspend inline fun <reified T> body(): T
suspend inline fun <reified T> bodyNullable(): T?
fun save(): SavedHttpCall
}
interface HttpRequest {
val call: HttpClientCall
val method: HttpMethod
val url: Url
val attributes: Attributes
val headers: Headers
val body: OutgoingContent
}
class HttpRequestPipeline : Pipeline<Any, HttpRequestBuilder>
class HttpResponsePipeline : Pipeline<HttpResponseContainer, HttpClientCall>
class HttpSendPipeline : Pipeline<Any, HttpClientCall>
class HttpReceivePipeline : Pipeline<HttpResponseContainer, HttpClientCall>class HttpClientConfig<T : HttpClientEngineConfig> {
var engine: T?
var developmentMode: Boolean
var expectSuccess: Boolean
var useDefaultTransformers: Boolean
var followRedirects: Boolean
fun engine(block: T.() -> Unit)
fun install(plugin: HttpClientPlugin<*, *>)
fun install(key: String, block: HttpClientConfig<HttpClientEngineConfig>.() -> Unit)
operator fun plus(other: HttpClientConfig<out HttpClientEngineConfig>): HttpClientConfig<T>
fun clone(): HttpClientConfig<T>
}
class ProxyConfig(
val type: ProxyType,
val address: SocketAddress
)
enum class ProxyType { HTTP, SOCKS }class ClientEngineClosedException(cause: Throwable? = null) : IllegalStateException("Client engine is already closed.", cause)
class DoubleReceiveException(call: HttpClientCall) : IllegalStateException("Response already received: $call")
class NoTransformationFoundException(from: KType, to: KType) : UnsupportedOperationException("No transformation found: $from -> $to")
class HttpRequestTimeoutException(url: String, timeoutMillis: Long) : IOException("Request timeout has expired [url=$url, timeout_ms=$timeoutMillis]")
class ConnectTimeoutException(message: String, cause: Throwable? = null) : IOException(message, cause)
class SocketTimeoutException(message: String, cause: Throwable? = null) : IOException(message, cause)