Hristijan
11/09/2025, 12:48 PMHristijan
11/09/2025, 12:49 PMcurl -X OPTIONS <https://api.local.test/api/v1/posts/groups> -H "Origin: <https://local.test>" -H "Access-Control-Request-Method: POST" -H "Access-Control-Request-Headers: authorization,content-type" -k -v 2>&1
| grep -E "HTTP/|access-control|< "
* using HTTP/2
* [HTTP/2] [1] OPENED stream for <https://api.local.test/api/v1/posts/groups>
* [HTTP/2] [1] [:method: OPTIONS]
* [HTTP/2] [1] [:scheme: https]
* [HTTP/2] [1] [:authority: api.local.test]
* [HTTP/2] [1] [:path: /api/v1/posts/groups]
* [HTTP/2] [1] [user-agent: curl/8.7.1]
* [HTTP/2] [1] [accept: */*]
* [HTTP/2] [1] [origin: <https://local.test>]
* [HTTP/2] [1] [access-control-request-method: POST]
* [HTTP/2] [1] [access-control-request-headers: authorization,content-type]
> OPTIONS /api/v1/posts/groups HTTP/2
< HTTP/2 200
< access-control-allow-credentials: true
< access-control-allow-headers: Accept-Encoding, Access-Control-Allow-Credentials, Access-Control-Allow-Headers, Access-Control-Allow-Methods, Access-Control-Allow-Origin, Access-Control-Max-Age, Access-Control-Request-Headers, Access-Control-Request-Method, Authorization, Content-Disposition, Content-Encoding, Content-Type, Origin, Referer, User-Agent, X-Forwarded-Host, X-Http-Method-Override, X-Request-Hash, X-Request-ID, X-Request-Nonce, X-Request-Signature, X-Request-Timestamp, X-Requested-With, X-Total-Count
< access-control-allow-methods: DELETE, OPTIONS, PATCH, PUT
< access-control-allow-origin: <https://local.test>
< access-control-max-age: 3600
< alt-svc: h3=":443"; ma=2592000
< date: Sun, 09 Nov 2025 12:37:25 GMT
< permissions-policy: camera=(), microphone=(), geolocation=()
< referrer-policy: strict-origin-when-cross-origin
< referrer-policy: strict-origin-when-cross-origin
< server: Ktor/3.3.2
< vary: Origin
< via: 1.1 Caddy
< x-content-type-options: nosniff
< x-content-type-options: nosniff
< x-frame-options: DENY
< x-frame-options: DENY
< x-request-id: =66+i+7f=zydipj1qfmru=gd8kgn7a5+svs2h-/ljegk2zxa349y2exu-2k5f/gf
< x-request-id: =66+i+7f=zydipj1qfmru=gd8kgn7a5+svs2h-/ljegk2zxa349y2exu-2k5f/gf
< x-xss-protection: 1; mode=block
< content-length: 0
<
curl
fun Application.corsPlugin(
isDebug: Boolean = BackendComponent.isDebug
) {
install(CORS) {
allowNonSimpleContentTypes = true
allowSameOrigin = true
allowCredentials = true
maxAgeInSeconds = 3600L
allowXHttpMethodOverride()
allowHeader(HttpHeaders.AccessControlAllowOrigin)
allowHeader(HttpHeaders.AccessControlAllowMethods)
allowHeader(HttpHeaders.AccessControlAllowCredentials)
allowHeader(HttpHeaders.AccessControlAllowHeaders)
allowHeader(HttpHeaders.AccessControlRequestHeaders)
allowHeader(HttpHeaders.AccessControlRequestMethod)
allowHeader(HttpHeaders.AccessControlMaxAge)
allowHeader(HttpHeaders.Origin)
allowHeader(HttpHeaders.Referrer)
allowHeader(HttpHeaders.ContentType)
allowHeader(HttpHeaders.Authorization)
allowHeader(HttpHeaders.UserAgent)
allowHeader(HttpHeaders.Accept)
allowHeader(HttpHeaders.ContentDisposition)
allowHeader(HttpHeaders.AcceptEncoding)
allowHeader(HttpHeaders.AcceptLanguage)
allowHeader(HttpHeaders.ContentEncoding)
allowHeader(HttpHeaders.XRequestId)
allowHeader(HttpHeaders.XTotalCount)
allowHeader(HttpHeaders.XForwardedHost)
allowHeader("X-Request-Timestamp")
allowHeader("X-Request-Signature")
allowHeader("X-Request-Nonce")
allowHeader("X-Request-Hash")
allowHeader("X-Requested-With")
if (isDebug) {
allowHost("local.test", schemes = listOf("https", "http"))
allowHost("api.local.test", schemes = listOf("https", "http"))
allowHost("localhost:5173", schemes = listOf("https", "http"))
allowHost("localhost:8080", schemes = listOf("https", "http"))
allowHost("127.0.0.1:5173", schemes = listOf("https", "http"))
allowHost("127.0.0.0:5173", schemes = listOf("https", "http"))
} else {
allowHost(
host = BuildKonfig.serverUrl.substringAfter("://").substringBefore("/"),
schemes = listOf("https")
)
}
allowMethod(HttpMethod.Get)
allowMethod(HttpMethod.Post)
allowMethod(HttpMethod.Put)
allowMethod(HttpMethod.Delete)
allowMethod(HttpMethod.Patch)
allowMethod(HttpMethod.Head)
allowMethod(HttpMethod.Options)
}
}Hristijan
11/09/2025, 12:51 PM< access-control-allow-methods: DELETE, OPTIONS, PATCH, PUT
as you can see the methods aren’t here, only few of them are but it’s missing GET and POSTHristijan
11/09/2025, 1:04 PMHristijan
11/09/2025, 1:10 PMAleksei Tirman [JB]
11/10/2025, 8:12 AMHristijan
11/10/2025, 9:55 AM<logger name="io.ktor.server.plugins.cors.routing.CORS" level="TRACE"/>
like this or?Aleksei Tirman [JB]
11/10/2025, 10:23 AMio.ktor.server.plugins.cors.CORS .Hristijan
11/10/2025, 11:18 AM10-11-2025 11:17:04.767 [eventLoopGroupProxy-4-2] 54+d1dmc+z2gf5sqga567d=gtumjeq=u7d6-6knsnzh1stn6jq27rqlacl56u5bx TRACE io.ktor.server.plugins.cors.CORS - Return Forbidden for /api/v1/posts/groups: request has not allowed headers.
10-11-2025 11:17:06.798 [eventLoopGroupProxy-4-2] 1vzy-1lm9uefqyju=x1x689/i6m16/c8m9qje=w8uxwpma80--sun9zks45523nh TRACE io.ktor.server.plugins.cors.CORS - Respond preflight on OPTIONS for /api/v1/posts/groups
10-11-2025 11:17:06.798 [eventLoopGroupProxy-4-2] 1vzy-1lm9uefqyju=x1x689/i6m16/c8m9qje=w8uxwpma80--sun9zks45523nh TRACE io.ktor.server.plugins.cors.CORS - Return Forbidden for /api/v1/posts/groups: request has not allowed headers.
10-11-2025 11:17:10.833 [eventLoopGroupProxy-4-2] -3x3t/bx1-7hp0wqqa8jxw35clw1z90bm-gel27bk=+m9bjb9y=d6tum+=18gzxc TRACE io.ktor.server.plugins.cors.CORS - Respond preflight on OPTIONS for /api/v1/posts/groups
10-11-2025 11:17:10.833 [eventLoopGroupProxy-4-2] -3x3t/bx1-7hp0wqqa8jxw35clw1z90bm-gel27bk=+m9bjb9y=d6tum+=18gzxc TRACE io.ktor.server.plugins.cors.CORS - Return Forbidden for /api/v1/posts/groups: request has not allowed headers.Hristijan
11/10/2025, 11:19 AMAleksei Tirman [JB]
11/10/2025, 11:32 AMinternal fun corsCheckRequestHeaders method to see which request methods aren't expected?Hristijan
11/10/2025, 11:35 AMHristijan
11/10/2025, 11:38 AMcorsCheckRequestHeaders was actually the function i had to utilize to debug, thank you so muchAleksei Tirman [JB]
11/10/2025, 12:01 PM