CtrlK
BlogDocsLog inGet started
Tessl Logo

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

Ktor HTTP client core library providing asynchronous HTTP client functionality for multiplatform applications with macOS ARM64 support.

Pending
Overview
Eval results
Files

built-in-plugins.mddocs/

Built-in Plugins and Features

Comprehensive set of built-in plugins providing essential HTTP client features including authentication, cookies, redirects, timeouts, content negotiation, and WebSocket support.

Core Plugins

HttpRequestLifecycle

Core plugin for managing request lifecycle events.

/**
 * Plugin for managing HTTP request lifecycle events
 */
object HttpRequestLifecycle : HttpClientPlugin<Unit, Unit>

BodyProgress

Plugin for tracking upload and download progress.

/**
 * Plugin for tracking request/response body progress
 */
object BodyProgress : HttpClientPlugin<Unit, Unit>

SaveBody

Plugin for saving response bodies for multiple access.

/**
 * Plugin for saving response bodies to enable multiple reads
 */
object SaveBody : HttpClientPlugin<Unit, Unit>

Authentication

Auth Plugin

Comprehensive authentication plugin supporting multiple authentication schemes.

/**
 * Authentication plugin supporting multiple auth providers
 */
object Auth : HttpClientPlugin<AuthConfig, Auth> {
    /** Install bearer token authentication */
    fun AuthConfig.bearer(block: BearerAuthConfig.() -> Unit)
    
    /** Install basic authentication */
    fun AuthConfig.basic(block: BasicAuthConfig.() -> Unit)
    
    /** Install digest authentication */
    fun AuthConfig.digest(block: DigestAuthConfig.() -> Unit)
    
    /** Install OAuth authentication */
    fun AuthConfig.oauth(block: OAuthConfig.() -> Unit)
}

/**
 * Bearer token authentication configuration
 */
class BearerAuthConfig {
    /** Load tokens for authentication */
    fun loadTokens(block: suspend () -> BearerTokens?)
    
    /** Refresh tokens when expired */
    fun refreshTokens(block: suspend (BearerTokens) -> BearerTokens?)
    
    /** Send credentials without waiting for 401 */
    var sendWithoutRequest: Boolean
    
    /** Realm for authentication */
    var realm: String?
}

/**
 * Bearer tokens for OAuth-style authentication
 */
data class BearerTokens(
    val accessToken: String,
    val refreshToken: String?
)

/**
 * Basic authentication configuration
 */
class BasicAuthConfig {
    /** Username for authentication */
    var username: String
    
    /** Password for authentication */
    var password: String
    
    /** Send credentials without waiting for 401 */
    var sendWithoutRequest: Boolean
    
    /** Realm for authentication */
    var realm: String?
}

Usage Examples:

import io.ktor.client.*
import io.ktor.client.plugins.auth.*
import io.ktor.client.plugins.auth.providers.*

// Bearer token authentication
val bearerClient = HttpClient {
    install(Auth) {
        bearer {
            loadTokens {
                // Load tokens from storage
                BearerTokens(
                    accessToken = "your_access_token",
                    refreshToken = "your_refresh_token"
                )
            }
            
            refreshTokens { tokens ->
                // Refresh expired tokens
                val response = client.post("https://auth.example.com/refresh") {
                    setBody("""{"refresh_token": "${tokens.refreshToken}"}""")
                }
                val newTokens = response.body<TokenResponse>()
                BearerTokens(newTokens.accessToken, newTokens.refreshToken)
            }
            
            sendWithoutRequest = false
            realm = "api"
        }
    }
}

// Basic authentication
val basicClient = HttpClient {
    install(Auth) {
        basic {
            username = "user"
            password = "password"
            sendWithoutRequest = true
            realm = null
        }
    }
}

// Multiple auth providers
val multiAuthClient = HttpClient {
    install(Auth) {
        basic {
            username = "api_user"
            password = "api_password"
            realm = "api"
        }
        
        bearer {
            loadTokens { bearerTokens }
            realm = "oauth"
        }
    }
}

Cookie Management

HttpCookies Plugin

Automatic cookie handling with customizable storage.

/**
 * HTTP cookies plugin for automatic cookie management
 */
object HttpCookies : HttpClientPlugin<HttpCookiesConfig, HttpCookies>

/**
 * Cookie configuration
 */
class HttpCookiesConfig {
    /** Cookie storage implementation */
    var storage: CookiesStorage = AcceptAllCookiesStorage()
}

/**
 * Cookie storage interface
 */
interface CookiesStorage {
    /** Get cookies for specific URL */
    suspend fun get(requestUrl: Url): List<Cookie>
    
    /** Add cookie received from response */
    suspend fun addCookie(requestUrl: Url, cookie: Cookie)
    
    /** Close storage and cleanup resources */
    fun close()
}

/**
 * Cookie storage that accepts all cookies
 */
class AcceptAllCookiesStorage : CookiesStorage

/**
 * Cookie representation
 */
data class Cookie(
    val name: String,
    val value: String,
    val encoding: CookieEncoding = CookieEncoding.URI_ENCODING,
    val maxAge: Int = 0,
    val expires: GMTDate? = null,
    val domain: String? = null,
    val path: String? = null,
    val secure: Boolean = false,
    val httpOnly: Boolean = false,
    val extensions: Map<String, String?> = emptyMap()
)

/** Get cookies for specific URL */
suspend fun HttpClient.cookies(url: String): List<Cookie>

Usage Examples:

import io.ktor.client.*
import io.ktor.client.plugins.cookies.*

// Basic cookie handling
val cookieClient = HttpClient {
    install(HttpCookies) {
        storage = AcceptAllCookiesStorage()
    }
}

// Custom cookie storage
class CustomCookieStorage : CookiesStorage {
    private val cookies = mutableMapOf<String, MutableList<Cookie>>()
    
    override suspend fun get(requestUrl: Url): List<Cookie> {
        return cookies[requestUrl.host] ?: emptyList()
    }
    
    override suspend fun addCookie(requestUrl: Url, cookie: Cookie) {
        cookies.getOrPut(requestUrl.host) { mutableListOf() }.add(cookie)
    }
    
    override fun close() {
        cookies.clear()
    }
}

val customCookieClient = HttpClient {
    install(HttpCookies) {
        storage = CustomCookieStorage()
    }
}

// Access cookies
val cookies = cookieClient.cookies("https://example.com")
cookies.forEach { cookie ->
    println("Cookie: ${cookie.name}=${cookie.value}")
}

Request/Response Processing

HttpRedirect Plugin

Automatic handling of HTTP redirects.

/**
 * Plugin for automatic HTTP redirect handling
 */
object HttpRedirect : HttpClientPlugin<Unit, Unit>

HttpCallValidator Plugin

Response validation and error handling.

/**
 * Plugin for HTTP call validation and error handling
 */
object HttpCallValidator : HttpClientPlugin<Unit, Unit>

HttpPlainText Plugin

Plain text content transformation.

/**
 * Plugin for plain text content transformation
 */
object HttpPlainText : HttpClientPlugin<Unit, Unit>

DefaultRequest Plugin

Sets default request parameters for all requests including base URL and common headers.

/**
 * Plugin for setting default request parameters including base URL and headers
 */
object DefaultRequest : HttpClientPlugin<DefaultRequestConfig, Unit>

/**
 * Default request configuration
 */
class DefaultRequestConfig {
    /** Configure default URL */
    fun url(block: URLBuilder.() -> Unit)
    
    /** Configure default headers */
    fun headers(block: HeadersBuilder.() -> Unit)
    
    /** Set default header value */
    fun header(key: String, value: String)
}

Usage Examples:

import io.ktor.client.*
import io.ktor.client.plugins.*

// Set default base URL and headers
val client = HttpClient {
    install(DefaultRequest) {
        url {
            protocol = URLProtocol.HTTPS
            host = "api.example.com"
            path("v1/")
        }
        
        headers {
            append("User-Agent", "MyApp/1.0")
            append("Accept", "application/json")
        }
    }
}

// All requests will use the default configuration
val response = client.get("users/123") // Requests https://api.example.com/v1/users/123

DataConversion Plugin

Data conversion utilities for request/response parameters.

/**
 * Plugin for data conversion utilities
 */
object DataConversion : HttpClientPlugin<DataConversion.Configuration, DataConversion>

Timeout Management

HttpTimeout Plugin

Configurable timeouts for HTTP requests.

/**
 * Plugin for configuring HTTP request timeouts
 */
object HttpTimeout : HttpClientPlugin<HttpTimeoutCapabilityConfiguration, Unit>

/**
 * Timeout configuration
 */
class HttpTimeoutCapabilityConfiguration {
    /** Request timeout in milliseconds */
    var requestTimeoutMillis: Long? = null
    
    /** Connection timeout in milliseconds */
    var connectTimeoutMillis: Long? = null
    
    /** Socket timeout in milliseconds */
    var socketTimeoutMillis: Long? = null
}

/**
 * Request timeout exception
 */
class HttpRequestTimeoutException(
    val url: String,
    val timeoutMillis: Long
) : IOException("Request timeout has expired [url=$url, timeout_ms=$timeoutMillis]")

Usage Examples:

import io.ktor.client.*
import io.ktor.client.plugins.timeout.*

// Global timeout configuration
val timeoutClient = HttpClient {
    install(HttpTimeout) {
        requestTimeoutMillis = 30000  // 30 seconds
        connectTimeoutMillis = 10000  // 10 seconds
        socketTimeoutMillis = 20000   // 20 seconds
    }
}

// Per-request timeout
val response = timeoutClient.get ("https://slow-api.example.com") {
    timeout {
        requestTimeoutMillis = 60000  // 1 minute for this request
    }
}

Caching

HttpCache Plugin

HTTP response caching with cache control support.

/**
 * Plugin for HTTP response caching
 */
object HttpCache : HttpClientPlugin<Unit, Unit>

WebSocket Support

WebSockets Plugin

WebSocket connection support for real-time communication.

/**
 * Plugin for WebSocket support
 */
object WebSockets : HttpClientPlugin<WebSocketConfig, Unit>

/**
 * WebSocket configuration
 */
class WebSocketConfig {
    /** Maximum frame size in bytes */
    var maxFrameSize: Long = Long.MAX_VALUE
    
    /** Masking for outgoing frames */
    var masking: Boolean = true
    
    /** Extensions for WebSocket protocol */
    val extensions: MutableList<WebSocketExtension<*>> = mutableListOf()
}

/**
 * WebSocket session interface
 */
interface ClientWebSocketSession : WebSocketSession {
    /** Send text frame */
    suspend fun send(data: String)
    
    /** Send binary frame */
    suspend fun send(data: ByteArray)
    
    /** Receive incoming frames */
    val incoming: ReceiveChannel<Frame>
    
    /** Outgoing frames channel */
    val outgoing: SendChannel<Frame>
    
    /** Close WebSocket connection */
    suspend fun close(reason: CloseReason = CloseReason(CloseReason.Codes.NORMAL, ""))
}

/** WebSocket connection function */
suspend fun HttpClient.webSocket(
    host: String = "localhost",
    port: Int = DEFAULT_PORT,
    path: String = "/",
    block: suspend ClientWebSocketSession.() -> Unit
)

suspend fun HttpClient.ws(
    urlString: String,
    block: suspend ClientWebSocketSession.() -> Unit
)

Usage Examples:

import io.ktor.client.*
import io.ktor.client.plugins.websocket.*
import io.ktor.websocket.*

// Install WebSocket plugin
val wsClient = HttpClient {
    install(WebSockets) {
        maxFrameSize = 1024 * 1024  // 1MB frames
        masking = true
    }
}

// WebSocket connection
wsClient.webSocket("ws://localhost:8080/websocket") {
    // Send message
    send("Hello WebSocket!")
    
    // Receive messages
    for (frame in incoming) {
        when (frame) {
            is Frame.Text -> {
                val message = frame.readText()
                println("Received: $message")
            }
            is Frame.Binary -> {
                val data = frame.readBytes()
                println("Received binary: ${data.size} bytes")
            }
            is Frame.Close -> {
                println("WebSocket closed: ${frame.readReason()}")
                break
            }
        }
    }
}

// WebSocket with URL string
wsClient.ws("wss://echo.websocket.org") {
    send("Echo test message")
    
    val response = incoming.receive()
    if (response is Frame.Text) {
        println("Echo response: ${response.readText()}")
    }
}

Server-Sent Events

SSE Plugin

Server-Sent Events support for streaming data.

/**
 * Plugin for Server-Sent Events (SSE) support
 */
object SSE : HttpClientPlugin<Unit, Unit>

/**
 * Server-Sent Event representation
 */
data class ServerSentEvent(
    val data: String? = null,
    val event: String? = null,
    val id: String? = null,
    val retry: Long? = null,
    val comments: String? = null
)

/** SSE connection function */
suspend fun HttpClient.sse(
    host: String = "localhost",
    port: Int = DEFAULT_PORT,
    path: String = "/",
    block: suspend SSESession.() -> Unit
)

/**
 * SSE session interface
 */
interface SSESession {
    /** Incoming server-sent events */
    val incoming: ReceiveChannel<ServerSentEvent>
}

Usage Examples:

import io.ktor.client.*
import io.ktor.client.plugins.sse.*

// Install SSE plugin
val sseClient = HttpClient {
    install(SSE)
}

// SSE connection
sseClient.sse("localhost", 8080, "/events") {
    for (event in incoming) {
        when (event.event) {
            "message" -> println("Message: ${event.data}")
            "update" -> println("Update: ${event.data}")
            "error" -> println("Error: ${event.data}")
            else -> println("Event: ${event.event}, Data: ${event.data}")
        }
    }
}

Logging

Logging Plugin

Comprehensive request/response logging with configurable levels.

/**
 * Plugin for HTTP request/response logging
 */
object Logging : HttpClientPlugin<LoggingConfig, Unit>

/**
 * Logging configuration
 */
class LoggingConfig {
    /** Logger implementation */
    var logger: Logger = Logger.DEFAULT
    
    /** Logging level */
    var level: LogLevel = LogLevel.HEADERS
    
    /** Log request body */
    var logRequestBody: Boolean = false
    
    /** Log response body */
    var logResponseBody: Boolean = false
    
    /** Sanitize sensitive headers */
    var sanitizeHeader: (String) -> String = { it }
}

/**
 * Logging levels
 */
enum class LogLevel {
    ALL, HEADERS, BODY, INFO, NONE
}

/**
 * Logger interface
 */
interface Logger {
    fun log(message: String)
    
    companion object {
        val DEFAULT: Logger = object : Logger {
            override fun log(message: String) {
                println(message)
            }
        }
        val SIMPLE: Logger = DEFAULT
        val EMPTY: Logger = object : Logger {
            override fun log(message: String) {}
        }
    }
}

Usage Examples:

import io.ktor.client.*
import io.ktor.client.plugins.logging.*

// Basic logging
val loggingClient = HttpClient {
    install(Logging) {
        logger = Logger.DEFAULT
        level = LogLevel.HEADERS
    }
}

// Detailed logging
val detailedClient = HttpClient {
    install(Logging) {
        logger = Logger.DEFAULT
        level = LogLevel.ALL
        logRequestBody = true
        logResponseBody = true
        
        sanitizeHeader { header ->
            when {
                header.lowercase().contains("authorization") -> "***"
                header.lowercase().contains("cookie") -> "***"
                else -> header
            }
        }
    }
}

// Custom logger
val customLogger = object : Logger {
    override fun log(message: String) {
        // Custom logging implementation
        writeToLogFile(message)
    }
}

val customLoggingClient = HttpClient {
    install(Logging) {
        logger = customLogger
        level = LogLevel.INFO
    }
}

Types

Plugin Configuration Types

data class PluginInstallationConfig<TConfig : Any>(
    val plugin: HttpClientPlugin<TConfig, *>,
    val config: TConfig
)

interface AuthProvider {
    val sendWithoutRequest: Boolean
    suspend fun addRequestHeaders(request: HttpRequestBuilder)
    suspend fun refreshToken(response: HttpResponse): Boolean
}

data class CloseReason(val code: Short, val message: String) {
    companion object Codes {
        const val NORMAL: Short = 1000
        const val GOING_AWAY: Short = 1001
        const val PROTOCOL_ERROR: Short = 1002
        const val UNSUPPORTED_DATA: Short = 1003
        const val NO_STATUS: Short = 1005
        const val ABNORMAL_CLOSURE: Short = 1006
        const val INVALID_DATA: Short = 1007
        const val POLICY_VIOLATION: Short = 1008
        const val TOO_BIG: Short = 1009
        const val MANDATORY_EXTENSION: Short = 1010
        const val INTERNAL_ERROR: Short = 1011
        const val SERVICE_RESTART: Short = 1012
        const val TRY_AGAIN_LATER: Short = 1013
        const val TLS_HANDSHAKE_FAILED: Short = 1015
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-io-ktor--ktor-client-core-macosarm64

docs

built-in-plugins.md

engine-configuration.md

form-data-content.md

http-client.md

index.md

plugin-system.md

request-building.md

response-handling.md

tile.json