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 测试了控制台应用程序。

  1. 在 VS2017 中发布
  2. 转到输出文件夹并运行 dotnet Console.dll。验证 header 是否存在于 Fiddler 中。
  3. 复制整个输出文件夹并部署到服务器
  4. 再次
  5. 运行 dotnet Console.dll 并使用 Fiddler 验证服务器上缺少 header。

HttpClientRestSharp 我都试过了,我很困惑。

转到响应请求的页面的概念证明 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"
    }
}

这让我觉得 HttpClientAccept-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 之外,否则您将获得压缩的有效负载。