从WebAPI调用时,HttpClient更改请求URI

问题描述 投票:1回答:1

我正在为一个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源代码来弄清楚究竟发生了什么。

c# asp.net-web-api dotnet-httpclient
1个回答
1
投票

好的,我找到了问题的原因;我需要设置更改主机头;对代理的初始请求将其设置为UI的主机名(ui.myserver.com),并覆盖在请求中设置的代理的主机名。所以,如果我添加以下内容:

request.Headers.Host = $"{ApiUri.Host}:{ApiUri.Port}";

然后一切都神奇地起作用。

© www.soinside.com 2019 - 2024. All rights reserved.