zoukankan      html  css  js  c++  java
  • HTTP Range

    Range,是在 HTTP/1.1(http://www.w3.org/Protocols/rfc2616/rfc2616.html)里新增的一个 header field,也是现在众多号称多线程下载工具(如 FlashGet、迅雷等)实现多线程下载的核心所在。

    Range 的规范定义如下:
    ranges-specifier = byte-ranges-specifier
    byte-ranges-specifier = bytes-unit “=” byte-range-set
    byte-range-set = 1#( byte-range-spec | suffix-byte-range-spec )
    byte-range-spec = first-byte-pos “-” [last-byte-pos]
    first-byte-pos = 1*DIGIT
    last-byte-pos = 1*DIGIT
    (RFC2616 里充斥着这种形式的定义,一开始觉得挺乱,后来习惯了就发现其实挺科学,挺好理解的:))

    值得注意的就是 byte-range-set 是一个 byte-range 的集合,所以在实际请求中完全可能会出现如下这种形式:
    Range: bytes=123-567,789-
    这个数据区间是个闭合区间,起始值是 0,所以“Range: bytes=0-1”这样一个请求实际上是在请求开头的 2 个字节。

    byte-range-spec 里的 last-byte-pos 可以省略,代表从 first-byte-pos 一直请求到结束位置。其实 first-byte-pos 也是可以省略的,只不过就不叫 byte-range-spec 了,而是叫 suffix-byte-range-spec,规范如下:
    suffix-byte-range-spec = “-” suffix-length
    suffix-length = 1*DIGIT
    比如“Range: bytes=-200”,它不是表示请求文件开始位置的 201 个字节,而是表示要请求文件结尾处的 200 个字节。

    如果 byte-range-spec 的 last-byte-pos 小于 first-byte-pos,那么这个 Range 请求就是无效请求,server 需要忽略这个 Range 请求,然后回应一个 200 OK,把整个文件发给 client。
    如果 byte-range-spec 里的 first-byte-pos 大于文件长度,或者 suffix-byte-range-spec 里的 suffix-length 等于 0,那么这个 Range 请求被认为是不能满足的,server 需要回应一个 416 Requested range not satisfiable。

    server 除了要能理解 Range 请求之外,在回应 client 时还要使用 Content-Range 来告诉 client 他到底发送了多少数据,Content-Range 的规范定义如下:
    Content-Range = “Content-Range” “:” content-range-spec
    content-range-spec = byte-content-range-spec
    byte-content-range-spec = bytes-unit SP byte-range-resp-spec “/” ( instance-length | “*” )
    byte-range-resp-spec = (first-byte-pos “-” last-byte-pos) | “*”
    instance-length = 1*DIGIT

    详尽的细枝末节就不在这里记述了,举个例子说明一下,比如某文件的大小是 1000 字节,client 请求这个文件时用了 “Range: bytes=0-500”,那么 server 应该把这个文件开头的 501 个字节发回给 client,同时回应头要有如下内容:
    Content-Range: bytes 0-500/1000

    Range 请求的一些注意事项:
    1) 不支持 Range 请求的 server 要用“Accept-Ranges: none”对 client 表明心意;server 也可以主动告诉 client “Accept-Ranges: bytes”,但是 client 也可以在没有收到这个指示的前提下向 server 发 Range 请求。
    2) byte-range-set 中的区间可以是“有洞”的,也可以是部分重叠的
    3) 单区间的 byte-range-set 正常回应就可以了,但是多区间 byte-range-set 需要 server 使用 multipart/byterange 来回应

    Range头域  
      Range头域可以请求实体的一个或者多个子范围。例如,  
      表示头500个字节:bytes=0-499  
      表示第二个500字节:bytes=500-999  
      表示最后500个字节:bytes=-500  
      表示500字节以后的范围:bytes=500-  
      第一个和最后一个字节:bytes=0-0,-1  
      同时指定几个范围:bytes=500-600,601-999 

  • 相关阅读:
    基于apache httpclient 调用Face++ API
    布隆过滤器(BloomFilter)持久化
    布隆过滤器
    基于firebird的数据转存
    kafka和rabbitmq对比
    python操作rabbitmq
    TCP窗口
    python操作kafka实践
    python使用etcd
    快速排序的python实现
  • 原文地址:https://www.cnblogs.com/Googler/p/1803700.html
Copyright © 2011-2022 走看看