public HttpClient CreateHttpClient(HttpMessageHandler handler = null) { var client = underlyingFactories.CreateHttpClient(handler); // Twitter can't handle the Expect 100 Continue HTTP header. client.DefaultRequestHeaders.ExpectContinue = false; return(client); }
/// <summary> /// Sends a YADIS HTTP request as part of identifier discovery. /// </summary> /// <param name="uri">The URI to GET.</param> /// <param name="requireSsl">Whether only HTTPS URLs should ever be retrieved.</param> /// <param name="hostFactories">The host factories.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <param name="acceptTypes">The value of the Accept HTTP header to include in the request.</param> /// <returns> /// The HTTP response retrieved from the request. /// </returns> internal static async Task <HttpResponseMessage> RequestAsync(Uri uri, bool requireSsl, IHostFactories hostFactories, CancellationToken cancellationToken, params string[] acceptTypes) { Requires.NotNull(uri, "uri"); Requires.NotNull(hostFactories, "hostFactories"); using (var httpClient = hostFactories.CreateHttpClient(requireSsl, IdentifierDiscoveryCachePolicy)) { var request = new HttpRequestMessage(HttpMethod.Get, uri); if (acceptTypes != null) { request.Headers.Accept.AddRange(acceptTypes.Select(at => new MediaTypeWithQualityHeaderValue(at))); } HttpResponseMessage response = null; try { // http://stackoverflow.com/questions/14103154/how-to-determine-if-an-httpresponsemessage-was-fulfilled-from-cache-using-httpcl response = await httpClient.SendAsync(request, cancellationToken); if (!response.IsSuccessStatusCode && response.Headers.Age.HasValue && response.Headers.Age.Value > TimeSpan.Zero) { // We don't want to report error responses from the cache, since the server may have fixed // whatever was causing the problem. So try again with cache disabled. Logger.Messaging.ErrorFormat("An HTTP {0} response was obtained from the cache. Retrying with cache disabled.", response.StatusCode); response.Dispose(); // discard the old one var nonCachingRequest = request.Clone(); using (var nonCachingHttpClient = hostFactories.CreateHttpClient(requireSsl, new RequestCachePolicy(RequestCacheLevel.Reload))) { response = await nonCachingHttpClient.SendAsync(nonCachingRequest, cancellationToken); } } return(response); } catch { response.DisposeIfNotNull(); throw; } } }
/// <summary> /// Creates a new HTTP client for use by OpenID relying parties and providers. /// </summary> /// <param name="hostFactories">The host factories.</param> /// <param name="requireSsl">if set to <c>true</c> [require SSL].</param> /// <param name="cachePolicy">The cache policy.</param> /// <returns>An HttpClient instance with appropriate caching policies set for OpenID operations.</returns> internal static HttpClient CreateHttpClient(this IHostFactories hostFactories, bool requireSsl, RequestCachePolicy cachePolicy = null) { Requires.NotNull(hostFactories, "hostFactories"); var rootHandler = hostFactories.CreateHttpMessageHandler(); var handler = rootHandler; bool sslRequiredSet = false, cachePolicySet = false; do { var webRequestHandler = handler as WebRequestHandler; var untrustedHandler = handler as UntrustedWebRequestHandler; var delegatingHandler = handler as DelegatingHandler; if (webRequestHandler != null) { if (cachePolicy != null) { webRequestHandler.CachePolicy = cachePolicy; cachePolicySet = true; } } else if (untrustedHandler != null) { untrustedHandler.IsSslRequired = requireSsl; sslRequiredSet = true; } if (delegatingHandler != null) { handler = delegatingHandler.InnerHandler; } else { break; } }while (true); if (cachePolicy != null && !cachePolicySet) { Logger.OpenId.Warn( "Unable to set cache policy due to HttpMessageHandler instances not being of type WebRequestHandler."); } ErrorUtilities.VerifyProtocol(!requireSsl || sslRequiredSet, "Unable to set RequireSsl on message handler because no HttpMessageHandler was of type {0}.", typeof(UntrustedWebRequestHandler).FullName); return(hostFactories.CreateHttpClient(rootHandler)); }