请求 header "Range" 的 .NET HttpClient 不工作

.NET HttpClient with request header "Range" is not working

使用此 curl 命令:

> curl --range 0-999 -I https://us.download.nvidia.com/Windows/497.09/497.09-desktop-win10-win11-64bit-international-dch-whql.exe

正确响应returns为:

HTTP/1.1 206 Partial Content
Accept-Ranges: bytes
Cache-Control: max-age=86400
Content-Range: bytes 0-999/870849168
Content-Type: application/octet-stream
Date: Sun, 12 Dec 2021 17:38:31 GMT
Etag: "1774295931"
Last-Modified: Wed, 01 Dec 2021 12:42:07 GMT
Content-Length: 1000

使用 .NET HttpClient 时,它似乎因范围请求 header:

而失败
var url = "https://us.download.nvidia.com/Windows/497.09/497.09-desktop-win10-win11-64bit-international-dch-whql.exe";

var req = new HttpRequestMessage();
req.Method = HttpMethod.Get;
req.RequestUri = new Uri(url);
// req.Headers.Range = new RangeHeaderValue(0, 999);  // not working
req.Headers.Add("Range", "bytes=0-999");  // not working
WriteLine(req.ToString() );

var client2 = new HttpClient();
var respTask2 = client2.SendAsync(req, HttpCompletionOption.ResponseHeadersRead);
var resp2 = respTask2.GetAwaiter().GetResult();
WriteLine(resp.ToString() );

HttpClient 响应 returns 为:

Method: GET, RequestUri: 'https://us.download.nvidia.com/Windows/497.09/497.09-desktop-win10-win11-64bit-international-dch-whql.exe', Version: 1.1, Content: <null>, Headers:
{
  Range: bytes=0-999
}
StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.HttpConnectionResponseContent, Headers:
{
  Accept-Ranges: bytes
  Date: Sun, 12 Dec 2021 17:44:07 GMT
  ETag: "1774295931"
  Content-Type: application/octet-stream
  Last-Modified: Wed, 01 Dec 2021 12:42:07 GMT
  Content-Length: 870849168
}

如何使用 Range header 和 HttpClient 请求?请问这是bug还是什么?

参考:HttpRequestHeaders.Range Property

RangeHeaderValue 似乎在 net5.0 下按预期工作:

var url = "https://us.download.nvidia.com/Windows/497.09/497.09-desktop-win10-win11-64bit-international-dch-whql.exe";
var client = new HttpClient();
var req = new HttpRequestMessage { RequestUri = new Uri( url ) };
req.Headers.Range = new RangeHeaderValue( 0, 999 );

var resp = await client.SendAsync( req );

Console.WriteLine( $"\r\nResponse:\r\n{resp}" );

响应输出:

StatusCode: 206, ReasonPhrase: 'Partial Content', Version: 1.1, Content: System.Net.Http.HttpConnectionResponseContent, Headers:
{
  Accept-Ranges: bytes
  Age: 18147
  Cache-Control: max-age=86400
  Date: Sun, 12 Dec 2021 18:25:42 GMT
  ETag: "1774295931"
  Server: ECAcc
  Server: (daa/7CFD)
  X-Cache: HIT
  x-vdms-version: 117
  Content-Range: bytes 0-999/870849168
  Content-Type: application/octet-stream
  Expires: Mon, 13 Dec 2021 18:25:42 GMT
  Last-Modified: Wed, 01 Dec 2021 12:42:07 GMT
  Content-Length: 1000
}

进一步检查您发布的代码后:

var resp2 = respTask2.GetAwaiter().GetResult();
WriteLine(resp.ToString() );

请注意 WriteLine 适用于 resp.ToString(),但应该使用 resp2.ToString()。所以,看起来您实际上是在打印出一些其他响应。