private HttpClientNode CreateHttpClientNode(HttpClientHandlerOptions handlerOptions) { var httpClientHandler = CreateHttpMessageHandler(handlerOptions); var httpClient = new HttpClient(httpClientHandler); var expirationTimeUtc = DateTime.UtcNow.AddHours(1); return(new HttpClientNode(httpClient, expirationTimeUtc)); }
protected virtual HttpMessageHandler CreateHttpMessageHandler(HttpClientHandlerOptions options) { if (options == null) { throw new ArgumentNullException(nameof(options)); } var handler = new HttpClientHandler(); handler.AllowAutoRedirect = options.AllowAutoRedirect; handler.AutomaticDecompression = System.Net.DecompressionMethods.GZip | System.Net.DecompressionMethods.Deflate; handler.UseCookies = false; return(handler); }
/// <summary> /// Creates and returns a <see cref="IHttpClient"/> using the given options, /// which may share an internal <see cref="HttpClient"/> with other instances. /// </summary> /// <param name="handlerOptions"></param> /// <returns></returns> public IHttpClient Create(HttpClientHandlerOptions handlerOptions) { // You're not supposed to create an HttpClient for each request: // * https://github.com/mspnp/performance-optimization/blob/master/ImproperInstantiation/docs/ImproperInstantiation.md // * https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/ // But maybe an HttpClient never updates its DNS cache, so we might // not want to keep the same instance forever: // * https://github.com/dotnet/corefx/issues/11224 // * http://byterot.blogspot.co.uk/2016/07/singleton-httpclient-dns.html // * http://www.nimaara.com/2016/11/01/beware-of-the-net-httpclient/ // So for now we're going to keep a shared HttpClient around, but // only for an hour or so before we recreate it. if (handlerOptions == null) { handlerOptions = CreateDefaultHttpClientHandlerOptions(); } HttpClientNode httpClientNode; HttpClientNode oldHttpClientNode = null; if (cachedHttpClientDictionary.TryGetValue(handlerOptions, out httpClientNode)) { if (httpClientNode.ExpirationTimeUtc < DateTime.UtcNow) { cachedHttpClientDictionary.TryRemove(handlerOptions, out oldHttpClientNode); httpClientNode = null; } } if (httpClientNode == null) { httpClientNode = cachedHttpClientDictionary.GetOrAdd(handlerOptions, CreateHttpClientNode); } var result = new HttpClientAdapter(httpClientNode.HttpClient); return(result); }