in src/Covi/Services/Http/AuthorizationHandling/TokenRefreshDelegatingHandler.cs [50:109]
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var authToken = await GetAuthTokenAsync().ConfigureAwait(false);
HttpResponseMessage response = null;
string requestContent = string.Empty;
using (await _tokenRefreshLock.ReaderLockAsync())
{
// Content is saved for the http message request copy below
if (request.Content != null)
{
requestContent = await request.Content.ReadAsStringAsync().ConfigureAwait(false);
}
response = await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
}
if (ShouldRefreshExpiredToken(response))
{
var isTokenRefreshSucceed = true;
using (await _tokenRefreshLock.WriterLockAsync())
{
// Check whether token hasn't been changed by other request handler
// and skip token refresh if changed
var session = await GetSessionInfoAsync().ConfigureAwait(false);
var currentToken = GetAuthTokenFromSession(session);
if (string.Equals(currentToken, authToken, StringComparison.OrdinalIgnoreCase))
{
isTokenRefreshSucceed = await _tokenRefreshStrategy.TryRefreshSessionAsync(session).ConfigureAwait(false);
}
}
if (isTokenRefreshSucceed)
{
// Fetch new session
authToken = await GetAuthTokenAsync().ConfigureAwait(false);
// Request is recreated due to HttpMessageRequest.Content is disposed
// after previous call to the backend with Unauthorized response code
var recreatedRequest = request.GetCopyWithoutContent();
if (!string.IsNullOrEmpty(requestContent))
{
recreatedRequest.SetContent(requestContent);
}
ApplyAuthenticationToken(recreatedRequest, authToken);
response = await base.SendAsync(recreatedRequest, cancellationToken).ConfigureAwait(false);
return response;
}
}
return response;
}