jamireh
10/03/2022, 6:09 PMsendPipeline
after State
as well as intercepting HttpSend
. Both had issues that didn't meet my expectations. What I expect to happen is:
1. Developer triggers my companion plugin through a debug tool of their choice so the next API call will return an HTTP 401
2. Developer triggers another API call and within one execution context:
a. My companion plugin is triggered, rewriting the response to HTTP 401
b. The provided Auth plugin is triggered, with the refresh token logic being invoked & in Bearer token providers, the access_token
& refresh_token
are rotated
c. The provided Auth plugin retries the original API with the new access_token
and returns the responsejamireh
10/03/2022, 6:12 PMsendPipeline
, I get a JobCancellationException
if I call finish()
but if I don't, I get java.lang.IllegalStateException: No request transformation found
When intercepting HttpSend
, the Auth plugin doesn't process the HTTP 401 response and the exception just bubbles up normallyjamireh
10/03/2022, 8:16 PMHttpSend
was what eventually worked. The issue I was running into was my companion Plugin was installed before the Auth plugin so when the HTTP 401 returned back up the interceptor chain, the Auth plugin was never included, hence why the exception was normally rethrown to the callerjamireh
10/03/2022, 8:17 PM@OptIn(InternalAPI::class)
override fun install(plugin: ForceLogout, scope: HttpClient) {
scope.plugin(HttpSend).intercept { context ->
val shouldForceLogout = _shouldForceLogout.tryReceive().getOrNull() ?: false
val call = if (shouldForceLogout) {
val request = context.build()
val response = HttpResponseData(
statusCode = HttpStatusCode.Unauthorized,
requestTime = GMTDate(),
headers = Headers.Empty,
version = HttpProtocolVersion.HTTP_1_1,
body = ByteReadChannel(ByteArray(0)),
callContext = request.executionContext
)
HttpClientCall(scope, request, response)
} else {
execute(context)
}
return@intercept call
}
}
Where _shouldForceLogout
is a Channel<Boolean>
initialized with Channel(1)