I have the following code:
import io.ktor.serialization.kotlinx.json.*
import io.ktor.server.application.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
import io.ktor.server.plugins.*
import io.ktor.server.plugins.contentnegotiation.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
fun main() {
embeddedServer(Netty, 8087) {
fun isSecureRequest(call: ApplicationCall): Boolean = call.request.origin.scheme == "https"
install(ContentNegotiation) {
json()
}
routing {
get("/cookies") {
val cookies = call.request.cookies.rawCookies
call.respond(mapOf("cookies" to cookies))
}
get("/cookies/set/{name}/{value}") {
val name = call.parameters["name"] ?: ""
val value = call.parameters["value"] ?: ""
val secure = isSecureRequest(call)
//call.response.cookies.append(Cookie(name, value, secure = secure))
call.response.cookies.append(name, value, secure = secure)
call.respondRedirect("/cookies")
}
get("/cookies/set") {
val secure = isSecureRequest(call)
call.request.queryParameters.entries().forEach { (key, values) ->
values.forEach { value ->
call.response.cookies.append(key, value, secure = secure)
}
}
call.respondRedirect("/cookies")
}
}
}.start(wait = true)
}
When following the url: http://localhost:8087/cookies/set?cookieSetFromQuery=hello
the cookie is set and I see it in the response.
However, if use the variant with the path parameters: http://localhost:8087/cookies/set/cookieFromPath/hello
i do not see the cookie in the response.
Even after going through the debugger I do not understand why is there a difference in behavior.
In both cases, the cookies are set with all.response.cookies.append(name, value, secure = secure)
and in both cases a redirect to the /cookies
path is made. Why is the variant using the path parameters not working?
The reason must be that the cookie set from the /cookies/set
path unlike /cookies/set/cookieFromPath/hello
, is within the scope of the /cookies
path and therefore browser sends the Cookie
header.
To solve the problem, you can specify the explicit path for the Set-Cookie
header:
call.response.cookies.append(name, value, path = "/cookies", secure = secure)
You can find more information about the Path
attribute on MDN.