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  
 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章