http协议-- Range、If-Range

来源:互联网 发布:金蝶软件广州分公司 编辑:程序博客网 时间:2024/05/16 08:06

转载,请注明出处!

原文地址:http://www.greenbytes.de/tech/webdav/draft-ietf-httpbis-p5-range-latest.html

一、 byte ranges

        因为HTTP entity是以字节流的形式传递,所以byte-range这个概念对一些HTTP实体就很有意义。额外提一句,并非所有的客户/服务器都需要支持byte-range操作。
Byte-range适用于entity-body部分的字节流。
        一个byte range操作可以只操作一个range, 也可已操作属于同一entity的多个range。

ranges-specifier = byte-ranges-specifierbyte-ranges-specifier = bytes-unit "=" byte-range-setbyte-range-set = 1#( byte-range-spec | suffix-byte-range-spec )byte-range-spec = first-byte-pos "-" [last-byte-pos]first-byte-pos = 1*DIGITlast-byte-pos = 1*DIGIT

        byte-range-spec定义了range包含的字节。其中,first-byte-pos是range第一个字节的偏移量,last-byte-pos是range最后一个字节的偏移量。偏移量从0开始计数。

        last-byte-pos是可选的,可以存在,也可以不存在。last-byte-pos如果存在,那么必须大于或者等于first-byte-pos。否则,byte-range-spec是非法的。非法的bye-range-spec会被忽略,相当于不存在。如果last-byte-pos不存在或者last-byte-pos大于等于entity-body的长度,那么last-byte-pos会被作为entity-body长度-1。
在不知道entity-body的长度的情况下,客户端可以通过设置last-byte-pos字段来限制自己接收的字节数量。

suffix-byte-range-spec = "-" suffix-lengthsuffix-length = 1*DIGIT
        suffix-byte-range-spec将entity-body结尾的字符定义成一个range。也就是说entity-body结尾倒数suffix-length个字节作为一个range。如果suffix-length大于entity-body的长度,那么整个entity-body作为一个range。

        假设entity-body有10000个字节。如下是一些例子。

entity-body头500个字节作为一个range:bytes=0-499entity-body次500个字节作为一个range:bytes=500-999entity-body倒数500个字节作为一个range: bytes=-500 或者 bytes= 9500-entity-body第一个字节和最后一个字节作为一个range:bytes=0-0,-1entity-body次500个字节作为一个range,非标准但合法的写法:bytes=500-600,601-999或者bytes=500-700,601-999

二、 range Retrieval Requests

        只要请求报文包含Range首部行,那么就可以获得range数据。

Range = "Range" ":" ranges-specifier

        服务器可能会忽略Range首部行。因为Range首部行可以用于实现断点续传以及多线程并行下载功能,所以HTTP/1.1 源服务器和代理服务器应该尽可能支持Range首部行。
        如果服务器支持Range首部行且目标range也存在,那么GET方法的应答报文包含206状态码和Range首部行。如果条件GET方法的条件为假,那么应答报文的状态码仍然为304。

三、 If-Range首部行

        假设如下场景:客户端缓存了entity的一部份,现在希望把该部分所属的整个entity一起缓存下来。使用携带Range首部行的条件GET方法来完成这件事,使用If-Unmodified-Since或者If-Match首部行来定义条件。如果条件失败了,也就是entity内容发生了变化,那么客户端只能再重新发请求把整个entity下载下来。
        如果使用If-Range首部行定义条件,那么不需要发第二次请求也可已把整个entity下载下来。If-Range的意思是:“如果entity没有发生变化,那么把我缺失的部分发送给我。如果entity发生了变化,那么把整个entity发送给我”。
If-Range = "If-Range" ":" ( entity-tag | HTTP-date )
        如果客户端没有ETage却有Last-modified,那么也可以把last-modified作为If-Range字段的值。If-Range首部行必须与Range首部行配套使用。如果请求报文中没有Range首部行,那么If-Range首部行就会被忽略。如果服务器不支持If-Range,那么Range首部行也会被忽略。
        如果请求报文中的Etag与服务器目标内容的Etag相等,即没有发生变化,那么应答报文的状态码为206。如果服务器目标内容发生了变化,那么应答报文的状态码为200。
原创粉丝点击