diff --git a/VersionHistory.md b/VersionHistory.md
index 30a4442..fb01d38 100644
--- a/VersionHistory.md
+++ b/VersionHistory.md
@@ -7,6 +7,8 @@ is updated in preparation for publishing an updated NuGet package.
Prefix the description of the change with `[major]`, `[minor]` or `[patch]` in accordance with [SemVer](http://semver.org).
+* [minor] Add `WebServiceRequestSettings.GetHttpClient` to allow `HttpClient` reuse.
+
## Released
### 0.5.0
diff --git a/src/Faithlife.WebRequests/WebServiceRequestBase.cs b/src/Faithlife.WebRequests/WebServiceRequestBase.cs
index 778521f..f6ef2a0 100644
--- a/src/Faithlife.WebRequests/WebServiceRequestBase.cs
+++ b/src/Faithlife.WebRequests/WebServiceRequestBase.cs
@@ -79,7 +79,7 @@ public string Method
public string IfNoneMatch { get; set; }
///
- /// Gets or sets the timeout.
+ /// Gets or sets the timeout. If is set, then this property is ignored.
///
/// The timeout.
public TimeSpan? Timeout { get; set; }
@@ -125,7 +125,7 @@ public string Method
public ByteRange Range { get; set; }
///
- /// True if HTTP redirects should not be followed automatically.
+ /// True if HTTP redirects should not be followed automatically. If is set, then this property is ignored.
///
public bool DisableAutoRedirect { get; set; }
@@ -188,12 +188,34 @@ protected virtual void OnWebRequestCreated(HttpRequestMessage request)
{
}
- private HttpRequestMessage CreateWebRequest(out HttpClient client)
+ private HttpClientHandler CreateHttpClientHandler(WebServiceRequestSettings settings)
{
- WebServiceRequestSettings settings = Settings ?? new WebServiceRequestSettings();
- var request = new HttpRequestMessage(new HttpMethod(Method ?? "GET"), RequestUri);
var handler = new HttpClientHandler();
- client = new HttpClient(handler);
+ if (settings.CookieManager != null)
+ handler.CookieContainer = settings.CookieManager.CookieContainer;
+
+ handler.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
+
+ if (DisableAutoRedirect)
+ handler.AllowAutoRedirect = false;
+
+ return handler;
+ }
+
+ private HttpClient CreateHttpClient(WebServiceRequestSettings settings)
+ {
+ if (settings.GetHttpClient != null)
+ return settings.GetHttpClient();
+
+ var client = new HttpClient(CreateHttpClientHandler(settings));
+ var timeout = Timeout ?? settings.DefaultTimeout;
+ client.Timeout = timeout ?? System.Threading.Timeout.InfiniteTimeSpan;
+ return client;
+ }
+
+ private HttpRequestMessage CreateHttpRequestMessage(WebServiceRequestSettings settings)
+ {
+ var request = new HttpRequestMessage(new HttpMethod(Method ?? "GET"), RequestUri);
if (settings.DefaultHeaders != null)
request.Headers.AddWebHeaders(settings.DefaultHeaders);
@@ -204,7 +226,7 @@ private HttpRequestMessage CreateWebRequest(out HttpClient client)
if (!string.IsNullOrEmpty(Accept))
request.Headers.Accept.ParseAdd(Accept);
- string userAgent = UserAgent ?? settings.UserAgent;
+ var userAgent = UserAgent ?? settings.UserAgent;
if (!string.IsNullOrEmpty(userAgent))
request.Headers.UserAgent.ParseAdd(userAgent);
@@ -220,19 +242,10 @@ private HttpRequestMessage CreateWebRequest(out HttpClient client)
if (settings.Host != null)
request.Headers.Host = settings.Host;
- TimeSpan? timeout = Timeout ?? settings.DefaultTimeout;
- if (timeout.HasValue)
- client.Timeout = timeout.Value;
-
- if (settings.CookieManager != null)
- handler.CookieContainer = settings.CookieManager.CookieContainer;
-
- string authorizationHeader = settings.AuthorizationHeader ?? (settings.AuthorizationHeaderCreator != null ? settings.AuthorizationHeaderCreator(new WebServiceRequestInfo(request)) : null);
+ var authorizationHeader = settings.AuthorizationHeader ?? settings.AuthorizationHeaderCreator?.Invoke(new WebServiceRequestInfo(request));
if (authorizationHeader != null)
request.Headers.Authorization = AuthenticationHeaderValue.Parse(authorizationHeader);
- handler.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
-
if (IfMatch != null)
request.Headers.IfMatch.ParseAdd(IfMatch);
@@ -242,22 +255,20 @@ private HttpRequestMessage CreateWebRequest(out HttpClient client)
if (IfNoneMatch != null)
request.Headers.IfNoneMatch.ParseAdd(IfNoneMatch);
- if (DisableAutoRedirect)
- handler.AllowAutoRedirect = false;
-
if (Range != null)
- {
- if (!Range.HasEnd)
- request.Headers.Range = new RangeHeaderValue(Range.From, null);
- else
- request.Headers.Range = new RangeHeaderValue(Range.From, Range.To);
- }
+ request.Headers.Range = new RangeHeaderValue(Range.From, Range.HasEnd ? Range.To : default(long?));
OnWebRequestCreated(request);
-
return request;
}
+ private HttpRequestMessage CreateWebRequest(out HttpClient client)
+ {
+ var settings = Settings ?? new WebServiceRequestSettings();
+ client = CreateHttpClient(settings);
+ return CreateHttpRequestMessage(settings);
+ }
+
private HttpContent GetRequestContent(HttpRequestMessage webRequest)
{
HttpContent requestContent = Content;
diff --git a/src/Faithlife.WebRequests/WebServiceRequestSettings.cs b/src/Faithlife.WebRequests/WebServiceRequestSettings.cs
index 38a0bce..b6eed15 100644
--- a/src/Faithlife.WebRequests/WebServiceRequestSettings.cs
+++ b/src/Faithlife.WebRequests/WebServiceRequestSettings.cs
@@ -23,7 +23,7 @@ public WebServiceRequestSettings()
public string UserAgent { get; set; }
///
- /// Gets or sets the cookie manager.
+ /// Gets or sets the cookie manager. If is set, then this property is ignored.
///
/// The cookie manager.
public CookieManager CookieManager { get; set; }
@@ -51,7 +51,7 @@ public WebServiceRequestSettings()
public WebHeaderCollection DefaultHeaders { get; set; }
///
- /// Gets or sets the default timeout.
+ /// Gets or sets the default timeout. If is set, then this property is ignored.
///
/// The default timeout.
public TimeSpan? DefaultTimeout { get; set; }
@@ -87,6 +87,14 @@ public WebServiceRequestSettings()
///
public Func StartTrace { get; set; }
+ ///
+ /// A delegate that, if set, is called to retrieve an . If this property is set, then the consumer is responsible for the entire lifetime of the , including disposal.
+ ///
+ ///
+ /// If this property is set, then , , , and are ignored.
+ ///
+ public Func GetHttpClient { get; set; }
+
///
/// Clones this instance.
///