-
-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Upgrade to Ktor 3 and add krossbow-websocket-ktor-legacy module for K…
…tor 2
- Loading branch information
1 parent
77f3a41
commit eb0eb26
Showing
27 changed files
with
551 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Krossbow Web Socket Ktor | ||
|
||
See the documentation for this module [on the project's website](https://joffrey-bion.github.io/krossbow/websocket/ktor/). |
8 changes: 8 additions & 0 deletions
8
krossbow-websocket-ktor-legacy/api/krossbow-websocket-ktor-legacy.api
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
public final class org/hildan/krossbow/websocket/ktor/KtorWebSocketClient : org/hildan/krossbow/websocket/WebSocketClient { | ||
public fun <init> ()V | ||
public fun <init> (Lio/ktor/client/HttpClient;)V | ||
public synthetic fun <init> (Lio/ktor/client/HttpClient;ILkotlin/jvm/internal/DefaultConstructorMarker;)V | ||
public fun connect (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; | ||
public fun getSupportsCustomHeaders ()Z | ||
} | ||
|
8 changes: 8 additions & 0 deletions
8
krossbow-websocket-ktor-legacy/api/krossbow-websocket-ktor.api
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
public final class org/hildan/krossbow/websocket/ktor/KtorWebSocketClient : org/hildan/krossbow/websocket/WebSocketClient { | ||
public fun <init> ()V | ||
public fun <init> (Lio/ktor/client/HttpClient;)V | ||
public synthetic fun <init> (Lio/ktor/client/HttpClient;ILkotlin/jvm/internal/DefaultConstructorMarker;)V | ||
public fun connect (Ljava/lang/String;Ljava/util/List;Ljava/util/Map;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; | ||
public fun getSupportsCustomHeaders ()Z | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
plugins { | ||
id("krossbow-multiplatform") | ||
id("krossbow-publish") | ||
alias(libs.plugins.kotlin.atomicfu) | ||
id("websocket-test-server") | ||
} | ||
|
||
description = "Multiplatform implementation of Krossbow's WebSocket API using Ktor's web sockets." | ||
|
||
kotlin { | ||
ktor2Targets() | ||
|
||
sourceSets { | ||
all { | ||
languageSettings.optIn("org.hildan.krossbow.io.InternalKrossbowIoApi") | ||
} | ||
val commonMain by getting { | ||
dependencies { | ||
api(projects.krossbowWebsocketCore) | ||
api(libs.ktorLegacy.client.websockets) | ||
implementation(projects.krossbowIo) | ||
} | ||
} | ||
val commonTest by getting { | ||
dependencies { | ||
implementation(kotlin("test")) | ||
implementation(projects.krossbowWebsocketTest) | ||
} | ||
} | ||
val cioSupportTest by creating { | ||
dependsOn(commonTest) | ||
dependencies { | ||
implementation(libs.ktorLegacy.client.cio) | ||
} | ||
} | ||
val jsMain by getting { | ||
dependencies { | ||
// workaround for https://youtrack.jetbrains.com/issue/KT-57235 | ||
implementation(libs.kotlinx.atomicfu.runtime) | ||
} | ||
} | ||
val jvmTest by getting { | ||
dependsOn(cioSupportTest) | ||
dependencies { | ||
implementation(libs.ktorLegacy.client.java) | ||
implementation(libs.ktorLegacy.client.okhttp) | ||
implementation(libs.slf4j.simple) | ||
} | ||
} | ||
val linuxX64Test by getting { | ||
dependsOn(cioSupportTest) | ||
} | ||
val mingwX64Test by getting { | ||
dependencies { | ||
implementation(libs.ktorLegacy.client.winhttp) | ||
} | ||
} | ||
val appleTest by getting { | ||
dependsOn(cioSupportTest) | ||
dependencies { | ||
implementation(libs.ktorLegacy.client.darwin) | ||
} | ||
} | ||
} | ||
} | ||
|
||
dokkaExternalDocLink( | ||
docsUrl = "https://api.ktor.io/ktor-client/", | ||
packageListUrl = "https://api.ktor.io/package-list", | ||
) |
30 changes: 30 additions & 0 deletions
30
...gacy/src/appleMain/kotlin/org/hildan/krossbow/websocket/ktor/HandshakeExceptionsDarwin.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package org.hildan.krossbow.websocket.ktor | ||
|
||
internal actual fun extractHandshakeFailureDetails(handshakeException: Exception): HandshakeFailureDetails = | ||
genericFailureDetails(handshakeException) | ||
|
||
/* | ||
We cannot extract any response code from the exception. | ||
The original error is almost the same for all response codes: | ||
io.ktor.client.engine.darwin.DarwinHttpRequestException: Exception in http request: Error Domain=NSURLErrorDomain Code=-1011 "There was a bad response from the server." | ||
NSError object attached to the DarwinHttpRequestException: | ||
{ | ||
code = -1011 | ||
description = Error Domain=NSURLErrorDomain Code=-1011 "There was a bad response from the server." UserInfo={NSErrorFailingURLStringKey=ws://localhost:49504/failHandshakeWithStatusCode/200, NSErrorFailingURLKey=ws://localhost:49504/failHandshakeWithStatusCode/200, _NSURLErrorWebSocketHandshakeFailureReasonKey=0, NSLocalizedDescription=There was a bad response from the server.} | ||
userInfo = { | ||
NSErrorFailingURLStringKey = ws://localhost:49347/failHandshakeWithStatusCode/200, | ||
NSErrorFailingURLKey = ws://localhost:49347/failHandshakeWithStatusCode/200, | ||
_NSURLErrorWebSocketHandshakeFailureReasonKey = 0, // sometimes different for tvOS | ||
_NSURLErrorRelatedURLSessionTaskErrorKey = ("LocalWebSocketTask <26F4D5BA-7104-4506-A521-DBC19B1CC2B0>.<1>"), | ||
_NSURLErrorFailingURLSessionTaskErrorKey = LocalWebSocketTask <26F4D5BA-7104-4506-A521-DBC19B1CC2B0>.<1>, | ||
NSLocalizedDescription=There was a bad response from the server. | ||
} | ||
underlyingErrors = [] | ||
localizedFailureReason = null | ||
localizedRecoveryOptions = null | ||
helpAnchor = null | ||
recoveryAttempter = null | ||
} | ||
*/ |
12 changes: 12 additions & 0 deletions
12
.../src/appleTest/kotlin/org/hildan/krossbow/websocket/ktor/KtorDarwinWebSocketClientTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package org.hildan.krossbow.websocket.ktor | ||
|
||
import io.ktor.client.engine.* | ||
import io.ktor.client.engine.darwin.* | ||
|
||
class KtorDarwinWebSocketClientTest : KtorClientTestSuite( | ||
supportsStatusCodes = false, | ||
// See https://youtrack.jetbrains.com/issue/KTOR-6970 | ||
shouldTestNegotiatedSubprotocol = false, | ||
) { | ||
override fun provideEngine(): HttpClientEngineFactory<*> = Darwin | ||
} |
21 changes: 21 additions & 0 deletions
21
...rc/cioSupportTest/kotlin/org/hildan/krossbow/websocket/ktor/KtorCioWebSocketClientTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package org.hildan.krossbow.websocket.ktor | ||
|
||
import io.ktor.client.* | ||
import io.ktor.client.engine.cio.* | ||
import io.ktor.client.plugins.websocket.* | ||
import org.hildan.krossbow.websocket.* | ||
import org.hildan.krossbow.websocket.test.* | ||
|
||
class KtorCioWebSocketClientTest : WebSocketClientTestSuite() { | ||
|
||
override fun provideClient(): WebSocketClient = KtorWebSocketClient( | ||
HttpClient(CIO) { | ||
// The CIO engine seems to follow 301 redirects by default, but our test server doesn't provide a Location | ||
// header with the URL to redirect to, so the client retries the same URL indefinitely. | ||
// To avoid a SendCountExceedException in status code tests, we disable redirect-following explicitly here. | ||
followRedirects = false | ||
|
||
install(WebSockets) | ||
}, | ||
) | ||
} |
24 changes: 24 additions & 0 deletions
24
...or-legacy/src/commonMain/kotlin/org/hildan/krossbow/websocket/ktor/HandshakeExceptions.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package org.hildan.krossbow.websocket.ktor | ||
|
||
internal data class HandshakeFailureDetails(val statusCode: Int?, val additionalInfo: String?) | ||
|
||
// This is the message for invalid status codes on CIO engine | ||
private val wrongStatusExceptionMessageRegex = Regex("""Handshake exception, expected status code 101 but was (\d{3})""") | ||
|
||
internal fun extractKtorHandshakeFailureDetails(handshakeException: Exception): HandshakeFailureDetails { | ||
val message = handshakeException.message | ||
?: return extractHandshakeFailureDetails(handshakeException) | ||
val match = wrongStatusExceptionMessageRegex.matchEntire(message) | ||
?: return extractHandshakeFailureDetails(handshakeException) | ||
return HandshakeFailureDetails( | ||
statusCode = match.groupValues[1].toInt(), | ||
additionalInfo = message, | ||
) | ||
} | ||
|
||
internal expect fun extractHandshakeFailureDetails(handshakeException: Exception): HandshakeFailureDetails | ||
|
||
internal fun genericFailureDetails(handshakeException: Exception) = HandshakeFailureDetails( | ||
statusCode = null, | ||
additionalInfo = handshakeException.toString(), // not only the message because the exception name is useful | ||
) |
Oops, something went wrong.