-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
KTOR-5199 Support WebSockets in Curl engine #3950
Conversation
ktor-client/ktor-client-curl/desktop/src/io/ktor/client/engine/curl/CurlClientEngine.kt
Outdated
Show resolved
Hide resolved
ktor-client/ktor-client-curl/desktop/src/io/ktor/client/engine/curl/CurlProcessor.kt
Outdated
Show resolved
Hide resolved
ktor-client/ktor-client-curl/desktop/src/io/ktor/client/engine/curl/internal/CurlAdapters.kt
Show resolved
Hide resolved
ktor-client/ktor-client-curl/desktop/src/io/ktor/client/engine/curl/internal/CurlAdapters.kt
Outdated
Show resolved
Hide resolved
ktor-client/ktor-client-curl/desktop/src/io/ktor/client/engine/curl/internal/CurlCallbacks.kt
Outdated
Show resolved
Hide resolved
...ent/ktor-client-curl/desktop/src/io/ktor/client/engine/curl/internal/CurlHttpResponseBody.kt
Outdated
Show resolved
Hide resolved
...ent/ktor-client-curl/desktop/src/io/ktor/client/engine/curl/internal/CurlWebSocketSession.kt
Show resolved
Hide resolved
ktor-client/ktor-client-curl/desktop/test/io/ktor/client/engine/curl/test/CurlWebSocketTests.kt
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @dtretyakov, thanks for the PR.
Please let me know when you have an update about the Curl binary version. I will run tests on CI
ktor-client/ktor-client-curl/desktop/src/io/ktor/client/engine/curl/CurlProcessor.kt
Outdated
Show resolved
Hide resolved
Trying to connect to After some further debugging the New issue |
This comment was marked as outdated.
This comment was marked as outdated.
@DRSchlaubi thanks a lot for verification and review.
Maybe you could share a test case when it could be reproduced?
Thanks, I added a list of WebSocket headers which are handled by cURL itself, so connection to this service should work. |
Sure fun main() = runBlocking {
val client = HttpClient {
install(WebSockets)
}
launch {
client.webSocket("wss://echo.websocket.org") {
while(!incoming.isClosedForReceive) {
// Keep connection alive
incoming.receive()
}
}
}
println("Wait for websocket to connect")
delay(10.seconds)
println("Requesting now!")
println(client.get("https://httpbin.org/200"))
} |
Fix in review comment |
ktor-client/ktor-client-curl/desktop/src/io/ktor/client/engine/curl/internal/CurlAdapters.kt
Outdated
Show resolved
Hide resolved
After more debugging it seems like the issue is this loop @OptIn(ExperimentalForeignApi::class)
internal fun perform() {
if (activeHandles.isEmpty()) return
memScoped {
val transfersRunning = alloc<IntVar>()
do {
println("Transfers running:${transfersRunning.value}")
synchronized(easyHandlesToUnpauseLock) {
var handle = easyHandlesToUnpause.removeFirstOrNull()
while (handle != null) {
curl_easy_pause(handle, CURLPAUSE_CONT)
handle = easyHandlesToUnpause.removeFirstOrNull()
}
}
println("Running curl_multi_perform")
curl_multi_perform(multiHandle, transfersRunning.ptr).verify()
println("Ran curl_multi_perform")
if (transfersRunning.value != 0) {
curl_multi_poll(multiHandle, null, 0.toUInt(), 10000, null).verify()
println("Ran curl_multi_poll")
}
if (transfersRunning.value < activeHandles.size) {
handleCompleted()
println("Ran complete")
}
println("Loop done")
} while (transfersRunning.value != 0)
}
} Because |
6e5aaf1
to
7b95cc5
Compare
@DRSchlaubi hopefully it was also addressed in the last commit, so you could try updating. |
At first glance your new test case should cover this, will test myself tmr 👍 |
That indeed fixed it |
Currently we're waiting when static linking of libcurl with it's dependencies will be in the repository for all targets and after that could merge the changes.
|
Any updates |
Hey @dtretyakov , thanks a lot for your work on this PR. I noticed some strange behaviour when receiving payloads greater than 1024 bytes and it seems to be a libcurl quirk, have raised a PR here: dtretyakov#1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey, @dtretyakov! Sorry for the long delay.
Could you rebase it on 3.1.0-eap
branch before merging?
I actually have a branch which is based on 3.0.0 for kord, I could push that as it might be easier to migrate to 3.1.0 as 2.x |
I pushed my work to curl/ws |
…EmbeddedServer.stop (ktorio#4481) * Add startSuspend/stopSuspend in EmbeddedServer * Make EngineTestBase work on js/wasmJs
0a9f16f
to
f996e9d
Compare
It was rebased, but now we need to have a libcurl with websockets enabled: |
It looks that Conan libcurl receipt does no support option to enable WebSockets: conan-io/conan-center-index#26221 |
7c22c8a
to
f555d1a
Compare
2c3b4d8
to
4a59355
Compare
@dtretyakov, could you please re-open this PR from |
Subsystem
Client, Curl engine
Motivation
Curl 7.86.0 added experimental support for WebSockets.
Solution
This PR brings support of experimental WebSockets in libcurl KTOR-5199.
To verify WebSockets availability we're using
curl_version_info
which returns list of enabled protocols.The
CurlResponseBodyData
become interface withCurlHttpResponseBody
/CurlWebSocketResponseBody
implementations.The
bodyStartedReceiving
is used to detect the end of headers section.We're using WebSocket with callbacks approach where:
curl_ws_send
used to send outgoing framesonBodyChunkReceived
withcurl_ws_meta
used to receive incoming framesEnvironment
Since WebSockets feature is experimental we need to enable them during curl compliation.
macOS
linux