diff --git a/CoderPatros.AuthenticatedHttpClient.AuthorizationHeader.Tests/AuthorizationHeaderAuthenticatedHttpClientTests.cs b/CoderPatros.AuthenticatedHttpClient.AuthorizationHeader.Tests/AuthorizationHeaderAuthenticatedHttpClientTests.cs index 76eac0b..dc9e3bf 100644 --- a/CoderPatros.AuthenticatedHttpClient.AuthorizationHeader.Tests/AuthorizationHeaderAuthenticatedHttpClientTests.cs +++ b/CoderPatros.AuthenticatedHttpClient.AuthorizationHeader.Tests/AuthorizationHeaderAuthenticatedHttpClientTests.cs @@ -15,19 +15,21 @@ public class AuthorizationHeaderAuthenticatedHttpClientTests [Fact] public async Task TestRequestAddsAuthenticationHeader() { - var mockHttp = new MockHttpMessageHandler(); - mockHttp - .Expect("https://www.example.com") - .WithHeaders("Authorization", "test-value") - .Respond(HttpStatusCode.OK); - var client = AuthorizationHeaderAuthenticatedHttpClient.GetClient(new AuthorizationHeaderAuthenticatedHttpClientOptions + using (var mockHttp = new MockHttpMessageHandler()) { - Value = "test-value" - }, mockHttp); + mockHttp + .Expect("https://www.example.com") + .WithHeaders("Authorization", "test-value") + .Respond(HttpStatusCode.OK); + var client = AuthorizationHeaderAuthenticatedHttpClient.GetClient(new AuthorizationHeaderAuthenticatedHttpClientOptions + { + Value = "test-value" + }, mockHttp); - await client.GetStringAsync("https://www.example.com"); + await client.GetStringAsync(new Uri("https://www.example.com")).ConfigureAwait(false); - mockHttp.VerifyNoOutstandingExpectation(); + mockHttp.VerifyNoOutstandingExpectation(); + } } } } diff --git a/CoderPatros.AuthenticatedHttpClient.AuthorizationHeader.Tests/CoderPatros.AuthenticatedHttpClient.AuthorizationHeader.Tests.csproj b/CoderPatros.AuthenticatedHttpClient.AuthorizationHeader.Tests/CoderPatros.AuthenticatedHttpClient.AuthorizationHeader.Tests.csproj index fd425bd..d0d0640 100644 --- a/CoderPatros.AuthenticatedHttpClient.AuthorizationHeader.Tests/CoderPatros.AuthenticatedHttpClient.AuthorizationHeader.Tests.csproj +++ b/CoderPatros.AuthenticatedHttpClient.AuthorizationHeader.Tests/CoderPatros.AuthenticatedHttpClient.AuthorizationHeader.Tests.csproj @@ -7,6 +7,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/CoderPatros.AuthenticatedHttpClient.AuthorizationHeader/AuthorizationHeaderAuthenticatedHttpMessageHandler.cs b/CoderPatros.AuthenticatedHttpClient.AuthorizationHeader/AuthorizationHeaderAuthenticatedHttpMessageHandler.cs index 3285df4..77877e9 100644 --- a/CoderPatros.AuthenticatedHttpClient.AuthorizationHeader/AuthorizationHeaderAuthenticatedHttpMessageHandler.cs +++ b/CoderPatros.AuthenticatedHttpClient.AuthorizationHeader/AuthorizationHeaderAuthenticatedHttpMessageHandler.cs @@ -24,7 +24,7 @@ public AuthorizationHeaderAuthenticatedHttpMessageHandler( protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { request.Headers.Authorization = _authorizationHeader; - return await base.SendAsync(request, cancellationToken); + return await base.SendAsync(request, cancellationToken).ConfigureAwait(false); } } } \ No newline at end of file diff --git a/CoderPatros.AuthenticatedHttpClient.AzureAd.Tests/AzureAdAuthenticatedHttpClientTests.cs b/CoderPatros.AuthenticatedHttpClient.AzureAd.Tests/AzureAdAuthenticatedHttpClientTests.cs index 74470a5..5bf224f 100644 --- a/CoderPatros.AuthenticatedHttpClient.AzureAd.Tests/AzureAdAuthenticatedHttpClientTests.cs +++ b/CoderPatros.AuthenticatedHttpClient.AzureAd.Tests/AzureAdAuthenticatedHttpClientTests.cs @@ -19,80 +19,94 @@ public class AzureAdAuthenticatedHttpClientTests [Fact] public async Task TestRequestHasAuthorizationHeader() { - var mockHttp = new MockHttpMessageHandler(); - mockHttp - .Expect("https://www.example.com") - .WithHeaders("Authorization", "Bearer test-access-token") - .Respond(HttpStatusCode.OK); - var mockMsgHandler = new Mock(new AzureAdAuthenticatedHttpClientOptions + using (var mockHttp = new MockHttpMessageHandler()) { - Tenant = "test-tenant", - ClientId = "test-client-id", - AppKey = "test-client-app-key", - ResourceId = "test-resource-id" - }, mockHttp); - mockMsgHandler - .Setup(handler => handler.AcquireAccessTokenAsync()) - .Returns(Task.FromResult("test-access-token")); - mockMsgHandler.CallBase = true; - var client = new HttpClient(mockMsgHandler.Object); + mockHttp + .Expect("https://www.example.com") + .WithHeaders("Authorization", "Bearer test-access-token") + .Respond(HttpStatusCode.OK); + var mockMsgHandler = new Mock(new AzureAdAuthenticatedHttpClientOptions + { + Tenant = "test-tenant", + ClientId = "test-client-id", + AppKey = "test-client-app-key", + ResourceId = "test-resource-id" + }, mockHttp); + mockMsgHandler + .Setup(handler => handler.AcquireAccessTokenAsync()) + .Returns(Task.FromResult("test-access-token")); + mockMsgHandler.CallBase = true; - await client.GetStringAsync("https://www.example.com"); + using (var client = new HttpClient(mockMsgHandler.Object)) + { + await client.GetStringAsync(new Uri("https://www.example.com")).ConfigureAwait(false); - mockHttp.VerifyNoOutstandingExpectation(); + mockHttp.VerifyNoOutstandingExpectation(); + } + } } [Fact] public async Task TestRequestRetriesThreeTimesToAcquireAccessToken() { - var mockHttp = new MockHttpMessageHandler(); - mockHttp - .Expect("https://www.example.com") - .WithHeaders("Authorization", "Bearer test-access-token") - .Respond(HttpStatusCode.OK); - var mockMsgHandler = new Mock(new AzureAdAuthenticatedHttpClientOptions + using (var mockHttp = new MockHttpMessageHandler()) { - Tenant = "test-tenant", - ClientId = "test-client-id", - AppKey = "test-client-app-key", - ResourceId = "test-resource-id" - }, mockHttp); - mockMsgHandler - .SetupSequence(handler => handler.AcquireAccessTokenAsync()) - .Throws(new AdalException("temporarily_unavailable")) - .Throws(new AdalException("temporarily_unavailable")) - .Returns(Task.FromResult("test-access-token")); - mockMsgHandler.CallBase = true; - var client = new HttpClient(mockMsgHandler.Object); + mockHttp + .Expect("https://www.example.com") + .WithHeaders("Authorization", "Bearer test-access-token") + .Respond(HttpStatusCode.OK); + var mockMsgHandler = new Mock(new AzureAdAuthenticatedHttpClientOptions + { + Tenant = "test-tenant", + ClientId = "test-client-id", + AppKey = "test-client-app-key", + ResourceId = "test-resource-id" + }, mockHttp); + mockMsgHandler + .SetupSequence(handler => handler.AcquireAccessTokenAsync()) + .Throws(new AdalException("temporarily_unavailable")) + .Throws(new AdalException("temporarily_unavailable")) + .Returns(Task.FromResult("test-access-token")); + mockMsgHandler.CallBase = true; - await client.GetStringAsync("https://www.example.com"); + using (var client = new HttpClient(mockMsgHandler.Object)) + { + await client.GetStringAsync(new Uri("https://www.example.com")).ConfigureAwait(false); - mockHttp.VerifyNoOutstandingExpectation(); - } + mockHttp.VerifyNoOutstandingExpectation(); + } + } + } [Fact] public async Task TestRequestFailsOnRepeatedFailuresToAcquireAccessTokenFailure() { - var mockHttp = new MockHttpMessageHandler(); - mockHttp.Fallback.Respond(req => new HttpResponseMessage(HttpStatusCode.Unauthorized)); - var mockMsgHandler = new Mock(new AzureAdAuthenticatedHttpClientOptions + using (var mockHttp = new MockHttpMessageHandler()) { - Tenant = "test-tenant", - ClientId = "test-client-id", - AppKey = "test-client-app-key", - ResourceId = "test-resource-id" - }, mockHttp); - mockMsgHandler - .SetupSequence(handler => handler.AcquireAccessTokenAsync()) - .Throws(new AdalException("temporarily_unavailable")) - .Throws(new AdalException("temporarily_unavailable")) - .Throws(new AdalException("temporarily_unavailable")); - mockMsgHandler.CallBase = true; - var client = new HttpClient(mockMsgHandler.Object); + mockHttp.Fallback.Respond(req => new HttpResponseMessage(HttpStatusCode.Unauthorized)); + var mockMsgHandler = new Mock(new AzureAdAuthenticatedHttpClientOptions + { + Tenant = "test-tenant", + ClientId = "test-client-id", + AppKey = "test-client-app-key", + ResourceId = "test-resource-id" + }, mockHttp); + mockMsgHandler + .SetupSequence(handler => handler.AcquireAccessTokenAsync()) + .Throws(new AdalException("temporarily_unavailable")) + .Throws(new AdalException("temporarily_unavailable")) + .Throws(new AdalException("temporarily_unavailable")); + mockMsgHandler.CallBase = true; - var exc = await Record.ExceptionAsync(async () => await client.GetStringAsync("https://www.example.com")); + using (var client = new HttpClient(mockMsgHandler.Object)) + { + var exc = await Record.ExceptionAsync( + async () => await client.GetStringAsync(new Uri("https://www.example.com")).ConfigureAwait(false) + ).ConfigureAwait(false); - Assert.IsType(exc); - } + Assert.IsType(exc); + } + } + } } } diff --git a/CoderPatros.AuthenticatedHttpClient.AzureAd.Tests/CoderPatros.AuthenticatedHttpClient.AzureAd.Tests.csproj b/CoderPatros.AuthenticatedHttpClient.AzureAd.Tests/CoderPatros.AuthenticatedHttpClient.AzureAd.Tests.csproj index 60c489d..50f9235 100644 --- a/CoderPatros.AuthenticatedHttpClient.AzureAd.Tests/CoderPatros.AuthenticatedHttpClient.AzureAd.Tests.csproj +++ b/CoderPatros.AuthenticatedHttpClient.AzureAd.Tests/CoderPatros.AuthenticatedHttpClient.AzureAd.Tests.csproj @@ -7,6 +7,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/CoderPatros.AuthenticatedHttpClient.AzureAd/AzureAdAuthenticatedHttpClient.cs b/CoderPatros.AuthenticatedHttpClient.AzureAd/AzureAdAuthenticatedHttpClient.cs index 7167539..095c588 100644 --- a/CoderPatros.AuthenticatedHttpClient.AzureAd/AzureAdAuthenticatedHttpClient.cs +++ b/CoderPatros.AuthenticatedHttpClient.AzureAd/AzureAdAuthenticatedHttpClient.cs @@ -6,12 +6,14 @@ namespace CoderPatros.AuthenticatedHttpClient // https://github.com/Azure-Samples/active-directory-dotnet-daemon/blob/master/TodoListDaemon/Program.cs public static class AzureAdAuthenticatedHttpClient { + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope")] public static HttpClient GetClient(AzureAdAuthenticatedHttpClientOptions options) { var msgHandler = new AzureAdAuthenticatedHttpMessageHandler(options); return new HttpClient(msgHandler); } + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope")] public static HttpClient GetClient(AzureAdAuthenticatedHttpClientOptions options, HttpMessageHandler innerHandler) { var msgHandler = new AzureAdAuthenticatedHttpMessageHandler(options, innerHandler); diff --git a/CoderPatros.AuthenticatedHttpClient.AzureAd/AzureAdAuthenticatedHttpMessageHandler.cs b/CoderPatros.AuthenticatedHttpClient.AzureAd/AzureAdAuthenticatedHttpMessageHandler.cs index 6ccb1ee..7135a96 100644 --- a/CoderPatros.AuthenticatedHttpClient.AzureAd/AzureAdAuthenticatedHttpMessageHandler.cs +++ b/CoderPatros.AuthenticatedHttpClient.AzureAd/AzureAdAuthenticatedHttpMessageHandler.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.Contracts; using System.Net.Http; using System.Net.Http.Headers; using System.Globalization; @@ -18,6 +19,8 @@ public class AzureAdAuthenticatedHttpMessageHandler : DelegatingHandler public AzureAdAuthenticatedHttpMessageHandler(AzureAdAuthenticatedHttpClientOptions options) { + Contract.Requires(options != null); + _resourceId = options.ResourceId; var authority = String.Format(CultureInfo.InvariantCulture, options.AadInstance, options.Tenant); @@ -35,7 +38,7 @@ public AzureAdAuthenticatedHttpMessageHandler( internal virtual async Task AcquireAccessTokenAsync() { - var result = await _authContext.AcquireTokenAsync(_resourceId, _clientCredential); + var result = await _authContext.AcquireTokenAsync(_resourceId, _clientCredential).ConfigureAwait(false); return result?.AccessToken; } @@ -55,7 +58,7 @@ private async Task AcquireTokenWithRetriesAsync(CancellationToken cancel try { // ADAL includes an in memory cache, so this call will only send a message to the server if the cached token is expired. - token = await AcquireAccessTokenAsync(); + token = await AcquireAccessTokenAsync().ConfigureAwait(false); } catch (AdalException ex) { @@ -80,7 +83,9 @@ private async Task AcquireTokenWithRetriesAsync(CancellationToken cancel protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { - var accessToken = await AcquireTokenWithRetriesAsync(cancellationToken); + Contract.Requires(request != null); + + var accessToken = await AcquireTokenWithRetriesAsync(cancellationToken).ConfigureAwait(false); if (cancellationToken.IsCancellationRequested) { return null; @@ -90,7 +95,7 @@ protected override async Task SendAsync(HttpRequestMessage "Bearer", accessToken); - return await base.SendAsync(request, cancellationToken); + return await base.SendAsync(request, cancellationToken).ConfigureAwait(false); } } } \ No newline at end of file diff --git a/CoderPatros.AuthenticatedHttpClient.AzureAd/CoderPatros.AuthenticatedHttpClient.AzureAd.csproj b/CoderPatros.AuthenticatedHttpClient.AzureAd/CoderPatros.AuthenticatedHttpClient.AzureAd.csproj index 9ae61ec..32b9aeb 100644 --- a/CoderPatros.AuthenticatedHttpClient.AzureAd/CoderPatros.AuthenticatedHttpClient.AzureAd.csproj +++ b/CoderPatros.AuthenticatedHttpClient.AzureAd/CoderPatros.AuthenticatedHttpClient.AzureAd.csproj @@ -13,6 +13,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/CoderPatros.AuthenticatedHttpClient.AzureAppServiceManagedIdentity.Tests/AzureAppSericeManagedIdentityAuthenticatedHttpClientTests.cs b/CoderPatros.AuthenticatedHttpClient.AzureAppServiceManagedIdentity.Tests/AzureAppSericeManagedIdentityAuthenticatedHttpClientTests.cs index 4b56f86..32a9fd5 100644 --- a/CoderPatros.AuthenticatedHttpClient.AzureAppServiceManagedIdentity.Tests/AzureAppSericeManagedIdentityAuthenticatedHttpClientTests.cs +++ b/CoderPatros.AuthenticatedHttpClient.AzureAppServiceManagedIdentity.Tests/AzureAppSericeManagedIdentityAuthenticatedHttpClientTests.cs @@ -18,24 +18,28 @@ public class AzureAppServiceManagedIdentityAuthenticatedHttpClientTests [Fact] public async Task TestRequestHasAuthorizationHeader() { - var mockHttp = new MockHttpMessageHandler(); - mockHttp - .Expect("https://www.example.com") - .WithHeaders("Authorization", "Bearer test-access-token") - .Respond(HttpStatusCode.OK); - var mockMsgHandler = new Mock(new AzureAppServiceManagedIdentityAuthenticatedHttpClientOptions + using (var mockHttp = new MockHttpMessageHandler()) { - ResourceId = "test-resource-id" - }, mockHttp); - mockMsgHandler - .Setup(handler => handler.GetAccessTokenAsync()) - .Returns(Task.FromResult("test-access-token")); - mockMsgHandler.CallBase = true; - var client = new HttpClient(mockMsgHandler.Object); + mockHttp + .Expect("https://www.example.com") + .WithHeaders("Authorization", "Bearer test-access-token") + .Respond(HttpStatusCode.OK); + var mockMsgHandler = new Mock(new AzureAppServiceManagedIdentityAuthenticatedHttpClientOptions + { + ResourceId = "test-resource-id" + }, mockHttp); + mockMsgHandler + .Setup(handler => handler.GetAccessTokenAsync()) + .Returns(Task.FromResult("test-access-token")); + mockMsgHandler.CallBase = true; - await client.GetStringAsync("https://www.example.com"); + using (var client = new HttpClient(mockMsgHandler.Object)) + { + await client.GetStringAsync(new Uri("https://www.example.com")).ConfigureAwait(false); - mockHttp.VerifyNoOutstandingExpectation(); + mockHttp.VerifyNoOutstandingExpectation(); + } + } } } } diff --git a/CoderPatros.AuthenticatedHttpClient.AzureAppServiceManagedIdentity.Tests/CoderPatros.AuthenticatedHttpClient.AzureAppServiceManagedIdentity.Tests.csproj b/CoderPatros.AuthenticatedHttpClient.AzureAppServiceManagedIdentity.Tests/CoderPatros.AuthenticatedHttpClient.AzureAppServiceManagedIdentity.Tests.csproj index 4e2581b..368dc80 100644 --- a/CoderPatros.AuthenticatedHttpClient.AzureAppServiceManagedIdentity.Tests/CoderPatros.AuthenticatedHttpClient.AzureAppServiceManagedIdentity.Tests.csproj +++ b/CoderPatros.AuthenticatedHttpClient.AzureAppServiceManagedIdentity.Tests/CoderPatros.AuthenticatedHttpClient.AzureAppServiceManagedIdentity.Tests.csproj @@ -7,6 +7,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/CoderPatros.AuthenticatedHttpClient.AzureAppServiceManagedIdentity/AzureAppServiceManagedIdentityAuthenticatedHttpClient.cs b/CoderPatros.AuthenticatedHttpClient.AzureAppServiceManagedIdentity/AzureAppServiceManagedIdentityAuthenticatedHttpClient.cs index 003733b..f626042 100644 --- a/CoderPatros.AuthenticatedHttpClient.AzureAppServiceManagedIdentity/AzureAppServiceManagedIdentityAuthenticatedHttpClient.cs +++ b/CoderPatros.AuthenticatedHttpClient.AzureAppServiceManagedIdentity/AzureAppServiceManagedIdentityAuthenticatedHttpClient.cs @@ -4,13 +4,15 @@ namespace CoderPatros.AuthenticatedHttpClient { public static class AzureAppServiceManagedIdentityAuthenticatedHttpClient { - public static HttpClient GetClient(AzureAppServiceManagedIdentityAuthenticatedHttpClientOptions options) + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope")] + public static HttpClient GetClient(AzureAppServiceManagedIdentityAuthenticatedHttpClientOptions options) { var msgHandler = new AzureAppServiceManagedIdentityAuthenticatedHttpMessageHandler(options); return new HttpClient(msgHandler); } - public static HttpClient GetClient(AzureAppServiceManagedIdentityAuthenticatedHttpClientOptions options, HttpMessageHandler innerHandler) + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope")] + public static HttpClient GetClient(AzureAppServiceManagedIdentityAuthenticatedHttpClientOptions options, HttpMessageHandler innerHandler) { var msgHandler = new AzureAppServiceManagedIdentityAuthenticatedHttpMessageHandler(options, innerHandler); return new HttpClient(msgHandler); diff --git a/CoderPatros.AuthenticatedHttpClient.AzureAppServiceManagedIdentity/AzureAppServiceManagedIdentityAuthenticatedHttpMessageHandler.cs b/CoderPatros.AuthenticatedHttpClient.AzureAppServiceManagedIdentity/AzureAppServiceManagedIdentityAuthenticatedHttpMessageHandler.cs index 12cdddc..974c5c3 100644 --- a/CoderPatros.AuthenticatedHttpClient.AzureAppServiceManagedIdentity/AzureAppServiceManagedIdentityAuthenticatedHttpMessageHandler.cs +++ b/CoderPatros.AuthenticatedHttpClient.AzureAppServiceManagedIdentity/AzureAppServiceManagedIdentityAuthenticatedHttpMessageHandler.cs @@ -1,4 +1,6 @@ -using System.Net.Http; +using System; +using System.Diagnostics.Contracts; +using System.Net.Http; using System.Net.Http.Headers; using System.Threading; using System.Threading.Tasks; @@ -15,6 +17,8 @@ public class AzureAppServiceManagedIdentityAuthenticatedHttpMessageHandler : Del public AzureAppServiceManagedIdentityAuthenticatedHttpMessageHandler( AzureAppServiceManagedIdentityAuthenticatedHttpClientOptions options) { + Contract.Requires(options != null); + _resourceId = options.ResourceId; } @@ -22,24 +26,28 @@ public AzureAppServiceManagedIdentityAuthenticatedHttpMessageHandler( AzureAppServiceManagedIdentityAuthenticatedHttpClientOptions options, HttpMessageHandler innerHandler) : this(options) { + Contract.Requires(options != null); + InnerHandler = innerHandler; } [ExcludeFromCodeCoverage] internal virtual async Task GetAccessTokenAsync() { - return await _azureServiceTokenProvider.GetAccessTokenAsync(_resourceId); + return await _azureServiceTokenProvider.GetAccessTokenAsync(_resourceId).ConfigureAwait(false); } protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { - var accessToken = await GetAccessTokenAsync(); + Contract.Requires(request != null); + + var accessToken = await GetAccessTokenAsync().ConfigureAwait(false); request.Headers.Authorization = new AuthenticationHeaderValue( "Bearer", accessToken); - return await base.SendAsync(request, cancellationToken); + return await base.SendAsync(request, cancellationToken).ConfigureAwait(false); } } } \ No newline at end of file diff --git a/CoderPatros.AuthenticatedHttpClient.AzureAppServiceManagedIdentity/CoderPatros.AuthenticatedHttpClient.AzureAppServiceManagedIdentity.csproj b/CoderPatros.AuthenticatedHttpClient.AzureAppServiceManagedIdentity/CoderPatros.AuthenticatedHttpClient.AzureAppServiceManagedIdentity.csproj index 702e83f..82e80b2 100644 --- a/CoderPatros.AuthenticatedHttpClient.AzureAppServiceManagedIdentity/CoderPatros.AuthenticatedHttpClient.AzureAppServiceManagedIdentity.csproj +++ b/CoderPatros.AuthenticatedHttpClient.AzureAppServiceManagedIdentity/CoderPatros.AuthenticatedHttpClient.AzureAppServiceManagedIdentity.csproj @@ -13,6 +13,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + diff --git a/CoderPatros.AuthenticatedHttpClient.Basic.Tests/BasicAuthenticatedHttpClientTests.cs b/CoderPatros.AuthenticatedHttpClient.Basic.Tests/BasicAuthenticatedHttpClientTests.cs index 5684e7d..dd10286 100644 --- a/CoderPatros.AuthenticatedHttpClient.Basic.Tests/BasicAuthenticatedHttpClientTests.cs +++ b/CoderPatros.AuthenticatedHttpClient.Basic.Tests/BasicAuthenticatedHttpClientTests.cs @@ -29,20 +29,22 @@ public void TestGenerateAuthenticationParameterRFC7617() [Fact] public async Task TestRequestHasAuthorizationHeader() { - var mockHttp = new MockHttpMessageHandler(); - mockHttp - .Expect("https://www.example.com") - .WithHeaders("Authorization", "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==") - .Respond(HttpStatusCode.OK); - var client = BasicAuthenticatedHttpClient.GetClient(new BasicAuthenticatedHttpClientOptions + using (var mockHttp = new MockHttpMessageHandler()) { - UserId = "Aladdin", - Password = "open sesame" - }, mockHttp); + mockHttp + .Expect("https://www.example.com") + .WithHeaders("Authorization", "Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==") + .Respond(HttpStatusCode.OK); + var client = BasicAuthenticatedHttpClient.GetClient(new BasicAuthenticatedHttpClientOptions + { + UserId = "Aladdin", + Password = "open sesame" + }, mockHttp); - await client.GetStringAsync("https://www.example.com"); + await client.GetStringAsync(new Uri("https://www.example.com")).ConfigureAwait(false); - mockHttp.VerifyNoOutstandingExpectation(); + mockHttp.VerifyNoOutstandingExpectation(); + } } } } diff --git a/CoderPatros.AuthenticatedHttpClient.Basic.Tests/CoderPatros.AuthenticatedHttpClient.Basic.Tests.csproj b/CoderPatros.AuthenticatedHttpClient.Basic.Tests/CoderPatros.AuthenticatedHttpClient.Basic.Tests.csproj index 4c6c288..d4758c9 100644 --- a/CoderPatros.AuthenticatedHttpClient.Basic.Tests/CoderPatros.AuthenticatedHttpClient.Basic.Tests.csproj +++ b/CoderPatros.AuthenticatedHttpClient.Basic.Tests/CoderPatros.AuthenticatedHttpClient.Basic.Tests.csproj @@ -7,6 +7,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/CoderPatros.AuthenticatedHttpClient.Basic/BasicAuthenticatedHttpMessageHandler.cs b/CoderPatros.AuthenticatedHttpClient.Basic/BasicAuthenticatedHttpMessageHandler.cs index 3435e49..5688d5f 100644 --- a/CoderPatros.AuthenticatedHttpClient.Basic/BasicAuthenticatedHttpMessageHandler.cs +++ b/CoderPatros.AuthenticatedHttpClient.Basic/BasicAuthenticatedHttpMessageHandler.cs @@ -36,7 +36,7 @@ internal static string GenerateAuthenticationParameter(string userId, string pas protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { request.Headers.Authorization = _authorizationHeader; - return await base.SendAsync(request, cancellationToken); + return await base.SendAsync(request, cancellationToken).ConfigureAwait(false); } } } \ No newline at end of file diff --git a/CoderPatros.AuthenticatedHttpClient.CustomHeader.Tests/CoderPatros.AuthenticatedHttpClient.CustomHeader.Tests.csproj b/CoderPatros.AuthenticatedHttpClient.CustomHeader.Tests/CoderPatros.AuthenticatedHttpClient.CustomHeader.Tests.csproj index 8323245..ef6ec3a 100644 --- a/CoderPatros.AuthenticatedHttpClient.CustomHeader.Tests/CoderPatros.AuthenticatedHttpClient.CustomHeader.Tests.csproj +++ b/CoderPatros.AuthenticatedHttpClient.CustomHeader.Tests/CoderPatros.AuthenticatedHttpClient.CustomHeader.Tests.csproj @@ -7,6 +7,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/CoderPatros.AuthenticatedHttpClient.CustomHeader.Tests/CustomHeaderAuthenticatedHttpClientTests.cs b/CoderPatros.AuthenticatedHttpClient.CustomHeader.Tests/CustomHeaderAuthenticatedHttpClientTests.cs index 48376d5..544963e 100644 --- a/CoderPatros.AuthenticatedHttpClient.CustomHeader.Tests/CustomHeaderAuthenticatedHttpClientTests.cs +++ b/CoderPatros.AuthenticatedHttpClient.CustomHeader.Tests/CustomHeaderAuthenticatedHttpClientTests.cs @@ -12,68 +12,74 @@ public class CustomHeaderAuthenticatedHttpClientTests [Fact] public async Task TestRequestAddsAuthenticationHeader() { - var mockHttp = new MockHttpMessageHandler(); - mockHttp - .Expect("https://www.example.com") - .WithHeaders("test-name", "test-value") - .Respond(HttpStatusCode.OK); - var client = CustomHeaderAuthenticatedHttpClient.GetClient(new CustomHeaderAuthenticatedHttpClientOptions + using (var mockHttp = new MockHttpMessageHandler()) { - Name = "test-name", - Value = "test-value" - }, mockHttp); + mockHttp + .Expect("https://www.example.com") + .WithHeaders("test-name", "test-value") + .Respond(HttpStatusCode.OK); + var client = CustomHeaderAuthenticatedHttpClient.GetClient(new CustomHeaderAuthenticatedHttpClientOptions + { + Name = "test-name", + Value = "test-value" + }, mockHttp); - await client.GetStringAsync("https://www.example.com"); + await client.GetStringAsync(new Uri("https://www.example.com")).ConfigureAwait(false); - mockHttp.VerifyNoOutstandingExpectation(); + mockHttp.VerifyNoOutstandingExpectation(); + } } [Fact] public async Task TestMultipleParameterRequestAddsAuthenticationParameters() { - var mockHttp = new MockHttpMessageHandler(); - mockHttp - .Expect("https://www.example.com") - .WithHeaders(new Dictionary { - { "test-name-1", "test-value-1" }, - { "test-name-2", "test-value-2" } - }) - .Respond(HttpStatusCode.OK); - var client = CustomHeaderAuthenticatedHttpClient.GetClient(new MultipleCustomHeaderAuthenticatedHttpClientOptions + using (var mockHttp = new MockHttpMessageHandler()) { - Headers = new Dictionary + mockHttp + .Expect("https://www.example.com") + .WithHeaders(new Dictionary { + { "test-name-1", "test-value-1" }, + { "test-name-2", "test-value-2" } + }) + .Respond(HttpStatusCode.OK); + var client = CustomHeaderAuthenticatedHttpClient.GetClient(new MultipleCustomHeaderAuthenticatedHttpClientOptions { - { "test-name-1", "test-value-1"}, - { "test-name-2", "test-value-2"} - } - }, mockHttp); + Headers = new Dictionary + { + { "test-name-1", "test-value-1"}, + { "test-name-2", "test-value-2"} + } + }, mockHttp); - await client.GetStringAsync("https://www.example.com"); + await client.GetStringAsync(new Uri("https://www.example.com")).ConfigureAwait(false); - mockHttp.VerifyNoOutstandingExpectation(); + mockHttp.VerifyNoOutstandingExpectation(); + } } [Fact] public async Task TestMultipleParameterWithSingleParameterRequestAddsAuthenticationParameter() { - var mockHttp = new MockHttpMessageHandler(); - mockHttp - .Expect("https://www.example.com") - .WithHeaders(new Dictionary { - { "test-name-1", "test-value-1" } - }) - .Respond(HttpStatusCode.OK); - var client = CustomHeaderAuthenticatedHttpClient.GetClient(new MultipleCustomHeaderAuthenticatedHttpClientOptions + using (var mockHttp = new MockHttpMessageHandler()) { - Headers = new Dictionary + mockHttp + .Expect("https://www.example.com") + .WithHeaders(new Dictionary { + { "test-name-1", "test-value-1" } + }) + .Respond(HttpStatusCode.OK); + var client = CustomHeaderAuthenticatedHttpClient.GetClient(new MultipleCustomHeaderAuthenticatedHttpClientOptions { - { "test-name-1", "test-value-1"} - } - }, mockHttp); + Headers = new Dictionary + { + { "test-name-1", "test-value-1"} + } + }, mockHttp); - await client.GetStringAsync("https://www.example.com"); + await client.GetStringAsync(new Uri("https://www.example.com")).ConfigureAwait(false); - mockHttp.VerifyNoOutstandingExpectation(); + mockHttp.VerifyNoOutstandingExpectation(); + } } } } diff --git a/CoderPatros.AuthenticatedHttpClient.CustomHeader/CustomHeaderAuthenticatedHttpMessageHandler.cs b/CoderPatros.AuthenticatedHttpClient.CustomHeader/CustomHeaderAuthenticatedHttpMessageHandler.cs index 49badb2..4f22d02 100644 --- a/CoderPatros.AuthenticatedHttpClient.CustomHeader/CustomHeaderAuthenticatedHttpMessageHandler.cs +++ b/CoderPatros.AuthenticatedHttpClient.CustomHeader/CustomHeaderAuthenticatedHttpMessageHandler.cs @@ -26,7 +26,7 @@ protected override async Task SendAsync( { request.Headers.Remove(_options.Name); request.Headers.Add(_options.Name, _options.Value); - return await base.SendAsync(request, cancellationToken); + return await base.SendAsync(request, cancellationToken).ConfigureAwait(false); } } } \ No newline at end of file diff --git a/CoderPatros.AuthenticatedHttpClient.QueryStringParameter.Tests/CoderPatros.AuthenticatedHttpClient.QueryStringParameter.Tests.csproj b/CoderPatros.AuthenticatedHttpClient.QueryStringParameter.Tests/CoderPatros.AuthenticatedHttpClient.QueryStringParameter.Tests.csproj index 44e96f0..c1a4b0b 100644 --- a/CoderPatros.AuthenticatedHttpClient.QueryStringParameter.Tests/CoderPatros.AuthenticatedHttpClient.QueryStringParameter.Tests.csproj +++ b/CoderPatros.AuthenticatedHttpClient.QueryStringParameter.Tests/CoderPatros.AuthenticatedHttpClient.QueryStringParameter.Tests.csproj @@ -7,6 +7,10 @@ + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/CoderPatros.AuthenticatedHttpClient.QueryStringParameter.Tests/QueryStringParameterAuthenticatedHttpClientTests.cs b/CoderPatros.AuthenticatedHttpClient.QueryStringParameter.Tests/QueryStringParameterAuthenticatedHttpClientTests.cs index 6489a41..b6f3074 100644 --- a/CoderPatros.AuthenticatedHttpClient.QueryStringParameter.Tests/QueryStringParameterAuthenticatedHttpClientTests.cs +++ b/CoderPatros.AuthenticatedHttpClient.QueryStringParameter.Tests/QueryStringParameterAuthenticatedHttpClientTests.cs @@ -12,134 +12,146 @@ public class QueryStringParameterAuthenticatedHttpClientTests [Fact] public async Task TestRequestAddsAuthenticationParameter() { - var mockHttp = new MockHttpMessageHandler(); - mockHttp - .Expect("https://www.example.com") - .WithQueryString(new Dictionary { - { "test-name", "test-value" } - }) - .Respond(HttpStatusCode.OK); - var client = QueryStringParameterAuthenticatedHttpClient.GetClient(new QueryStringParameterAuthenticatedHttpClientOptions + using (var mockHttp = new MockHttpMessageHandler()) { - Name = "test-name", - Value = "test-value" - }, mockHttp); + mockHttp + .Expect("https://www.example.com") + .WithQueryString(new Dictionary { + { "test-name", "test-value" } + }) + .Respond(HttpStatusCode.OK); + var client = QueryStringParameterAuthenticatedHttpClient.GetClient(new QueryStringParameterAuthenticatedHttpClientOptions + { + Name = "test-name", + Value = "test-value" + }, mockHttp); - await client.GetStringAsync("https://www.example.com"); + await client.GetStringAsync(new Uri("https://www.example.com")).ConfigureAwait(false); - mockHttp.VerifyNoOutstandingExpectation(); + mockHttp.VerifyNoOutstandingExpectation(); + } } [Fact] public async Task TestRequestAddsAuthenticationParameterWithEmptyQuery() { - var mockHttp = new MockHttpMessageHandler(); - mockHttp - .Expect("https://www.example.com") - .WithQueryString(new Dictionary { - { "test-name", "test-value" } - }) - .Respond(HttpStatusCode.OK); - var client = QueryStringParameterAuthenticatedHttpClient.GetClient(new QueryStringParameterAuthenticatedHttpClientOptions + using (var mockHttp = new MockHttpMessageHandler()) { - Name = "test-name", - Value = "test-value" - }, mockHttp); + mockHttp + .Expect("https://www.example.com") + .WithQueryString(new Dictionary { + { "test-name", "test-value" } + }) + .Respond(HttpStatusCode.OK); + var client = QueryStringParameterAuthenticatedHttpClient.GetClient(new QueryStringParameterAuthenticatedHttpClientOptions + { + Name = "test-name", + Value = "test-value" + }, mockHttp); - await client.GetStringAsync("https://www.example.com?"); + await client.GetStringAsync(new Uri("https://www.example.com?")).ConfigureAwait(false); - mockHttp.VerifyNoOutstandingExpectation(); + mockHttp.VerifyNoOutstandingExpectation(); + } } [Fact] public async Task TestRequestReplacesAuthenticationParameter() { - var mockHttp = new MockHttpMessageHandler(); - mockHttp - .Expect("https://www.example.com") - .WithQueryString(new Dictionary { - { "test-name", "test-value" } - }) - .Respond(HttpStatusCode.OK); - var client = QueryStringParameterAuthenticatedHttpClient.GetClient(new QueryStringParameterAuthenticatedHttpClientOptions + using (var mockHttp = new MockHttpMessageHandler()) { - Name = "test-name", - Value = "test-value" - }, mockHttp); + mockHttp + .Expect("https://www.example.com") + .WithQueryString(new Dictionary { + { "test-name", "test-value" } + }) + .Respond(HttpStatusCode.OK); + var client = QueryStringParameterAuthenticatedHttpClient.GetClient(new QueryStringParameterAuthenticatedHttpClientOptions + { + Name = "test-name", + Value = "test-value" + }, mockHttp); - await client.GetStringAsync("https://www.example.com?test-name=incorrect-value"); + await client.GetStringAsync(new Uri("https://www.example.com?test-name=incorrect-value")).ConfigureAwait(false); - mockHttp.VerifyNoOutstandingExpectation(); + mockHttp.VerifyNoOutstandingExpectation(); + } } [Fact] public async Task TestRequestAddsAuthenticationParameterToExistingQuery() { - var mockHttp = new MockHttpMessageHandler(); - mockHttp - .Expect("https://www.example.com") - .WithQueryString(new Dictionary { - { "test-name", "test-value" }, - { "other-name", "other-value" } - }) - .Respond(HttpStatusCode.OK); - var client = QueryStringParameterAuthenticatedHttpClient.GetClient(new QueryStringParameterAuthenticatedHttpClientOptions + using (var mockHttp = new MockHttpMessageHandler()) { - Name = "test-name", - Value = "test-value" - }, mockHttp); + mockHttp + .Expect("https://www.example.com") + .WithQueryString(new Dictionary { + { "test-name", "test-value" }, + { "other-name", "other-value" } + }) + .Respond(HttpStatusCode.OK); + var client = QueryStringParameterAuthenticatedHttpClient.GetClient(new QueryStringParameterAuthenticatedHttpClientOptions + { + Name = "test-name", + Value = "test-value" + }, mockHttp); - await client.GetStringAsync("https://www.example.com?other-name=other-value"); + await client.GetStringAsync(new Uri("https://www.example.com?other-name=other-value")).ConfigureAwait(false); - mockHttp.VerifyNoOutstandingExpectation(); + mockHttp.VerifyNoOutstandingExpectation(); + } } [Fact] public async Task TestMultipleParameterRequestAddsAuthenticationParameters() { - var mockHttp = new MockHttpMessageHandler(); - mockHttp - .Expect("https://www.example.com") - .WithQueryString(new Dictionary { - { "test-name-1", "test-value-1" }, - { "test-name-2", "test-value-2" } - }) - .Respond(HttpStatusCode.OK); - var client = QueryStringParameterAuthenticatedHttpClient.GetClient(new MultipleQueryStringParameterAuthenticatedHttpClientOptions + using (var mockHttp = new MockHttpMessageHandler()) { - Parameters = new Dictionary + mockHttp + .Expect("https://www.example.com") + .WithQueryString(new Dictionary { + { "test-name-1", "test-value-1" }, + { "test-name-2", "test-value-2" } + }) + .Respond(HttpStatusCode.OK); + var client = QueryStringParameterAuthenticatedHttpClient.GetClient(new MultipleQueryStringParameterAuthenticatedHttpClientOptions { - { "test-name-1", "test-value-1"}, - { "test-name-2", "test-value-2"} - } - }, mockHttp); + Parameters = new Dictionary + { + { "test-name-1", "test-value-1"}, + { "test-name-2", "test-value-2"} + } + }, mockHttp); - await client.GetStringAsync("https://www.example.com"); + await client.GetStringAsync(new Uri("https://www.example.com")).ConfigureAwait(false); - mockHttp.VerifyNoOutstandingExpectation(); + mockHttp.VerifyNoOutstandingExpectation(); + } } [Fact] public async Task TestMultipleParameterWithSingleParameterRequestAddsAuthenticationParameter() { - var mockHttp = new MockHttpMessageHandler(); - mockHttp - .Expect("https://www.example.com") - .WithQueryString(new Dictionary { - { "test-name", "test-value" } - }) - .Respond(HttpStatusCode.OK); - var client = QueryStringParameterAuthenticatedHttpClient.GetClient(new MultipleQueryStringParameterAuthenticatedHttpClientOptions + using (var mockHttp = new MockHttpMessageHandler()) { - Parameters = new Dictionary + mockHttp + .Expect("https://www.example.com") + .WithQueryString(new Dictionary { + { "test-name", "test-value" } + }) + .Respond(HttpStatusCode.OK); + var client = QueryStringParameterAuthenticatedHttpClient.GetClient(new MultipleQueryStringParameterAuthenticatedHttpClientOptions { - { "test-name", "test-value"} - } - }, mockHttp); + Parameters = new Dictionary + { + { "test-name", "test-value"} + } + }, mockHttp); - await client.GetStringAsync("https://www.example.com"); + await client.GetStringAsync(new Uri("https://www.example.com")).ConfigureAwait(false); - mockHttp.VerifyNoOutstandingExpectation(); + mockHttp.VerifyNoOutstandingExpectation(); + } } } } diff --git a/CoderPatros.AuthenticatedHttpClient.QueryStringParameter/QueryStringParameterAuthenticatedHttpMessageHandler.cs b/CoderPatros.AuthenticatedHttpClient.QueryStringParameter/QueryStringParameterAuthenticatedHttpMessageHandler.cs index 8f47823..ba28755 100644 --- a/CoderPatros.AuthenticatedHttpClient.QueryStringParameter/QueryStringParameterAuthenticatedHttpMessageHandler.cs +++ b/CoderPatros.AuthenticatedHttpClient.QueryStringParameter/QueryStringParameterAuthenticatedHttpMessageHandler.cs @@ -39,7 +39,7 @@ protected override async Task SendAsync(HttpRequestMessage } request.RequestUri = authenticatedUri.Uri; - return await base.SendAsync(request, cancellationToken); + return await base.SendAsync(request, cancellationToken).ConfigureAwait(false); } } } \ No newline at end of file