From 4d600bc09e85e7d17e27e6f1424e40459223fb20 Mon Sep 17 00:00:00 2001 From: Stephen Cleary Date: Fri, 27 Jul 2018 12:27:12 -0400 Subject: [PATCH 1/4] Add WebServiceRequestSettings.GetHttpClient. --- .../WebServiceRequestBase.cs | 63 +++++++++++-------- .../WebServiceRequestSettings.cs | 8 ++- 2 files changed, 44 insertions(+), 27 deletions(-) diff --git a/src/Faithlife.WebRequests/WebServiceRequestBase.cs b/src/Faithlife.WebRequests/WebServiceRequestBase.cs index 778521f..39a2c58 100644 --- a/src/Faithlife.WebRequests/WebServiceRequestBase.cs +++ b/src/Faithlife.WebRequests/WebServiceRequestBase.cs @@ -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) + { + var client = settings.GetHttpClient?.Invoke() ?? 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 : null as 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..570c015 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; } @@ -87,6 +87,12 @@ public WebServiceRequestSettings() /// public Func StartTrace { get; set; } + /// + /// A delegate that, if set, is called to retrieve an . + /// If this property is set, then and are ignored. + /// + public Func GetHttpClient { get; set; } + /// /// Clones this instance. /// From 9f9336af73a386b9441095da5e6434f1de32c398 Mon Sep 17 00:00:00 2001 From: Stephen Cleary Date: Wed, 8 Aug 2018 10:44:03 -0400 Subject: [PATCH 2/4] Do not set HttpClient.Timeout when reusing HttpClient instances. --- src/Faithlife.WebRequests/WebServiceRequestBase.cs | 7 ++++--- src/Faithlife.WebRequests/WebServiceRequestSettings.cs | 8 +++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Faithlife.WebRequests/WebServiceRequestBase.cs b/src/Faithlife.WebRequests/WebServiceRequestBase.cs index 39a2c58..7e8c0e1 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; } @@ -205,11 +205,12 @@ private HttpClientHandler CreateHttpClientHandler(WebServiceRequestSettings sett private HttpClient CreateHttpClient(WebServiceRequestSettings settings) { - var client = settings.GetHttpClient?.Invoke() ?? new HttpClient(CreateHttpClientHandler(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; } diff --git a/src/Faithlife.WebRequests/WebServiceRequestSettings.cs b/src/Faithlife.WebRequests/WebServiceRequestSettings.cs index 570c015..b6eed15 100644 --- a/src/Faithlife.WebRequests/WebServiceRequestSettings.cs +++ b/src/Faithlife.WebRequests/WebServiceRequestSettings.cs @@ -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; } @@ -88,9 +88,11 @@ public WebServiceRequestSettings() public Func StartTrace { get; set; } /// - /// A delegate that, if set, is called to retrieve an . - /// If this property is set, then and are ignored. + /// 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; } /// From f150320d6826dc1363c22f87bfa3e9cee1483d7c Mon Sep 17 00:00:00 2001 From: Stephen Cleary Date: Wed, 8 Aug 2018 10:52:20 -0400 Subject: [PATCH 3/4] Stylistic changes. --- src/Faithlife.WebRequests/WebServiceRequestBase.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Faithlife.WebRequests/WebServiceRequestBase.cs b/src/Faithlife.WebRequests/WebServiceRequestBase.cs index 7e8c0e1..f6ef2a0 100644 --- a/src/Faithlife.WebRequests/WebServiceRequestBase.cs +++ b/src/Faithlife.WebRequests/WebServiceRequestBase.cs @@ -188,7 +188,6 @@ protected virtual void OnWebRequestCreated(HttpRequestMessage request) { } - private HttpClientHandler CreateHttpClientHandler(WebServiceRequestSettings settings) { var handler = new HttpClientHandler(); @@ -257,7 +256,7 @@ private HttpRequestMessage CreateHttpRequestMessage(WebServiceRequestSettings se request.Headers.IfNoneMatch.ParseAdd(IfNoneMatch); if (Range != null) - request.Headers.Range = new RangeHeaderValue(Range.From, Range.HasEnd ? Range.To : null as long?); + request.Headers.Range = new RangeHeaderValue(Range.From, Range.HasEnd ? Range.To : default(long?)); OnWebRequestCreated(request); return request; From 0f07c6c52e6baa0fc4ded13d815c6b94c3e190de Mon Sep 17 00:00:00 2001 From: Stephen Cleary Date: Wed, 8 Aug 2018 13:23:51 -0400 Subject: [PATCH 4/4] Add version history docs. --- VersionHistory.md | 2 ++ 1 file changed, 2 insertions(+) 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