Osman Saral
01/25/2022, 9:48 PM@OptIn(ExperimentalTime::class)
class TokenKiller {
companion object Feature: HttpClientFeature<TokenKiller, TokenKiller> {
override val key: AttributeKey<TokenKiller> = AttributeKey("TokenKiller")
override fun prepare(block: TokenKiller.() -> Unit): TokenKiller {
return TokenKiller().apply(block)
}
override fun install(feature: TokenKiller, scope: HttpClient) {
var mark: TimeMark? = null
scope.requestPipeline.intercept(HttpRequestPipeline.Before) {
val duration = mark?.elapsedNow() ?: Duration.ZERO
if (duration.inWholeMinutes > 10) {
//cancel the request and with Unauthorized here, so my AuthProvider can do it's job
} else {
//continue
}
}
scope.feature(HttpSend)!!.intercept { origin, context ->
if (origin.response.status == HttpStatusCode.OK) {
mark = TimeSource.Monotonic.markNow() //I mark the last successful response here.I know i should store it
}
return@intercept origin
}
}
}
}
Aleksei Tirman [JB]
01/26/2022, 10:43 AMval needRefresh = AtomicBoolean(true)
suspend fun main(): Unit = coroutineScope {
val client = HttpClient(Apache) {}
val phase = PipelinePhase("")
client.requestPipeline.insertPhaseBefore(HttpRequestPipeline.Before, phase)
client.requestPipeline.intercept(phase) {
if (needRefresh.get()) {
client.refreshToken()
// Finishes execution of the whole pipeline so a request isn't sent
finish()
// Since a token is already refreshed we can execute the whole pipeline from the beginning again
proceedWith(client.requestPipeline.execute(context, subject))
}
}
val r = client.get<String>("<https://httpbin.org/get>")
println(r)
}
suspend fun HttpClient.refreshToken() {
println("Token refreshed")
needRefresh.set(false)
}
The bigger question is how to properly track the elapsed time.Osman Saral
01/26/2022, 11:01 AMAleksei Tirman [JB]
01/26/2022, 11:03 AMOsman Saral
01/26/2022, 11:07 AMrefreshTokens
block in install(Auth)
the only way to call it is respond with Unauthorized. I should add another interceptor then? Like you did.Aleksei Tirman [JB]
01/26/2022, 11:14 AMrefreshTokens
's block?Osman Saral
01/26/2022, 11:15 AMAleksei Tirman [JB]
01/26/2022, 11:49 AMAuth
plugin works with the HttpSend
plugin that executes callbacks only after an actual request is made. So in a crude way, it's possible to replace the response but then the HttpSend
plugin won't intercept a pipeline.Osman Saral
01/26/2022, 11:53 AM