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); }