502无法解析服务器标头_编写下载服务器。 第三部分:标头:内容长度和范围...

502无法解析服务器标头

这次,我们将探索更多HTTP请求和响应标头,以改善下载服务器的实现: Content-lengthRange 。 前者表示下载量很大,后者允许部分下载文件,或者从我们开始的地方失败后继续下载。

Content-length响应标头对于跟踪下载进度的客户端非常有用。 如果在甚至开始流传输字节之前就提前发送了预期的资源大小,则Web浏览器之类的客户端可以显示非常准确的进度条,甚至可以通过测量平均下载速度来估计总下载时间。 如果没有Content-length客户端,则客户端将仅保持尽可能长的下载时间,希望流结束一天。 但是,在某些情况下很难获得准确的内容长度。 例如,也许您从其他下载服务器流式传输资源,或者您的资源被即时压缩并直接发送到Servlet响应。 在这两种情况下,您能做的最好的事情就是实际上在磁盘上本地缓存数据,弄清楚大小是多少,并在数据可用时开始流式传输。 这与始终流式传输,永远不要完全保留在内存中的建议并不矛盾。 在这种情况下,我们将临时文件存储在磁盘上,但是在完全准备好并且知道其大小后仍将流式传输。

从Java的角度来看,提供内容长度非常简单:

private ResponseEntity<Resource> response(FilePointer filePointer, HttpStatus status, Resource body) {
    return ResponseEntity
            .status(status)
            .eTag(filePointer.getEtag())
            .contentLength(filePointer.getSize())
            .lastModified(filePointer.getLastModified().toEpochMilli())
            .body(body);
}

请注意,还存在一个Resource.contentLength()方法,但是不同类型的资源对它的计算方式有所不同,有时会急于读取整个资源。 我有自己的FilePointer抽象,知道我们要下载的文件大小。

Range标头是RFC 7233中很好描述的HTTP / 1.1的“新”功能。 这个想法是客户端可以仅请求一部分资源(就字节范围而言),主要有两个原因:

  • 先前的下载已中断,我们不想重复相同的工作。 在这种情况下,客户端知道收到了多少字节并要求剩余部分
  • 我们正在流式传输数据(例如视频),我们想跳过某些部分。 考虑一下像Youtube这样的在线播放器,然后单击进度条中间的。 客户可以简单地估计它现在需要文件的哪一部分,与电影持续时间成比例。

并非所有服务器都需要实现Range请求,因此需要进行一些协商。 第一个客户端发送一个请求,仅请求文件的一部分,在此示例中为前100个字节:

> GET /big_buck_bunny_1080p_surround.avi HTTP/1.1
> Range: bytes=0-99
...

如果目标服务器支持范围请求,则响应206 Partial Content

< HTTP/1.1 206 Partial Content
< Last-Modified: Tue, 06 May 2008 11:21:35 GMT
< ETag: "8000089-375a6422-44c8e0d0f0dc0"
< Accept-Ranges: bytes
< Content-Length: 100
< Content-Range: bytes 0-99/928670754

这里有很多有趣的标题。 首先是206,而不是通常的200 OK。 如果为200 OK,则客户端必须假定服务器不支持范围请求。 示例服务器的运行情况非常好,它还会向我们发送Last-ModifiedETag标头,以改善缓存。 此外,服务器通过发送Accept-Ranges标头确认其能够处理Range请求。 当前仅广泛使用bytes ,但是RFC将来允许其他范围单位(秒?帧?),最后两个标头是最有趣的。 Content-Length不再声明资源的总大小,而是我们请求的范围的大小,在这种情况下为100字节。 完整资源的大小以Content-Range编码: bytes 0-99/928670754 。 就我们收到的内容而言,服务器非常精确:前100个字节( 0-99 ),而总资源大小为928670754 。 知道客户端的总大小后,基本上可以请求多个文件中的文件部分。

Range请求的规范具有很大的灵活性,例如,我们可以在一个请求中请求多个范围,例如:

> GET /big_buck_bunny_1080p_surround.avi HTTP/1.1
> Range: bytes=0-9,1000-1009
...
< HTTP/1.1 206 Partial Content
< Accept-Ranges: bytes
< Content-Type: multipart/byteranges; boundary=5187ab27335732
<
 
--5187ab27335732
Content-type: video/x-msvideo
Content-range: bytes 0-9/928670754
 
[data]
--5187ab27335732
Content-type: video/x-msvideo
Content-range: bytes 1000-1009/928670754
 
[data]
--5187ab27335732--

但是,服务器可以自由地优化多个范围请求,例如重新布置它们,合并等。从头开始实现部分请求超出了本文的范围,我希望您不必自己做。 例如,从4.2.x开始的Spring对静态资源的部分请求具有全面的内置支持,请参阅: ResourceHttpRequestHandler第463行

编写下载服务器

翻译自: https://www.javacodegeeks.com/2015/07/writing-a-download-server-part-iii-headers-content-length-and-range.html

502无法解析服务器标头

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值