带有请求标头“范围”的 .NET HttpClient 不起作用
Posted
技术标签:
【中文标题】带有请求标头“范围”的 .NET HttpClient 不起作用【英文标题】:.NET HttpClient with request header "Range" is not working 【发布时间】:2021-12-12 18:05:55 【问题描述】:使用这个curl
命令:
> curl --range 0-999 -I https://us.download.nvidia.com/Windows/497.09/497.09-desktop-win10-win11-64bit-international-dch-whql.exe
响应正确返回为:
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
时,它似乎因范围请求标头而失败:
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
响应返回为:
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
标头与HttpClient
请求一起使用?我想知道这是一个错误还是什么?
参考:HttpRequestHeaders.Range Property
【问题讨论】:
req.Headers.Add("Range", "bytes");
效果更好吗?
@LajosArpad 那么我将如何指定范围数字呢?
您的代码无法编译,一旦修复,就不会产生您发布的响应。它实际上返回Content-Length: 1000
。看起来您混合了多个请求和响应并打印了错误的响应。不要急于假设每个 .NET Core 开发人员使用的东西都坏了。创建一个新的空项目并添加重现错误所需的minimal 代码。如果不能,则问题出在您的其余代码中
PS:不要使用GetAwaiter().GetResult()
。请改用async/await
。您可以在 Main 方法中使用 async Task Main(string[] args)
,因此很少有任何理由阻止
@PanagiotisKanavos 当控制台应用程序的Main
变为async
时,它只是在到达await
行时返回到控制台提示符。我只是不喜欢这种行为,因为它似乎超出了我的控制范围,所以来了好老的GetAwaiter
。
【参考方案1】:
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\nresp" );
使用响应输出:
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()
。所以,看起来你实际上是在打印一些其他的响应。
【讨论】:
以上是关于带有请求标头“范围”的 .NET HttpClient 不起作用的主要内容,如果未能解决你的问题,请参考以下文章