https://kotlinlang.org logo
Join the conversationJoin Slack
Channels
100daysofcode
100daysofkotlin
100daysofkotlin-2021
advent-of-code
aem
ai
alexa
algeria
algolialibraries
amsterdam
android
android-architecture
android-databinding
android-studio
androidgithubprojects
androidthings
androidx
androidx-xprocessing
anime
anko
announcements
apollo-kotlin
appintro
arabic
argentina
arkenv
arksemdevteam
armenia
arrow
arrow-contributors
arrow-meta
ass
atlanta
atm17
atrium
austin
australia
austria
awesome-kotlin
ballast
bangladesh
barcelona
bayarea
bazel
beepiz-libraries
belgium
berlin
big-data
books
boston
brazil
brikk
budapest
build
build-tools
bulgaria
bydgoszcz
cambodia
canada
carrat
carrat-dev
carrat-feed
chicago
chile
china
chucker
cincinnati-user-group
cli
clikt
cloudfoundry
cn
cobalt
code-coverage
codeforces
codemash-precompiler
codereview
codingame
codingconventions
coimbatore
collaborations
colombia
colorado
communities
competitive-programming
competitivecoding
compiler
compose
compose-android
compose-desktop
compose-hiring
compose-ios
compose-mp
compose-ui-showcase
compose-wear
compose-web
connect-audit-events
corda
cork
coroutines
couchbase
coursera
croatia
cryptography
cscenter-course-2016
cucumber-bdd
cyprus
czech
dagger
data2viz
databinding
datascience
dckotlin
debugging
decompose
decouple
denmark
deprecated
detekt
detekt-hint
dev-core
dfw
docs-revamped
dokka
domain-driven-design
doodle
dsl
dublin
dutch
eap
eclipse
ecuador
edinburgh
education
effective-kotlin
effectivekotlin
emacs
embedded-kotlin
estatik
event21-community-content
events
exposed
failgood
fb-internal-demo
feed
firebase
flow
fluid-libraries
forkhandles
forum
fosdem
fp-in-kotlin
framework-elide
freenode
french
fritz2
fuchsia
functional
funktionale
gamedev
ge-kotlin
general-advice
georgia
geospatial
german-lang
getting-started
github-workflows-kt
glance
godot-kotlin
google-io
gradle
graphic
graphkool
graphql
graphql-kotlin
graviton-browser
greece
grpc
gsoc
gui
hackathons
hacktoberfest
hamburg
hamkrest
helios
helsinki
hexagon
hibernate
hikari-cp
hire-me
hiring
hongkong
hoplite
http4k
hungary
hyderabad
image-processing
india
indonesia
inkremental
intellij
intellij-plugins
intellij-tricks
internships
introduce-yourself
io
ios
iran
israel
istanbulcoders
italian
jackson-kotlin
jadx
japanese
jasync-sql
java-to-kotlin-refactoring
javadevelopers
javafx
javalin
javascript
jdbi
jhipster-kotlin
jobsworldwide
jpa
jshdq
juul-libraries
jvm-ir-backend-feedback
jxadapter
k2-early-adopters
kaal
kafka
kakao
kalasim
kapt
karachi
karg
karlsruhe
kash_shell
kaskade
kbuild
kdbc
kgen-doc-tools
kgraphql
kinta
klaxon
klock
kloudformation
kmdc
kmm-español
kmongo
knbt
knote
koalaql
koans
kobalt
kobweb
kodein
kodex
kohesive
koin
koin-dev
komapper
kondor-json
kong
kontent
kontributors
korau
korean
korge
korim
korio
korlibs
korte
kotest
kotest-contributors
kotless
kotlick
kotlin-asia
kotlin-beam
kotlin-by-example
kotlin-csv
kotlin-data-storage
kotlin-foundation
kotlin-fuel
kotlin-in-action
kotlin-inject
kotlin-latam
kotlin-logging
kotlin-multiplatform-contest
kotlin-mumbai
kotlin-native
kotlin-pakistan
kotlin-plugin
kotlin-pune
kotlin-roadmap
kotlin-samples
kotlin-sap
kotlin-serbia
kotlin-spark
kotlin-szeged
kotlin-website
kotlinacademy
kotlinbot
kotlinconf
kotlindl
kotlinforbeginners
kotlingforbeginners
kotlinlondon
kotlinmad
kotlinprogrammers
kotlinsu
kotlintest
kotlintest-devs
kotlintlv
kotlinultimatechallenge
kotlinx-datetime
kotlinx-files
kotlinx-html
kotrix
kotson
kovenant
kprompt
kraph
krawler
kroto-plus
ksp
ktcc
ktfmt
ktlint
ktor
ktp
kubed
kug-leads
kug-torino
kvision
kweb
lambdaworld_cadiz
lanark
language-evolution
language-proposals
latvia
leakcanary
leedskotlinusergroup
lets-have-fun
libgdx
libkgd
library-development
linkeddata
lithuania
london
losangeles
lottie
love
lychee
macedonia
machinelearningbawas
madrid
malaysia
mathematics
meetkotlin
memes
meta
metro-detroit
mexico
miami
micronaut
minnesota
minutest
mirror
mockk
moko
moldova
monsterpuzzle
montreal
moonbean
morocco
motionlayout
mpapt
mu
multiplatform
mumbai
munich
mvikotlin
mvrx
myndocs-oauth2-server
naming
navigation-architecture-component
nepal
new-mexico
new-zealand
newname
nigeria
nodejs
norway
npm-publish
nyc
oceania
ohio-kotlin-users
oldenburg
oolong
opensource
orbit-mvi
osgi
otpisani
package-search
pakistan
panamá
pattern-matching
pbandk
pdx
peru
philippines
phoenix
pinoy
pocketgitclient
polish
popkorn
portugal
practical-functional-programming
proguard
prozis-android-backup
pyhsikal
python
python-contributors
quasar
random
re
react
reaktive
realm
realworldkotlin
reductor
reduks
redux
redux-kotlin
refactoring-to-kotlin
reflect
refreshversions
reports
result
rethink
revolver
rhein-main
rocksdb
romania
room
rpi-pico
rsocket
russian
russian_feed
russian-kotlinasfirst
rx
rxjava
san-diego
science
scotland
scrcast
scrimage
script
scripting
seattle
serialization
server
sg-user-group
singapore
skia-wasm-interop-temp
skrape-it
slovak
snake
sofl-user-group
southafrica
spacemacs
spain
spanish
speaking
spek
spin
splitties
spotify-mobius
spring
spring-security
squarelibraries
stackoverflow
stacks
stayhungrystayfoolish
stdlib
stlouis
strife-discord-lib
strikt
students
stuttgart
sudan
swagger-gradle-codegen
swarm
sweden
swing
swiss-user-group
switzerland
talking-kotlin
tallinn
tampa
teamcity
tegal
tempe
tensorflow
terminal
test
testing
testtestest
texas
tgbotapi
thailand
tornadofx
touchlab-tools
training
tricity-kotlin-user-group
trójmiasto
truth
tunisia
turkey
turkiye
twitter-feed
uae
udacityindia
uk
ukrainian
uniflow
unkonf
uruguay
utah
uuid
vancouver
vankotlin
vertx
videos
vienna
vietnam
vim
vkug
vuejs
web-mpp
webassembly
webrtc
wimix_sentry
wwdc
zircon
Powered by Linen
ktor
  • d

    Daniel

    03/20/2023, 4:48 PM
    Is there a reason
    io.ktor.client.plugins.auth.providers.AuthTokenHolder
    is declared internal? I would like to utilize it in custom client
    AuthProvider
    a
    • 2
    • 1
  • t

    Tolga ÇAĞLAYAN

    03/20/2023, 5:43 PM
    fun isTokenBlacklistedAdmin(token: Payload): Boolean {
        val fetch =  transaction {
            AdminTokenTable.select {
                AdminTokenTable.token eq token.toString()
            }.firstOrNull()?.let {
                AdminTokenList(
                    token = it[AdminTokenTable.token],
                    blackList = it[AdminTokenTable.blackList]
                )
            }
        }
        return when (
           fetch?.blackList
        ) {
            1 -> {
    
                true
            }
    
            0 -> {
                println("0")
                false
            }
    
            else -> {
                true
            }
        }
    }
    I have such a code block. While performing JWT validation, I want to check from the database whether the token is blacklisted. But how can I read the token from Payload? token.toString() doesn't work. I couldn't find any detailed information.
    b
    • 2
    • 2
  • j

    Jilles van Gurp

    03/21/2023, 7:55 AM
    I'm using ktor client with the CIO engine for my kt-search client (a rest client for opensearch and elasticsearch). We recently switched to this with our main application (Spring Boot) and now running our multi threaded tests (we run with ten or so junit threads), I get a few weird exceptions that randomly fail small portion of the tests (see stacktrace below) After a bit of digging, I narrowed the problem down to the CIO engine and I suspect it's not completely threadsafe somehow. Switching to the Java engine makes the problem go away completely. I haven't tried any of the other engines. The previous version of the client would have used Elastic's RestHighLevel client, which in turn uses Apache http client if I recall correctly. So the main change here is that we are now using a different Rest client. Looking at the documentation, I wonder if there is any guidance on pros/cons of each engine. There seem to be a lot of them at least. For reference, this is the stack trace. It looks to me like different threads are ending up trying to open the same port somehow or messing with the same connection.
    java.net.BindException: Can't assign requested address
    	at java.base/sun.nio.ch.Net.connect0(Native Method)
    	at java.base/sun.nio.ch.Net.connect(Net.java:579)
    	at java.base/sun.nio.ch.Net.connect(Net.java:586)
    	at java.base/sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:853)
    	at io.ktor.network.sockets.SocketImpl.connect$ktor_network(SocketImpl.kt:44)
    	at io.ktor.network.sockets.ConnectUtilsJvmKt.connect(ConnectUtilsJvm.kt:21)
    	at io.ktor.network.sockets.TcpSocketBuilder.connect(TcpSocketBuilder.kt:37)
    	at io.ktor.client.engine.cio.ConnectionFactory.connect(ConnectionFactory.kt:29)
    	at io.ktor.client.engine.cio.Endpoint$connect$2$connect$1.invokeSuspend(Endpoint.kt:156)
    	at io.ktor.client.engine.cio.Endpoint$connect$2$connect$1.invoke(Endpoint.kt)
    	at io.ktor.client.engine.cio.Endpoint$connect$2$connect$1.invoke(Endpoint.kt)
    	at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturnIgnoreTimeout(Undispatched.kt:100)
    	at kotlinx.coroutines.TimeoutKt.setupTimeout(Timeout.kt:146)
    	at kotlinx.coroutines.TimeoutKt.withTimeoutOrNull(Timeout.kt:103)
    	at io.ktor.client.engine.cio.Endpoint.connect(Endpoint.kt:164)
    	at io.ktor.client.engine.cio.Endpoint.makeDedicatedRequest(Endpoint.kt:98)
    	at io.ktor.client.engine.cio.Endpoint.execute(Endpoint.kt:62)
    	at io.ktor.client.engine.cio.CIOEngine.execute(CIOEngine.kt:84)
    	at io.ktor.client.engine.HttpClientEngine$executeWithinCallContext$2.invokeSuspend(HttpClientEngine.kt:99)
    	at ???(Coroutine boundary.?(?)
    	at io.ktor.client.engine.HttpClientEngine$DefaultImpls.executeWithinCallContext(HttpClientEngine.kt:100)
    	at io.ktor.client.engine.HttpClientEngine$install$1.invokeSuspend(HttpClientEngine.kt:70)
    	at io.ktor.client.plugins.HttpSend$DefaultSender.execute(HttpSend.kt:138)
    	at io.ktor.client.plugins.HttpRedirect$Plugin$install$1.invokeSuspend(HttpRedirect.kt:61)
    	at io.ktor.client.plugins.HttpCallValidator$Companion$install$3.invokeSuspend(HttpCallValidator.kt:147)
    	at io.ktor.client.plugins.HttpSend$Plugin$install$1.invokeSuspend(HttpSend.kt:104)
    	at io.ktor.client.plugins.DefaultTransformKt$defaultTransformers$1.invokeSuspend(DefaultTransform.kt:53)
    	at io.ktor.client.plugins.HttpCallValidator$Companion$install$1.invokeSuspend(HttpCallValidator.kt:126)
    	at io.ktor.client.plugins.HttpRequestLifecycle$Plugin$install$1.invokeSuspend(HttpRequestLifecycle.kt:35)
    	at io.ktor.client.HttpClient.execute$ktor_client_core(HttpClient.kt:191)
    	at io.ktor.client.statement.HttpStatement.executeUnsafe(HttpStatement.kt:108)
    	at io.ktor.client.statement.HttpStatement.execute(HttpStatement.kt:47)
    	at com.tryformation.api.graphql.FormationClient.executeRaw(FormationClient.kt:1037)
    	at com.tryformation.api.graphql.FormationClient.execute(FormationClient.kt:919)
    	at com.tryformation.graphqlapi.TestTeamAndClientCreator.createTeam$suspendImpl(APITest.kt:211)
    	at com.tryformation.graphqlapi.analytics.ArmyTestFixture.create(ArmyTestFixture.kt:272)
    	at com.tryformation.graphqlapi.analytics.ArmyTestFixture$armyWorkspace$2$1.invokeSuspend(ArmyTestFixture.kt:269)
    	at com.tryformation.graphqlapi.TestbeansKt$runTest$1.invokeSuspend(testbeans.kt:257)
    Caused by: java.net.BindException: Can't assign requested address
    	at java.base/sun.nio.ch.Net.connect0(Native Method)
    	at java.base/sun.nio.ch.Net.connect(Net.java:579)
    	at java.base/sun.nio.ch.Net.connect(Net.java:586)
    	at java.base/sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:853)
    	at io.ktor.network.sockets.SocketImpl.connect$ktor_network(SocketImpl.kt:44)
    	at io.ktor.network.sockets.ConnectUtilsJvmKt.connect(ConnectUtilsJvm.kt:21)
    	at io.ktor.network.sockets.TcpSocketBuilder.connect(TcpSocketBuilder.kt:37)
    	at io.ktor.client.engine.cio.ConnectionFactory.connect(ConnectionFactory.kt:29)
    	at io.ktor.client.engine.cio.Endpoint$connect$2$connect$1.invokeSuspend(Endpoint.kt:156)
    	at io.ktor.client.engine.cio.Endpoint$connect$2$connect$1.invoke(Endpoint.kt)
    	at io.ktor.client.engine.cio.Endpoint$connect$2$connect$1.invoke(Endpoint.kt)
    	at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturnIgnoreTimeout(Undispatched.kt:100)
    	at kotlinx.coroutines.TimeoutKt.setupTimeout(Timeout.kt:146)
    	at kotlinx.coroutines.TimeoutKt.withTimeoutOrNull(Timeout.kt:103)
    	at io.ktor.client.engine.cio.Endpoint.connect(Endpoint.kt:164)
    	at io.ktor.client.engine.cio.Endpoint.makeDedicatedRequest(Endpoint.kt:98)
    	at io.ktor.client.engine.cio.Endpoint.execute(Endpoint.kt:62)
    	at io.ktor.client.engine.cio.CIOEngine.execute(CIOEngine.kt:84)
    	at io.ktor.client.engine.HttpClientEngine$executeWithinCallContext$2.invokeSuspend(HttpClientEngine.kt:99)
    	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
    	at kotlinx.coroutines.internal.LimitedDispatcher.run(LimitedDispatcher.kt:42)
    	at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:95)
    	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
    	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
    	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
    	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)
    a
    • 2
    • 6
  • s

    Satyam Agarwal

    03/21/2023, 12:40 PM
    Hei Ktor team. • We have seen this issue since 1.6.x, and have been bitten by it pretty much every other day in production. • This issue only occurs on apis where response header has transfer-enconding=chunked and without content length specified. • As soon as this happens, it poisons the whole ktor client and only way it comes back to normal is by restarting our servers. • We have seen this issue being raised in youtrack and marked as solved, but we still see it. we are using 2.2.2 as current ktor client version, with CIO as http client engine. • We have tried removing different http client plugins to eliminate points of failure, but it keeps happening. • We have also tried using Apache engine in the ktor HttpClient, it still happens. Problem is, we have never been successful in reproducing this issue locally. Can you look at the stack trace and give us some clue, eventually, identify if something needs to be done in the ktor client libraries ?
    java.io.EOFException: Invalid chunk: content block of size <8192| multiple of 8> ended unexpectedly
    	at io.ktor.http.cio.ChunkedTransferEncodingKt.decodeChunked(ChunkedTransferEncoding.kt:93)
    	at io.ktor.http.cio.ChunkedTransferEncodingKt$decodeChunked$3.invokeSuspend(ChunkedTransferEncoding.kt)
    	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
    	at kotlinx.coroutines.internal.LimitedDispatcher.run(LimitedDispatcher.kt:42)
    	at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:95)
    	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
    	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
    	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
    	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)
    	Suppressed: java.io.EOFException: Invalid chunk: content block of size 8192 ended unexpectedly
    		at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    		at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
    		at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    		at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
    		at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
    		at io.ktor.utils.io.ExceptionUtilsJvmKt$createConstructor$$inlined$safeCtor$3.invoke(ExceptionUtilsJvm.kt:103)
    		at io.ktor.utils.io.ExceptionUtilsJvmKt$createConstructor$$inlined$safeCtor$3.invoke(ExceptionUtilsJvm.kt:90)
    		at io.ktor.utils.io.ExceptionUtilsJvmKt.tryCopyException(ExceptionUtilsJvm.kt:66)
    		at io.ktor.utils.io.ByteBufferChannelKt.rethrowClosed(ByteBufferChannel.kt:2400)
    		at io.ktor.utils.io.ByteBufferChannelKt.access$rethrowClosed(ByteBufferChannel.kt:1)
    		at io.ktor.utils.io.ByteBufferChannel.setupStateForRead(ByteBufferChannel.kt:295)
    		at io.ktor.utils.io.ByteBufferChannel.copyDirect$ktor_io(ByteBufferChannel.kt:3377)
    		at io.ktor.utils.io.ByteBufferChannel$copyDirect$1.invokeSuspend(ByteBufferChannel.kt)
    		... 8 more
    	Caused by: [CIRCULAR REFERENCE: java.io.EOFException: Invalid chunk: content block of size 8192 ended unexpectedly]
    Another stacktrace I see on the same issue
    java.io.EOFException: Invalid chunk: content block of size 8192 ended unexpectedly
    	at io.ktor.http.cio.ChunkedTransferEncodingKt.decodeChunked(ChunkedTransferEncoding.kt:93)
    	at io.ktor.http.cio.ChunkedTransferEncodingKt$decodeChunked$3.invokeSuspend(ChunkedTransferEncoding.kt)
    	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
    	at kotlinx.coroutines.internal.LimitedDispatcher.run(LimitedDispatcher.kt:42)
    	at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:95)
    	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
    	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
    	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
    	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)
    s
    e
    • 3
    • 8
  • d

    Daniel

    03/21/2023, 1:08 PM
    Is there a ktor-client plugin that adds set of default headers such as Date (counterpart to server plugin DefaultHeaders)?
    c
    b
    • 3
    • 5
  • a

    Adam S

    03/22/2023, 8:39 AM
    I’m trying to set up a Ktor server. When I copy and paste the example for configuration in code, IntelliJ gives a warning that I don’t really understand.
    EmbeddedServer should reference top level Application module extension
    IntelliJ provides a quick-fix, but this prevents me from passing in any arguments to the configuration function. I want to configure the Ktor server using main args 🧵, but I can’t see how to do that without this warning. Any ideas?
    a
    • 2
    • 4
  • c

    Christian H.

    03/22/2023, 12:17 PM
    Hello. My kotlin multiplatform project is based on https://kotlinlang.org/docs/multiplatform-full-stack-app.html The application works in production mode, but throws the following JavaScript error on page load when I switch to development mode. It happens while trying to fetch data via REST via React's
    useEffectOnce {
        scope.launch {
            ...
        }
    }
    ReferenceError: Job is not defined at HttpClient (webpack-internal:///./kotlin/ktor-ktor-client-core-js-ir.js:599:24)
    Dependency versions:
    val kotlinVersion = "1.8.0"
    val kotlinxCoroutinesVersion = "1.6.4"
    val serializationVersion = "1.3.3"
    val ktorVersion = "2.0.3"
    val logbackVersion = "1.2.11"
    val kotlinWrappersVersion = "1.0.0-pre.354"
    using js(IR) compiler Thanks for your help in advance!
    e
    i
    • 3
    • 4
  • r

    ribesg

    03/22/2023, 1:15 PM
    There should be an error somewhere when calling
    <http://io.ktor.server.routing.post|io.ktor.server.routing.post>
    if the reified type used is marked with
    @Resource
    . Just had everything fail with 404 errors because I didn't manually import
    <http://io.ktor.server.resources.post|io.ktor.server.resources.post>
    and my IDE saw nothing wrong with that.
    a
    • 2
    • 3
  • a

    Austin Pederson

    03/22/2023, 6:27 PM
    Hey I'm using the
    RequestValidation
    plugin and I was curious if there was any way to either extend
    ValidationResult.Invalid
    to include a Throwable, or a way to pass a throwable to
    StatusPages
    using
    ValidationResult
    . Currently I am just throwing an error in the
    install(RequestValidation) {}
    block and always returning
    ValidationResult.Valid
    but that feels like a gross workaround
    • 1
    • 1
  • b

    brabo-hi

    03/22/2023, 7:39 PM
    Hello guys, what is the best way to send one time data between request? Like a flash session? After a post request, i want to redirect to another page and to display a success/error message, what is the best way in ktor to redirect to another page and to pass data to it.
    c
    • 2
    • 2
  • o

    Osman Saral

    03/22/2023, 8:46 PM
    Hi, Also posted to #serialization but it's also related to ktor: Can anyone help me with this?
  • k

    Kirill Zhukov

    03/22/2023, 11:01 PM
    What dispatcher does ktor client make requests on? Does it depend on engine? I’m seeing
    DarwinClientEngine
    declares
    Unconfined
    dispatcher, but not sure this it’s actually being used for requests?
    a
    • 2
    • 2
  • l

    Lev Teytelman

    03/23/2023, 4:21 AM
    I've got a strange issue that I can't seem to resolve. I have some data classes that look as follows:
    @Serializable
    data class Tag(
        val name: String,
        @Serializable(with = TagStringSerializer::class)
        val parent: Tag? = null,
        val subTags: MutableSet<@Serializable(with = TagStringSerializer::class) Tag> = ConcurrentSet(),
        val files: MutableSet<@Serializable(with = SavedFileStringSerializer::class) SavedFile> = ConcurrentSet()
    )
    
    @Serializable
    data class SavedFile(
        @Serializable(with = FileSerializer::class)
        val file: File,
        val tags: MutableSet<@Serializable(with = TagStringSerializer::class) Tag> = ConcurrentSet()
    )
    Of course, I don't want recursive Tags/SavedFiles in my serialization, as that would lead to infinite loops; I only serialize the names (all my custom serializers do is extract names). When I use
    ApplicationCall#respond(savedFile)
    , this works properly and sends
    {"file":"example","tags":["test"]}
    . However, when I do
    ApplicationCall#respond(savedFile.tags)
    , I receive an array of default-serialized tags instead of just the names, as if it's ignoring the annotation in the set:
    [{"name":"test","subTags":[],"files":["example"]}]
    . Even stranger, when I do just
    Json.encodeToString(savedFile.tags)
    , it works just fine and gives me a properly-encoded array
    ["test"]
    . Of course, I could just create a function like
    respondJson
    and wrap a call to
    respondText(Json.encodeToString(
    , but this seems hacky and non-ideal. I'm just very confused as to why the two functions are behaving differently and how I can fix the serialization done within
    ApplicationCall#respond
    .
    a
    • 2
    • 8
  • a

    Arjan van Wieringen

    03/23/2023, 10:26 AM
    What is the preferred way of validating query, path and headers? Wrapping everything in try/catches is not really DRY in my opinion. For instance, I'd have a UUID as a path parameter. I use UUID.fromString which might fail. I can wrap that with a try/catch and send a response. What is the idiomatic thing of repeatedly handling validation of these parameters?
    b
    j
    ł
    • 4
    • 5
  • b

    Benedikt Kaiser

    03/23/2023, 2:48 PM
    hi, i am currently testing kmm and i am building a small app with a simple api request generated with openapi generator. the get request was pretty straight forward now i am trying to implement a post request and i always get the error "java.lang.IllegalStateException: Fail to prepare request body for sending. " despite the correct declaration in the openapi file. does anybody know if i need to change the openapi file in order to work properly with ktor or if there is a special setting i need for the generation? Openapi file is in the thread
    c
    t
    • 3
    • 4
  • a

    Abe Sol

    03/23/2023, 9:14 PM
    Hi! I'm a total ktor noob. I helped someone connect OPENRNDR with websockets, but it works only on localhost: https://openrndr.discourse.group/t/using-openrndr-as-a-websocket-client/532/9?u=abe I don't see examples in the ktor website for connecting to WSS servers. Any pointers as to what I should change in that code to connect to an online service? Thanks!
    a
    • 2
    • 2
  • o

    Osman Saral

    03/24/2023, 4:54 PM
    Can anyone tell me what's wrong here? What am I doing wrong.
    @Test
        fun test() = testApplication {
            externalServices {
                hosts("<wss://test.com>") {
                    install(io.ktor.server.websocket.WebSockets) { }
    
                    routing {
                        webSocket("/test") {
                            send(Frame.Text("hello"))
                        }
                    }
                }
            }
    
            val client = createClient {
                install(WebSockets) {
                    contentConverter = KotlinxWebsocketSerializationConverter(
                        Json {
                            ignoreUnknownKeys = true
                        }
                    )
                }
            }
    
            runBlocking {
                client.wss(host = "<http://test.com|test.com>", path = "test") {
                    val string = Json.encodeToString(User("foo"))
    //                     val string = """{"name":"foo"}"""
                    println(string)
                    send(Frame.Text(string))
                }
            }
        }
    On the runBlocking block; both lines prints
    {"name":"foo"}
    but the`send` function throws
    java.util.concurrent.CancellationException: ArrayChannel was cancelled
    error for the first
    string
    , and it doesn't throw for the second.
    • 1
    • 1
  • p

    Piotr Krzemiński

    03/25/2023, 5:38 PM
    Regarding ktor-client, is there a tool for creating record/replay tests?
  • n

    Nishant Aanjaney Jalan

    03/26/2023, 12:17 AM
    Which free hosting website should I use to deploy my Ktor apps?
    b
    j
    j
    • 4
    • 7
  • d

    dephinera

    03/26/2023, 3:54 PM
    Is anyone here working on both mobile and backend professionally? Can anyone be defined as a full stack mobile dev or full stack kotlin dev? Did you have to convince your company for that career path or was it already established?
  • m

    Manuel Pérez Alcolea

    03/26/2023, 7:15 PM
    I'm using a library designed around coroutines that also uses ktor so I also have ktor goodies to use. I noticed ktor provides "channels" (
    ByteReadChannel
    ,
    ByteWriteChannel
    , what's the benefit of them? And what does the following mean?
    Operations on this channel cannot be invoked concurrently.
    when is a
    ByteWriteChannel
    more convenient than this?
    val url = URL(...)
    val targetDir = Path.of(...)
    
    withContext(<http://Dispatchers.IO|Dispatchers.IO>) {
      url.openStream().use { stream ->
        Files.copy(stream, targetDir)
      }
    }
    are they just meant to be used to read and write in chunks without blocking everything else in a thread, and to yield it to other coroutines?
    a
    • 2
    • 1
  • k

    Konstantin Zolotov

    03/26/2023, 7:36 PM
    Hello there! I'm trying to send a UDP message using ktor and getting this exception
    Exception in thread "main" java.net.BindException: Can't assign requested address
    	at java.base/sun.nio.ch.DatagramChannelImpl.send0(Native Method)
    	at java.base/sun.nio.ch.DatagramChannelImpl.sendFromNativeBuffer(DatagramChannelImpl.java:587)
    	at java.base/sun.nio.ch.DatagramChannelImpl.send(DatagramChannelImpl.java:549)
    	at java.base/sun.nio.ch.DatagramChannelImpl.send(DatagramChannelImpl.java:532)
    	at io.ktor.network.sockets.DatagramSendChannel$send$2$1.invokeSuspend(DatagramSendChannel.kt:80)
    	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
    	at kotlinx.coroutines.internal.LimitedDispatcher.run(LimitedDispatcher.kt:42)
    	at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:95)
    	at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
    	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
    	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
    	at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)
    This is my code:
    fun main() {
    	runBlocking {
    	    val selectorManager = SelectorManager(<http://Dispatchers.IO|Dispatchers.IO>)
            val socket = aSocket(selectorManager)
                .udp()
                .bind(InetSocketAddress("127.0.0.1", 4756))
    
            launch(<http://Dispatchers.IO|Dispatchers.IO>) {
                for (datagram in socket.incoming) {
                    val bytes = datagram.packet.readBytes()
                    val decoded = decode(bytes)
                    <http://logger.info|logger.info>("Received: $decoded from ${datagram.address}")
                }
            }
    
    
            val packet = BytePacketBuilder().apply { request }.build() // Here I create the packet to send, just raw bytes, nothing related to the problem
            val message = Datagram(
                packet = packet,
                address = InetSocketAddress("<http://router.bittorrent.com|router.bittorrent.com>", 6881)
            )
    
            socket.send(message)
    	}
    }
    No idea why this is happening, can any one help me please?
    a
    • 2
    • 3
  • d

    dany giguere

    03/26/2023, 7:38 PM
    Regarding the request validation : https://ktor.io/docs/request-validation.html#validation-exception, how does it work when I’ll have a ton of routes, can I apply the validation to specific routes or even to a single route ? According to the doc, I should do :
    install(RequestValidation) {
            validate<Post> { post ->
                if (post.title.length < 4)
                    ValidationResult.Invalid("A post ID should be greater than 0")
                else ValidationResult.Valid
            }
            ...
    But eventually there will be a lot of validations in there. It would be nice if I could apply to my post routes, only the validation regarding the posts…
    a
    • 2
    • 1
  • t

    Tung97 Hl

    03/27/2023, 4:36 AM
    Hi everyone. I’m using Ktor to make a localhost. I want it can be restarted so this is what I have done: • Create embeddedServer • Start it by function start(wait = true) • Stop it by function stop() • Create new instance of embeddedServer then start it again. I don’t know why whenever I restart the server it’s always throw exception: port already in use. Is the port does not released by Ktor or I was doing wrong?
    s
    • 2
    • 5
  • o

    Osman Saral

    03/27/2023, 3:39 PM
    Hi, I'm trying to write unit tests for a websocket client and I was looking at the tests on ktor. 🧵
    a
    • 2
    • 18
  • d

    Daniel

    03/27/2023, 3:43 PM
    Hi. Can I somehow create routes in Ktor that are only matched against certain client IP addresses or based on which server IP it came from? I would like to handle requests to localhost differently than others.
    a
    • 2
    • 2
  • d

    Daniel

    03/28/2023, 10:29 AM
    Is it possible to share type safe definition of the API defined using the Resources plugin between ktor client and server? (io.ktor:ktor-server-resources and io.ktor:ktor-client-resources)
    h
    • 2
    • 1
  • j

    joelkmuraguri21

    03/28/2023, 3:48 PM
    Is there any workaround in dealing with nullable values in json when working with ktor client(Android)?
  • f

    Fred Friis

    03/28/2023, 4:17 PM
    what's the difference between @resource and @location? they look so similar to me i've searched around but all i found was this dead forum link https://kotlinlang.slack.com/archives/C0X8H6XFA/p1677816564379959
    r
    • 2
    • 2
  • m

    Marcus Cvjeticanin

    03/28/2023, 5:41 PM
    With Ktor, do we have an easy way as with Spring to decorate methods to automatically generate OpenAPI definitions or some plugin in IntelliJ to generate it based on the available routes etc? Would be very handy. If there isn't any out there that is convenient, I'm thinking of creating one. But would be awesome if someone already built it!
    s
    r
    a
    • 4
    • 5
Powered by Linen
Title
m

Marcus Cvjeticanin

03/28/2023, 5:41 PM
With Ktor, do we have an easy way as with Spring to decorate methods to automatically generate OpenAPI definitions or some plugin in IntelliJ to generate it based on the available routes etc? Would be very handy. If there isn't any out there that is convenient, I'm thinking of creating one. But would be awesome if someone already built it!
s

simon.vergauwen

03/28/2023, 6:01 PM
I've been using Tegral OpenAPI, Example. You can easily also create top-level functions for common things, common OpenAPI functions. I'd love something like this but 1st party, and integrated with Resources plugin but it's been fulfilling all my needs so far so I haven't really bother looking deeply into it 😄
I like it because it works with the existing Ktor API, instead of building a new Route DSL as some other libraries have done.
r

Ryan Brink

03/28/2023, 6:29 PM
I maintain kompendium https://bkbn.gitbook.io/kompendium There is a jetbrains official generator, tho I believe it requires IntelliJ paid license
Kompendium has a resource plugin integration btw 😉
a

Arjan van Wieringen

03/28/2023, 8:27 PM
The IntelliJ plugin, although paid, is almost worthless at this point. No POST request support, no customization, defaults that don’t make a lot of sense. It feels more like an alpha.
View count: 2