HTTP 斷點續傳(分塊傳輸)

2021-10-03 06:04:26 字數 3616 閱讀 2559

在 linux/unix 系統下,常用支援斷點續傳的 ftp 客戶端軟體是 lftp。

range

用於請求頭中,指定第乙個位元組的位置和最後乙個位元組的位置,一般格式:

range:(unit=first byte pos)-[last byte pos]

range 頭部的格式有以下幾種情況:

range: bytes=0-499 表示第 0-499 位元組範圍的內容

range: bytes=500-999 表示第 500-999 位元組範圍的內容

range: bytes=-500 表示最後 500 位元組的內容

range: bytes=500- 表示從第 500 位元組開始到檔案結束部分的內容

range: bytes=0-0,-1 表示第乙個和最後乙個位元組

range: bytes=500-600,601-999 同時指定幾個範圍

content-range

用於響應頭中,在發出帶 range 的請求後,伺服器會在 content-range 頭部返回當前接受的範圍和檔案總大小。一般格式:

content-range: bytes (unit first byte pos) - [last byte pos]/[entity legth]

例如:content-range: bytes 0-499/22400

0-499 是指當前傳送的資料的範圍,而 22400 則是檔案的總大小。

而在響應完成後,返回的響應頭內容也不同:

http/1.1 200 ok(不使用斷點續傳方式)

http/1.1 206 partial content(使用斷點續傳方式)

增強校驗

在實際場景中,會出現一種情況,即在終端發起續傳請求時,url 對應的檔案內容在伺服器端已經發生變化,此時續傳的資料肯定是錯誤的。如何解決這個問題了?顯然此時需要有乙個標識檔案唯一性的方法。

在 rfc2616 中也有相應的定義,比如實現 last-modified 來標識檔案的最後修改時間,這樣即可判斷出續傳檔案時是否已經發生過改動。同時 fc2616 中還定義有乙個 etag 的頭,可以使用 etag 頭來放置檔案的唯一標識。

last-modified

if-modified-since,和 last-modified 一樣都是用於記錄頁面最後修改時間的 http 頭資訊,只是 last-modified 是由伺服器往客戶端傳送的 http 頭,而 if-modified-since 則是由客戶端往伺服器傳送的頭,可以看到,再次請求本地存在的 cache 頁面時,客戶端會通過 if-modified-since 頭將先前伺服器端發過來的 last-modified 最後修改時間戳傳送回去,這是為了讓伺服器端進行驗證,通過這個時間戳判斷客戶端的頁面是否是最新的,如果不是最新的,則返回新的內容,如果是最新的,則返回 304 告訴客戶端其本地 cache 的頁面是最新的,於是客戶端就可以直接從本地載入頁面了,這樣在網路上傳輸的資料就會大大減少,同時也減輕了伺服器的負擔。

etag

etag(entity tags)主要為了解決 last-modified 無法解決的一些問題。

一些檔案也許會週期性的更改,但是內容並不改變(僅改變修改時間),這時候我們並不希望客戶端認為這個檔案被修改了,而重新 get。

某些檔案修改非常頻繁,例如:在秒以下的時間內進行修改(1s 內修改了 n 次),if-modified-since 能檢查到的粒度是 s 級的,這種修改無法判斷(或者說 unix 記錄 mtime 只能精確到秒)。

某些伺服器不能精確的得到檔案的最後修改時間。

為此,http/1.1 引入了 etag。etag 僅僅是乙個和檔案相關的標記,可以是乙個版本標記,例如:v1.0.0;或者說 「627-4d648041f6b80」 這麼一串看起來很神秘的編碼。但是 http/1.1 標準並沒有規定 etag 的內容是什麼或者說要怎麼實現,唯一規定的是 etag 需要放在 「」 內。

if-range

用於判斷實體是否發生改變,如果實體未改變,伺服器傳送客戶端丟失的部分,否則傳送整個實體。一般格式:

也就是說,if-range 可以使用 etag 或者 last-modified 返回的值。當沒有 etage 卻有 last-modified 時,可以把 last-modified 作為 if-range 欄位的值。

例如:if-range: 「627-4d648041f6b80」

if-range: fri, 22 feb 2013 03:45:02 gmt

if-range 必須與 range 配套使用。如果請求報文中沒有 range,那麼 if-range 就會被忽略。如果伺服器不支援 if-range,那麼 range 也會被忽略。

如果請求報文中的 etag 與伺服器目標內容的 etag 相等,即沒有發生變化,那麼應答報文的狀態碼為 206。如果伺服器目標內容發生了變化,那麼應答報文的狀態碼為 200。

用於校驗的其他 http 頭資訊:if-match/if-none-match、if-modified-since/if-unmodified-since。

工作原理

etag 由伺服器端生成,客戶端通過 if-range 條件判斷請求來驗證資源是否修改。請求乙個檔案的流程如下:

第一次請求:

客戶端發起 http get 請求乙個檔案。

伺服器處理請求,返回檔案內容以及相應的 header,其中包括 etag(例如:627-4d648041f6b80)(假設伺服器支援 etag 生成並已開啟了 etag)狀態碼為 200。

第二次請求(斷點續傳):

客戶端發起 http get 請求乙個檔案,同時傳送 if-range(該頭的內容就是第一次請求時伺服器返回的 etag:627-4d648041f6b80)。

伺服器判斷接收到的 etag 和計算出來的 etag 是否匹配,如果匹配,那麼響應的狀態碼為 206;否則,狀態碼為 200。

檢測伺服器是否支援斷點續傳

curl 實現檢測:

HTTP斷點續傳(分塊傳輸)

檢測伺服器是否支援斷點續傳 在 linux unix 系統下,常用支援斷點續傳的 ftp 客戶端軟體是 lftp。range 用於請求頭中,指定第乙個位元組的位置和最後乙個位元組的位置,一般格式 range unit first byte pos last byte pos range 頭部的格式有...

HTTP斷點續傳(分塊傳輸)

檢測伺服器是否支援斷點續傳 在 linux unix 系統下,常用支援斷點續傳的 ftp 客戶端軟體是 lftp。range 用於請求頭中,指定第乙個位元組的位置和最後乙個位元組的位置,一般格式 range unit first byte pos last byte pos range 頭部的格式有...

HTTP 斷點續傳(分塊傳輸)

斷點續傳的用途在 linux unix 系統下,常用支援斷點續傳的 ftp 客戶端軟體是lftp。1 http1.1 之後支援端點續傳 1 range content range 2 響應頭 content range 用於指定整個實體中的一部分的插入位置,他也指示了整個實體的長度。在伺服器向客戶返...