Decompression

This concern will analyze incoming requests for compressed content and will automatically decompress the body using a suitable decompression algorithm.

In contrast to automatic compression of responses, this concern is not enabled by default and needs to be activated on the host:

Kotlin
val app = Layout.create()

Host.create()
    .handler(app)
    .defaults(decompression = true)
    .run()

Custom Algorithms

The concern analyzes the Content-Encoding header of incoming requests and supports automatic decompression of gzip, br and zstd compressed request bodies.

If you would like to add support for an additional algorithm, you need to implement and supply a CompressionAlgorithm instance - the same interface used to compress responses, but only its decompress(InputStream) member is relevant here. The following example shows how to add deflate support to your server:

Kotlin
import org.genhttp.api.content.io.AlgorithmName
import org.genhttp.api.content.io.CompressionAlgorithm
import org.genhttp.api.content.io.CompressionLevel
import org.genhttp.api.infrastructure.Priority
import org.genhttp.api.protocol.ResponseContent

import org.genhttp.engine.internal.Host

import org.genhttp.modules.compression.DecompressedContent
import org.genhttp.modules.layouting.Layout
import org.genhttp.modules.practices.defaults

import java.io.InputStream
import java.util.zip.InflaterInputStream

class DeflateAlgorithm : CompressionAlgorithm {

    override val name = AlgorithmName("deflate")

    override val fileExtension = "zz"

    override val priority = Priority.Low

    override fun compress(content: ResponseContent, level: CompressionLevel): ResponseContent =
        throw UnsupportedOperationException("This algorithm is only used for decompression")

    override fun decompress(content: InputStream): InputStream = InflaterInputStream(content)

}

suspend fun main() {
    val decompression = DecompressedContent.default()
        .add(DeflateAlgorithm())

    val app = Layout.create()
        .add(decompression)

    Host.create()
        .handler(app)
        .defaults()
        .development()
        .run()
}

Once a matching algorithm is found for the request’s Content-Encoding, the concern calls request.wrapBody { ... } to transparently replace the request body with a DecompressedBody that decompresses on read - handlers downstream keep reading request.getBody() as usual and never see the compressed bytes. wrapBody on Request is the same extension point other body-rewriting concerns can build on; only one wrapper can be active per request.