CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-ktor--ktor-server-compression-jvm

A Ktor server plugin that provides HTTP response compression and request decompression capabilities with support for gzip, deflate, and identity encoding algorithms.

Pending
Overview
Eval results
Files

conditions.mddocs/

Compression Conditions

Compression conditions determine when responses should be compressed based on content type, size, and custom predicates. Conditions can be applied globally to all encoders or specifically to individual encoders.

Condition Interface

interface ConditionsHolderBuilder {
    val conditions: MutableList<ApplicationCall.(OutgoingContent) -> Boolean>
}

Both CompressionConfig and CompressionEncoderBuilder implement this interface, allowing conditions at both global and per-encoder levels.

Built-in Condition Functions

Custom Predicates

fun ConditionsHolderBuilder.condition(predicate: ApplicationCall.(OutgoingContent) -> Boolean)

Add custom logic to determine when compression should be applied:

install(Compression) {
    // Global condition - applies to all encoders
    condition { call, content ->
        // Only compress responses for specific routes
        call.request.uri.startsWith("/api/")
    }
    
    gzip {
        // Encoder-specific condition
        condition { call, content ->
            // Don't compress responses for mobile clients
            call.request.headers["User-Agent"]?.contains("Mobile") != true
        }
    }
}

Minimum Size

fun ConditionsHolderBuilder.minimumSize(minSize: Long)

Only compress content that meets the minimum size threshold:

install(Compression) {
    // Global minimum size
    minimumSize(1024)  // Only compress responses >= 1KB
    
    gzip {
        // Override for gzip - compress smaller JSON responses
        minimumSize(200)
        matchContentType(ContentType.Application.Json)
    }
}

Content Type Matching

fun ConditionsHolderBuilder.matchContentType(vararg mimeTypes: ContentType)

Only compress responses with matching content types:

install(Compression) {
    matchContentType(
        ContentType.Text.Plain,
        ContentType.Text.Html,
        ContentType.Application.Json,
        ContentType.Application.JavaScript
    )
}

Content Type Exclusion

fun ConditionsHolderBuilder.excludeContentType(vararg mimeTypes: ContentType)

Exclude specific content types from compression:

install(Compression) {
    // Exclude media files and streams
    excludeContentType(
        ContentType.Video.Any,
        ContentType.Image.Any,
        ContentType.Audio.Any,
        ContentType.Text.EventStream,
        ContentType.MultiPart.Any
    )
}

Default Conditions

When no conditions are explicitly configured, the plugin applies sensible defaults:

// Default exclusions applied automatically
excludeContentType(
    ContentType.Video.Any,
    ContentType.Image.JPEG,
    ContentType.Image.PNG,
    ContentType.Audio.Any,
    ContentType.MultiPart.Any,
    ContentType.Text.EventStream
)
minimumSize(200)  // DEFAULT_MINIMAL_COMPRESSION_SIZE

Condition Evaluation

Conditions are evaluated in the following order:

  1. Global conditions (on CompressionConfig) - must all return true
  2. Encoder-specific conditions (on CompressionEncoderBuilder) - must all return true
  3. Built-in checks - content not already encoded, not SSE response, etc.

If any condition returns false, compression is skipped for that request.

Advanced Condition Examples

Dynamic Content Type Checking

install(Compression) {
    condition { call, content ->
        val contentType = content.contentType ?: 
            call.response.headers[HttpHeaders.ContentType]?.let { ContentType.parse(it) }
        
        contentType?.let { 
            it.match(ContentType.Application.Json) || 
            it.match(ContentType.Text.Any)
        } ?: false
    }
}

Request Header Based Conditions

install(Compression) {
    condition { call, _ ->
        // Only compress for API versions that support it
        val apiVersion = call.request.headers["API-Version"]
        apiVersion != null && apiVersion >= "2.0"
    }
    
    condition { call, _ ->
        // Skip compression for debug requests
        call.request.queryParameters["debug"] != "true"
    }
}

Response Size Based Logic

install(Compression) {
    condition { _, content ->
        when (val length = content.contentLength) {
            null -> true  // Unknown length - allow compression
            in 0..100 -> false  // Too small
            in 101..1000 -> content.contentType?.match(ContentType.Application.Json) == true
            else -> true  // Large content - always compress
        }
    }
}

Condition Interaction

When both global and encoder-specific conditions are present:

install(Compression) {
    // Global: must be JSON or text
    matchContentType(ContentType.Application.Json, ContentType.Text.Any)
    minimumSize(100)
    
    gzip {
        // Additional encoder requirement: minimum 500 bytes for gzip
        minimumSize(500)
        // Inherits global content type matching
    }
    
    deflate {
        // Uses global conditions only (JSON/text, >= 100 bytes)
    }
}

In this example:

  • deflate compresses JSON/text >= 100 bytes
  • gzip compresses JSON/text >= 500 bytes (more restrictive)

Install with Tessl CLI

npx tessl i tessl/maven-io-ktor--ktor-server-compression-jvm

docs

conditions.md

configuration.md

control.md

decompression.md

encoding.md

index.md

tile.json