Http 請求頭 Range

HTTP 請求頭 Range

請求資源的部份內容(不包括響應頭的大小),單位是byte,即字節,從0開始.html

若是服務器可以正常響應的話,服務器會返回 206 Partial Content 的狀態碼及說明.算法

若是不能處理這種Range的話,就會返回整個資源以及響應狀態碼爲 200 OK .(這個要注意,要分段下載時,要先判斷這個)緩存

好比:相似下面的ruby

➜  /tmp  curl -H "Range: bytes=0-10" http://127.0.0.1:8180/bg-upper.png -v
* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8180 (#0)
> GET /bg-upper.png HTTP/1.1
> User-Agent: curl/7.35.0
> Host: 127.0.0.1:8180
> Accept: */*
> Range: bytes=0-10
>
< HTTP/1.1 206 Partial Content
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< Accept-Ranges: bytes
< ETag: W/"3103-1435633968000"
< Last-Modified: Tue, 30 Jun 2015 03:12:48 GMT
< Content-Range: bytes 0-10/3103
< Content-Type: image/png
< Content-Length: 11
< Date: Tue, 29 Dec 2015 09:18:36 GMT
<
�PNG

* Connection #0 to host 127.0.0.1 left intact
➜

 

響應頭就是 HTTP/1.1 206 Partial Content服務器

Range 請求頭格式

Range: bytes=start-end

 

例如:多線程

Range: bytes=10- :第10個字節及最後個字節的數據

Range: bytes=40-100 :第40個字節到第100個字節之間的數據.

 

注意,這個表示[start,end],便是包含請求頭的start及end字節的,因此,下一個請求,應該是上一個請求的[end+1, nextEnd]app

響應頭

Content-Range

Content-Range: bytes 0-10/3103

 

這個表示,服務器響應了前(0-10)個字節的數據,該資源一共有(3103)個字節大小。curl

Content-Type

Content-Type: image/png

 

表示這個資源的類型分佈式

Content-Length

Content-Length: 11

 

表示此次服務器響應了11個字節的數據(0-10)url

Last-Modified

Last-Modified: Tue, 30 Jun 2015 03:12:48 GMT

 

表示資源最近修改的時間(分段下載時要注意這個東西,由於若是修改了,分段下載可能就要從新下載了)

ETag

ETag: W/&quot;3103-1435633968000&quot;

 

這個響應頭表示資源版本的標識符,一般是消息摘要(相似MD5同樣)(分段下載時要注意這個東西,或者緩存控制也要注意這個東西)

注意,每種服務器對生成ETag的算法不一樣,這個要特別注意 若是使用分佈式緩存,要特別要保證每臺服務器生成的ETag算法是一致的.

緩存的過時,要同時結合(ETag + Last-Modified)這兩個響應頭來判斷.

強ETag

只要實體發生任何改變,都會改變ETag值.如:

ETag: &quot;1234234234&quot;

弱ETag

它在前面會有個 W/ ,如:

ETag: W/&quot;12342423&quot;

分段下載

利用這個特色,咱們可使用分段下載(多線程下載,分佈式下載)

思想:先請求一個 HEAD 方法的請求,獲取總文件大小:

HEAD 請求

➜  /tmp  curl -X HEAD http://127.0.0.1:8180/bg-upper.png -v
* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
* Connected to 127.0.0.1 (127.0.0.1) port 8180 (#0)
> HEAD /bg-upper.png HTTP/1.1
> User-Agent: curl/7.35.0
> Host: 127.0.0.1:8180
> Accept: */*
>
< HTTP/1.1 200 OK
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< Accept-Ranges: bytes
< ETag: W/"3103-1435633968000"
< Last-Modified: Tue, 30 Jun 2015 03:12:48 GMT
< Content-Type: image/png
< Content-Length: 3103
< Date: Tue, 29 Dec 2015 10:16:16 GMT
<
* transfer closed with 3103 bytes remaining to read
* Closing connection 0
curl: (18) transfer closed with 3103 bytes remaining to read
➜  /tmp

 

那個響應頭的 Content-Length 就是總字節大小了(3103)字節.

多線程下載

假設分2條線程

線程1 下載

3103 / 2 = 1551

➜  /tmp  curl -H "Range: bytes=0-1551" http://127.0.0.1:8180/bg-upper.png -v -o 0-1151.png
* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Connected to 127.0.0.1 (127.0.0.1) port 8180 (#0)
> GET /bg-upper.png HTTP/1.1
> User-Agent: curl/7.35.0
> Host: 127.0.0.1:8180
> Accept: */*
> Range: bytes=0-1551
>
< HTTP/1.1 206 Partial Content
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< Accept-Ranges: bytes
< ETag: W/"3103-1435633968000"
< Last-Modified: Tue, 30 Jun 2015 03:12:48 GMT
< Content-Range: bytes 0-1551/3103
< Content-Type: image/png
< Content-Length: 1552
< Date: Tue, 29 Dec 2015 10:19:43 GMT
<
{ [data not shown]
100  1552  100  1552    0     0  1376k      0 --:--:-- --:--:-- --:--:-- 1515k
* Connection #0 to host 127.0.0.1 left intact
➜  /tmp

 

這樣子,線程1就下載了(0-1551)字節的數據了.

線程2 下載

➜  /tmp  curl -H "Range: bytes=1552-3103" http://127.0.0.1:8180/bg-upper.png -v -o 1552-end.png
* Hostname was NOT found in DNS cache
*   Trying 127.0.0.1...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Connected to 127.0.0.1 (127.0.0.1) port 8180 (#0)
> GET /bg-upper.png HTTP/1.1
> User-Agent: curl/7.35.0
> Host: 127.0.0.1:8180
> Accept: */*
> Range: bytes=1552
>
< HTTP/1.1 416 Requested Range Not Satisfiable
* Server Apache-Coyote/1.1 is not blacklisted
< Server: Apache-Coyote/1.1
< Accept-Ranges: bytes
< Content-Range: bytes */3103
< Content-Type: text/html;charset=utf-8
< Content-Language: en
< Content-Length: 954
< Date: Tue, 29 Dec 2015 10:26:18 GMT
<
{ [data not shown]
100   954  100   954    0     0   457k      0 --:--:-- --:--:-- --:--:--  931k
* Connection #0 to host 127.0.0.1 left intact
➜  /tmp

 

合併

cat 0-1151.png 1552-end.png > filename.png 

這樣子就OK了.

HTTP 請求頭注意

根據HTTP規範,HTTP的消息頭部的字段名,是不區分大小寫的.

3.2. Header Fields

Each header field consists of a case-insensitive field name followed

by a colon (「:」), optional leading whitespace, the field value, and

optional trailing whitespace.

RFC7230

相關文章
相關標籤/搜索