diff --git a/README.md b/README.md index 00542ad3..060982d5 100644 --- a/README.md +++ b/README.md @@ -142,20 +142,33 @@ VaultConfiguration config = new VaultConfiguration("http:127.0.0.1:8200"); VaultClient vaultClient = new VaultClient(config); ``` -You can also add custom configuration including a custom `HttpClientHandler`. -This can be used to intercept requests and add custom logic before the base -`SendAsync` is called by the HttpClient. See [HttpClientHandler docs][http-client-handler-docs] for more details. +We also allow you to bring your own `HttpClient` through a delegate. This can work +with any current factory pattern that you're using to create an `HttpClient` +object, which is one of the recommended patterns for managing your `HttpClient` +lifecycle. More on the `IHttpClientFactory` can be found [here][[http-client-factory]] ```csharp -// Create a custom HttpClientHandler -HttpClientHandler myClientHandler = new HttpClientHandler(); +// Create a HttpClient Provider Function + public static HttpClient MyHttpClientProvider(HttpClientHandler handler) + { + // Configuring your own HttpClient + HttpClient httpClient = new HttpClient(handler); + httpClient.Timeout = TimeSpan.FromSeconds(60); + return httpClient; + } +``` +```csharp +// Configuring Vault with your custom HttpClient Provider VaultConfiguration config = new VaultConfiguration("http://127.0.0.1:8200", - myClientHandler); + httpClientProvider: MyHttpClientProvider); ``` The VaultClient also allows you to set a custom Timeout for all API calls. +_**Note**_: This timeout will override any timeout in a preconfigured `HttpClient` + + ```csharp VaultConfiguration config = new VaultConfiguration(basePath: address, httpClientHandler: httpClientHandler, diff --git a/generate/templates/Configuration.mustache b/generate/templates/Configuration.mustache index 55c1adee..1a3a5e76 100644 --- a/generate/templates/Configuration.mustache +++ b/generate/templates/Configuration.mustache @@ -15,7 +15,7 @@ using System.Security.Cryptography.X509Certificates; using System.Text; namespace {{packageName}}.Client -{ +{ /// /// Represents the TLS Configuration /// @@ -168,17 +168,17 @@ namespace {{packageName}}.Client #region Constructors /// - /// Initializes a new instance of the class + /// Initializes a new instance of the class /// - public {{packageName}}Configuration(string basePath, - HttpClientHandler httpClientHandler = null, + public VaultConfiguration(string basePath, + Func httpClientProvider = null, TimeSpan? timeout = null, RetryConfiguration retryConfiguration = null, RateLimitConfiguration rateLimitConfiguration = null, TLSConfiguration tlsConfiguration = null) { if (string.IsNullOrEmpty(basePath)) throw new ArgumentException("Cannot be empty", "BasePath"); - HttpClientHandler = httpClientHandler ?? new HttpClientHandler(); + HttpClientHandler = new HttpClientHandler(); if (tlsConfiguration != null) { @@ -189,7 +189,7 @@ namespace {{packageName}}.Client { throw new ArgumentException("Certificate does not contain a private key"); } - httpClientHandler.ClientCertificates.Add(TLSConfiguration.ClientCertificate); + HttpClientHandler.ClientCertificates.Add(TLSConfiguration.ClientCertificate); } else if (TLSConfiguration.ClientCertificateCollection != null) { @@ -201,7 +201,7 @@ namespace {{packageName}}.Client } } - httpClientHandler.ClientCertificates.AddRange(TLSConfiguration.ClientCertificateCollection); + HttpClientHandler.ClientCertificates.AddRange(TLSConfiguration.ClientCertificateCollection); } Func ValidateServiceCertficate = @@ -225,17 +225,17 @@ namespace {{packageName}}.Client return true; }; - httpClientHandler.ClientCertificateOptions = ClientCertificateOption.Manual; - httpClientHandler.ServerCertificateCustomValidationCallback = ValidateServiceCertficate; + HttpClientHandler.ClientCertificateOptions = ClientCertificateOption.Manual; + HttpClientHandler.ServerCertificateCustomValidationCallback = ValidateServiceCertficate; } - - timeout = timeout ?? TimeSpan.FromSeconds(100); RetryConfiguration = retryConfiguration ?? new RetryConfiguration(5, TimeSpan.FromMilliseconds(500)); RateLimitConfiguration = rateLimitConfiguration ?? new RateLimitConfiguration(50, TimeSpan.FromSeconds(5)); BasePath = basePath.EndsWith("/") ? basePath : basePath + "/"; - HttpClient = new HttpClient(HttpClientHandler); + + HttpClient = httpClientProvider == null ? new HttpClient(HttpClientHandler) : httpClientProvider(HttpClientHandler); + timeout = timeout ?? TimeSpan.FromSeconds(100); HttpClient.Timeout = (TimeSpan)timeout; } @@ -246,7 +246,7 @@ namespace {{packageName}}.Client /// /// Gets or sets the base path for API access. /// - public virtual string BasePath + public virtual string BasePath { get { return _basePath; } set { _basePath = value; } @@ -344,7 +344,7 @@ namespace {{packageName}}.Client return apiKeyValue; } - + /// /// Gets or sets the access token for OAuth2 authentication. /// diff --git a/generate/templates/README.mustache b/generate/templates/README.mustache index 5d19ec8f..32ec84ea 100644 --- a/generate/templates/README.mustache +++ b/generate/templates/README.mustache @@ -164,20 +164,33 @@ VaultConfiguration config = new VaultConfiguration("http:127.0.0.1:8200"); VaultClient vaultClient = new VaultClient(config); ``` -You can also add custom configuration including a custom `HttpClientHandler`. -This can be used to intercept requests and add custom logic before the base -`SendAsync` is called by the HttpClient. See [HttpClientHandler docs][http-client-handler-docs] for more details. +We also allow you to bring your own `HttpClient` through a delegate. This can work +with any current factory pattern that you're using to create an `HttpClient` +object, which is one of the recommended patterns for managing your `HttpClient` +lifecycle. More on the `IHttpClientFactory` can be found [here][[http-client-factory]] ```csharp -// Create a custom HttpClientHandler -HttpClientHandler myClientHandler = new HttpClientHandler(); +// Create a HttpClient Provider Function + public static HttpClient MyHttpClientProvider(HttpClientHandler handler) + { + // Configuring your own HttpClient + HttpClient httpClient = new HttpClient(handler); + httpClient.Timeout = TimeSpan.FromSeconds(60); + return httpClient; + } +``` +```csharp +// Configuring Vault with your custom HttpClient Provider VaultConfiguration config = new VaultConfiguration("http://127.0.0.1:8200", - myClientHandler); + httpClientProvider: MyHttpClientProvider); ``` The VaultClient also allows you to set a custom Timeout for all API calls. +_**Note**_: This timeout will override any timeout in a preconfigured `HttpClient` + + ```csharp VaultConfiguration config = new VaultConfiguration(basePath: address, httpClientHandler: httpClientHandler, diff --git a/src/Vault/Client/Configuration.cs b/src/Vault/Client/Configuration.cs index 3fcb4885..4a1c2ace 100644 --- a/src/Vault/Client/Configuration.cs +++ b/src/Vault/Client/Configuration.cs @@ -21,7 +21,7 @@ using System.Text; namespace Vault.Client -{ +{ /// /// Represents the TLS Configuration /// @@ -161,14 +161,14 @@ public class VaultConfiguration /// Initializes a new instance of the class /// public VaultConfiguration(string basePath, - HttpClientHandler httpClientHandler = null, + Func httpClientProvider = null, TimeSpan? timeout = null, RetryConfiguration retryConfiguration = null, RateLimitConfiguration rateLimitConfiguration = null, TLSConfiguration tlsConfiguration = null) { if (string.IsNullOrEmpty(basePath)) throw new ArgumentException("Cannot be empty", "BasePath"); - HttpClientHandler = httpClientHandler ?? new HttpClientHandler(); + HttpClientHandler = new HttpClientHandler(); if (tlsConfiguration != null) { @@ -179,7 +179,7 @@ public VaultConfiguration(string basePath, { throw new ArgumentException("Certificate does not contain a private key"); } - httpClientHandler.ClientCertificates.Add(TLSConfiguration.ClientCertificate); + HttpClientHandler.ClientCertificates.Add(TLSConfiguration.ClientCertificate); } else if (TLSConfiguration.ClientCertificateCollection != null) { @@ -191,7 +191,7 @@ public VaultConfiguration(string basePath, } } - httpClientHandler.ClientCertificates.AddRange(TLSConfiguration.ClientCertificateCollection); + HttpClientHandler.ClientCertificates.AddRange(TLSConfiguration.ClientCertificateCollection); } Func ValidateServiceCertficate = @@ -215,17 +215,17 @@ public VaultConfiguration(string basePath, return true; }; - httpClientHandler.ClientCertificateOptions = ClientCertificateOption.Manual; - httpClientHandler.ServerCertificateCustomValidationCallback = ValidateServiceCertficate; + HttpClientHandler.ClientCertificateOptions = ClientCertificateOption.Manual; + HttpClientHandler.ServerCertificateCustomValidationCallback = ValidateServiceCertficate; } - - timeout = timeout ?? TimeSpan.FromSeconds(100); RetryConfiguration = retryConfiguration ?? new RetryConfiguration(5, TimeSpan.FromMilliseconds(500)); RateLimitConfiguration = rateLimitConfiguration ?? new RateLimitConfiguration(50, TimeSpan.FromSeconds(5)); BasePath = basePath.EndsWith("/") ? basePath : basePath + "/"; - HttpClient = new HttpClient(HttpClientHandler); + + HttpClient = httpClientProvider == null ? new HttpClient(HttpClientHandler) : httpClientProvider(HttpClientHandler); + timeout = timeout ?? TimeSpan.FromSeconds(100); HttpClient.Timeout = (TimeSpan)timeout; } @@ -236,7 +236,7 @@ public VaultConfiguration(string basePath, /// /// Gets or sets the base path for API access. /// - public virtual string BasePath + public virtual string BasePath { get { return _basePath; } set { _basePath = value; } @@ -334,7 +334,7 @@ public string GetApiKeyWithPrefix(string apiKeyIdentifier) return apiKeyValue; } - + /// /// Gets or sets the access token for OAuth2 authentication. ///