or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

configuration.mdencoders.mdindex.mdrequest-compression.mdresponse-decompression.md
tile.json

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

HTTP client content encoding plugin for compression and decompression in Ktor applications.

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

To install, run

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

index.mddocs/

Ktor Client Content Encoding

HTTP content compression and decompression plugin for Ktor client applications supporting gzip, deflate, and identity encodings with automatic header management and transparent content processing.

Package Information

  • Name: ktor-client-encoding
  • Type: Ktor Client Plugin Library
  • Language: Kotlin (Multiplatform)
  • Maven Coordinates: io.ktor:ktor-client-encoding:3.2.0

Installation

dependencies {
    implementation("io.ktor:ktor-client-encoding:3.2.0")
}

Core Imports

import io.ktor.client.*
import io.ktor.client.plugins.compression.*
import io.ktor.client.request.*
import io.ktor.client.statement.*
import io.ktor.http.content.*
import io.ktor.util.*

Basic Usage

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

val client = HttpClient {
    install(ContentEncoding) {
        gzip()
        deflate()
        identity()
    }
}

// Automatic response decompression
val response = client.get("https://api.example.com/data")
val data = response.body<String>() // Automatically decompressed if needed

// Manual request compression
client.post("https://api.example.com/upload") {
    compress("gzip")
    setBody(largePayload)
}

Architecture

The content encoding system consists of four main components:

  1. ContentEncoding Plugin - Main plugin for HTTP client content processing
  2. ContentEncodingConfig - Configuration DSL for encoding options and modes
  3. ContentEncoder Interface - Abstraction for compression algorithms
  4. Operation Modes - Control whether to compress requests, decompress responses, or both

Plugin API

val ContentEncoding: ClientPlugin<ContentEncodingConfig>

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

Configuration API

class ContentEncodingConfig {
    enum class Mode(internal val request: Boolean, internal val response: Boolean) {
        CompressRequest(true, false),
        DecompressResponse(false, true),
        All(true, true)
    }
    
    var mode: Mode
    
    fun gzip(quality: Float? = null): Unit
    fun deflate(quality: Float? = null): Unit
    fun identity(quality: Float? = null): Unit
    fun customEncoder(encoder: ContentEncoder, quality: Float? = null): Unit
}

Core Capabilities

Plugin Installation and Configuration

Install and configure the ContentEncoding plugin with compression algorithms, quality values, and operation modes.

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

val client = HttpClient {
    install(ContentEncoding) {
        mode = ContentEncodingConfig.Mode.All
        gzip(0.9f)  // High priority
        deflate(0.8f)  // Medium priority
        identity(0.1f)  // Low priority fallback
    }
}

Key API:

  • ContentEncoding plugin object for installation
  • ContentEncodingConfig.Mode enum for operation control
  • Quality value specification for Accept-Encoding header preferences

See Configuration for detailed configuration options.

Compression Modes

Control whether the plugin compresses outgoing requests, decompresses incoming responses, or handles both operations.

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

Usage:

// Only decompress responses (default)
install(ContentEncoding) {
    mode = ContentEncodingConfig.Mode.DecompressResponse
}

// Only compress requests  
install(ContentEncoding) {
    mode = ContentEncodingConfig.Mode.CompressRequest
}

// Both compress requests and decompress responses
install(ContentEncoding) {
    mode = ContentEncodingConfig.Mode.All
}

See Configuration for mode-specific behaviors and use cases.

Built-in Encoders

Pre-built content encoders for standard HTTP compression algorithms with platform-specific implementations.

object GZipEncoder : ContentEncoder {
    override val name: String // "gzip"
}

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

object IdentityEncoder : ContentEncoder {
    override val name: String // "identity"
}

Usage:

install(ContentEncoding) {
    gzip()     // Enable gzip compression
    deflate()  // Enable deflate compression
    identity() // Enable identity (no-op) encoding
}

See Encoders for encoder details and custom encoder implementation.

Request Compression

Compress outgoing request bodies using specified encoding algorithms for individual requests or globally.

fun HttpRequestBuilder.compress(vararg contentEncoderName: String): Unit
fun HttpRequestBuilder.compress(contentEncoderNames: List<String>): Unit

Usage:

// Per-request compression
client.post("/api/upload") {
    compress("gzip", "deflate")
    setBody(largeData)
}

// List-based compression
client.put("/api/update") {
    compress(listOf("gzip"))
    setBody(payload)
}

Key Features:

  • Multiple encoder support per request
  • Automatic Content-Encoding header management
  • Pipeline integration with request processing

See Request Compression for advanced compression scenarios and configuration.

Response Decompression

Automatically decompress incoming response bodies based on Content-Encoding headers with transparent processing.

val HttpResponse.appliedDecoders: List<String>

Usage:

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

// Access decompressed content directly
val content = response.body<String>()

// Check which decoders were applied
val usedEncodings = response.appliedDecoders
println("Applied decoders: $usedEncodings") // e.g., ["gzip", "deflate"]

Key Features:

  • Automatic Content-Encoding header parsing
  • Multi-layer decompression support
  • Decoder chain tracking for debugging

See Response Decompression for decompression behavior and troubleshooting.

Content Compression Utilities

Utilities for compressing OutgoingContent using ContentEncoder implementations.

fun OutgoingContent.compressed(
    contentEncoder: ContentEncoder,
    coroutineContext: CoroutineContext = EmptyCoroutineContext
): OutgoingContent?

Usage:

import io.ktor.http.content.*
import io.ktor.util.*

// Manually compress content before sending
val originalContent: OutgoingContent = TextContent("Large text payload", ContentType.Text.Plain)
val compressedContent = originalContent.compressed(GZipEncoder)

Key Features:

  • Support for all OutgoingContent types (ReadChannelContent, WriteChannelContent, ByteArrayContent)
  • Automatic Content-Encoding header management
  • Content-Length prediction when possible
  • Preserves original content properties and headers

Content Encoder Interface

interface ContentEncoder : Encoder {
    /**
     * Encoder identifier to use in http headers.
     */
    val name: String
    
    /**
     * Provides an estimation for the compressed length based on the originalLength or return null if it's impossible.
     */
    fun predictCompressedLength(contentLength: Long): Long? = null
}

interface Encoder {
    /**
     * Launch coroutine to encode source bytes.
     */
    fun encode(
        source: ByteReadChannel,
        coroutineContext: CoroutineContext = EmptyCoroutineContext
    ): ByteReadChannel
    
    /**
     * Launch coroutine to encode source bytes.
     */
    fun encode(
        source: ByteWriteChannel,
        coroutineContext: CoroutineContext = EmptyCoroutineContext
    ): ByteWriteChannel
    
    /**
     * Launch coroutine to decode source bytes.
     */
    fun decode(
        source: ByteReadChannel,
        coroutineContext: CoroutineContext = EmptyCoroutineContext
    ): ByteReadChannel
}

Exception Handling

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

Error Scenarios:

try {
    val response = client.get("https://api.example.com/data")
    val content = response.body<String>()
} catch (e: UnsupportedContentEncodingException) {
    println("Unsupported encoding: ${e.message}")
    // Handle unsupported encoding
}

Internal Attributes

Internal attribute keys used by the plugin for tracking compression state.

val CompressionListAttribute: AttributeKey<List<String>>
val DecompressionListAttribute: AttributeKey<List<String>>

Usage:

// These attributes are used internally by the plugin
// CompressionListAttribute - tracks requested compression encoders
// DecompressionListAttribute - tracks applied decompression encoders

// Access applied decoders through the convenience property
val appliedDecoders = response.appliedDecoders // Uses DecompressionListAttribute internally

Complete Example

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.*

suspend fun main() {
    val client = HttpClient(CIO) {
        install(ContentEncoding) {
            mode = ContentEncodingConfig.Mode.All
            gzip(0.9f)
            deflate(0.8f)  
            identity()
        }
    }
    
    // Upload with compression
    val uploadResponse = client.post("https://api.example.com/upload") {
        compress("gzip")
        setBody("Large payload data...")
    }
    
    // Download with automatic decompression
    val downloadResponse = client.get("https://api.example.com/download")
    val content = downloadResponse.body<String>()
    
    // Check applied decoders
    val decoders = downloadResponse.appliedDecoders
    println("Response decompressed with: $decoders")
    
    client.close()
}