diff --git a/ktor-server/ktor-server-plugins/ktor-server-double-receive/common/src/io/ktor/server/plugins/doublereceive/ByteArrayCache.kt b/ktor-server/ktor-server-plugins/ktor-server-double-receive/common/src/io/ktor/server/plugins/doublereceive/ByteArrayCache.kt index f93f92c70cc..8cbe4681ea5 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-double-receive/common/src/io/ktor/server/plugins/doublereceive/ByteArrayCache.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-double-receive/common/src/io/ktor/server/plugins/doublereceive/ByteArrayCache.kt @@ -53,7 +53,7 @@ internal class MemoryCache( override fun dispose() { GlobalScope.launch { reader.discard() - fullBody?.discard() } + fullBody?.discard() } } diff --git a/ktor-server/ktor-server-tests/jvm/test/io/ktor/server/http/ApplicationRequestContentTestJvm.kt b/ktor-server/ktor-server-tests/jvm/test/io/ktor/server/http/ApplicationRequestContentTestJvm.kt index a75f2b33dcd..82964debc91 100644 --- a/ktor-server/ktor-server-tests/jvm/test/io/ktor/server/http/ApplicationRequestContentTestJvm.kt +++ b/ktor-server/ktor-server-tests/jvm/test/io/ktor/server/http/ApplicationRequestContentTestJvm.kt @@ -5,10 +5,17 @@ package io.ktor.server.http import io.ktor.client.request.* +import io.ktor.http.HttpStatusCode import io.ktor.server.application.* import io.ktor.server.plugins.doublereceive.* +import io.ktor.server.plugins.statuspages.StatusPages import io.ktor.server.request.* +import io.ktor.server.response.* +import io.ktor.server.routing.* import io.ktor.server.testing.* +import kotlinx.coroutines.joinAll +import kotlinx.coroutines.launch +import kotlinx.coroutines.test.runTest import kotlin.test.* class ApplicationRequestContentTest { @@ -41,4 +48,35 @@ class ApplicationRequestContentTest { setBody("bodyContent") } } + + @Test + fun testDoubleReceiveRaceCondition() = runTest { + (1..100).map { + launch { + testApplication { + application { + install(DoubleReceive) {} + + install(StatusPages) { + status(HttpStatusCode.BadRequest) { call, status -> + call.respondText(text = "400: Bad Request", status = status) + } + } + routing { + post("/") { + val request = call.receiveText() + call.respond(HttpStatusCode.BadRequest, request) + } + } + } + + client.post("/") { + setBody("Hello World") + }.also { + assertEquals(HttpStatusCode.BadRequest, it.status) + } + } + } + }.joinAll() + } }