or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/maven-io-ktor--ktor-client-encoding-jvm

Ktor client plugin for content encoding support including compression and decompression

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
mavenpkg:maven/io.ktor/ktor-client-encoding-jvm@3.2.x

To install, run

npx @tessl/cli install tessl/maven-io-ktor--ktor-client-encoding-jvm@3.2.0

index.mddocs/

Ktor Client Content Encoding

Ktor Client Content Encoding is a plugin that provides content encoding and compression capabilities for Ktor HTTP client applications. It enables automatic compression of request bodies and decompression of response bodies using standard algorithms like gzip, deflate, and identity encoding.

Package Information

  • Package Name: ktor-client-encoding-jvm
  • Package Type: maven
  • Language: Kotlin
  • Group ID: io.ktor
  • Artifact ID: ktor-client-encoding-jvm
  • Installation:
    implementation("io.ktor:ktor-client-encoding-jvm:3.2.0")

Core Imports

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

Basic Usage

import io.ktor.client.*
import io.ktor.client.engine.cio.*
import io.ktor.client.plugins.compression.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.client.call.*

// Create client with content encoding support
val client = HttpClient(CIO) {
    install(ContentEncoding) {
        gzip()
        deflate()
        identity()
    }
}

// Client will automatically decompress responses and set Accept-Encoding header
val response: HttpResponse = client.get("https://api.example.com/data")
val responseText = response.bodyAsText()

// Check which decoders were applied to the response
val appliedDecoders = response.appliedDecoders
println("Applied decoders: $appliedDecoders")

// Compress request body
client.post("https://api.example.com/upload") {
    compress("gzip")
    setBody("large data payload")
}

Architecture

The ContentEncoding plugin is built around several key components:

  • Plugin Architecture: Integrates with Ktor's client plugin system using ClientPlugin<ContentEncodingConfig>
  • Request Pipeline: Hooks into the request pipeline to add Accept-Encoding headers and compress request bodies
  • Response Pipeline: Intercepts responses to automatically decompress content based on Content-Encoding headers
  • ContentEncoder Interface: Extensible system supporting built-in encoders (gzip, deflate, identity) and custom encoders
  • Mode System: Configurable behavior for compression/decompression (request-only, response-only, or both)

Capabilities

Plugin Installation

Install and configure the ContentEncoding plugin on an HttpClient.

val ContentEncoding: ClientPlugin<ContentEncodingConfig>

fun HttpClientConfig<*>.ContentEncoding(
    mode: ContentEncodingConfig.Mode = ContentEncodingConfig.Mode.DecompressResponse,
    block: ContentEncodingConfig.() -> Unit = {
        gzip()
        deflate()
        identity()
    }
)

Configuration

Configure encoding algorithms and compression modes.

@KtorDsl
class ContentEncodingConfig {
    var mode: Mode
    
    fun gzip(quality: Float? = null)
    fun deflate(quality: Float? = null)
    fun identity(quality: Float? = null)
    fun customEncoder(encoder: ContentEncoder, quality: Float? = null)
}

enum class ContentEncodingConfig.Mode(
    internal val request: Boolean, 
    internal val response: Boolean
) {
    CompressRequest(true, false),
    DecompressResponse(false, true),
    All(true, true)
}

Usage Examples:

import io.ktor.client.*
import io.ktor.client.engine.cio.*
import io.ktor.client.plugins.compression.*

// Configure with specific mode and encoders
val client = HttpClient(CIO) {
    ContentEncoding(mode = ContentEncodingConfig.Mode.All) {
        gzip(quality = 1.0f)
        deflate(quality = 0.8f)
        // Custom encoder support
        customEncoder(MyCustomEncoder, quality = 0.5f)
    }
}

// Request compression only  
val client = HttpClient(CIO) {
    ContentEncoding(mode = ContentEncodingConfig.Mode.CompressRequest) {
        gzip()
    }
}

Request Compression

Compress request bodies using specified encoding algorithms.

/**
 * Compresses request body using ContentEncoding plugin
 * @param contentEncoderName names of compression encoders to use
 */
fun HttpRequestBuilder.compress(vararg contentEncoderName: String)

/**
 * Compress request body using ContentEncoding plugin
 * @param contentEncoderNames names of compression encoders to use
 */
fun HttpRequestBuilder.compress(contentEncoderNames: List<String>)

Usage Examples:

import io.ktor.client.request.*

// Single encoder
client.post("/upload") {
    compress("gzip")
    setBody(largeData)
}

// Multiple encoders applied in sequence
client.post("/upload") {
    compress("deflate", "gzip")  // Applied as deflate first, then gzip
    setBody(largeData)
}

// Using list
client.post("/upload") {
    compress(listOf("gzip", "deflate"))
    setBody(largeData)
}

Response Decompression

Automatic decompression of response bodies and tracking of applied decoders.

/**
 * List of ContentEncoder names that were used to decode response body
 */
val HttpResponse.appliedDecoders: List<String>

Usage Examples:

import io.ktor.client.call.*

val response = client.get("https://compressed-api.example.com/data")

// Check what decompression was applied
val decoders = response.appliedDecoders
if (decoders.contains("gzip")) {
    println("Response was gzip compressed")
}

// Response body is automatically decompressed
val content = response.bodyAsText()

Content Encoders

Built-in and extensible content encoder system.

interface ContentEncoder : Encoder {
    val name: String
    fun predictCompressedLength(contentLength: Long): Long?
}

interface Encoder {
    fun encode(
        source: ByteReadChannel,
        coroutineContext: CoroutineContext = EmptyCoroutineContext
    ): ByteReadChannel
    
    fun encode(
        source: ByteWriteChannel,
        coroutineContext: CoroutineContext = EmptyCoroutineContext
    ): ByteWriteChannel
    
    fun decode(
        source: ByteReadChannel,
        coroutineContext: CoroutineContext = EmptyCoroutineContext
    ): ByteReadChannel
}

// Built-in encoders
object GZipEncoder : ContentEncoder {
    override val name: String // = "gzip"
}

object DeflateEncoder : ContentEncoder {
    override val name: String // = "deflate"
}

object IdentityEncoder : ContentEncoder {
    override val name: String // = "identity"
    override fun predictCompressedLength(contentLength: Long): Long
}

Usage Examples:

import io.ktor.util.*
import io.ktor.utils.io.*
import kotlin.coroutines.*

// Using built-in encoders by name
compress(GZipEncoder.name)
compress("gzip")  // Equivalent

// Custom encoder implementation
object BrotliEncoder : ContentEncoder {
    override val name = "br"
    
    override fun encode(source: ByteReadChannel, coroutineContext: CoroutineContext): ByteReadChannel {
        // Custom implementation
    }
    
    override fun decode(source: ByteReadChannel, coroutineContext: CoroutineContext): ByteReadChannel {
        // Custom implementation
    }
}

// Register custom encoder
val client = HttpClient(CIO) {
    install(ContentEncoding) {
        customEncoder(BrotliEncoder, quality = 0.9f)
    }
}

Error Handling

Exception handling for unsupported encoding algorithms.

class UnsupportedContentEncodingException(encoding: String) : 
    IllegalStateException("Content-Encoding: $encoding unsupported.")

Usage Examples:

try {
    client.post("/upload") {
        compress("unknown-algorithm")
        setBody(data)
    }
} catch (e: UnsupportedContentEncodingException) {
    println("Encoding not supported: ${e.message}")
}

Types

import io.ktor.util.*
import io.ktor.client.plugins.api.*
import io.ktor.http.content.*

// Request/Response pipeline attributes (internal use)
internal val CompressionListAttribute: AttributeKey<List<String>>
internal val DecompressionListAttribute: AttributeKey<List<String>>

// Hook interfaces for internal pipeline integration
internal object AfterRenderHook : ClientHook<suspend (HttpRequestBuilder, OutgoingContent) -> OutgoingContent?>
internal object ReceiveStateHook : ClientHook<suspend (HttpResponse) -> HttpResponse?>

Dependencies

  • Ktor Client Core: Core HTTP client functionality
  • Ktor Utils: ContentEncoder interface and built-in encoder implementations
  • Kotlinx Coroutines: Coroutine support for async operations
  • Ktor HTTP: HTTP headers and content handling utilities