我正在使用HttpWebRequest和AddRange函数,如:
HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(URL);
myHttpWebRequest.AddRange(20, 30);
HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
Stream streamResponse = myHttpWebResponse.GetResponseStream();
SaveFileStream(name, streamResponse); //save file function
...但是整个文件已经下载了。
上面代码中的AddRange()需要下载20到30之间的字节(换句话说,从文件中下载这10个字节)。
但我的代码无效,因为下载没有分段。此链接提供了一个示例:http://stackoverflow.com/robots.txt该文件已完整下载。为什么呢?
答案 0 :(得分:0)
HTTP服务器不需要支持Range
标头请求。您可以通过发出HEAD请求并检查Accept-Ranges
标头的值来验证服务器的范围支持(请参阅HTTP range requests)。但是这仍然不能保证服务器不会忽略Range
标头,特别是对于非常小的范围(HTTP服务器在这么小的段中提供内容效率非常低)。
来自RFC7233:
因为服务器可以自由地忽略Range,所以很多实现都会 只需用200(OK)中的整个选定表示进行响应 响应。这部分是因为大多数客户都准备接收 200(OK)完成任务(尽管效率较低)和部分任务 因为客户可能不会停止发出无效的部分请求,直到 他们收到了完整的陈述。因此,客户不能 取决于接收416(范围不满足)响应,即使 这是最合适的。
要确定服务器是接受还是忽略Range
标头,您必须检查响应状态代码。 200 (OK)
表示服务器忽略Range
标头并返回整个响应正文,206 (Partial Content)
表示服务器返回标头中指定的范围,416 (Range Not Satisfiable)
表示请求的范围集已经因无效范围或过小的或重叠范围请求而被拒绝。
如果是http://stackoverflow.com/robots.txt,则服务器会在Range
请求的响应中返回Accept-Ranges: bytes
标头,但在使用AddRange的HEAD
请求时,表示支持GET
标头(20,30)指定,响应是200 (OK)
,所以服务器只是忽略了这样一个小范围的返回整个响应体。如果需要,您必须自己从响应中减少请求的范围。