Laurent SOULET
06/07/2022, 3:58 PMpackage com.example
import io.ktor.client.*
import io.ktor.client.plugins.*
import io.ktor.client.request.*
import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import io.ktor.server.testing.*
import kotlin.test.Test
import kotlin.test.assertEquals
fun Application.configureRouting(httpClient: HttpClient) {
routing {
get("/test") {
httpClient.get("<http://fake.site.io/toto>") {
timeout {
requestTimeoutMillis = 100
}
}
call.respondText("Hello World!")
}
}
}
class ApplicationTest {
@Test
fun testRoot() = testApplication {
val myClient = createClient {
install(HttpTimeout)
}
application {
configureRouting(myClient)
}
externalServices {
hosts ("<http://fake.site.io>") {
routing {
get("/toto") {
call.respond(HttpStatusCode.OK)
}
}
}
}
myClient.get("/test").apply {
assertEquals(HttpStatusCode.OK, status)
}
}
}
When I execute this code, I receive this exception.
Engine doesn't support io.ktor.client.plugins.HttpTimeout$Plugin@3db8b930
java.lang.IllegalArgumentException: Engine doesn't support io.ktor.client.plugins.HttpTimeout$Plugin@3db8b930
at io.ktor.client.engine.HttpClientEngine$DefaultImpls.checkExtensions(HttpClientEngine.kt:101)
at io.ktor.client.engine.HttpClientEngine$DefaultImpls.access$checkExtensions(HttpClientEngine.kt:23)
at io.ktor.client.engine.HttpClientEngine$install$1.invokeSuspend(HttpClientEngine.kt:64)
at io.ktor.client.engine.HttpClientEngine$install$1.invoke(HttpClientEngine.kt)
at io.ktor.client.engine.HttpClientEngine$install$1.invoke(HttpClientEngine.kt)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:123)
at io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:81)
at io.ktor.util.pipeline.SuspendFunctionGun.execute$ktor_utils(SuspendFunctionGun.kt:101)
at io.ktor.util.pipeline.Pipeline.execute(Pipeline.kt:77)
at io.ktor.client.plugins.HttpSend$DefaultSender.execute(HttpSend.kt:135)
at io.ktor.client.plugins.HttpRedirect$Plugin$install$1.invokeSuspend(HttpRedirect.kt:61)
at io.ktor.client.plugins.HttpRedirect$Plugin$install$1.invoke(HttpRedirect.kt)
at io.ktor.client.plugins.HttpRedirect$Plugin$install$1.invoke(HttpRedirect.kt)
at io.ktor.client.plugins.HttpSend$InterceptedSender.execute(HttpSend.kt:113)
at io.ktor.client.plugins.HttpCallValidator$Companion$install$3.invokeSuspend(HttpCallValidator.kt:147)
at io.ktor.client.plugins.HttpCallValidator$Companion$install$3.invoke(HttpCallValidator.kt)
at io.ktor.client.plugins.HttpCallValidator$Companion$install$3.invoke(HttpCallValidator.kt)
at io.ktor.client.plugins.HttpSend$InterceptedSender.execute(HttpSend.kt:113)
at io.ktor.client.plugins.HttpSend$Plugin$install$1.invokeSuspend(HttpSend.kt:101)
at io.ktor.client.plugins.HttpSend$Plugin$install$1.invoke(HttpSend.kt)
at io.ktor.client.plugins.HttpSend$Plugin$install$1.invoke(HttpSend.kt)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:123)
at io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:81)
at io.ktor.util.pipeline.SuspendFunctionGun.proceedWith(SuspendFunctionGun.kt:91)
at io.ktor.client.plugins.HttpCallValidator$Companion$install$1.invokeSuspend(HttpCallValidator.kt:126)
at io.ktor.client.plugins.HttpCallValidator$Companion$install$1.invoke(HttpCallValidator.kt)
at io.ktor.client.plugins.HttpCallValidator$Companion$install$1.invoke(HttpCallValidator.kt)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:123)
at io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:81)
at io.ktor.client.plugins.HttpRequestLifecycle$Plugin$install$1.invokeSuspend(HttpRequestLifecycle.kt:35)
at io.ktor.client.plugins.HttpRequestLifecycle$Plugin$install$1.invoke(HttpRequestLifecycle.kt)
at io.ktor.client.plugins.HttpRequestLifecycle$Plugin$install$1.invoke(HttpRequestLifecycle.kt)
at io.ktor.util.pipeline.SuspendFunctionGun.loop(SuspendFunctionGun.kt:123)
at io.ktor.util.pipeline.SuspendFunctionGun.proceed(SuspendFunctionGun.kt:81)
at io.ktor.util.pipeline.SuspendFunctionGun.execute$ktor_utils(SuspendFunctionGun.kt:101)
at io.ktor.util.pipeline.Pipeline.execute(Pipeline.kt:77)
at io.ktor.client.HttpClient.execute$ktor_client_core(HttpClient.kt:187)
at io.ktor.client.statement.HttpStatement.executeUnsafe(HttpStatement.kt:107)
at io.ktor.client.statement.HttpStatement.execute(HttpStatement.kt:46)
at io.ktor.client.statement.HttpStatement.execute(HttpStatement.kt:61)
Tim Abil
06/07/2022, 5:56 PMSatyam Agarwal
06/08/2022, 10:45 AMBenjamin Deroche
06/08/2022, 4:13 PMimport io.ktor.client.engine.cio.CIO
now show an error. I have implementation("io.ktor:ktor-client-core:2.0.2")
in the commonMain dependencies of my KMM app, but after looking into the related jar downloaded by Gradle it appear to now be empty.Viktor Orlyk
06/09/2022, 10:19 AMAnders Sveen
06/09/2022, 10:41 AMAndi J
06/09/2022, 7:03 PMWhen handling a session, you can check a frame type, for example:
• Frame.Text is a text frame. For this frame type, you can read its content using Frame.Text.readText().
• Frame.Binary is a binary frame. For this type, you can read its content using Frame.Binary.readBytes().
• Frame.Close is a closing frame. You can call Frame.Close.readReason() to get a close reason for the current session.
Use the close function to send a close frame with the specified reason.
I need to remove my Connection instance from a set, when the channel is closed. But in this code the cleanup is never called, when the other side uses the close function:
try {
for (frame in session.incoming) {
when (frame) {
is Frame.Text -> {
// ...
}
is Frame.Close -> {
// Do cleanup
}
else -> {}
}
}
} catch (e: ClosedReceiveChannelException) {
println("onClose ${session.closeReason.await()}")
// Do cleanup
} catch (e: Throwable) {
println("onError ${session.closeReason.await()}")
// Do cleanup
}
So how do I react to closing frames correctly?Julius
06/10/2022, 1:09 AMfor (frame in incoming) {
val data = receiveDeserialized<Data>()
println(data)
}
This is pretty much what I'd like to do, but the for (frame in incoming)
part already consumes data from the queue, so I'm kinda confused how to properly iterate over itArnab
06/10/2022, 9:35 AMstartsWith
as a method that can be called on a string 😮 Any clues?Benjamin Deroche
06/10/2022, 3:07 PMHttpClient(OkHttp) {
engine {
config {
hostnameVerifier {
_, _ -> true
}
}
}
}
Mikhail
06/12/2022, 10:10 AMkevin.cianfarini
06/13/2022, 3:51 AMIsaacMart
06/13/2022, 6:12 AMStefan Oltmann
06/13/2022, 3:04 PMCoroutineWorker.withContext(Dispatchers.Default) {}
block. I use the IosClientEngine
for my HttpClient. In normal conditions it works fine, but in a CoroutineWorker context I get
kotlin.native.concurrent.FreezingException: freezing of InvokeOnCompletion@e9e588[job@149d2c8] has failed, first blocker is BlockingCoroutine{Completing}@e5b248
Because it's not production ready I can't really use the new memory model yet. So I need to solve it with the old one and CoroutineWorker.
How do I need to wrap my KTor HttpClient calls?MarkRS
06/13/2022, 4:48 PMval customer: Customer = client.get("<http://localhost:8080/customer/3>").body()
and I'm assuming this works for post too, but whatever I do I can't find a way to do this in commonMain of a KMM app. Does this need to be platform specific? I've got the content negotiation plugin loaded into the HttpClient, and imported into the class making the call, it just complains that "body" is an unresolved reference.
Can someone point me in the right direction, please.Tucker Barbour
06/14/2022, 12:46 PMBig Chungus
06/14/2022, 4:40 PMJúlio Santos
06/14/2022, 9:25 PMMikhail
06/15/2022, 2:07 PMjmfayard
06/15/2022, 5:19 PMbbaldino
06/15/2022, 10:00 PMval mockHttpClient = HttpClient(MockEngine) {
engine {
addHandler { request -> {
when (request.url.encodedPath) {
"url1" -> respond(someSuccessResponse)
}
}
}
}
val client = MyClient(mockHttpClient)
...
but I want to be able to test how MyClient
handles different kinds of responses when hitting url1
, but the mock engine config is fixed…is there a good way to be able to change it to simulate different responses?Helio
06/16/2022, 7:09 AMtestApplication
starts a separate Classloader where the mocked classes/objects are not visible. Is this expected?IsaacMart
06/16/2022, 2:17 PMdodalovic
06/17/2022, 6:11 AM2.0.1
to 2.0.2
my tests using externalServices
started failing. Any experience of that kind?Joakim Forslund
06/17/2022, 1:48 PMrrva
06/18/2022, 6:58 PMMatt Nelson
06/19/2022, 9:09 PMandroid.net.LocalSocket
-OR- java.net.UnixDomainSocketAddress
?dodalovic
06/20/2022, 7:22 AM2.0.1
that are very outdated, and that impose security risks. Will this be addressed?robin
06/20/2022, 10:51 AMoptions("{...}") { }
But that feels like a hack, and I'm not even sure it doesn't produce unwanted side effects, even though CORS seems to work correctly with it. Isn't there a way to let CORS handle preflight requests fully automatically without having to add this?Partho Paul
06/20/2022, 4:28 PMgetDynamoDbClient().getItem {
tableName = TABLE_NAME
key = request
}
When I’m running this piece of code, I’m getting VerifyError Exception. Can someone please help me figuring out what I’m doing wrong? Attached in thread is the full error message.
Kotlin version: 1.7.0, Ktor version: 2.0.2, aws version: 0.16.0
TIA