CtrlK
BlogDocsLog inGet started
Tessl Logo

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

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

Pending
Overview
Eval results
Files

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()
}

Install with Tessl CLI

npx tessl i tessl/maven-io-ktor--ktor-client-encoding
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
mavenpkg:maven/io.ktor/ktor-client-encoding@3.2.x
Publish Source
CLI
Badge
tessl/maven-io-ktor--ktor-client-encoding badge