Http協議斷點續傳和其他特性

目錄

一、長連接和短連接

長連接和短連接的使用環境區分

二、HTTP代理服務

三、HTTP網關的分類

1、HTTP/*:服務器端Web網關

2、HTTP/HTTPS:服務器端安全網關

3、HTTPS/HTTP客戶端安全加速器網關

4、資源網關

(1)CGI

(2)服務器擴展API

四、HTTP斷點續傳和多線程下載

1、HTTP 斷點續傳示例

增強校驗

2、多線程下載示例

3、斷點續傳關聯header字段

檢測服務器是否支持斷點續傳


一、長連接和短連接

HTTP的長連接和短連接實質上是TCP的長連接和短連接。HTTP屬於應用層協議,在傳輸層使用TCP協議,在網絡層使用IP協議。

在HTTP/1.0 中,默認使用短連接。 就是說:瀏覽器和服務器每進行一次HTTP操作,就建立一次連接,但任務結束就中斷連接。

從 HTTP/1.1 起,默認使用長連接保持連接持續性。 一個網頁打開完成後,客戶端和服務器之間用於傳輸HTTP數據的TCP連接不會關閉,如果客戶端再次訪問這個服務器上的的網頁, 會繼續使用這一條已經建立好的連接。

注:Keep-Alive不會永久保持連接,它有一個保持的時間,可以在不同服務器軟件中設定這個時間(Apache)。 要實現長連接,客戶端、服務器端首先得支持。

短連接步驟:

建立連接 – 數據傳輸 – 關閉連接  ——

長連接步驟:

建立連接 – 數據傳輸 –(保持連接)– 數據傳輸 – 數據傳輸 – 關閉連接  ——

長連接和短連接的使用環境區分

長連接多用於操作頻繁,點對點的通訊,而且連接數不能太多情況,每個TCP連接都需要三步握手,這需要時間,如果每個操作都是先連接,再操作的話那麼處理速度會降低很多,所以每個操作完後都不斷開,次處理時直接發送數據包就OK了,不用建立TCP連接。

例如:數據庫的連接用長連接, 如果用短連接頻繁的通信會造成socket錯誤,而且頻繁的socket 創建也是對資源的浪費。

而像WEB網站的http服務一般都用短鏈接,因爲長連接對於服務端來說會耗費一定的資源,而像WEB網站這麼頻繁的成千上萬甚至上億客戶端的連接用短連接會更省一些資源

如果用長連接而且同時有成千上萬的用戶,如果每個用戶都佔用一個連接的話,那可想而知吧。所以併發量大,但每個用戶無需頻繁操作情況下需用短連好。

總結:

長連接省去了較多的TCP建立、關閉操作,減少了浪費,節約時間。對於頻繁請求資源的客戶來說,適合用長連接。 

短連接對於服務器來說管理較爲簡單,存在的連接都是有用的連接,不需要額外的控制手段。但如果客戶請求頻繁,將在TCP的建立和關閉操作上浪費時間和帶寬。

二、HTTP代理服務

HTTP代理服務(proxy server) 器就是客戶端也是服務端,是一個事務處理的中間人,如圖所示:

代理服務器的作用有很多,例如:兒童過濾器、文檔訪問控制、安全防火牆、web緩存等等。

三、HTTP網關的分類

網關概念

網關(Gateway)又稱網間連接器、協議轉換。網關在網絡層以上實現網絡互連,是複雜的網絡互連設備,僅用於兩個高層協議不同的網絡互連。網關是一種充當轉換重任的計算機系統或設備。使用在不同的通信協議、數據格式或語言,甚至體系結構完全不同的兩種系統之間,網關是一個翻譯器。          ——百度百科

1、HTTP/*:服務器端Web網關

請求流入原始服務器時,服務器端Web網關會將客戶度的HTTP請求轉換成其他協議,如圖:

在圖8-5中,網關收到了一條對FTP資源的HTTP請求:

ftp://ftp.irs.gov/pub/00-index.txt

網關會打開一條道原始服務器FTP端口(端口21)的FTP連接,通過FTP協議獲取對象。網關會做下列事情:

(1)發送USER和PASS命令登錄到服務器上去;

(2)發佈CWD命令,轉移到服務器上合適的目錄中去;

(3)將下載類型設置爲ASCII;

(4)用MDTM獲取文檔的最後修改時間;

(5)用PASV告訴服務器將有被動數據獲取請求到達;

(6)用RETR請求進行對象獲取;

(7)打開到FTP服務器的數據連接,服務器端口由控制信道返回;一旦數據通信打開了就將對象內容回送給網關

2、HTTP/HTTPS:服務器端安全網關

一個組織可以通過網關對所有的輸入Web請求加密,以提供額外的隱私和安全性保護。客戶端可以用普通的HTTP瀏覽Web內容,但網關會自動加密用戶的對話(參見圖8-6)

3、HTTPS/HTTP客戶端安全加速器網關

將HTTPS/HTTP網關作爲安全加速器使用的情況是越來越多了。這些HTTPS/HTTP網關位於Web服務器之前,通常作爲不可見的攔截網關或反向代理使用。它們接收安全的HTTPS流量,對安全流量進行解密,並向Web服務器發送普通的http請求(見圖8-7)

這些網關中通常包含專用的解密硬件,以比原始服務器有效得多的方式來解密安全流量,以減輕原始服務器的負荷。這些網關在網關和原始服務器之間發送的是未加密的流量,所以,要謹慎使用,確保網關和原始服務器之間的網絡是安全的。

4、資源網關

前面我們一直說的是通過網絡連接客戶端和服務器的網關。但最常見的網關,應用程序服務器會將目標服務器與網關結合在一個服務器中實現。應用程序服務器是服務器端網關,與客戶端通過HTTP進行通信,並與服務器端的應用程序相連(參見圖8-8)

在圖8-8中,兩個客戶端是通過HTTP連接到應用程序服務器的。但應用程序服務器並沒有回送文件,而是將請求通過一個網關應用編程接口(Application Programming Interface)發送給運行在服務器上的應用程序。

(1)收到客戶端A的請求,根據URL將其通過API發送給一個數碼攝像機應用程序。將得到的圖片綁定到一條HTTP響應報文中,再回送給客戶端,在客戶端的瀏覽器中顯示。

(2)客戶端B的URL請求的是一個電子商務應用程序。客戶端B的請求是通過服務器網關API發送給電子商務軟件的,結果會被回送給瀏覽器。電子商務軟件與客戶端進行交互,應道用戶通過一系列HTML頁面來完成購物的。

第一個流行的應用程序網關API就是通用網關接口(Common Gateway Interface,CGI)。CGI是一個標準接口集,Web服務器可以用它來裝載程序以響應對特定URL的HTTP請求,並收集程序的輸出數據,將其放在HTTP響應中回送。商業的web服務器提供了一些更復雜的接口,以便將Web服務器連接到應用程序上。

請求需要使用網關的資源時,服務器會請輔助應用程序來處理請求。服務器會將輔助應用程序所需的數據傳送給它。通常就是整條請求,或者用戶想在數據庫上運行的請求(來自URL的請求字符串)之類的東西。

然後它會向服務器返回一條響應或響應數據,服務器會將其轉發給客戶端。服務器和網關是相互獨立的應用程序,因此,它們的責任是分得很清楚的。圖8-9顯示了服務器與網關應用程序之間交互的基本運行機制。

(1)CGI

CGI是第一個得到最廣泛應用的服務器擴展。在Web上廣泛用於動態HTML、信用卡處理以及數據庫查詢等任務。

CGI應用程序是獨立於服務器的,所以,幾乎可以用任意語言來實現。CGI很簡單,幾乎所有的HTTP服務器都支持它。

CGI的處理對用戶來說是不可見的。從客戶端的角度來看,就像發起一個普通請求一樣。它完全不清楚服務器和CGI應用程序之間的轉接過程。URL中出現字符CGI和可能出現的“?”是客戶端發現使用了CGI應用程序的唯一線索。

(2)服務器擴展API

CGI協議外部翻譯器與現有的HTTP服務器提供了一種簡潔的接口方式,但如果想要改變服務器自身的行爲,或者只是想提升從服務器上獲得的性能呢?服務器開發者爲這兩種需求提供了幾種服務器擴展API,爲Web開發者提供了強大的接口,以便他們將自己的模塊與HTTP服務器直接連接。擴展API允許程序員將自己的代碼嫁接到服務器上,或者用自己的代碼將服務器的一個組件完整的替換出來。

四、HTTP斷點續傳和多線程下載

斷點續傳就是從文件上次中斷的地方開始重新下載或上傳,當下載或上傳文件的時候,如果沒有實現斷點續傳功能,那麼每次出現異常或者用戶主動的暫停,都會去重頭下載,這樣很浪費時間。所以斷點續傳的功能就應運而生了。要實現斷點續傳的功能,需要客戶端記錄下當前的下載或上傳進度,並在需要續傳的時候通知服務端本次需要下載或上傳的內容片段。

1、HTTP 斷點續傳示例

其實斷點續傳的原理很簡單,就是在Http的請求上多定義了斷點續傳相關的HTTP頭RangeContent-Range字段而已,例如:

(1)瀏覽器請求服務器上的一個文件名爲test.zip時,請求內容只展示了一些與本文有關的信息

GET /test.zip HTTP/1.1

Accept-Language: zh-cn

Accept-Encoding: gzip, deflate

Connection: Keep-Alive

(2)服務器收到請求後,按要求尋找請求的文件,提取文件的信息,然後返回給瀏覽器,返回信息如下:

200

Content-Length=66667777

Accept-Ranges=bytes

Content-Type=application/octet-stream

(3)爲了實現從文件已經下載的地方開始繼續下載。所以在客戶端傳給服務器的時候要多加一條信息--從哪裏開始。下面是客戶端請求時的請求信息,要求從44445555字節開始。

GET /test.zip HTTP/1.0

User-Agent: NetFox

RANGE: bytes=44445555-

(4)上面的請求信息多了一個新的字段RANGE RANGE:bytes=44445555-,這段話的意思就是告訴服務器test.zip這個文件從44445555字節開始傳,前面的字節不用傳了。服務器收到這個請求以後,返回的信息如下:

206

Content-Length=66667777

Content-Range=bytes 44445555-66667777

Content-Type=application/octet-stream

和第一次服務器返回的信息相比,增加了一行:Content-Range=bytes 44445555-66667777,返回的代碼也改爲206了,而不再是200了。

增強校驗

但是在實際場景中,會出現一種情況,即在終端發起續傳請求時,URL對應的文件內容在服務端已經發生變化,此時續傳的數據肯定是錯誤的。如何解決這個問題了?顯然此時我們需要有一個標識文件唯一性的方法。在RFC2616中也有相應的定義,比如實現Last-Modified來標識文件的最後修改時間,這樣即可判斷出續傳文件時是否已經發生過改動。同時RFC2616中還定義有一個ETag的頭,可以使用ETag頭來放置文件的唯一標識,比如文件的MD5值。
終端在發起續傳請求時應該在HTTP頭中申明If-Match 或者If-Modified-Since 字段,幫助服務端判別文件變化。 

另外RFC2616中同時定義有一個If-Range頭,終端如果在續傳是使用If-Range。If-Range中的內容可以爲最初收到的ETag頭或者是Last-Modfied中的最後修改時間。服務端在收到續傳請求時,通過If-Range中的內容進行校驗,校驗一致時返回206的續傳回應,不一致時服務端則返回200迴應,迴應的內容爲新的文件的全部數據。

2、多線程下載示例

假設你要開發一個多線程下載工具,你會自然的想到把文件分割成多個部分,比如4個部分,然後創建4個線程,每個線程負責下載一個部分,如果文件大小爲403個byte,那麼你的分割方式可以爲:0-99 (前100個字節),100-199(第二個100字節),200-299(第三個100字節),300-402(最後103個字節)。
分割完成,每個線程都明白自己的任務,比如線程3的任務是負責下載200-299這部分文件,現在的問題是:線程3發送一個什麼樣的請求報文,才能夠保證只請求文件的200-299字節,而不會干擾其他線程的任務。這時,我們可以使用HTTP1.1的Range頭。Range頭域可以請求實體的一個或者多個子範圍,Range的值爲0表示第一個字節,也就是Range計算字節數是從0開始的

  • 表示頭500個字節:Range: bytes=0-499
  • 表示第二個500字節:Range: bytes=500-999
  • 表示最後500個字節:Range: bytes=-500
  • 表示500字節以後的範圍:Range: bytes=500-
  • 第一個和最後一個字節:Range: bytes=0-0,-1
  • 同時指定幾個範圍:Range: bytes=500-600,601-999

所以,線程3發送的請求報文必須有這一行:

Range: bytes=200-299

服務器接收到線程3的請求報文,發現這是一個帶有Range頭的GET請求,如果一切正常,服務器的響應報文會有下面這行:

HTTP/1.1 206 OK

表示處理請求成功,響應報文還有這一行:

Content-Range: bytes 200-299/403

斜槓後面的403表示文件的大小。通常Content-Range的用法爲:

.The first 500 bytes:

 Content-Range: bytes 0-499/1234

.The second 500 bytes:

 Content-Range: bytes 500-999/1234
 
.All except for the first 500 bytes:

 Content-Range: bytes 500-1233/1234

.The last 500 bytes:

 Content-Range: bytes 734-1233/1234

3、斷點續傳關聯header字段

HTTP 1.1默認支持斷點續傳。關聯header字段如下:

If-Modified-SinceLast-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 無法解決的一些問題

  1. 一些文件也許會週期性的更改,但是內容並不改變(僅改變修改時間),這時候我們並不希望客戶端認爲這個文件被修改了,而重新 GET。
  2. 某些文件修改非常頻繁,例如:在秒以下的時間內進行修改(1s 內修改了 N 次),If-Modified-Since 能檢查到的粒度是 s 級的,這種修改無法判斷(或者說 UNIX 記錄 MTIME 只能精確到秒)。
  3. 某些服務器不能精確的得到文件的最後修改時間。

爲此,HTTP/1.1 引入了 Etag。Etag 僅僅是一個和文件相關的標記,可以是一個版本標記,例如:v1.0.0;或者說 “627-4d648041f6b80” 這麼一串看起來很神祕的編碼。但是 HTTP/1.1 標準並沒有規定 Etag 的內容是什麼或者說要怎麼實現,唯一規定的是 Etag 需要放在 “” 內。

Range:用於客戶端到服務端的請求,可以通過改字段指定下載文件的某一段大小及其單位,字節偏移從0開始。典型格式:

  • Ranges:    (unit=first byte pos)-[last byte pos]
  • Ranges:    bytes=4000- 下載從第4000字節開始到文件結束部分
  • Ranges:    bytes=0~N 下載第0-N字節範圍的內容
  • Ranges:    bytes=M-N 下載第M-N字節範圍的內容
  • Ranges:    bytes=-N 下載最後N字節內容

If-Range:用於客戶端到服務端的請求,用於判斷實體是否發生改變。若實體未被修改,則響應所缺少的那部分;否則,響應整個新的實體。一般格式爲:

If-Range: Etag | HTTP-Date

也就是說,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 條件判斷請求來驗證資源是否修改。請求一個文件的流程如下:

第一次請求:

  1. 客戶端發起 HTTP GET 請求一個文件。
  2. 服務器處理請求,返回文件內容以及相應的 Header,其中包括 Etag(例如:627-4d648041f6b80)(假設服務器支持 Etag 生成並已開啓了 Etag)狀態碼爲 200。

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

  1. 客戶端發起 HTTP GET 請求一個文件,同時發送 If-Range(該頭的內容就是第一次請求時服務器返回的 Etag:627-4d648041f6b80)。
  2. 服務器判斷接收到的 Etag 和計算出來的 Etag 是否匹配,如果匹配,那麼響應的狀態碼爲 206;否則,狀態碼爲 200。

Accept-Ranges:用於服務端到客戶端的應答,client通過該字段判斷server是否支持斷點續傳。

  • Accept-Ranges:bytes    表示支持以bytes爲單位進行傳輸。
  • Accept-Ranges:none     表示不支持斷點續傳

Content-Ranges:用於服務端到客戶端的應答,與Accept-Ranges在同一個報文內,通過該字段指定了返回的文件資源的字節範圍。格式如下:

  • Content-Ranges:bytes M-N/size 大小爲size的文件的第M-N字節範圍的內容

斷點續傳響應碼206:斷點續傳,如果返回文件的一部分,則使用HTTP 206狀態碼;如果返回整個文件,則使用HTTP 200響應碼。

  • HTTP/1.1 200 OK(不使用斷點續傳)
  • HTTP/1.1 206 Partial Content(使用斷點續傳)

檢測服務器是否支持斷點續傳

CURL 實現檢測:

[root@localhost ~]# curl -i --range 0-9 http://www.baidu.com/img/bdlogo.gif
HTTP/1.1 206 Partial Content
Date: Mon, 21 Nov 2016 05:26:29 GMT
Server: Apache
P3P: CP=" OTI DSP COR IVA OUR IND COM "
Set-Cookie: BAIDUID=0CD0E23B4D4F739954DFEDB92BE6CE03:FG=1; expires=Tue, 21-Nov-17 05:26:29 GMT; max-age=31536000; path=/; domain=.baidu.com; version=1
Last-Modified: Fri, 22 Feb 2013 03:45:02 GMT
ETag: "627-4d648041f6b80"
Accept-Ranges: bytes
Content-Length: 10
Cache-Control: max-age=315360000
Expires: Thu, 19 Nov 2026 05:26:29 GMT
Content-Range: bytes 0-9/1575
Connection: Keep-Alive
Content-Type: image/gif

GIF89a[root@localhost ~]#

能夠找到 Content-Range,則表明服務器支持斷點續傳。有些服務器還會返回 Accept-Ranges,輸出結果 Accept-Ranges: bytes ,說明服務器支持按字節下載。

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