HttpClient 未在 Windows 2008 R2 上发送 Accept-Encoding
HttpClient not sending Accept-Encoding on Windows 2008 R2
我有一个执行 GET 请求的 .NET Core 2.0 控制台应用程序。
似乎已发布的版本不会发送 Accept-Encoding
header 用于测试机器上的压缩,但在我的本地机器上可以。
我找不到任何其他 pre-requesites 会使压缩失败。两者都 运行 .NET Core 2.1.4 SDK。
我已经在两种环境中通过 运行ning dotnet Console.dll
测试了控制台应用程序。
- 在 VS2017 中发布
- 转到输出文件夹并运行
dotnet Console.dll
。验证 header 是否存在于 Fiddler 中。
- 复制整个输出文件夹并部署到服务器
再次 - 运行
dotnet Console.dll
并使用 Fiddler 验证服务器上缺少 header。
HttpClient
和 RestSharp
我都试过了,我很困惑。
转到响应请求的页面的概念证明 headers:
var handler = new HttpClientHandler()
{
AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip
};
using (var client = new HttpClient(handler))
{
response = client.GetStringAsync("http://scooterlabs.com/echo").Result;
}
本地环境(Win10)
GET http://scooterlabs.com/echo HTTP/1.1
Connection: Keep-Alive
Accept-Encoding: gzip, deflate
Host: scooterlabs.com
服务器(AWS 上的 Win2008 R2)
GET http://scooterlabs.com/echo HTTP/1.1
Connection: Keep-Alive
Host: scooterlabs.com
不是答案,尽管我尝试在 Azure 的 Win Server 2008 R2 上使用不同的 Echo 服务器 (.NET Core SDK 2.1.4) 重现此问题
// http://scooterlabs.com/echo output
[headers] => Array
(
[Connection] => Keep-Alive
[Host] => scooterlabs.com
)
// http://httpbin.org/headers output
{
"headers": {
"Connection": "close",
"Host": "httpbin.org"
}
}
// https://postman-echo.com/headers output
{
"headers": {
"host": "postman-echo.com",
"x-forwarded-port": "443",
"x-forwarded-proto": "https"
}
}
在 Win10 上我确实也有那些 header。
// http://scooterlabs.com/echo output
[headers] => Array
(
[Connection] => Keep-Alive
[Accept-Encoding] => gzip, deflate
[Host] => scooterlabs.com
)
// http://httpbin.org/headers output
{
"headers": {
"Accept-Encoding": "gzip, deflate",
"Connection": "close",
"Host": "httpbin.org"
}
}
// https://postman-echo.com/headers output
{
"headers": {
"host": "postman-echo.com",
"accept-encoding": "gzip, deflate",
"x-forwarded-port": "443",
"x-forwarded-proto": "https"
}
}
这让我觉得 HttpClient
的 Accept-Encoding
header 在 WS 2008 R2 上确实不受支持。
我最好的猜测是因为 WinHttp 库,HttpClient 默认使用 windows does not support gzip\deflate windows 之前的 Windows 版本] 8.1+。支持时 - WinHttp 还将设置 Accept-Encoding header。因此,在 Windows Server 2008 上,当 .NET 通过 WinHttp 路由请求时 - 它要么设置此选项并忽略它,要么检查是否支持此选项,如果不支持 - 则不设置它。
如果您手动设置此 header(如 client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
)- 选项仍然被忽略,但 header 通过并且服务器 returns 压缩响应。如果支持 - WinHttp 将解压缩该响应并删除 Content-Encoding header,因此响应将解压缩为 .NET。如果不支持 - 如果您设置 AutomaticDecompression
.
,响应将以压缩形式到达,.NET 本身将解压缩它
总而言之 - 在 8.1 之前的 Windows 版本上,您似乎需要设置 AutomaticDecompression
和相关的 Accept-Encoding
header 才能按预期工作。
根据 Ivan 和 Evk 的回答,这似乎是旧版本 Windows(早于 Win8.1)的特定问题。以下是如何解决并成功处理旧版本 Windows.
上的压缩
var handler = new HttpClientHandler()
{
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
};
using (var client = new HttpClient(handler))
{
client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate"));
response = client.GetStringAsync("http://scooterlabs.com/echo").Result;
}
AutomaticDecompression
必须 除了 headers 之外,否则您将获得压缩的有效负载。
我有一个执行 GET 请求的 .NET Core 2.0 控制台应用程序。
似乎已发布的版本不会发送 Accept-Encoding
header 用于测试机器上的压缩,但在我的本地机器上可以。
我找不到任何其他 pre-requesites 会使压缩失败。两者都 运行 .NET Core 2.1.4 SDK。
我已经在两种环境中通过 运行ning dotnet Console.dll
测试了控制台应用程序。
- 在 VS2017 中发布
- 转到输出文件夹并运行
dotnet Console.dll
。验证 header 是否存在于 Fiddler 中。 - 复制整个输出文件夹并部署到服务器 再次
- 运行
dotnet Console.dll
并使用 Fiddler 验证服务器上缺少 header。
HttpClient
和 RestSharp
我都试过了,我很困惑。
转到响应请求的页面的概念证明 headers:
var handler = new HttpClientHandler()
{
AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip
};
using (var client = new HttpClient(handler))
{
response = client.GetStringAsync("http://scooterlabs.com/echo").Result;
}
本地环境(Win10)
GET http://scooterlabs.com/echo HTTP/1.1
Connection: Keep-Alive
Accept-Encoding: gzip, deflate
Host: scooterlabs.com
服务器(AWS 上的 Win2008 R2)
GET http://scooterlabs.com/echo HTTP/1.1
Connection: Keep-Alive
Host: scooterlabs.com
不是答案,尽管我尝试在 Azure 的 Win Server 2008 R2 上使用不同的 Echo 服务器 (.NET Core SDK 2.1.4) 重现此问题
// http://scooterlabs.com/echo output
[headers] => Array
(
[Connection] => Keep-Alive
[Host] => scooterlabs.com
)
// http://httpbin.org/headers output
{
"headers": {
"Connection": "close",
"Host": "httpbin.org"
}
}
// https://postman-echo.com/headers output
{
"headers": {
"host": "postman-echo.com",
"x-forwarded-port": "443",
"x-forwarded-proto": "https"
}
}
在 Win10 上我确实也有那些 header。
// http://scooterlabs.com/echo output
[headers] => Array
(
[Connection] => Keep-Alive
[Accept-Encoding] => gzip, deflate
[Host] => scooterlabs.com
)
// http://httpbin.org/headers output
{
"headers": {
"Accept-Encoding": "gzip, deflate",
"Connection": "close",
"Host": "httpbin.org"
}
}
// https://postman-echo.com/headers output
{
"headers": {
"host": "postman-echo.com",
"accept-encoding": "gzip, deflate",
"x-forwarded-port": "443",
"x-forwarded-proto": "https"
}
}
这让我觉得 HttpClient
的 Accept-Encoding
header 在 WS 2008 R2 上确实不受支持。
我最好的猜测是因为 WinHttp 库,HttpClient 默认使用 windows does not support gzip\deflate windows 之前的 Windows 版本] 8.1+。支持时 - WinHttp 还将设置 Accept-Encoding header。因此,在 Windows Server 2008 上,当 .NET 通过 WinHttp 路由请求时 - 它要么设置此选项并忽略它,要么检查是否支持此选项,如果不支持 - 则不设置它。
如果您手动设置此 header(如 client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
)- 选项仍然被忽略,但 header 通过并且服务器 returns 压缩响应。如果支持 - WinHttp 将解压缩该响应并删除 Content-Encoding header,因此响应将解压缩为 .NET。如果不支持 - 如果您设置 AutomaticDecompression
.
总而言之 - 在 8.1 之前的 Windows 版本上,您似乎需要设置 AutomaticDecompression
和相关的 Accept-Encoding
header 才能按预期工作。
根据 Ivan 和 Evk 的回答,这似乎是旧版本 Windows(早于 Win8.1)的特定问题。以下是如何解决并成功处理旧版本 Windows.
上的压缩 var handler = new HttpClientHandler()
{
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
};
using (var client = new HttpClient(handler))
{
client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
client.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate"));
response = client.GetStringAsync("http://scooterlabs.com/echo").Result;
}
AutomaticDecompression
必须 除了 headers 之外,否则您将获得压缩的有效负载。