Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bug causing headers to be omitted when connecting to websocket using K/JS (nodejs) (KTOR-1629) #2307

Merged
merged 11 commits into from
Jun 15, 2021

Conversation

DRSchlaubi
Copy link
Contributor

@DRSchlaubi DRSchlaubi commented Jan 16, 2021

Subsystem
Websocket client on Kotlin/JS (nodejs)

Motivation
Because the browser websocket client does not support custom headers on the WS handshake the Ktor JS engine just ignores them completely however
the used NodeJS package (ws) supports setting custom headers

Issue: KTOR-1629

Solution
Change the JsClientEngine.createWebsocketFunction() to also acknowledge the headers on nodejs

- private fun createWebSocket(urlString_capturingHack: String): WebSocket {
+ private fun createWebSocket(urlString_capturingHack: String, headers: Headers): WebSocket {
        return if (PlatformUtils.IS_NODE) {
            val ws_capturingHack = js("require('ws')")
+            val headers_capturingHack: dynamic = object {}
+           headers.forEach { name, values ->
+                val value = values.first()
+                headers_capturingHack[name] = value
+           }
-            js("new ws_capturingHack(urlString_capturingHack)")
+            js("new ws_capturingHack(urlString_capturingHack, { headers: headers_capturingHack })")
        } else {
            js("new WebSocket(urlString_capturingHack)")
        }
    }

@DRSchlaubi DRSchlaubi force-pushed the bugfix/ws-headers-js branch from 63035b0 to 6bdf821 Compare January 16, 2021 14:57
@Stexxe Stexxe requested a review from e5l January 18, 2021 16:51
Copy link
Member

@e5l e5l left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @DRSchlaubi, thanks for the PR.
Could you add a test that fails before and pass after the PR?

@DRSchlaubi
Copy link
Contributor Author

Hey @DRSchlaubi, thanks for the PR.
Could you add a test that fails before and pass after the PR?

I don't really know-how. I thought I just copy the echo test, but echo.websocket.org does not send back the headers
So I thought to check whether the headers get added to DefaultWebsocketSession.call.request but it does that either way

@e5l
Copy link
Member

e5l commented Jan 19, 2021

Sure, you can add the test here: https://github.com/ktorio/ktor/blob/master/ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/WebSocketTest.kt similar to other tests. And here is the test server: https://github.com/ktorio/ktor/blob/master/ktor-client/ktor-client-tests/jvm/src/io/ktor/client/tests/utils/tests/WebSockets.kt. It will start automatically on the test run.

For instance, you can set up a server handler to collect header fields from a request and send them back in a text frame(and verify them on the client-side for sure :) )

@DRSchlaubi
Copy link
Contributor Author

this would work for the ws tests but what about the wss tests since the test server can't use https

@e5l
Copy link
Member

e5l commented Jan 19, 2021

Could you tell me why do we need wss to test headers content?

@DRSchlaubi
Copy link
Contributor Author

It's just that we test the connection to ws and wss. I don't really think this matters though

@e5l
Copy link
Member

e5l commented Jan 19, 2021

Yep, let's just have a regular ws test

@DRSchlaubi
Copy link
Contributor Author

DRSchlaubi commented Jan 19, 2021

I can't actually read the code style check so don't know what to change

EDIT: I finally found the login as a guest button to teamcity and could read the linter checks, but there seem to be a lot in files i didn't even change

@ahardewig
Copy link

ahardewig commented Feb 12, 2021

Hey there, this issue seems to be affecting me too. A host exposes a WSS endpoint that needs a custom header to be sent in the request for validation. Despite being specified in the HttpHeaders, it's not propagated up to the actual request. Glad to see a fix is already being worked on! Is there anything I can do to help out?

@DRSchlaubi
Copy link
Contributor Author

Actually this should be done already not sure if the lot team wants me to fix anything

@DRSchlaubi DRSchlaubi requested a review from e5l February 12, 2021 18:34
@hfhbd
Copy link
Contributor

hfhbd commented Feb 17, 2021

@DRSchlaubi could you rebase your PR with the latest master, which refactored the JS engine?


Eg:

// JsClientEngine.kt
val properties: dynamic = object { }
headers.forEach { name, values ->
    val value = values.joinToString(",")
    properties.headers[name] = value
}
NodeWebsocket(urlString, properties)

@DRSchlaubi
Copy link
Contributor Author

Oh you now separated between nodeWebsocket and JS WebSocket, right? I*ll try to update the PR

# Conflicts:
#	ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/JsClientEngine.kt
#	ktor-client/ktor-client-tests/common/test/io/ktor/client/tests/WebSocketTest.kt
@Stexxe Stexxe requested review from cy6erGn0m and removed request for e5l February 17, 2021 13:08
@DRSchlaubi
Copy link
Contributor Author

I couldn't run the tests after merging in master. I let them run for about an hour and Intellij still displayed "instanceiating tests"

@hfhbd
Copy link
Contributor

hfhbd commented Feb 18, 2021

@DRSchlaubi Did you use ./gradlew allTests using the terminal or IntelliJ?
Bildschirmfoto 2021-02-18 um 10 02 31

@DRSchlaubi
Copy link
Contributor Author

I used Intellij. Will try cli later. Wouldn't be the first time that K/JS test don't work in Intellij

@DRSchlaubi
Copy link
Contributor Author

@DRSchlaubi Did you use ./gradlew allTests using the terminal or IntelliJ?
Bildschirmfoto 2021-02-18 um 10 02 31

That is not even one of my tests or related to code I changed

@hfhbd
Copy link
Contributor

hfhbd commented Feb 18, 2021

@DRSchlaubi Did you use ./gradlew allTests using the terminal or IntelliJ?
Bildschirmfoto 2021-02-18 um 10 02 31

That is not even one of my tests or related to code I changed

I know, the screenshot shows not your test. It is only an example.

@DRSchlaubi
Copy link
Contributor Author

Also Intellij doesn't like to import ktor properly

@DRSchlaubi
Copy link
Contributor Author

Yeah now i am stuck with this again

[TestServer] start
<========-----> 64% EXECUTING [15m 47s]
> IDLE
> IDLE
> IDLE
> IDLE
> IDLE
> :kotlinNpmInstall > [4/4] Building fresh packages...
> IDLE
> IDLE
> IDLE

@DRSchlaubi
Copy link
Contributor Author

Tests are stuck at downloading yarn deps

assertEquals(CUSTOM_HEADER_VALUE, header)
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Compile error, this bracket is false

assertEquals(listOf(CUSTOM_HEADER_VALUE, CUSTOM_HEADER_VALUE), header)
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Compile error, this bracket is false

@@ -7,7 +7,7 @@ package io.ktor.client.engine.js.node
import io.ktor.client.engine.js.compatibility.*
import org.w3c.dom.*
import org.w3c.fetch.*
import kotlin.js.*
import kotlin.js.Promise
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

code style, use star import

@cy6erGn0m
Copy link
Contributor

@DRSchlaubi could you please rebase the branch? Is it ready for review at the moment?

@DRSchlaubi
Copy link
Contributor Author

I can't import ktor into intellij due to the error above

# Conflicts:
#	ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/JsClientEngine.kt
#	ktor-client/ktor-client-core/js/src/io/ktor/client/engine/js/node/NodeDefinitions.kt
@DRSchlaubi
Copy link
Contributor Author

I rebased, but i couldn't run the tests as all tests give me an iOS error and core test complains about no module being specified

@e5l e5l merged commit b40e900 into ktorio:main Jun 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants