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. ///