Я реализую прозрачный серверный прокси для приложения ASP.NET MVC, которое хочет взаимодействовать с API на другом сервере;код довольно прост:
public class TransparentProxyDelegatingHandler : DelegatingHandler
{
private static readonly Uri ApiUri;
private static readonly HttpClient Client;
static TransparentProxyDelegatingHandler()
{
var apiServer = new Uri(ConfigurationManager.AppSettings["ApiUrl"]);
ApiUri = new Uri(apiServer);
Client = new HttpClient();
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
request.Headers.Add("X-Forwarded-For", request.GetClientIpAddress());
request.RequestUri = TranslateIncomingRequestToUpstreamApi(request);
request.Headers.AcceptEncoding.Clear();
var response = await Client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
return response;
}
private static Uri TranslateIncomingRequestToUpstreamApi(HttpRequestMessage request)
{
var forwardUri = new UriBuilder(request.RequestUri)
{
Host = ApiUri.Host,
Path = request.RequestUri.AbsolutePath.Replace("/Proxy", string.Empty)
};
return forwardUri.Uri;
}
}
Так что, если я запрашиваю GET https://ui.myserver.com/proxy/timesheets?from=2018-01-01
, URI запроса меняется на прокси на GET https://api.myserver.com/timesheets?from=2018-01-01
, и я могу проверить это в отладчике;однако, когда вызывается метод SendAsync
, часть имени хоста URI запроса изменяется на https://ui.myserver.com
, и вызов завершается неудачей.
Почему он изменяет значение request.RequestUri
при вызовеSendAsync
?Я проверил источник в GitHub (https://github.com/dotnet/corefx/blob/master/src/System.Net.Http/src/System/Net/Http/HttpClient.cs),, но ни одно из условий для изменения значения, кажется, не применимо в моем случае. К сожалению, источник GitHub не совпадает с символами отладки, поэтому я не могувойдите в источник HttpClient
, чтобы понять, что на самом деле происходит.