大文件传输
Last updated
Last updated
数据压缩:默认开启,通常是保底的。详见内容协商
request Accept-Encoding
header
response Content-Encoding
header
分块传输:response 化整为零
范围请求:request 化整为零。可以仅一个范围,也可以多个范围
以上四种方式不是互斥的,可以混合起来使用。
一个 response 报文的 body 总长度,要么已知 Content-Length
,要么未知 chunked
。
分块传输时 body 的编码规则:length 和 chunked data,如下:
每个 chunk 包含两个部分:length 是 16 进制的数字,data 紧跟在 length 之后,最后也以 CRLF 结尾,但数据不包含 CRLF。
最后用一个 length 为 0 的 chunk 表示结束,即 0\r\n\r\n
。其中,第一个 \r\n
表示 CRLF(回车换行),第二个 \r\n
表示正常 HTTP 报文中 header 和 body 的分隔空行。
需要说明的是,浏览器在收到分块传输的数据后,会自动按照规则去掉分块编码,重新组装好内容。若想看 server 发出的分块的原始报文形态,要用 Wireshark 抓包,或用 Telnet 手工发送请求。
范围请求,range request,可以只获取部分数据,从而实现视频拖拽、断点续传、多段下载等。可以一次只请求一个范围,也可以一次请求“多个”范围。
范围请求,允许客户端在请求 header 里使用专用字段 Range
来表示只想获取文件的一部分。
Range: bytes=x-y
206 Partial Content
Content-Range: bytes x-y/length
Range: bytes=x-y, x1-y1
Content-Type: multipart/byteranges; boundary=xx
Range
格式是 bytes=x-y
,其中 x 和 y 是以字节为单位的数据偏移量,且都可以省略。
在服务器收到 Range 字段后:
检查范围是否合法。若越界了,会返回状态码 416
如果范围正确,便根据 Range 计算偏移量,读取文件的片段
206 Partial Content
状态码
Content-Range
header 告诉片段的实际偏移量和资源总大小,格式是 bytes x-y/length
发送数据,把片段用 TCP 发给客户端
MIME 类型 multipart/byteranges
,表示报文的 body 是由多段字节序列组成的
参数 boundary
给出段之间的分隔标记
多段数据的格式,如下:
每个分段必须以 --boundary
开始
之后用 Content-Type
和 Content-Range
标记这段数据的类型和所在范围
最后用一个 --boundary--
表示所有的分段结束
这时响应报文的 body 里的多个部分会用 boundary
字符串 00000000001
分隔。