From 99c22c1cf079bc9e577e3d145a219775f48d6030 Mon Sep 17 00:00:00 2001 From: "leonid.stashevsky" Date: Wed, 12 Feb 2025 08:51:08 +0100 Subject: [PATCH] KTOR-6671 Fix Resources: a / route isn't resolved when there is a sibling --- .../ktor/server/http/content/StaticContent.kt | 25 ++++++----- .../ktor/tests/resources/ResourcesTestJvm.kt | 41 ++++++++++++++++--- 2 files changed, 51 insertions(+), 15 deletions(-) diff --git a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/StaticContent.kt b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/StaticContent.kt index 75a542e6286..ae10ec62b14 100644 --- a/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/StaticContent.kt +++ b/ktor-server/ktor-server-core/jvm/src/io/ktor/server/http/content/StaticContent.kt @@ -607,16 +607,21 @@ private fun Route.staticContentRoute( remotePath: String, autoHead: Boolean, handler: suspend (ApplicationCall).() -> Unit -) = route(remotePath) { - route("{$pathParameterName...}") { - get { - call.handler() - } - if (autoHead) { - method(HttpMethod.Head) { - install(StaticContentAutoHead) - handle { - call.handler() +) = createChild(object : RouteSelector() { + override suspend fun evaluate(context: RoutingResolveContext, segmentIndex: Int): RouteSelectorEvaluation = + RouteSelectorEvaluation.Success(quality = RouteSelectorEvaluation.qualityTailcard) +}).apply { + route(remotePath) { + route("{$pathParameterName...}") { + get { + call.handler() + } + if (autoHead) { + method(HttpMethod.Head) { + install(StaticContentAutoHead) + handle { + call.handler() + } } } } diff --git a/ktor-server/ktor-server-plugins/ktor-server-resources/jvm/test/io/ktor/tests/resources/ResourcesTestJvm.kt b/ktor-server/ktor-server-plugins/ktor-server-resources/jvm/test/io/ktor/tests/resources/ResourcesTestJvm.kt index cf6951f4956..fd92b03462c 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-resources/jvm/test/io/ktor/tests/resources/ResourcesTestJvm.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-resources/jvm/test/io/ktor/tests/resources/ResourcesTestJvm.kt @@ -4,15 +4,25 @@ package io.ktor.tests.resources +import io.ktor.client.request.* +import io.ktor.client.statement.* +import io.ktor.http.* import io.ktor.resources.* +import io.ktor.server.http.content.* import io.ktor.server.resources.* import io.ktor.server.response.* import io.ktor.server.routing.* -import kotlinx.serialization.* -import kotlinx.serialization.descriptors.* -import kotlinx.serialization.encoding.* -import java.math.* -import kotlin.test.* +import kotlinx.serialization.KSerializer +import kotlinx.serialization.Serializable +import kotlinx.serialization.descriptors.PrimitiveKind +import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder +import java.math.BigDecimal +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertTrue class ResourcesTestJvm { @@ -57,4 +67,25 @@ class ResourcesTestJvm { "/?bd=123456789012345678901234567890&bi=123456789012345678901234567890" ) } + + @Resource("/") + class Home + + @Test + fun testHomeResourceWithStaticResource() = testResourcesApplication { + var executed = false + routing { + get { + executed = true + call.respondText("OK") + } + staticResources("/", "static") + } + + client.get("/").let { response -> + assertTrue(executed) + assertEquals(HttpStatusCode.OK, response.status) + assertEquals("OK", response.bodyAsText()) + } + } }