俺在把博客放在Github后,除了发现Github的Web Server将Cache-Control设置为max-age=86400外,还发现一个有趣的地方。Chrome在对于MP3文件的访问,Github返回的都是206 Partial Content
,后来发现,原来Chrome在请求MP3的时候,会在请求头带上Range: bytes=0-
。
对于2xx的返回码,都是成功的,不过常见的基本都是200,206到时挺少见滴,于是俺决定看看206究竟有什么特别的地方。
rfc2616日:对于206的定义是请求必须包含Range
头来标示我们想要的范围,于是这也就说明Chrome访问MP3的时候因为加了Range
头,于是被返回了206。
我们来看一下下面的例子:用curl请求http://everet.org/2013/01/chrome-edit-with-emacs.html,返回200 OK
,其中Content-Length: 15845
。
1 | $ curl --head http://everet.org/2013/01/chrome-edit-with-emacs.html |
那根据rfc2616的说法,是不是加上Range
后,Web Server就会返回206 Partial Content
了呢?我们来通过telnet试一试:
1 | $ telnet everet.org www |
可以看到,服务器返回了100个字节的字符。为了方便测试,我们使用curl来尝试分块下载。
1 | $ curl http://everet.org/2013/01/chrome-edit-with-emacs.html -o a.html |
我们将原始页面下载回命名为a.html。然后通过增加Range
这个header来下载0-10000
为p1,以及10001-
下载剩余部分为p2。然后合并p1、p2为b.html。通过diff a.html b.html
发现a.html和b.html内容完全一样。
嗯,正如我们所想的那样,加上Range
后可以下载指定部分的内容,相应地服务器会返回206 Partial Content
。
Range范围的例子
这个例子是rfc2616里面的,首先假定entity-body长度为10000。
- 获取前500个字节 (byte offsets 0-499, inclusive): bytes=0-499
- 获取第二个500字节 (byte offsets 500-999, inclusive): bytes=500-999
- 获取最后500字节 (byte offsets 9500-9999, inclusive): bytes=-500
- 获取最后500字节 bytes=9500-
- 第一个和最后一个字节 (bytes 0 and 9999): bytes=0-0,-1
- Several legal but not canonical specifications of the second 500
bytes (byte offsets 500-999, inclusive):
bytes=500-600,601-999
bytes=500-700,601-999
总结
我们可以通过Range
和206 Partial Content
来分块获取一个大文件。在offset有效的时候,Web Server会返回206,否则会返回416 Requested Range Not Satisfiable
。