private static HttpRequestMessage CreateNewRequestToProxiedApi(HttpRequestMessage request,
            ApiHostForwardingSettings hostDetails, string apiToForwardToHostName)
        {
            var scheme = string.IsNullOrWhiteSpace(hostDetails.Scheme) ? request.RequestUri.Scheme : hostDetails.Scheme;

            var port = GetTargetPort(hostDetails, scheme);

            var builder = new  UriBuilder(scheme, apiToForwardToHostName, port, request.RequestUri.PathAndQuery);

            return request.Clone(Uri.UnescapeDataString(builder.Uri.ToString()));
        }
        protected override HttpResponseMessage TryAuthenticate(AuthenticationHeaderValue authHeaderValue,
            HttpResponseMessage response,
            HttpRequestMessage issuedRequest)
        {
            var credentials = _getCredentials(authHeaderValue.Parameter);
            if (credentials == null)
            {
                return response;
            }

            var request = issuedRequest.Clone();
            var auth = "{0}:{1}".FormatWith(credentials.Item1, credentials.Item2).ToBase64();
            request.With().Authorization(new AuthenticationHeaderValue(Scheme, auth));

            var newResponse = new HttpClient { Channel = _channel }.Send(request);

            if (newResponse.IsSuccessStatusCode)
            {
                _cache.TryAdd(request.RequestUri, auth);
                return newResponse;
            }

            return response;
        }
		/// <summary>
		/// Send an HTTP request as an asynchronous operation.
		/// </summary>
		/// <param name="request">The HTTP request message to send.</param>
		/// <param name="cancellationToken">The cancellation token to cancel operation.</param>
		/// <returns>
		/// Returns <see cref="T:System.Threading.Tasks.Task`1" />.The task object representing the asynchronous operation.
		/// </returns>
		protected override async Task<HttpResponseMessage> SendAsync(
			HttpRequestMessage request, CancellationToken cancellationToken) {
			this.EnsureAllowableRequestUri(request.RequestUri);

			// Since we may require SSL for every redirect, we handle each redirect manually
			// in order to detect and fail if any redirect sends us to an HTTP url.
			// We COULD allow automatic redirect in the cases where HTTPS is not required,
			// but our mock request infrastructure can't do redirects on its own either.
			Uri originalRequestUri = request.RequestUri;
			int i;
			for (i = 0; i < this.MaxAutomaticRedirections; i++) {
				this.EnsureAllowableRequestUri(request.RequestUri);
				var response = await base.SendAsync(request, cancellationToken);
				if (this.AllowAutoRedirect) {
					if (response.StatusCode == HttpStatusCode.MovedPermanently || response.StatusCode == HttpStatusCode.Redirect
						|| response.StatusCode == HttpStatusCode.RedirectMethod
						|| response.StatusCode == HttpStatusCode.RedirectKeepVerb) {
						// We have no copy of the post entity stream to repeat on our manually
						// cloned HttpWebRequest, so we have to bail.
						ErrorUtilities.VerifyProtocol(
							request.Method != HttpMethod.Post, MessagingStrings.UntrustedRedirectsOnPOSTNotSupported);
						Uri redirectUri = new Uri(request.RequestUri, response.Headers.Location);
						request = request.Clone();
						request.RequestUri = redirectUri;
						continue;
					}
				}

				if (response.StatusCode == HttpStatusCode.ExpectationFailed) {
					// Some OpenID servers doesn't understand the Expect header and send 417 error back.
					// If this server just failed from that, alter the ServicePoint for this server
					// so that we don't send that header again next time (whenever that is).
					// "Expect: 100-Continue" HTTP header. (see Google Code Issue 72)
					// We don't want to blindly set all ServicePoints to not use the Expect header
					// as that would be a security hole allowing any visitor to a web site change
					// the web site's global behavior when calling that host.
					// TODO 5.0: verify that this still works in DNOA 5.0
					var servicePoint = ServicePointManager.FindServicePoint(request.RequestUri);
					Logger.Http.InfoFormat(
						"HTTP POST to {0} resulted in 417 Expectation Failed.  Changing ServicePoint to not use Expect: Continue next time.",
						request.RequestUri);
					servicePoint.Expect100Continue = false;
				}

				return response;
			}

			throw ErrorUtilities.ThrowProtocol(MessagingStrings.TooManyRedirects, originalRequestUri);
		}