protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { var accessToken = await _httpConnection.GetAccessTokenAsync(); if (!string.IsNullOrEmpty(accessToken)) { request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); } return(await base.SendAsync(request, cancellationToken)); }
protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { var isNegotiate = false; if (string.IsNullOrEmpty(_accessToken) || // Negotiate redirects likely will have a new access token so let's always grab a (potentially) new access token on negotiate #if NET5_0_OR_GREATER request.Options.TryGetValue(new HttpRequestOptionsKey <bool>("IsNegotiate"), out var value) && value == true #else request.Properties.TryGetValue("IsNegotiate", out var value) && value is true #endif ) { isNegotiate = true; _accessToken = await _httpConnection.GetAccessTokenAsync().ConfigureAwait(false); } if (!string.IsNullOrEmpty(_accessToken)) { request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _accessToken); } var result = await base.SendAsync(request, cancellationToken).ConfigureAwait(false); // retry once with a new token on auth failure if (!isNegotiate && result.StatusCode is HttpStatusCode.Unauthorized) { HttpConnection.Log.RetryAccessToken(_httpConnection._logger, result.StatusCode); result.Dispose(); _accessToken = await _httpConnection.GetAccessTokenAsync().ConfigureAwait(false); if (!string.IsNullOrEmpty(_accessToken)) { request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _accessToken); } // Retrying the request relies on any HttpContent being non-disposable. // Currently this is true, the only HttpContent we send is type ReadOnlySequenceContent which is used by SSE and LongPolling for sending an already buffered byte[] result = await base.SendAsync(request, cancellationToken).ConfigureAwait(false); } return(result); }