1.断点续传——下载
其实断点续传的原理很简单,就是在Http的请求上和一般的下载有所不同而已。
以七牛文件服务器为例,使用curl命令模拟分段请求,请求时把 respons
的 header
dump 到一个文件里:
命令如下:
cd /tmp/range/
curl -D "/tmp/range/range-response-header.txt" -H 'Range: bytes=0-1198680' https://ghost.oss.sherlocky.com/0/90/73d58da3592f5ada5d5f690061145.jpg > /tmp/range/test-range.jpg
curl -D "/tmp/range/range-response-header.txt" -H 'Range: bytes=1198681-' https://ghost.oss.sherlocky.com/0/90/73d58da3592f5ada5d5f690061145.jpg >> /tmp/range/test-range.jpg
服务器返回如下:
HTTP/1.1 206 Partial Content
Date: Tue, 18 Apr 2017 11:42:35 GMT
Content-Type: image/jpeg
Content-Length: 1198681
Connection: keep-alive
Server: nginx
Accept-Ranges: bytes
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: X-Log, X-Reqid
Access-Control-Max-Age: 2592000
Cache-Control: public, max-age=31536000
Content-Disposition: inline; filename="73d58da3592f5ada5d5f690061145.jpg"
Content-Transfer-Encoding: binary
ETag: "Fiy2dGxdQOOt7ZHdswwq_9Iw9AM4"
Last-Modified: Tue, 05 Apr 2016 16:28:16 GMT
X-Log: mc.g:2;IO:76
X-Reqid: h00AADBcnB8se7YU
X-Qiniu-Zone: 0
Content-Range: bytes 0-1198680/2198680
X-Ser: BC23_dx-henan-luoyang-2-cache-8
X-Cache: MISS from BC23_dx-henan-luoyang-2-cache-8(baishan)
所谓断点续传,也就是要从文件已经下载的地方开始继续下载。所以在客户端浏览器传给 Web服务器的时候要多加一条信息--从哪里开始。
正常的下载请求:
curl -D "/tmp/range/range-response-header-all.txt" https://ghost.oss.sherlocky.com/0/90/73d58da3592f5ada5d5f690061145.jpg > /tmp/range/test-range-all.jpg
服务器返回以下信息:
HTTP/1.1 200 OK
Date: Tue, 18 Apr 2017 11:45:37 GMT
Content-Type: image/jpeg
Content-Length: 2198680
Connection: keep-alive
Server: nginx
Accept-Ranges: bytes
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: X-Log, X-Reqid
Access-Control-Max-Age: 2592000
Cache-Control: public, max-age=31536000
Content-Disposition: inline; filename="73d58da3592f5ada5d5f690061145.jpg"
Content-Transfer-Encoding: binary
ETag: "Fiy2dGxdQOOt7ZHdswwq_9Iw9AM4"
Last-Modified: Tue, 05 Apr 2016 16:28:16 GMT
X-Log: mc.g;IO
X-Reqid: mysAAE0EYl5We7YU
X-Qiniu-Zone: 0
X-Ser: BC23_dx-henan-luoyang-2-cache-8
X-Cache: MISS from BC23_dx-henan-luoyang-2-cache-8(baishan)
和前面服务器返回的信息比较一下,就会发现增加了一行:
Content-Range: bytes 0-1198680/2198680
返回的代码也改为 206
了,而不再是 200
了。
注意:如果用户的请求中含有range ,则服务器的相应代码为206。
2.断点续传——上传
请求头说明
请求头 说明
Content-Disposition
attachment, filename=“上传的文件名”
Content-Type
待上传文件的mime type,如application/octet-stream(注:不能为multipart/form-data)
X-Content-Range
待上传文件字节范围,如第一片段bytes 0-51200/511920,最后一个片段bytes 460809-511919/511920(注:文件第一个字节标号为0,最后一个字节标号为n-1,其中n为文件字节大小)
X-Session-ID
上传文件的标识,由客户端随机指定.因为是断点续传,客户端必须确保同一个文件的所有片段上传标识一致
Content-Length
上传片段的大小
3.http/1.1 Range和Content-Range
在以前版本的 HTTP 协议是不支持断点的,HTTP/1.1 开始就支持了。一般断点下载时才用到 Range
和 Content-Range
实体头。
Range
用于请求头中,指定第一个字节的位置和最后一个字节的位置,一般格式:
Range:(unit=first byte pos)-[last byte pos]
Content-Range
用于响应头,指定整个实体中的一部分的插入位置,他也指示了整个实体的长度。在服务器向客户返回一个部分响应,它必须描述响应覆盖的范围和整个实体长度。一般格式:
Content-Range:bytes (unit first byte pos)-[last byte pos]/[entity legth]
请求下载整个文件:
GET /test.rar HTTP/1.1
Connection: close
Host: 116.1.219.219
Range: bytes=0-801 //一般请求下载整个文件是 bytes=0- 或不用这个头
一般正常回应
HTTP/1.1 206 Partial Content # 返回状态码是206
Content-Length: 801
Content-Type: application/octet-stream
Content-Range: bytes 0-800/801 //801:文件总大小
假设你要开发一个多线程下载工具,你会自然的想到把文件分割成多个部分,比如4个部分,然后创建4个线程,每个线程负责下载一个部分,如果文件大小为 403个byte,那么你的分割方式可以为:0-99 (前100个字节),100-199(第二个100字节),200-299(第三个100字节),300-402(最后103个字节)。
分割完成,每个线程都明白自己的任务,比如线程3的任务是负责下载200-299这部分文件,现在的问题是:线程3发送一个什么样的请求报文,才能够保证只请求文件的200-299字节,而不会干扰其他线程的任务。这时,我们可以使用HTTP1.1的Range头。Range头域可以请求实体的一个或者多个子范围,Range的值为0表示第一个字节,也就是Range计算字节数是从0开始的:
表示头500个字节:Range: bytes=0-499
表示第二个500字节:Range: bytes=500-999
表示最后500个字节:Range: bytes=-500
表示500字节以后的范围:Range: bytes=500-
第一个和最后一个字节:Range: bytes=0-0,-1
同时指定几个范围:Range: bytes=500-600,601-999
所以,线程3发送的请求报文必须有这一行:
Range: bytes=200-299
服务器接收到线程3的请求报文,发现这是一个带有Range头的GET请求,如果一切正常,服务器的响应报文会有下面这行:
HTTP/1.1 206 OK
表示处理请求成功,响应报文还有这一行
Content-Range: bytes 200-299/403
斜杠后面的403表示文件的大小,通常Content-Range的用法为:
. The first 500 bytes:
Content-Range: bytes 0-499/1234
. The second 500 bytes:
Content-Range: bytes 500-999/1234
. All except for the first 500 bytes:
Content-Range: bytes 500-1233/1234
. The last 500 bytes:
Content-Range: bytes 734-1233/1234
评论区