From 00c070a47658cb2adbdc81a077624e2ea4829601 Mon Sep 17 00:00:00 2001 From: Bogdan Gavril Date: Thu, 28 Mar 2019 11:33:19 -0700 Subject: [PATCH] Fix threading issue in HttpClientManager --- .../AppConfig/IMsalHttpClientFactory.cs | 7 ++++++- src/Microsoft.Identity.Client/Http/HttpManager.cs | 10 +++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.Identity.Client/AppConfig/IMsalHttpClientFactory.cs b/src/Microsoft.Identity.Client/AppConfig/IMsalHttpClientFactory.cs index c6dda49ef9..8a91d0ee82 100644 --- a/src/Microsoft.Identity.Client/AppConfig/IMsalHttpClientFactory.cs +++ b/src/Microsoft.Identity.Client/AppConfig/IMsalHttpClientFactory.cs @@ -30,8 +30,13 @@ namespace Microsoft.Identity.Client { /// - /// Http Client Factory + /// Factory responsible for creating HttpClient + /// .Net recommends to use a single instance of HttpClient /// + /// + /// Implementations must be thread safe. Consider creating and configuring an HttpClient in the constructor + /// of the factory, and returning the same object in + /// public interface IMsalHttpClientFactory { /// diff --git a/src/Microsoft.Identity.Client/Http/HttpManager.cs b/src/Microsoft.Identity.Client/Http/HttpManager.cs index bc14f84104..eb33f18f3e 100644 --- a/src/Microsoft.Identity.Client/Http/HttpManager.cs +++ b/src/Microsoft.Identity.Client/Http/HttpManager.cs @@ -37,6 +37,14 @@ namespace Microsoft.Identity.Client.Http { + /// + /// We invoke this class from different threads and they all use the same HttpClient. + /// To prevent race conditions, make sure you do not get / set anything on HttpClient itself, + /// instead rely on HttpRequest objects which are thread specific. + /// + /// In particular, do not change any properties on HttpClient such as BaseAddress, buffer sizes and Timeout. You should + /// also not access DefaultRequestHeaders because the getters are not thread safe (use HttpRequestMessage.Headers instead). + /// internal class HttpManager : IHttpManager { private readonly IMsalHttpClientFactory _httpClientFactory; @@ -210,7 +218,7 @@ private async Task ExecuteAsync( await client.SendAsync(requestMessage).ConfigureAwait(false)) { HttpResponse returnValue = await CreateResponseAsync(responseMessage).ConfigureAwait(false); - returnValue.UserAgent = client.DefaultRequestHeaders.UserAgent.ToString(); + returnValue.UserAgent = requestMessage.Headers.UserAgent.ToString(); return returnValue; } }