Rok Oblak
02/25/2025, 1:01 PMAccess to fetch at '<http://localhost:8080/sse/company/1>' from origin '<http://localhost:8081>' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
What am I missing?
Client:
client.serverSentEventsSession( url, deserialize = { typeInfo, jsonString -> ... })
Server:
install(CORS) {
anyHost()
allowMethod(HttpMethod.Options)
allowMethod(HttpMethod.Get)
allowMethod(HttpMethod.Post) // Allow POST requests
allowCredentials = true
allowNonSimpleContentTypes = true
allowHeader(HttpHeaders.Authorization)
allowHeader(HttpHeaders.ContentType)
allowHeader("X-Requested-With")
allowHeader(HttpHeaders.AccessControlAllowOrigin)
allowHeader(HEADER_APP_VERSION)
allowHeader(HEADER_SERVER_VERSION)
exposeHeader(HEADER_SERVER_VERSION)
}
install(SSE)
routing {
sse(url, serialize = { typeInfo, it ->...
}) {...}
Aleksei Tirman [JB]
02/25/2025, 1:11 PMOPTIONS
request to http://localhost:8080/sse/company/1 with the appropriate Origin
header?Rok Oblak
02/25/2025, 1:31 PMAleksei Tirman [JB]
02/25/2025, 2:30 PMconst evtSource = new EventSource("<http://localhost:8080/sse>");
evtSource.onmessage = (event) => {
console.log(event.data)
}
אליהו הדס
02/25/2025, 2:54 PMinstall(CORS) {
anyHost()
allowHeaders { true }
anyMethod()
}
אליהו הדס
02/25/2025, 2:55 PMRok Oblak
02/25/2025, 2:57 PMcurl --location --request OPTIONS '<http://localhost:8080/test_sse>' \
--header 'Accept: application/json' \
--header 'Origin: <http://localhost:8081>'
GET call works fine
but my wasm client makes an options call before trying to connect to the SSE endpointAleksei Tirman [JB]
02/25/2025, 3:02 PMAccess-Control-Request-Method
header is included in the preflight request:
--header 'Access-Control-Request-Method: GET'
Rok Oblak
02/25/2025, 5:44 PMallowHeader("cache-control")
in the CORS block.
(Chrome sends it in the preflight request)S.
03/06/2025, 9:33 AMinstall(CORS) {
allowMethod(HttpMethod.Get)
allowMethod(<http://HttpMethod.Post|HttpMethod.Post>)
allowMethod(HttpMethod.Options)
allowMethod(HttpMethod.Put)
allowMethod(HttpMethod.Delete)
allowMethod(HttpMethod.Patch)
allowHeader(HttpHeaders.Authorization)
allowHeader(HttpHeaders.Upgrade)
allowHeader(HttpHeaders.ContentType)
allowHeader(HttpHeaders.Origin)
allowHeader(HttpHeaders.AccessControlAllowOrigin)
allowHeader(HttpHeaders.AccessControlRequestMethod)
allowHeader(HttpHeaders.AccessControlRequestHeaders)
allowHeader("Access-Control-Request-Private-Network")
allowHeader(HttpHeaders.CacheControl)
allowNonSimpleContentTypes = true
allowCredentials = true
allowSameOrigin = true
allowXHttpMethodOverride()
anyHost()
anyMethod()
allowHeaders { true }
allowOrigins { true }
}
Aleksei Tirman [JB]
03/06/2025, 9:34 AMS.
03/06/2025, 9:35 AMTRACE io.ktor.server.plugins.cors.CORS - Return Forbidden for /bla: CORS method doesn't match HttpMethod(value=OPTIONS)
also not sure what this exactly means. it's a request sent with OPTIONS and it's also allowed in my cors setupS.
03/06/2025, 9:35 AMTRACE io.ktor.server.plugins.cors.CORS - Respond preflight on OPTIONS for /v1/annotations
TRACE io.ktor.server.plugins.cors.CORS - Return Forbidden for /v1/annotations: CORS method doesn't match HttpMethod(value=OPTIONS)
TRACE i.k.s.p.c.ContentNegotiation - Skipping response body transformation from HttpStatusCode to OutgoingContent for the OPTIONS /v1/annotations request because the HttpStatusCode type is ignored. See [ContentNegotiationConfig::ignoreType].
TRACE i.k.s.p.compression.Compression - Skip compression for /v1/annotations because no accept encoding provided.
INFO io.ktor.server.Application - URL: /v1/annotations, Status: 403 Forbidden, HTTP method: OPTIONS, User agent: null
TRACE i.k.s.p.compression.Compression - Skip decompression for /v1/annotations because no content encoding provided.
TRACE io.ktor.server.routing.Routing - Trace for [v1, annotations]
Aleksei Tirman [JB]
03/06/2025, 9:38 AMS.
03/06/2025, 9:40 AMAleksei Tirman [JB]
03/06/2025, 9:41 AMAccess-Control-Request-Method: GET
header replacing the GET method with the original request method.S.
03/06/2025, 9:44 AMe5l
03/06/2025, 3:59 PMS.
03/06/2025, 6:50 PMinstall(CORS) {
allowMethod(HttpMethod.Get)
allowMethod(<http://HttpMethod.Post|HttpMethod.Post>)
allowMethod(HttpMethod.Options)
allowMethod(HttpMethod.Put)
allowMethod(HttpMethod.Delete)
allowMethod(HttpMethod.Patch)
allowHeader(HttpHeaders.Authorization)
allowHeader(HttpHeaders.Upgrade)
allowHeader(HttpHeaders.ContentType)
allowHeader(HttpHeaders.Origin)
allowHeader(HttpHeaders.AccessControlAllowOrigin)
allowHeader(HttpHeaders.AccessControlRequestMethod)
allowHeader(HttpHeaders.AccessControlRequestHeaders)
allowHeader("Access-Control-Request-Private-Network")
allowHeader(HttpHeaders.CacheControl)
allowNonSimpleContentTypes = true
allowCredentials = true
allowSameOrigin = true
allowXHttpMethodOverride()
anyHost()
}