Hello all :wave:, I am using Ktor Client in Kotlin...
# ktor
t
Hello all 👋, I am using Ktor Client in Kotlin Multiplatform app. And theres one use case where i need help/suggestion. ktor Version Details • ktor Ktor 3.1.0 Problem • When I try to inspect the response in a response interceptor, reading
response.body
(or
bodyAsText()
) consumes it so downstream code can’t receive it anymore. • The usual auth callback flow only triggers on network/HTTP 401 — here the HTTP status is 200 so that doesn’t help. eg.
refreshToken
from auth provider Usecase • Server sometimes returns HTTP 200 but the JSON body contains a
"code"
field. If
"code" == 401"
I need to call the refresh-token API, update the auth token, then replay the original request with the new token. So even in HTTPStatus code 200 I need check response and validate about 401 case. So how to intercept response, call the required api in between based on response and Replay the request. ? can anyone please suggest better approach or any document or link ?
a
If a request is made with methods
get
,
post
, and so on, the response body is automatically saved into memory. You can intercept the
Send
hook and check if the response body was saved, receive the body, and parse it into an object. Then, based on the
code
, the new request can be created and sent with the refreshed access token. Here is an example:
Copy code
@Serializable
data class MyResponse(val code: Int)

val json = Json {
    ignoreUnknownKeys = true
}

val client = HttpClient(CIO) {
    install(createClientPlugin("Plugin") {
        on(Send) { request ->
            val call = proceed(request)

            val response = call.response

            if (response.isSaved) {
                response.rawContent.awaitContent()
                val body = json.decodeFromString<MyResponse>(response.bodyAsText())

                if (body.code == 401) {
                    // Get new token
                    // Create new request based on initial one
                    val newRequest = HttpRequestBuilder().takeFrom(request)
                    // Update the request
                    // Send the new request
                    return@on proceed(newRequest)
                }
            }

            call
        }
    })
}

val response = client.get("<http://localhost:8080>")
println("Response body: ${response.bodyAsText()}")
The code above has been tested with the latest stable version of Ktor, 3.3.2.
🫶 1
d
Slightly unrelated, but did you have AI write your question for you? Not shaming, genuinely curious.
t
Yes, for some of pointers 😊 @Daniel Pitts
👍 1