C# HttpClient 不处理 304/307 重定向

C# HttpClient not handling 304/307 redirects

我正在尝试让 HttpClient 从网站中提取网站图标,并且在 99% 的情况下,此代码都按预期工作:

var httpClient = new HttpClient();
httpClient.Timeout = TimeSpan.FromSeconds(10);

var response = await httpClient.GetAsync("https://www.tesco.com/favicon.ico");
response.EnsureSuccessStatusCode();

我在几个网站上发现我的 GetAsync 方法只是超时,我相信这与它的重定向有关。如果您 运行 在控制台应用程序中执行上述代码,则 10 秒后会在 TaskCanceledException 和 IOException 中抛出以下异常:

SocketException: The I/O operation has been aborted because of either a thread exit or an application request.

此请求在 Postman 上完全正常,我已经尝试过 https 和 http 但没有成功。当访问该站点并使用 Chrome 的开发工具时,如果您使用 http 而不是 https,它会 returns 一个 307 并将您重定向到 https 站点,然后 returns a 304。我不明白为什么 HttpClient 只是超时而不是给出有用的响应。

有什么方法可以让它工作吗?我错过了一些简单的东西吗?

更新 - 2021-01-29

我已经在多个不同的 .NET 版本上进行了尝试,发现这可能是 HttpClient 的错误,因为此代码适用于 .NET Core 2.0 但不适用于 .NET Core 2.1。

测试版本

事实证明这根本不是 .NET 问题。我在 GitHub 上提出了 this 问题,因为所有证据都指向 .NET Core 2.1 之后的 HttpClientHandler 中断。 Stephen 能够向我指出,在 .NET Core 2.1 之前,HttpClient 默认设置 Connection: Keep-Alive header。

我一直在测试的罪魁祸首 URL 似乎需要以下条件之一才能工作:

  • 一个Connection: Keep-Aliveheader
  • Accept: */*header,或更具体的请求内容
  • 要使用 HTTP/2 协议发送的请求。

作为参考,要应用 Header 修复之一,请使用 httpClient.DefaultRequestHeaders.Add(string, string), and to set the HTTP protocol, use httpClient.DefaultRequestVersion = HttpVersion.Version20;

这个问题原来不是 C# 的直接问题,而是在 .NET Core 2.1 之后发送的默认 headers 发生了变化。如果禁用所有 header(包括 Postman 令牌 header),我发现该问题可在 Postman 上重现。