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

configuration.mddocs/

Configuration

Comprehensive configuration options for the ContentEncoding plugin including operation modes, encoder settings, and quality value management.

ContentEncodingConfig 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
    
    /**
     * Installs the `gzip` encoder.
     * @param quality a priority value to use in the `Accept-Encoding` header.
     */
    fun gzip(quality: Float? = null): Unit
    
    /**
     * Installs the `deflate` encoder.
     * @param quality a priority value to use in the `Accept-Encoding` header.
     */
    fun deflate(quality: Float? = null): Unit
    
    /**
     * Installs the `identity` encoder.
     * @param quality a priority value to use in the `Accept-Encoding` header.
     */
    fun identity(quality: Float? = null): Unit
    
    /**
     * Installs a custom encoder.
     * @param encoder a custom encoder to use.
     * @param quality a priority value to use in the `Accept-Encoding` header.
     */
    fun customEncoder(encoder: ContentEncoder, quality: Float? = null): Unit
}

Installation and Configuration

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

Basic Configuration

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

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

Advanced Configuration with Modes

val client = HttpClient {
    install(ContentEncoding) {
        mode = ContentEncodingConfig.Mode.All
        gzip(0.9f)
        deflate(0.8f)
        identity(0.1f)
    }
}

Operation Modes

DecompressResponse (Default)

Only decompresses incoming response bodies. Does not compress outgoing requests.

install(ContentEncoding) {
    mode = ContentEncodingConfig.Mode.DecompressResponse
    gzip()
    deflate()
}

Behavior:

  • Sets Accept-Encoding header on outgoing requests
  • Automatically decompresses response bodies based on Content-Encoding header
  • Does not compress request bodies

Use Cases:

  • Client applications consuming compressed APIs
  • Bandwidth optimization for downloads
  • Standard web client behavior

CompressRequest

Only compresses outgoing request bodies. Does not decompress incoming responses.

install(ContentEncoding) {
    mode = ContentEncodingConfig.Mode.CompressRequest
    gzip()
    deflate()
}

Behavior:

  • Compresses request bodies when explicitly requested via compress() function
  • Does not set Accept-Encoding header
  • Does not decompress response bodies

Use Cases:

  • Upload-heavy applications
  • API clients sending large payloads
  • Bandwidth optimization for uploads only

All (Bidirectional)

Both compresses outgoing requests and decompresses incoming responses.

install(ContentEncoding) {
    mode = ContentEncodingConfig.Mode.All
    gzip()
    deflate()
}

Behavior:

  • Sets Accept-Encoding header on requests
  • Decompresses response bodies automatically
  • Compresses request bodies when requested
  • Full bidirectional compression support

Use Cases:

  • Full-featured API clients
  • Applications with heavy upload and download requirements
  • Maximum bandwidth optimization

Quality Values

Quality values (q-values) specify preference order in the Accept-Encoding header, ranging from 0.0 to 1.0.

Basic Quality Configuration

install(ContentEncoding) {
    gzip(0.9f)     // Highest preference
    deflate(0.8f)  // Medium preference  
    identity(0.1f) // Lowest preference (fallback)
}

Generated Accept-Encoding Header:

Accept-Encoding: gzip;q=0.9,deflate;q=0.8,identity;q=0.1

Quality Value Rules

install(ContentEncoding) {
    // Valid quality values (0.0 to 1.0)
    gzip(1.0f)     // Maximum preference
    deflate(0.5f)  // Medium preference
    identity(0.0f) // Minimum preference
    
    // No quality value = included without q-value
    gzip()         // Equivalent to highest preference
}

Validation:

  • Quality values must be between 0.0 and 1.0 (inclusive)
  • Invalid quality values throw IllegalArgumentException
  • Null quality values omit the q-parameter in headers

Dynamic Quality Configuration

val highBandwidth = true

install(ContentEncoding) {
    if (highBandwidth) {
        gzip(0.9f)
        deflate(0.8f)
    } else {
        identity(1.0f)  // Prefer no compression on low bandwidth
    }
}

Custom Encoder Registration

fun customEncoder(encoder: ContentEncoder, quality: Float? = null): Unit

Adding Custom Encoders

class BrotliEncoder : ContentEncoder {
    override val name: String = "br"
    
    override fun encode(
        source: ByteReadChannel,
        coroutineContext: CoroutineContext
    ): ByteReadChannel {
        // Brotli compression implementation
        TODO("Implement Brotli compression")
    }
    
    override fun decode(
        source: ByteReadChannel,
        coroutineContext: CoroutineContext
    ): ByteReadChannel {
        // Brotli decompression implementation
        TODO("Implement Brotli decompression")
    }
    
    override fun predictCompressedLength(contentLength: Long): Long? {
        return (contentLength * 0.7).toLong() // Estimate 30% compression
    }
}

// Register custom encoder
install(ContentEncoding) {
    customEncoder(BrotliEncoder(), 0.95f)
    gzip(0.9f)
    deflate(0.8f)
}

Encoder Management

install(ContentEncoding) {
    // Add encoders
    gzip(0.9f)
    deflate(0.8f)
    
    // Remove encoder (by re-adding with null quality)
    gzip(null)  // Removes gzip encoder
    
    // Re-add with different quality
    gzip(0.5f)  // Adds gzip back with lower priority
}

Configuration Validation

Quality Value Validation

install(ContentEncoding) {
    try {
        gzip(1.5f)  // Invalid: > 1.0
    } catch (e: IllegalArgumentException) {
        println("Invalid quality value: ${e.message}")
    }
    
    try {
        deflate(-0.1f)  // Invalid: < 0.0
    } catch (e: IllegalArgumentException) {
        println("Invalid quality value: ${e.message}")
    }
}

Encoder Validation

class InvalidEncoder : ContentEncoder {
    override val name: String = ""  // Invalid: empty name
    // ... rest of implementation
}

install(ContentEncoding) {
    try {
        customEncoder(InvalidEncoder())
    } catch (e: IllegalArgumentException) {
        println("Invalid encoder: ${e.message}")
    }
}

Configuration Examples

Minimal Configuration

val client = HttpClient {
    install(ContentEncoding)  // Uses defaults: DecompressResponse mode with gzip, deflate, identity
}

Compression-Only Client

val uploadClient = HttpClient {
    install(ContentEncoding) {
        mode = ContentEncodingConfig.Mode.CompressRequest
        gzip()
    }
}

High-Performance Configuration

val performanceClient = HttpClient {
    install(ContentEncoding) {
        mode = ContentEncodingConfig.Mode.All
        gzip(1.0f)      // Prefer gzip for best compression
        deflate(0.8f)   // Fallback to deflate
        identity(0.1f)  // Last resort: no compression
    }
}

Development/Debug Configuration

val debugClient = HttpClient {
    install(ContentEncoding) {
        mode = ContentEncodingConfig.Mode.DecompressResponse
        identity(1.0f)  // Prefer uncompressed for easier debugging
        gzip(0.5f)      // Allow compression if server insists
    }
}

Install with Tessl CLI

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

docs

configuration.md

encoders.md

index.md

request-compression.md

response-decompression.md

tile.json