Ktor 3.0.0 Help

DoubleReceive

The DoubleReceive plugin provides the ability to receive a request body several times with no RequestAlreadyConsumedException exception. This might be useful if a plugin is already consumed a request body, so you cannot receive it inside a route handler. For example, you can use DoubleReceive to log a request body using the CallLogging plugin and then receive a body one more time inside the post route handler.

Add dependencies

To use DoubleReceive, you need to include the ktor-server-double-receive artifact in the build script:

implementation("io.ktor:ktor-server-double-receive:$ktor_version")
implementation "io.ktor:ktor-server-double-receive:$ktor_version"
<dependency> <groupId>io.ktor</groupId> <artifactId>ktor-server-double-receive-jvm</artifactId> <version>${ktor_version}</version> </dependency>

Install DoubleReceive

To install the DoubleReceive plugin to the application, pass it to the install function in the specified module. The code snippets below show how to install DoubleReceive...

  • ... inside the embeddedServer function call.

  • ... inside the explicitly defined module, which is an extension function of the Application class.

import io.ktor.server.application.* import io.ktor.server.plugins.doublereceive.* // ... fun main() { embeddedServer(Netty, port = 8080) { install(DoubleReceive) // ... }.start(wait = true) }
import io.ktor.server.application.* import io.ktor.server.plugins.doublereceive.* // ... fun Application.module() { install(DoubleReceive) // ... }

The DoubleReceive plugin can also be installed to specific routes. This might be useful if you need different DoubleReceive configurations for different application resources.

After installing DoubleReceive, you can receive a request body several times and every invocation returns the same instance. For example, you can enable logging of a request body using the CallLogging plugin...

install(CallLogging) { level = Level.TRACE format { call -> runBlocking { "Body: ${call.receiveText()}" } } }

... and then get a request body one more time inside a route handler.

post("/") { val receivedText = call.receiveText() call.respondText("Text '$receivedText' is received") }

You can find the full example here: double-receive.

Configure DoubleReceive

With the default configuration, DoubleReceive provides the ability to receive a request body as the following types:

  • ByteArray

  • String

  • Parameters

  • data classes used by the ContentNegotiation plugin

By default, DoubleReceive doesn't support:

Set the cacheRawRequest property to false, if you do not need to receive different types from the same request or receive a stream or channel:

install(DoubleReceive) { cacheRawRequest = false }
Last modified: 25 November 2022