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
  • a

    avolkmann

    06/10/2018, 11:13 AM
    @Deactivated User do you have any ideas for an optional jwt auth? I thought I could use the
    skipWhen
    flag, which according to doc:
    If there is no filters, authentication is required. If any filter returns true, authentication is not required.
    Meaning that when it returns true, auth is optional. But it seems more like it completely skips the auth process.
    ✅ 1
    📝 1
    d
    • 2
    • 4
  • d

    dave08

    06/13/2018, 12:42 PM
    Is there some kind of plugin for message queues like Kafka or RabbitMQ for Ktor? Also, is there some kind of integration w/ Prometheus monitoring?
    d
    • 2
    • 44
  • c

    coder82

    06/13/2018, 9:16 PM
    I thought the intercept was activated only for that specific route or static route whatever if inserted inside it
    ✅ 1
    📝 1
    d
    • 2
    • 1
  • d

    dave08

    06/14/2018, 4:18 PM
    Someone on Vert.x Gitter channel suggested replacing Netty's EventGroups w/ Vert.x's to implement a Vert.x bridge with Ktor, see: https://github.com/ktorio/ktor/blob/d1e3a495cfe26c32aa5af4b110f6af9ddbd329e4/ktor-server/ktor-server-netty/src/io/ktor/server/netty/NettyApplicationEngine.kt#L51 https://github.com/eclipse/vert.x/blob/master/src/main/java/io/vertx/core/http/impl/HttpServerImpl.java#L247 Then I could expose the Vert.x instance to the app somehow to use it to create Vert.x components like async dbs etc... is it possible that it's that easy, or are there possible pitfalls in this approach?
    d
    o
    k
    • 4
    • 25
  • c

    coder82

    06/14/2018, 8:52 PM
    isn't there a finished release 0.9.3 yet right?
    d
    • 2
    • 1
  • v

    vincent.brule

    06/15/2018, 9:44 AM
    Hello 🙂 Do you have a good tutorial to use Google Oauth with the ktor feature Oauth please ?
    📝 1
    ✅ 2
    d
    • 2
    • 3
  • n

    Nathan Hartwell

    06/15/2018, 1:36 PM
    Does anyone know of a way to get the built-in ContentNegotiaion feature to use a default output converter for requests with no
    Accept
    header? I'm not seeing an obvious way to configure the module to use a default, and also have not been able to figure out a way to mutate / replace the request headers before the ContentNegotiation module looks at them to fake it out.
    d
    • 2
    • 16
  • a

    Axel

    06/16/2018, 8:16 AM
    Hi everyone, I made a nice event based wrapper for Ktor WebSockets. Because this is my first library I could really use your feedbacks to improve my coding / sharing skills, so do not hesitate to point me anything ! https://github.com/rozaxe/hypercube
    👍 2
    d
    • 2
    • 2
  • k

    katokay

    06/17/2018, 12:58 AM
    I was doing some diligence over the weekend to see how ktor would hold up for some of our needs. I was checking to see how ktor handles coroutine suspend / resume because we have a need to use structured logging in our apps. We’ve traditionally handled things like requestId in spring by using MDC.putCloseable in an interceptor. I put together a simple example below with ktor. This seems to be working out of the box without me having to do anything special, but it seems like I’m just getting lucky (or maybe false positives) because it’s not what I would have expected.
    fun main(args: Array<String>) {
        val server = embeddedServer(Netty, port = 9000) {
            intercept(ApplicationCallPipeline.Infrastructure){
                val requestId = UUID.randomUUID()
                MDC.putCloseable("req.Id", requestId.toString()).use {
                    <http://this.context.application.log.info|this.context.application.log.info>("Interceptor")
                    proceed()
                }
            }
            routing {
                get("/") {
                    <http://call.application.log.info|call.application.log.info>("Inside /")
                    call.respondText("Hello World!", ContentType.Text.Plain)
                }
            }
        }
        server.start(wait = true)
    }
    I tested using
    wrk -t6 -c200 -d15s <http://localhost:9000/>
    just to get a little bit of concurrency. Added context: https://github.com/Kotlin/kotlinx.coroutines/issues/119
    ✅ 1
    📝 1
    d
    • 2
    • 35
  • c

    christophsturm

    06/17/2018, 12:54 PM
    can i have one gradle project that contains my server side code using ktor, and also the code for my web frontend, using the kotlin-frontend-plugin?
    d
    • 2
    • 3
  • c

    coder82

    06/18/2018, 7:53 AM
    I am trying to run some tests were I don't send anything back and let the test hang inside handleWebSocketConversation
    d
    • 2
    • 3
  • c

    coder82

    06/18/2018, 11:54 AM
    When I close a websocket, the exception is not propagated over the channel, when I call receive() on one side, and the channel was closed with close(e) on the other side, It doesn't trace the cause, receive() just throws ClosedReceiveChannelException, not the cause of it happened on the other side
    d
    e
    • 3
    • 20
  • s

    Slackbot

    06/18/2018, 12:58 PM
    This message was deleted.
    📝 1
    d
    v
    • 3
    • 19
  • v

    vincent.brule

    06/18/2018, 1:26 PM
    Another question about session feature. ow do you do to don’t create a new session if the same user log again and again please ?
    s
    d
    • 3
    • 19
  • d

    Deactivated User

    06/18/2018, 2:05 PM
    ^ :thread-please:
    v
    • 2
    • 32
  • c

    coder82

    06/18/2018, 3:00 PM
    how do I tell ktor to use secure websockets? "wss://" ?
    d
    • 2
    • 8
  • p

    pike

    06/19/2018, 3:59 AM
    are there any soap clients?
    d
    • 2
    • 2
  • p

    pike

    06/19/2018, 5:49 AM
    can I use socks5 proxy with the httpclient ?
    d
    • 2
    • 7
  • j

    jozefdransfield

    06/19/2018, 9:03 PM
    Is it possible to get the matched route in a intercepting feature. For metrics purposes it would be good if I could get /user/{name} not user/Jozef for response time metrics?
    ✅ 1
    📝 1
    d
    v
    • 3
    • 40
  • v

    vincent.brule

    06/20/2018, 7:24 AM
    Hello, one question about sessions feature. When you use Session Content (client-side), where the system stock the authentication please ?
    d
    • 2
    • 4
  • d

    Deactivated User

    06/20/2018, 1:34 PM
    ^ :thread-please:
    d
    • 2
    • 15
  • v

    vincent.brule

    06/20/2018, 1:38 PM
    Is it possible to custom the body of an Apache client post ? I want to send a post request like in postman (form-data) where you can put a key like “photo” and a value with the file corresponding to the photo.
    ✅ 2
    📝 1
    d
    • 2
    • 8
  • a

    avolkmann

    06/21/2018, 6:47 AM
    When using
    default
    to specify a default file, shouldn't it be served, when I call an otherwise unhandled endpoint?
    o
    • 2
    • 6
  • m

    Matt

    06/21/2018, 12:06 PM
    I'd like to run
    install(CORS) { anyHost() }
    just when I'm running locally in developer mode -- is there a standard way to check that programatically?
    📝 1
    ✅ 1
    ❤️ 1
    d
    • 2
    • 14
  • m

    mkporwit

    06/21/2018, 5:33 PM
    can’t you just do
    val result = client.get<HttpResponse> { /* your code here */ }
    val data = result.content.readRemaining().readText()
    d
    e
    • 3
    • 12
  • v

    vincent.brule

    06/22/2018, 8:35 AM
    Hello, Is it possible to add an expiration time (TTL) for session cookie (client side) please ?
    ✅ 2
    📝 1
    e
    c
    d
    • 4
    • 28
  • m

    mkporwit

    06/26/2018, 4:16 AM
    @cy @Deactivated User Thanks for merging my JWT fixes into master. We’re about to release code that will need those fixes this week, so this is very timely. Any time you guys want to do an
    0.9.3-alpha-6
    , that would be great with me 🙂
    c
    • 2
    • 1
  • m

    Matt

    06/26/2018, 11:37 AM
    I'm using
    withTestApplication
    to test my microservice, and wanted to send it data classes rather than JSON strings, and receive unmarshalled data classes as responses (rather than raw JSON strings from HTTP response bodies). Is it a case of just using Jackson directly, or is there any special support available in Ktor for this?
    c
    • 2
    • 4
  • c

    cy

    06/26/2018, 12:30 PM
    📣 ktor
    0.9.3
    has been released * Improved WebSocket API * Websocket header
    Sec-WebSocket-Key
    is now optional * Fixed client cookies rendering to avoid
    x-enc
    * Fixed plain text client reader (#392) * Added EC support in CIO TLS (#394: ECDHE_RSA_AES256_SHA384, ECDHE_RSA_AES128_SHA256) * Fix client certificate validation * Introduced optional authentication * Added
    ApplicationCall
    as receiver for auth
    validate
    functions * Introduced
    call.respondBytes
    (#395) * Improved JWT support: multiple schemes, nullable issuer * Conversion service enum type diagnostics improved (#403) * Avoided using apos entity in HTML escaping as IE doesn't support it (#400) * Converter support for java big numbers * Ability to add auth methods to existing feature on the fly * Improved auth header scheme and contents validation (#415) * Default charset for BasicAuth is now UTF-8 (#420) * Added
    ByteArrayContent.contentLength
    (#421) * Fixed
    headersOf
    case insensitive issue (#426) * Client deserialization improved by using type token * Ability to disable client default transformers * Explicit
    Accept
    header in client request * Turn on masking in client websockets (#423) * Fixed inverted
    PartialContent.Configuration.maxRangeCount
    check (#440) * Fixed uncaught
    UnsupportedMediaTypeException
    from
    receiveOrNull()
    (#442) * Fix multipart boundary header parsing * Upgraded jwks/jwt, applied RSA256 by default if unspecified (#434, #435) * Upgrade coroutine version to 0.23.3 * Upgrade Jetty version to 9.4.11.v20180605 * Add
    client-mock-engine
    for testing purpose * Use default available engine by deafult * Upgrade kotlin to 1.2.50 Move ktor-samples to a separate repository (#340). https://github.com/ktorio/ktor-samples See http://ktor.io/quickstart/migration/0.9.3.html for migration steps
    🎉 19
    👍 8
    r
    d
    z
    • 4
    • 3
  • r

    rocketraman

    06/26/2018, 2:08 PM
    I am sending response content from ktor where the content comes from an
    InputStream
    . Oddly, this doesn't appear to be a built-in function? I've created this class which I'm passing to
    call.respond
    , but can someone comment on whether I'm missing something here?
    class InputStreamContent(
      private val stream: InputStream,
      etag: String?,
      override val contentLength: Long?,
      override val contentType: ContentType): OutgoingContent.ReadChannelContent() {
    
      init {
        if (etag != null) versions += EntityTagVersion(etag)
      }
    
      override fun readFrom(): ByteReadChannel = stream.toByteReadChannel()
    }
    📝 1
    c
    d
    • 3
    • 33
Powered by Linen
Title
r

rocketraman

06/26/2018, 2:08 PM
I am sending response content from ktor where the content comes from an
InputStream
. Oddly, this doesn't appear to be a built-in function? I've created this class which I'm passing to
call.respond
, but can someone comment on whether I'm missing something here?
class InputStreamContent(
  private val stream: InputStream,
  etag: String?,
  override val contentLength: Long?,
  override val contentType: ContentType): OutgoingContent.ReadChannelContent() {

  init {
    if (etag != null) versions += EntityTagVersion(etag)
  }

  override fun readFrom(): ByteReadChannel = stream.toByteReadChannel()
}
📝 1
c

cy

06/26/2018, 2:34 PM
Looks good, it should work but remember that
InputStream
is blocking so it may cause problems once the
stream
get stuck
r

rocketraman

06/26/2018, 2:39 PM
Is there a more coroutine friendly construct I can use?
This stream is sourced over a network so it could definitely block.
Also note: the docs are getting way better but I found no docs related to implementing this.
Ok, so if I'm understanding this correctly, I need my stream source to use an Async mechanism instead, like
AsynchronousSocketChannel
or something.
c

cy

06/26/2018, 2:51 PM
Yes, exactly. If your source stream is transferred over http then you can try ktor client that is async and you can get content as a byte channel
@Deactivated User ^^^
d

Deactivated User

06/26/2018, 2:52 PM
@rocketraman related to implementing a custom OutgoingContent? Or to using channels?
r

rocketraman

06/26/2018, 2:53 PM
I'm going to try and integrate https://github.com/Azure/azure-storage-java/tree/New-Storage-SDK-V10-Preview, which uses ReactiveX (rx 2). Any samples I can look at that uses ktor + the rx2 coroutine extensions?
@Deactivated User For docs, yes
c

cy

06/26/2018, 2:59 PM
I don't see any async API...
Ah I see, they just didn't update javadocs,
but I still can't see download yet, only upload
r

rocketraman

06/26/2018, 3:08 PM
@cy Yeah, this is a beta of a new release of their driver so they likely haven't got much in the way of docs yet.
At the end of the day though, I guess I will have some type of
Single
or
Observable
to deal with.
`Single<BlobsDownloadResponse>`: https://github.com/Azure/azure-storage-java/blob/New-Storage-SDK-V10-Preview/src/main/java/com/microsoft/azure/storage/blob/models/BlobsDownloadResponse.java
d

Deactivated User

06/26/2018, 3:20 PM
You can use
writer
from kotlinx.coroutines-io to custom generate a
ByteReadChannel
. If you have a callback function receiving ByteBuffer chunks, you can create a channel and pass to that writer job
Flowable<ByteBuffer>
Maybe you can create an extension function to convert a Flowable<ByteBuffer> into a ByteReadChannel and then send a content with that ByteReadChannel. Also if the API allows you to get an endpoint + headers you can use the ktor’s HttpClient and pipe the client body to the server response
r

rocketraman

06/26/2018, 3:23 PM
Thanks guys, let me play with this a bit. I've done lots of async programming, but coroutines and rxjava are both mostly new to me, so this should be interesting.
👍 1
c

cy

06/26/2018, 4:15 PM
implementing backpressure with RX is the most difficult part so be careful 😉
r

rocketraman

06/26/2018, 4:23 PM
Ok, so really interesting 🙂
@cy @Deactivated User I believe this turned out to be quite simple -- I did as @Deactivated User suggested and converted a
Flowable<ByteBuffer>
to a
ByteReadChannel
via `writer`:
suspend fun Flowable<ByteBuffer>.toByteReadChannel(parent: Job = Job()) = writer(Unconfined, parent = parent, autoFlush = true) {
  try {
    this@toByteReadChannel.consumeEach {
      channel.writeFully(it)
    }
  } catch (e: Throwable) {
    channel.close(e)
  }
}.channel
I haven't fully explored whether this is doing all the right things under the hood, but it seems to work. If I put a breakpoint at the
writeFully
line I see the client getting bytes a chunk at a time, as each breakpoint is hit and run.
I think this handles back-pressure properly because the source is a
Flowable
that is being consumed by a suspendable.
c

cy

06/27/2018, 8:19 AM
this@toByteReadChannel.consumeEach
what does it do? Does Flowable have
consumeEach
? Where it is implemented?
r

rocketraman

06/27/2018, 2:14 PM
@cy NOTE: I had a bit of trouble with the opposite during upload: converting from a
ByteReadChannel
to a
Flowable<ByteBuffer>
. I ended up with this:
suspend fun ByteReadChannel.toFlowable(): Flowable<ByteBuffer> {
  return rxFlowable {
    this@toFlowable.lookAheadSuspend {
      consumeEachRemaining {
        // we have to make a copy otherwise the ByteBuffer gets recycled by ktor and the Flowable items get corrupted
        this@rxFlowable.channel.send(it.copy())
        true
      }
      this@rxFlowable.close()
    }
  }
}
Note the
copy()
in there on the
ByteBuffer
from ktor. Without that, the upload contained garbage. I'm pretty sure its due to concurrent ByteBuffer recycling by ktor, which corrupts the Flowable. Is there a better approach to this?
@cy This is a utility extension that comes from the rx2 kotlin coroutines library. https://github.com/Kotlin/kotlinx.coroutines/tree/master/reactive/kotlinx-coroutines-rx2
c

cy

06/27/2018, 2:17 PM
Well, the buffer inside of lookAheadSuspend is always the same: it is a ring buffer
r

rocketraman

06/27/2018, 2:20 PM
Ah that explains why I was having issues. Is there a better
ByteReadChannel
API I should use to split it up into `ByteBuffer`'s I can send to a
Flowable
? Btw,
rxFlowable
here also comes from the same rx2 coroutines adapter lib.
Or is this question better asked on #coroutines ?
c

cy

06/27/2018, 3:08 PM
as f ar as understand, Flowable doesn't provide any way to recycle sent elements, right ?
so copying is the only way I see...
r

rocketraman

06/27/2018, 3:18 PM
Yes, it seems so. Perhaps I will post on #coroutines just to get opinion from the experts there.
View count: 10