toneerav
11/17/2025, 5:04 PMresponse.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 ?Aleksei Tirman [JB]
11/17/2025, 7:57 PMget , 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:
@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.Daniel Pitts
11/19/2025, 8:37 PMtoneerav
11/20/2025, 5:22 AM