From 514901847e1c1c66c6785f54e843bfdbbb5ce821 Mon Sep 17 00:00:00 2001 From: Hasan <137738156+crow3080@users.noreply.github.com> Date: Tue, 19 May 2026 02:19:25 +0300 Subject: [PATCH 1/3] Fix default methods filtering in CORS plugin (#5103) --- .../src/io/ktor/server/plugins/cors/CORS.kt | 5 +--- .../io/ktor/tests/server/plugins/CORSTest.kt | 29 +++++++++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/ktor-server/ktor-server-plugins/ktor-server-cors/common/src/io/ktor/server/plugins/cors/CORS.kt b/ktor-server/ktor-server-plugins/ktor-server-cors/common/src/io/ktor/server/plugins/cors/CORS.kt index 95ccd47d773..1d8d33359d3 100644 --- a/ktor-server/ktor-server-plugins/ktor-server-cors/common/src/io/ktor/server/plugins/cors/CORS.kt +++ b/ktor-server/ktor-server-plugins/ktor-server-cors/common/src/io/ktor/server/plugins/cors/CORS.kt @@ -54,10 +54,7 @@ internal fun PluginBuilder.buildPlugin() { val allowNonSimpleContentTypes: Boolean = pluginConfig.allowNonSimpleContentTypes val headersList = pluginConfig.headers.filterNot { it in CORSConfig.CorsSimpleRequestHeaders } .let { if (allowNonSimpleContentTypes) it + HttpHeaders.ContentType else it } - val methodsListHeaderValue = methods.filterNot { it in CORSConfig.CorsDefaultMethods } - .map { it.value } - .sorted() - .joinToString(", ") + val methodsListHeaderValue = methods.map { it.value }.sorted().joinToString(", ") val maxAgeHeaderValue = pluginConfig.maxAgeInSeconds.let { if (it > 0) it.toString() else null } val exposedHeaders = when { pluginConfig.exposedHeaders.isNotEmpty() -> pluginConfig.exposedHeaders.sorted().joinToString(", ") diff --git a/ktor-server/ktor-server-tests/common/test/io/ktor/tests/server/plugins/CORSTest.kt b/ktor-server/ktor-server-tests/common/test/io/ktor/tests/server/plugins/CORSTest.kt index 98b15d52a33..7a57082a326 100644 --- a/ktor-server/ktor-server-tests/common/test/io/ktor/tests/server/plugins/CORSTest.kt +++ b/ktor-server/ktor-server-tests/common/test/io/ktor/tests/server/plugins/CORSTest.kt @@ -1592,4 +1592,33 @@ class CORSTest { assertEquals(response.status, HttpStatusCode.Forbidden) } } + + @Test + fun testDefaultMethodsIncludedInAllowMethodsHeader() = testApplication { + install(CORS) { + allowMethod(HttpMethod.Post) + anyHost() + } + + routing { + post("/") { + call.respond("OK") + } + } + + val response = client.options("/") { + header(HttpHeaders.Origin, "https://example.com") + header(HttpHeaders.AccessControlRequestMethod, "POST") + } + + assertEquals(HttpStatusCode.OK, response.status) + val allowMethodsHeader = response.headers[HttpHeaders.AccessControlAllowMethods] + + assertNotNull(allowMethodsHeader, "Access-Control-Allow-Methods header should not be null") + assertTrue( + allowMethodsHeader.contains("POST"), + "Expected Access-Control-Allow-Methods to include POST, but got: $allowMethodsHeader" + ) + } + } From 3bc2cceb6e857bae567b963d63527ed77997625e Mon Sep 17 00:00:00 2001 From: Hasan <137738156+crow3080@users.noreply.github.com> Date: Tue, 19 May 2026 12:36:00 +0300 Subject: [PATCH 2/3] Format Kotlin code using linter --- .../common/test/io/ktor/tests/server/plugins/CORSTest.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/ktor-server/ktor-server-tests/common/test/io/ktor/tests/server/plugins/CORSTest.kt b/ktor-server/ktor-server-tests/common/test/io/ktor/tests/server/plugins/CORSTest.kt index 7a57082a326..a38b31e059b 100644 --- a/ktor-server/ktor-server-tests/common/test/io/ktor/tests/server/plugins/CORSTest.kt +++ b/ktor-server/ktor-server-tests/common/test/io/ktor/tests/server/plugins/CORSTest.kt @@ -1620,5 +1620,4 @@ class CORSTest { "Expected Access-Control-Allow-Methods to include POST, but got: $allowMethodsHeader" ) } - } From 067b5012b158e64e5c6686b967571faf3276c745 Mon Sep 17 00:00:00 2001 From: Hasan <137738156+crow3080@users.noreply.github.com> Date: Tue, 19 May 2026 17:19:37 +0300 Subject: [PATCH 3/3] Update CORS test to use assertEquals for full header verification --- .../common/test/io/ktor/tests/server/plugins/CORSTest.kt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/ktor-server/ktor-server-tests/common/test/io/ktor/tests/server/plugins/CORSTest.kt b/ktor-server/ktor-server-tests/common/test/io/ktor/tests/server/plugins/CORSTest.kt index a38b31e059b..3a24535f2fb 100644 --- a/ktor-server/ktor-server-tests/common/test/io/ktor/tests/server/plugins/CORSTest.kt +++ b/ktor-server/ktor-server-tests/common/test/io/ktor/tests/server/plugins/CORSTest.kt @@ -1615,9 +1615,6 @@ class CORSTest { val allowMethodsHeader = response.headers[HttpHeaders.AccessControlAllowMethods] assertNotNull(allowMethodsHeader, "Access-Control-Allow-Methods header should not be null") - assertTrue( - allowMethodsHeader.contains("POST"), - "Expected Access-Control-Allow-Methods to include POST, but got: $allowMethodsHeader" - ) + assertEquals("GET, HEAD, POST", allowMethodsHeader) } }