阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

HTTP状态码206和416

142次阅读
没有评论

共计 5561 个字符,预计需要花费 14 分钟才能阅读完成。

HTTP 2xx 范围内的状态码表明了:” 客户端发送的请求已经被服务器接受并且被成功处理了 ”.

TTP/1.1 200 OK 是 HTTP 请求成功后的标准响应

HTTP/1.1 206 状态码表示的是:” 客户端通过发送范围请求头 Range 抓取到了资源的部分数据 ”,一般用来

解决大文件下载问题

解决 CDN 和原始 HTTP 服务器问题

使用工具例如 lftp,wget,telnet 测试断电续传

1、如何判断远程服务器是否支持 HTTP 206

root@linuxidc:~# curl -I http://static.linuxidc.com/images/icon_form.gif
HTTP/1.1 200 OK
Server: Tengine
Content-Type: image/gif
Content-Length: 913
Connection: keep-alive
Date: Mon, 22 Aug 2016 03:30:54 GMT
Cache-Control: public,max-age=86400
Accept-Ranges: bytes
ETag: “6821606d29bce1:0”
Last-Modified: Fri, 15 Feb 2013 03:06:19 GMT
Via: cache22.l2cm9-1[0,304-0,H], cache48.l2cm9-1[0,0], kunlun9.cn3[0,200-0,H], kunlun8.cn3[0,0]
Age: 38765
X-Cache: HIT TCP_MEM_HIT dirn:11:775286164
X-Swift-SaveTime: Mon, 22 Aug 2016 03:34:29 GMT
X-Swift-CacheTime: 86400
Timing-Allow-Origin: *
EagleId: d38a7a8814718754198854631e

其中有两个我们比较关注的请求头:

Accept-Ranges: bytes – 该响应头表明服务器支持 Range 请求, 以及服务器所支持的单位是字节(这也是唯一可用的单位). 我们还能知道: 服务器支持断点续传, 以及支持同时下载文件的多个部分, 也就是说下载工具可以利用范围请求加速下载该文件.Accept-Ranges: none 响应头表示服务器不支持范围请求.

Content-Length: 913  Content-Length 响应头表明了响应实体的大小, 也就是真实的图片文件的大小是 913 字节 .

2、如何发送一个 range 请求头
现在, 你知道了该图片所在的服务器支持范围请求, 你需要发送一个包含 Range 请求头的 GET 请求:

Range: bytes=0-1024

完整的请求数据应该是这样的. 首先第一行是:

GET /images/misc/static/2012/11/ifdata-welcome-0.png HTTP/1.1

然后需要发送 Host 请求头来指定请求资源所在的主机和端口号:

Host: static.linuxidc.com

最后是要发送的 Range 请求头, 指定了你想要的字节范围:

Range: bytes=0-1024

a、使用 telnet 命令
telnet 命令允许你使用 Telnet 协议来与远程主机(服务器) 进行通信. 所有的类 Unix 操作系统以及 MS-Windows 都包含有 Telnet 客户端. 启动 Telnet 客户端并进入 Telnet 提示符, 要执行命令:

telnet your-server-name-here www
telnet your-server-name-here 80 想要通过端口号 80 连接远程服务器 static.linuxidc.com, 输入:

telnet static.linuxidc.com 80

输出结果为:

root@linuxidc:~# telnet static.linuxidc.com 80
Trying 211.138.122.237…
Connected to static.linuxidc.com.w.alikunlun.com.
Escape character is ‘^]’.
GET /images/icon_form.gif HTTP/1.1
Host: static.linuxidc.com
Range: bytes=0-1024

在本例中, 使用范围请求 (0-1024 字节) 来请求 static.linuxidc.com 上的 /images/icon_form.gif 文件

b、使用 curl 命令
curl 命令是一个和远程服务器交换数据的工具. 它支持 HTTP/FTPSFTP/FILE 协议上的范围请求, 在下例中, 使用两段范围来请求远程文件 ifdata-welcome-0.png, 然后使用 cat 命令将两段数据合并成完整文件:

root@linuxidc:~# curl -v -s  –header “Range: bytes=0-2000” http://images2015.linuxidc.com/news/24442/201608/24442-20160805112458981-1554012564.jpg -o part1
* About to connect() to images2015.linuxidc.com port 80 (#0)
*  Trying 106.2.189.18… connected
> GET /news/24442/201608/24442-20160805112458981-1554012564.jpg HTTP/1.1
> User-Agent: curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3
> Host: images2015.linuxidc.com
> Accept: */*
> Range: bytes=0-2000
>
< HTTP/1.1 206 Partial Content
< Server: marco/0.17
< Date: Mon, 22 Aug 2016 14:31:15 GMT
< Content-Type: image/jpeg
< Content-Length: 2001
< Connection: keep-alive
< X-Request-Id: ebeb021b9075223913e28033da978ce5; 6402d8710dc2ba320b03fc7663555a1d
< X-Source: U/200
< ETag: “a7efeb9fca51518501be9e16d064c366”
< Last-Modified: Fri, 05 Aug 2016 03:26:04 GMT
< Expires: Fri, 26 Aug 2016 23:05:26 GMT
< Cache-Control: max-age=656155
< Accept-Ranges: bytes
< Age: 279706
< X-Cache: MISS(S) from mix-bj-pek-106; HIT(R) from ctn-bj-pek2-027
< Content-Range: bytes 0-2000/95164
< Via: T.77102.S.1, T.088.M.1, T.088.M.2, V.cache_img_92, S.mix-bj-pek-108, V.mix-bj-pek-106, T.18922.R.1, M.ctn-bj-pek2-027
<
{[data not shown]
* Connection #0 to host images2015.linuxidc.com left intact
* Closing connection #0

第二部分以及合并

curl  –header “Range: bytes=0-2000” http://images2015.linuxidc.com/news/24442/201608/24442-20160805112458981-1554012564.jpg -o part1
curl  –header “Range: bytes=2001-” http://images2015.linuxidc.com/news/24442/201608/24442-20160805112458981-1554012564.jpg -o part2
cat part1 part2 >> test1.png

还可以使用 - r 选项(可以同时添加 - v 选项查看请求头和响应头):

curl -r 0-2000 http://images2015.linuxidc.com/news/24442/201608/24442-20160805112458981-1554012564.jpg -o part1
curl -r 2001-” http://images2015.linuxidc.com/news/24442/201608/24442-20160805112458981-1554012564.jpg -o part2
cat part1 part2 >> test1.png

3、如何开启 Accept-Ranges 响应头?
大部分 web 服务器都原生支持字节范围请求. Apache 2.x 用户可以在 httpd.conf 中尝试 mod_headers:

1 Header set Accept-Ranges bytes

Lighttpd 用户尝试在 lighttpd.conf 中进行下面的配置:

## enabled for all file types ##
server.range-requests = “enable”
## But, disable it for pdf files ##
$HTTP[“url”] =~ “\.pdf$” {
    server.range-requests = “disable”
}

4、HTTP 416 错误与断点续传
先看下 HTTP 416 错误代表什么吧?

所请求的范围无法满足 (Requested Range not satisfiable)

看了不明觉厉,因为从没遇见过。

## 探索 问了下客户端的同学,发现下载使用的是 HttpURLConnection,于是 Google 一下,得到一些关键信息:

HTTP response code: 416 是由于读取文件时设置的 Range 有误造成的,具体的说就是下面这行代码有误:
httpConnection.setRequestProperty(“RANGE”, “bytes=1024-“);
这个 RANGE 显然不能超出文件的 size 而客户端设置的 RANGE 为文件大小。

试想,文件存在远程服务器上,如何知道文件大小?

至少要发起两次请求。第一次请求,不需要下载整个文件,只需要获得 Response 的 Content-Length 大小;第二次请求,将 Content-Length 值写进 RANGE,实现下载。

root@linuxidc:~$ curl -v -s  –header “Range: bytes=300000-” http://images2015.linuxidc.com/news/24442/201608/24442-20160805112458981-1554012564.jpg -o part2
* About to connect() to images2015.linuxidc.com port 80 (#0)
*  Trying 106.2.189.18… connected
> GET /news/24442/201608/24442-20160805112458981-1554012564.jpg HTTP/1.1
> User-Agent: curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3
> Host: images2015.linuxidc.com
> Accept: */*
> Range: bytes=300000-
>
< HTTP/1.1 416 Requested Range Not Satisfiable
< Server: marco/0.17
< Date: Mon, 22 Aug 2016 14:44:03 GMT
< Content-Type: text/html; charset=utf-8
< Content-Length: 207
< Connection: keep-alive
< Cache-Control: no-store
< Content-Language: en
< Via: T.18922.R.1, M.ctn-bj-pek2-026
< X-Cache: HIT(R) from ctn-bj-pek2-026
< X-Request-Id: e6817ee753535f32b25e7651400269b7
<
{[data not shown]
* Connection #0 to host images2015.linuxidc.com left intact
* Closing connection #0

造成返回码 416 的原因,是设置的 Range 有误。解决办法也很简单,将第一次请求时的 Range 去掉。

// 删掉之后,整个世界都清净了!
conn.setRequestProperty(“Range”, “bytes=” + startPosition);// startPosition=0

讨论 下载地址是 CDN 地址,莫非 CDN 不支持断点续传?
恰好相反,416 正是支持断点续传的标志。服务器得到一个 Range 之后,需要对它的取值进行检验,包括:

开始位置非负

结束位置需要大于开始位置

开始位置需要小于文件长度减一 (因为这里的位置索引是从 0 开始的)

若结束位置大于文件长度减一,则需要把它的值设置为文件长度减一

本文永久更新链接地址:http://www.linuxidc.com/Linux/2016-08/134505.htm

正文完
星哥说事-微信公众号
post-qrcode
 
星锅
版权声明:本站原创文章,由 星锅 2022-01-21发表,共计5561字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中