Hi, I want to spawn a short lived web server to li...
# ktor
o
Hi, I want to spawn a short lived web server to listen for a callback in an OAuth authentication flow. I designed an API to hide this from my call site. The idea is a do a blocking call that 1. creates the server waiting for a callback request 2. once the server is ready, call the first request that will in turn callback my server 3. once the callback is intercepted, stops the server 4. then notifies the original caller that it's done My question is: for 2. how can I be sure my server is ready before triggering the orignal request? (code in 🧵)
Copy code
suspend fun authorize(requestUserAuthorization: (url: String) -> Unit): String {
    return callbackFlow {
        val url = Url("... details omitted here ...")
        val server = embeddedServer(Netty, port = url.port, host = url.host) {
            routing {
                get("... details omitted here ...") {
                    try {
                        // ... details omitted here ...
                        call.respond(HttpStatusCode.OK)
                        send("my result")
                        close(null)
                    } catch (e: Exception) {
                        call.respond(HttpStatusCode.BadRequest)
                        close(e)
                    }
                }
            }
        }
        server.start(wait = false)
        // FIXME ensure server is started before
        delay(150)
        requestUserAuthorization("<https://third-party-service/oauth/authorize?callback_uri=$url>")
        awaitClose(server::stop)
    }.first()
}
If I use
server.start(wait = true)
it won't go further. If I call my callback to open the URL in a Web browser before the server creation & start, chances are my server isn't ready yet once the browser requests my callback URL.
Hence, the artificial & fragile
delay
a
You can subscribe to the
ApplicationStarted
event to make sure the server is ready to serve requests. For more information please read the documentation.
1
o
Indeed, works well! 👍
Copy code
server.environment.monitor.subscribe(ApplicationStarted) {
                requestUserAuthorization("<https://third-party-service/oauth/authorize?callback_uri=$url>")
            }
            server.start(wait = false)