Etag和斷點續傳(轉)


原文地址:http://blog.chinaunix.net/uid-20614434-id-2999833.html

 

Author:FinalBSD
Date:2008-07-08
之前講Etag的時候都只是對斷點續傳做了最簡單的說明,沒有深入研究。今天研究了一會,希望可以回答Laurence的問題,呵呵:)

1.斷點續傳概念
斷點續傳的理解可以分為兩部分:一部分是斷點,一部分是續傳。

    斷點的由來是在下載過程中,將一個下載文件分成了多個部分,同時進行多個部分一起的下載,當某個時間點,任務被暫停了,此時下載暫停的位置就是斷點了。

    續傳就更好理解些了,就是當一個未完成的下載任務再次開始時,會從上次的斷點繼續傳送。

:以上這短話來自迅雷網站的說明。

2.HTTP/1.1和斷點續傳
HTTP1.1的描述中有幾個東西可以支持斷點續傳

2.1 If-Range
If-Range是另一個起條件判斷的請求頭(我們之前講過If-Match/If-None-Match,If-Modified-Since/If-Unmodified-Since).If-Range頭用來避免客戶端在下載了某資源(比如圖片)的一部分后,下次重新下載又從頭開始下載。(這對於某些慢速網絡來說,也許一輩子也下載不了某完整文件)。使用If-Range之后,客戶端每次可以從上次下載的部分之后繼續開始下載。

If-Range的使用格式為:If-Range: Etag|Http-Date
也就是說If-Range后面可以使用Etag或者Last-Modified返回的值:

If-Range: "df6b0-b4a-3be1b5e1"
If-Range: Tue, 8 Jul 2008 05:05:56 GMT

邏輯上來講,上面2種方式分別和If-Match,If-Unmodified-Since的工作原理一樣,他們的值正是服務器返回的Etag和Last-Modified值。

2.2 Range
Range是另外一個Request Header,也就是由客戶端發給服務器的,如果沒有發送,客戶端發送的If-Range會被忽略。同樣,如果服務器端根本不支持斷點續傳,If-Range也一樣被忽略。總之,離開了Range,If-Range的存在沒有任何意義。

2.3 Accept-ranges
Accept-ranges是一個響應頭,服務器發送這個頭來告訴客戶端它支持Range(范圍)請求,后面的值,可以是bytes那么客戶端發回來的:Ranges: bytes=2400- 就表示請求2400字節到文件末尾的這些數據。

2.4 Content-Range
這是一個響應頭,說明了服務器提供的內容的字節范圍和整個資源的長度。

3.工作方式(這部分來自網絡上的文章)
下面的代碼顯示了IIS發送給客戶端的用於響應一個初始下載請求的一些頭信息,他向客戶端傳遞了被請求的文檔的周詳信息。

HTTP/1.1 200 OK
Connection: close
Date: Tue, 19 Oct 2004 15:11:23 GMT
Accept-Ranges: bytes
Last-Modified: Sun, 26 Sep 2004 15:52:45 GMT
ETag: "47febb2cfd76c41:2062"
Cache-Control: private
Content-Type: application/x-zip-compressed
Content-Length: 2844011

  在接收這些頭信息之后,假如下載被中斷了,IE瀏覽器在后來的下載請求中會把Etag值和Range頭信息發送回服務器。下面的代碼顯示了嘗試恢復被中斷下載時IE發送給服務器的一些頭信息。

GET http://192.168.100.100/download.zip HTTP/1.0
Range: bytes=822603-
Unless-Modified-Since: Sun, 26 Sep 2004 15:52:45 GMT
If-Range: "47febb2cfd76c41:2062"

  請注意,If-Range 元素包含服務器可用於標識要重新發送的文件的原始 ETag 值。您還會看到 Unless-Modified-Since 元素包含了最初下載的開始日期和時間。服務器將利用此信息來確定自最初下載開始后該文件是否已被修改過。如果已被修改,則服務器將從頭開始重新下載。這些頭信息表明IE緩存了IIS提供的實體標簽,並在If-Range頭信息中把他發送回服務器了,這是確保下載從准確相同的文檔恢復的一種途徑。不幸的是,並非任何的瀏覽器的工作方式都相同。客戶端發送的用於驗證文檔的其他HTTP頭信息可能是If-Match、If-Unmodified-Since或Unless-Modified-Since。很明顯,該規范對於客戶端軟件必須支持哪些頭信息,或必須使用哪些頭信息沒有明確的規定。因此,有些客戶端根本就沒有使用頭信息,而IE只使用If-Range和Unless-Modified-Since。您最好用代碼檢查這些信息。采用這種方式的時候,您的應用程式能夠在很高的層次遵循HTTP規范,並能夠使用多種瀏覽器。Range頭信息指明了被請求的字節范圍--在例子中他是服務器應該恢復文檔流的起始點。

  當IIS接收到恢復下載的請求類型時,他發回包含下面的頭信息的響應信息:

HTTP/1.1 206 Partial Content
Content-Range: bytes 822603-2844010/2844011
Accept-Ranges: bytes
Last-Modified: Sun, 26 Sep 2004 15:52:45 GMT
ETag: "47febb2cfd76c41:2062"
Cache-Control: private
Content-Type: application/x-zip-compressed
Content-Length: 2021408

  請注意上面的代碼和最初的下載請求的HTTP響應有點差別--恢復下載的請求是206而最初下載的請求是200。這表明通過線路傳遞進來的內容是部分文檔。這一次Content-Range頭信息指出了被傳遞字節的精確數量和位置。

  IE對於這些頭信息是很挑剔的。假如最初的響應沒有包含Etag頭信息,IE永遠不會嘗試恢復下載。我測試過的其他客戶端不使用ETag頭信息,他們簡單得依賴於文檔名、請求范圍,並使用Last-Modified頭信息(假如他們試圖驗證該文檔)。

圖片引用:(感謝i_amok :) )
resume-download.png

range2.png
range1.png

深入了解HTTP協議  

前面的部分中顯示的頭信息對於使恢復下載的解決方案運行來說是足夠的,但是他沒有完全覆蓋HTTP規范。  在單個請求中,Range頭信息能夠詢問多個范圍,這種特性稱為"多部分范圍(multipart ranges)"。請不要和分段下載(segmented downloading)混淆,幾乎任何的下載工具都使用分段下載來提高下載速度。這些工具聲稱通過打開兩個或多個並發的連接(每個連接請求文檔的不同范圍)提高了下載速度。  多部分范圍的想法並沒有開啟多個連接,但是他能夠使客戶端軟件能夠在單個請求/響應周期中請求某個文檔的最前面的十個和最后面的十個字節。

  誠實地說,我從來都沒有找到使用這種特性軟件片斷。但是我拒絕在代碼聲明中寫入"他並不是完全的HTTP兼容的"。略去這個特性必定會觸犯墨菲法則(Murphy's Law)。無論如何,多部分范圍還是被用於電子郵件傳輸中,把頭信息、普通文本和附件分開。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM