// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Web.Http; namespace System.Net.Http { public static class HttpClientFactory { /// /// Creates a new instance configured with the handlers provided and with an /// as the innermost handler. /// /// An ordered list of instances to be invoked as an /// travels from the to the network and an /// travels from the network back to . /// The handlers are invoked in a top-down fashion. That is, the first entry is invoked first for /// an outbound request message but last for an inbound response message. /// An instance with the configured handlers. [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Handler is disposed with HttpClient")] public static HttpClient Create(params DelegatingHandler[] handlers) { return Create(new HttpClientHandler(), handlers); } /// /// Creates a new instance configured with the handlers provided and with the /// provided as the innermost handler. /// /// The inner handler represents the destination of the HTTP message channel. /// An ordered list of instances to be invoked as an /// travels from the to the network and an /// travels from the network back to . /// The handlers are invoked in a top-down fashion. That is, the first entry is invoked first for /// an outbound request message but last for an inbound response message. /// An instance with the configured handlers. [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Handler is disposed with HttpClient")] public static HttpClient Create(HttpMessageHandler innerHandler, params DelegatingHandler[] handlers) { HttpMessageHandler pipeline = CreatePipeline(innerHandler, handlers); return new HttpClient(pipeline); } /// /// Creates an instance of an using the instances /// provided by . The resulting pipeline can be used to manually create /// or instances with customized message handlers. /// /// The inner handler represents the destination of the HTTP message channel. /// An ordered list of instances to be invoked as part /// of sending an and receiving an . /// The handlers are invoked in a top-down fashion. That is, the first entry is invoked first for /// an outbound request message but last for an inbound response message. /// The HTTP message channel. public static HttpMessageHandler CreatePipeline(HttpMessageHandler innerHandler, IEnumerable handlers) { if (innerHandler == null) { throw Error.ArgumentNull("innerHandler"); } if (handlers == null) { return innerHandler; } // Wire handlers up in reverse order starting with the inner handler HttpMessageHandler pipeline = innerHandler; IEnumerable reversedHandlers = handlers.Reverse(); foreach (DelegatingHandler handler in reversedHandlers) { if (handler == null) { throw Error.Argument("handlers", Properties.Resources.DelegatingHandlerArrayContainsNullItem, typeof(DelegatingHandler).Name); } if (handler.InnerHandler != null) { throw Error.Argument("handlers", Properties.Resources.DelegatingHandlerArrayHasNonNullInnerHandler, typeof(DelegatingHandler).Name, "InnerHandler", handler.GetType().Name); } handler.InnerHandler = pipeline; pipeline = handler; } return pipeline; } } }