• HTTP状态码206和416


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

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

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

    • 解决大文件下载问题

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

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

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

    root@iZ25n2yx37sZ:~# curl -I http://static.cnblogs.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.cnblogs.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.cnblogs.com,输入:

    telnet static.cnblogs.com 80 

    输出结果为:

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

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

    b、使用curl命令

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

    root@iZ25n2yx37sZ:~# curl -v -s  --header "Range: bytes=0-2000" http://images2015.cnblogs.com/news/24442/201608/24442-20160805112458981-1554012564.jpg -o part1
    * About to connect() to images2015.cnblogs.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.cnblogs.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.cnblogs.com left intact
    * Closing connection #0
    

    第二部分以及合并

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

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

    curl -r 0-2000 http://images2015.cnblogs.com/news/24442/201608/24442-20160805112458981-1554012564.jpg -o part1
    curl -r 2001-" http://images2015.cnblogs.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:

    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@iZ25n2yx37sZ:~$ curl -v -s  --header "Range: bytes=300000-" http://images2015.cnblogs.com/news/24442/201608/24442-20160805112458981-1554012564.jpg -o part2
    * About to connect() to images2015.cnblogs.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.cnblogs.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.cnblogs.com left intact
    * Closing connection #0

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

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

    讨论 下载地址是CDN地址,莫非CDN不支持断点续传?

    恰好相反,416正是支持断点续传的标志。服务器得到一个Range之后,需要对它的取值进行检验,包括:

    开始位置非负

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

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

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

      

    参考文章

    http://spetacular.github.io/2015/01/30/http-code-416-and-download.html
    http://www.checkupdown.com/status/E416_cn.html
    http://blog.csdn.net/zollty/article/details/9176829
    http://www.pureweber.com/article/resumable-download
    http://emacsist.github.io/2015/12/29/Http-%E5%8D%8F%E8%AE%AE%E4%B8%AD%E7%9A%84Range%E8%AF%B7%E6%B1%82%E5%A4%B4%E4%BE%8B%E5%AD%90/
    http://blog.csdn.net/zollty/article/details/9176829/

  • 相关阅读:
    CentOS6+nginx+uwsgi+mysql+django1.6.6+python2.6.6
    CentOS 6.5下安装Python+Django+Nginx+uWSGI
    python学习之旅
    Gitlab安装操作说明书
    快速上手git gitlab协同合作
    在centos6.3用yum安装redis
    CentOS 6.5 下安装 Redis 2.8.7
    Ruby Gems更换淘宝源方法
    Apache 日志分析(一)
    Apache 日志分析(二)
  • 原文地址:https://www.cnblogs.com/chenpingzhao/p/5797506.html
Copyright © 2020-2023  润新知