Ktor HTTP Client Core for tvOS ARM64 - multiplatform asynchronous HTTP client library with coroutines support
—
The Ktor HTTP Client Core provides a comprehensive set of utility classes and extension functions for common HTTP client operations. These utilities include exception types, content handling utilities, coroutine integration helpers, client events, and platform-specific extensions that simplify HTTP client development.
Specialized exception types for handling various timeout scenarios in HTTP client operations.
class ConnectTimeoutException(
message: String,
cause: Throwable? = null
) : Exception(message, cause)
class SocketTimeoutException(
message: String,
cause: Throwable? = null
) : Exception(message, cause)
class HttpRequestTimeoutException(
request: HttpRequestData,
cause: Throwable? = null
) : Exception("Request timeout has expired", cause) {
val request: HttpRequestData = request
}class SaveBodyAbandonedReadException : Exception("Response body read operation was abandoned")
class NoTransformationFoundException(
from: TypeInfo,
to: TypeInfo
) : Exception("No transformation found from $from to $to")
class DoubleReceiveException : Exception("Response has already been received")class ClientEngineClosedException : Exception("Client engine is closed")
class UnsupportedContentTypeException(
contentType: ContentType
) : Exception("Unsupported content type: $contentType")Extension functions for reading response bodies in various formats with proper resource management.
// Read response as text
suspend fun HttpResponse.bodyAsText(charset: Charset = Charsets.UTF_8): String
// Read response as byte array
suspend fun HttpResponse.bodyAsBytes(): ByteArray
// Get response body as byte read channel
fun HttpResponse.bodyAsChannel(): ByteReadChannel
// Read response as typed object (requires serialization plugin)
suspend inline fun <reified T> HttpResponse.body(): T
suspend fun <T> HttpResponse.body(typeInfo: TypeInfo): T
// Save response to file
suspend fun HttpResponse.bodyAsChannel(): ByteReadChannel
suspend fun HttpResponse.readBytes(): ByteArray
suspend fun HttpResponse.readText(charset: Charset = Charsets.UTF_8): String// Content type utilities
fun HttpResponse.contentType(): ContentType?
fun HttpResponse.contentLength(): Long?
fun HttpResponse.charset(): Charset?
// Header utilities
fun HttpResponse.etag(): String?
fun HttpResponse.lastModified(): GMTDate?
fun HttpResponse.cacheControl(): List<HeaderValue>?
// Status utilities
fun HttpResponse.isSuccess(): Boolean = status.isSuccess()
fun HttpResponse.isInformational(): Boolean = status.value in 100..199
fun HttpResponse.isRedirection(): Boolean = status.value in 300..399
fun HttpResponse.isClientError(): Boolean = status.value in 400..499
fun HttpResponse.isServerError(): Boolean = status.value in 500..599Utilities for working with HTTP content types and content negotiation.
// Content type matching and parsing
fun ContentType.match(other: ContentType): Boolean
fun ContentType.matchesWildcard(pattern: ContentType): Boolean
fun ContentType.withCharset(charset: Charset): ContentType
fun ContentType.withParameter(name: String, value: String): ContentType
// Default content types for common scenarios
object ContentType {
object Application {
val Json = ContentType("application", "json")
val Xml = ContentType("application", "xml")
val FormUrlEncoded = ContentType("application", "x-www-form-urlencoded")
val OctetStream = ContentType("application", "octet-stream")
val Pdf = ContentType("application", "pdf")
val Zip = ContentType("application", "zip")
}
object Text {
val Plain = ContentType("text", "plain")
val Html = ContentType("text", "html")
val CSS = ContentType("text", "css")
val JavaScript = ContentType("text", "javascript")
val CSV = ContentType("text", "csv")
}
object Image {
val JPEG = ContentType("image", "jpeg")
val PNG = ContentType("image", "png")
val GIF = ContentType("image", "gif")
val SVG = ContentType("image", "svg+xml")
val Any = ContentType("image", "*")
}
object Video {
val MP4 = ContentType("video", "mp4")
val AVI = ContentType("video", "x-msvideo")
val QuickTime = ContentType("video", "quicktime")
}
object Audio {
val MP3 = ContentType("audio", "mpeg")
val WAV = ContentType("audio", "wav")
val OGG = ContentType("audio", "ogg")
}
object MultiPart {
val FormData = ContentType("multipart", "form-data")
val Mixed = ContentType("multipart", "mixed")
val Alternative = ContentType("multipart", "alternative")
}
}
// File extension to content type mapping
fun ContentType.Companion.defaultForFile(file: File): ContentType
fun ContentType.Companion.defaultForExtension(extension: String): ContentType// Content encoding support
enum class ContentEncoding(val value: String) {
GZIP("gzip"),
DEFLATE("deflate"),
BR("br"),
COMPRESS("compress"),
IDENTITY("identity")
}
// Content length calculation
fun OutgoingContent.contentLength(): Long?
fun OutgoingContent.isChunked(): BooleanSpecial content type for protocol upgrades like WebSockets.
class ClientUpgradeContent : OutgoingContent {
override val contentType: ContentType? = null
override val contentLength: Long? = null
override fun upgrade(
input: ByteReadChannel,
output: ByteWriteChannel,
engineContext: CoroutineContext,
userContext: CoroutineContext
): Job
}Event definitions for monitoring HTTP client lifecycle and operations.
// Request lifecycle events
object HttpRequestCreated : EventDefinition<HttpRequestBuilder>()
object HttpRequestIsReadyForSending : EventDefinition<HttpRequest>()
// Response lifecycle events
object HttpResponseReceived : EventDefinition<HttpResponseContainer>()
object HttpResponseCancelled : EventDefinition<HttpResponseContainer>()
// Connection events
object HttpConnectionCreated : EventDefinition<HttpConnection>()
object HttpConnectionClosed : EventDefinition<HttpConnection>()
// Event containers
data class HttpResponseContainer(
val response: HttpResponse
)
data class HttpConnection(
val host: String,
val port: Int,
val secure: Boolean
)// Event monitoring with Events interface
interface Events {
fun <T> subscribe(definition: EventDefinition<T>, handler: suspend (T) -> Unit): Closeable
suspend fun <T> raise(definition: EventDefinition<T>, value: T)
}
// Usage example
val client = HttpClient()
val subscription = client.monitor.subscribe(HttpResponseReceived) { container ->
println("Response received: ${container.response.status}")
}
// Don't forget to unsubscribe
subscription.close()Utilities for proper coroutine context handling in HTTP client operations.
// Coroutine context utilities
fun CoroutineContext.clientContext(): CoroutineContext
fun CoroutineContext.withClientDefaults(): CoroutineContext
// Supervisor job for request isolation
fun SupervisorJob.createChildJob(): Job
// Cancellation utilities
suspend fun <T> withCancellation(block: suspend CoroutineScope.() -> T): T
fun Job.cancelWithCause(cause: Throwable? = null)// Timeout configuration
data class HttpTimeoutConfig(
val requestTimeoutMillis: Long? = null,
val connectTimeoutMillis: Long? = null,
val socketTimeoutMillis: Long? = null
)
// Timeout application
suspend fun <T> withHttpTimeout(
config: HttpTimeoutConfig,
block: suspend CoroutineScope.() -> T
): T
// Per-request timeout
fun HttpRequestBuilder.timeout(block: HttpTimeoutConfig.() -> Unit)Utilities for building and manipulating HTTP headers with type safety.
// Header building utilities
fun headersOf(vararg pairs: Pair<String, String>): Headers
fun headersOf(vararg pairs: Pair<String, List<String>>): Headers
class HeadersBuilder {
fun append(name: String, value: String)
fun appendAll(headers: Headers)
fun remove(name: String)
fun clear()
fun build(): Headers
}
// Common header utilities
fun Headers.authorization(): String?
fun Headers.cacheControl(): List<HeaderValue>
fun Headers.contentType(): ContentType?
fun Headers.contentLength(): Long?
fun Headers.userAgent(): String?
// Header value parsing
data class HeaderValue(
val value: String,
val parameters: Map<String, String> = emptyMap()
) {
companion object {
fun parse(headerValue: String): HeaderValue
fun parseList(headerValue: String): List<HeaderValue>
}
}// Authentication header utilities
fun HeadersBuilder.bearerAuth(token: String) {
append(HttpHeaders.Authorization, "Bearer $token")
}
fun HeadersBuilder.basicAuth(username: String, password: String) {
val credentials = "$username:$password".encodeBase64()
append(HttpHeaders.Authorization, "Basic $credentials")
}
fun HeadersBuilder.apiKeyAuth(apiKey: String, headerName: String = "X-API-Key") {
append(headerName, apiKey)
}Extension functions for working with ByteReadChannel and ByteWriteChannel.
// ByteReadChannel utilities
suspend fun ByteReadChannel.readUTF8Line(limit: Int = Int.MAX_VALUE): String?
suspend fun ByteReadChannel.readBytes(): ByteArray
suspend fun ByteReadChannel.readBytes(count: Int): ByteArray
suspend fun ByteReadChannel.copyTo(output: ByteWriteChannel): Long
suspend fun ByteReadChannel.copyTo(output: OutputStream): Long
// ByteWriteChannel utilities
suspend fun ByteWriteChannel.writeStringUtf8(s: String)
suspend fun ByteWriteChannel.writeFully(src: ByteArray)
suspend fun ByteWriteChannel.writeFully(src: ByteArray, offset: Int, length: Int)
// Content reading utilities
suspend fun ByteReadChannel.readRemaining(limit: Long = Long.MAX_VALUE): ByteReadPacket
suspend fun ByteReadChannel.readText(charset: Charset = Charsets.UTF_8): String// Convert between different stream types
fun ByteReadChannel.toInputStream(): InputStream
fun InputStream.toByteReadChannel(): ByteReadChannel
fun ByteWriteChannel.toOutputStream(): OutputStream
fun OutputStream.toByteWriteChannel(): ByteWriteChannel
// Buffered operations
fun ByteReadChannel.buffered(bufferSize: Int = DEFAULT_BUFFER_SIZE): ByteReadChannel
fun ByteWriteChannel.buffered(bufferSize: Int = DEFAULT_BUFFER_SIZE): ByteWriteChannelUtilities for parsing and constructing HTTP cache control directives.
// Cache control directive parsing
data class CacheControl(
val maxAge: Int? = null,
val maxStale: Int? = null,
val minFresh: Int? = null,
val noCache: Boolean = false,
val noStore: Boolean = false,
val noTransform: Boolean = false,
val onlyIfCached: Boolean = false,
val mustRevalidate: Boolean = false,
val public: Boolean = false,
val private: Boolean = false,
val proxyRevalidate: Boolean = false,
val immutable: Boolean = false,
val staleWhileRevalidate: Int? = null,
val staleIfError: Int? = null
) {
companion object {
fun parse(headerValue: String): CacheControl
}
fun toHeaderValue(): String
}
// Cache control builder
fun cacheControl(block: CacheControlBuilder.() -> Unit): CacheControl
class CacheControlBuilder {
fun maxAge(seconds: Int)
fun noCache()
fun noStore()
fun mustRevalidate()
fun private()
fun public()
// ... other directives
}// URL construction utilities
fun URLBuilder.takeFrom(url: Url): URLBuilder
fun URLBuilder.takeFrom(url: String): URLBuilder
// URL parameter utilities
fun URLBuilder.parameter(key: String, value: Any?)
fun URLBuilder.parameters(parameters: Parameters)
fun URLBuilder.encodedParameters(parameters: String)
// Path utilities
fun URLBuilder.path(vararg components: String)
fun URLBuilder.appendEncodedPathSegments(segments: String)
fun URLBuilder.pathSegments(segments: List<String>)
// Fragment utilities
fun URLBuilder.fragment(fragment: String?)
fun URLBuilder.encodedFragment(fragment: String?)// JVM-specific HttpClient extensions
fun HttpClient.executeBlocking(request: HttpRequestBuilder): HttpResponse
// Service loader integration
fun HttpClientEngineFactory.Companion.fromServiceLoader(): List<HttpClientEngineFactory<*>>
// Java interop utilities
fun HttpResponse.toCompletableFuture(): CompletableFuture<HttpResponse>
fun HttpClient.async(): AsyncHttpClient// JavaScript Fetch API integration
external interface FetchOptions {
var method: String?
var headers: dynamic
var body: dynamic
var mode: String?
var credentials: String?
}
// Browser-specific utilities
fun HttpClient.withCredentials(include: Boolean = true): HttpClient
fun HttpRequestBuilder.cors(block: CorsConfig.() -> Unit)
class CorsConfig {
var mode: RequestMode = RequestMode.CORS
var credentials: RequestCredentials = RequestCredentials.SAME_ORIGIN
}// Native platform networking utilities
fun HttpClientEngineConfig.configureNativeSocket(block: NativeSocketConfig.() -> Unit)
class NativeSocketConfig {
var keepAlive: Boolean = true
var tcpNoDelay: Boolean = true
var socketTimeout: Duration? = null
}
// Platform-specific SSL configuration
fun HttpClientEngineConfig.configureTLS(block: TLSConfig.() -> Unit)
class TLSConfig {
var trustManager: X509TrustManager? = null
var keyManager: X509KeyManager? = null
var protocols: List<String> = listOf("TLSv1.2", "TLSv1.3")
}// Exception conversion utilities
fun Throwable.wrapIfNeeded(): Exception
fun Exception.unwrapCancellation(): Exception?
// HTTP-specific exception utilities
fun HttpStatusCode.toException(response: HttpResponse): Exception
fun createHttpException(status: HttpStatusCode, message: String): Exception
// Retry utilities
suspend fun <T> retryIO(
times: Int = 3,
initialDelay: Long = 100,
maxDelay: Long = 1000,
factor: Double = 2.0,
block: suspend () -> T
): T// Request validation
fun HttpRequestBuilder.validate()
fun validateUrl(url: String): Boolean
fun validateHeaders(headers: Headers): List<String>
// Response validation
fun HttpResponse.validateContentType(expected: ContentType): Boolean
fun HttpResponse.validateStatus(validStatuses: Set<HttpStatusCode>): BooleanInstall with Tessl CLI
npx tessl i tessl/maven-io-ktor--ktor-client-core-tvosarm64