Is there an example on how to do websockets with a...
# ktor
j
Is there an example on how to do websockets with authentication on ktor 2.0.0 somewhere? 🙂 I'm using Firebase authentication in a custom plugin right now (it uses a Baerer Token), I'm currently assuming I have to do a http call first to establish session authentication?
To iterate, it seems it was possible before to add headers to the initial websocket http request according to this stackoverflow post. But my code doing the same isn't sending the headers (I'm looking at the request data with wireshark):
Copy code
client.webSocket(
                method = HttpMethod.Get,
                host = "localhost",
                port = 8080,
                path = "/ws",
                request = {
                    header(
                        "My-Test-Header",
                        "My-Test-Header-Value"
                    )
                }
            ) {
                send(Frame.Text("Hello from client"))
                while (true) {
                    val othersMessage = incoming.receive() as? Frame.Text
                    println(othersMessage?.readText())
                    val othersMessageText = othersMessage?.readText()
                    if (othersMessageText == "close") {
                        break
                    }
                    val myMessage = "Answer"
                    send(Frame.Text(myMessage))
                }
            }
It should at least allow the
Sec-WebSocket-Protocol
header since that's part of the spec it seems.
a
I’ve checked that the
My-Test-Header
header is actually sent while using the code from your example. I observe the same behavior with the
Sec-WebSocket-Protocol
header.
j
@Aleksei Tirman [JB] Thanks a lot! Could you send me the code you used? It must mean I'm doing something wrong at a different place 😔
a
I’ve used this part of your code:
Copy code
client.webSocket(
                method = HttpMethod.Get,
                host = "localhost",
                port = 8080,
                path = "/ws",
                request = {
                    header(
                        "My-Test-Header",
                        "My-Test-Header-Value"
                    )
                }
            )
j
@Aleksei Tirman [JB] Oh I meant the complete code example, just in case I messed up imports or dependencies, but I can also try to make a minimal reproducible example ✌️
@Aleksei Tirman [JB] I made a reproducible example: https://github.com/MinmoTech/ktor-websockets-test It's run with
./gradlew browserDevelopmentRun
and automatically creates the websocket connection on browser load
Wireshark capture of the request
Could the issue be that I'm making the request from the browser?
a
Yes. There is no way to send custom headers with an initial Websockets request in the browser environment. Also, there is this bug in Ktor that prevents from sending protocols via the
Sec-WebSocket-Protocol
header.
j
Thanks! Then I'll look into transmitting the info that I need through cookies ✌️
On that note, is it possible to send arbitrary cookies with the initial websockets request in the browser environment?
a
I don’t think you can send arbitrary cookies.
j
Copy code
fun createWebsocket() {
    GlobalScope.launch {
        val client = HttpClient(
            {
                install(WebSockets) {
                }
            }
        )
        println("Starting websocket")
        client.webSocket(
            method = HttpMethod.Get,
            host = "localhost",
            port = 8080,
            path = "/ws",
            request = {
                cookie(
                    name = "user_name",
                    value = "jetbrains",
                    expires =
                    GMTDate(
                        seconds = 0,
                        minutes = 0,
                        hours = 10,
                        dayOfMonth = 1,
                        month = Month.APRIL,
                        year = 2023
                    )
                )
            }
        ) {}
    }
}
Indeed this does not send the specified cookie. It does send all the cookies that are set in the browser session. Is that a requirement for sending cookies with websocket requests?
a
I guess It’s a browser security restriction.
j
A pity, since it now requires different implementations in my multiplatform project But thanks again for your help and sorry to take up so much of your time!