標籤:request 完數 動態 建立 它的 strong ted 重用 並且
1、什麼是Keep-Alive模式?
我們知道HTTP協議採用“請求-應答”模式,
當使用普通模式,即非KeepAlive模式時,每個請求/應答客戶和伺服器都要建立一個串連,完成 之後立即中斷連線(HTTP協議為不需連線的協議);
當使用Keep-Alive模式(又稱持久串連、串連重用)時,Keep-Alive功能使用戶端到服 務器端的串連持續有效,
當出現對伺服器的後繼請求時,Keep-Alive功能避免了建立或者重建立立串連。
http 1.0中預設是關閉的,需要在http頭加入"Connection: Keep-Alive",才能啟用Keep-Alive;
http 1.1中預設啟用Keep-Alive,如果加入"Connection: close ",才關閉。
目前大部分瀏覽器都是用http1.1協議,也就是說預設都會發起Keep-Alive的串連請求了,所以是否能完成一個完整的Keep- Alive串連就看伺服器設定情況。
2、啟用Keep-Alive的優點
從上面的分析來看,啟用Keep-Alive模式肯定更高效,效能更高。因為避免了建立/釋放串連的開銷;
注意:單使用者用戶端與任何伺服器或代理之間的串連數不應該超過2個。
一個代理與其它伺服器或代碼之間應該使用不超過2 * N的活躍並發串連。
這是為了提高HTTP回應時間,避免擁塞(冗餘的串連並不能代碼執行效能的提升)。
3、回到我們的問題(即如何判斷訊息內容/長度的大小?)
Keep-Alive模式,用戶端如何判斷請求所得到的響應資料已經接收完成(或者說如何知道伺服器已經發生完了資料)?
我們已經知道 了,Keep-Alive模式發送完資料HTTP伺服器不會自動中斷連線,所有不能再使用返回EOF(-1)來判斷;
(當然你一定要這樣使用也沒有辦法,可 以想象那效率是何等的低)!下面我介紹兩種來判斷方法。
3.1、使用訊息首部欄位Conent-Length
故名思意,Conent-Length表示實體內容長度,用戶端(伺服器)可以根據這個值來判斷資料是否接收完成。
但是如果訊息中沒有Conent-Length,那該如何來判斷呢?又在什麼情況下會沒有Conent-Length呢?請繼續往下看……
3.2、使用訊息首部欄位Transfer-Encoding
當用戶端向伺服器請求一個靜態頁面或者一張圖片時,伺服器可以很清楚的知道內容大小,
然後通過Content-length訊息首部欄位告訴用戶端 需要接收多少資料。
但是如果是動態網頁面等時,伺服器是不可能預Crowdsourced Security Testing道內容大小,這時就可以使用Transfer-Encoding:chunk模式來傳輸 資料了。
即如果要一邊產生資料,一邊發給用戶端,伺服器就需要使用"Transfer-Encoding: chunked"這樣的方式來代替Content-Length。
chunk編碼將資料分成一塊一塊的發生。
Chunked編碼將使用若干個Chunk串聯而成,由一個標明長度為0 的chunk標示結束。
每個Chunk分為頭部和本文兩部分,頭部內容指定本文的字元總數(十六進位的數字 )和數量單位(一般不寫),
本文部分就是指定長度的實際內容,兩部分之間用斷行符號換行(CRLF) 隔開。
在最後一個長度為0的Chunk中的內容是稱為footer的內容,是一些附加的Header資訊(通常可以直接忽略)。
Chunk編碼的格式如下:
複製代碼
代碼如下:
Chunked-Body = *<strong>chunk </strong>
"0" CRLF
footer
CRLF
chunk = chunk-size [ chunk-ext ] CRLF
chunk-data CRLF</p><p>hex-no-zero = <HEX excluding "0"></p><p>chunk-size = hex-no-zero *HEX
chunk-ext = *( ";" chunk-ext-name [ "=" chunk-ext-value ] )
chunk-ext-name = token
chunk-ext-val = token | quoted-string
chunk-data = chunk-size(OCTET)</p><p>footer = *entity-header
即Chunk編碼由四部分組成: 1、<strong>0至多個chunk塊</strong> ,2、<strong>"0" CRLF </strong>,3、<strong>footer </strong>,4、<strong>CRLF</strong> <strong>.</strong> 而每個chunk塊由:chunk-size、chunk-ext(可選)、CRLF、chunk-data、CRLF組成。
4、訊息長度的總結
其實,上面2中方法都可以歸納為是如何判斷http訊息的大小、訊息的數量。
RFC 2616 對 訊息的長度總結如下:一個訊息的transfer-length(傳輸長度)是指訊息中的message-body(訊息體)的長度。
當應用了 transfer-coding(傳輸編碼),每個訊息中的message-body(訊息體)的長度(transfer-length)由以下幾種情況 決定(優先順序由高到低):
任何不含有訊息體的訊息(如1XXX、204、304等響應訊息和任何頭(HEAD,首部)請求的響應訊息),總是由一個空行(CLRF)結束。
如果出現了Transfer-Encoding頭欄位 並且值為非“identity”,那麼transfer-length由“chunked” 傳輸編碼定義,除非訊息由於關閉串連而終止。
如果出現了Content-Length頭欄位,它的值表示entity-length(實體長度)和transfer-length(傳輸長 度)。如果這兩個長度的大小不一樣(i.e.設定了Transfer-Encoding頭欄位),那麼將不能發送Content-Length頭欄位。並 且如果同時收到了Transfer-Encoding欄位和Content-Length頭欄位,那麼必須忽略Content-Length欄位。
如果訊息使用媒體類型“multipart/byteranges”,並且transfer-length 沒有另外指定,那麼這種自定界(self-delimiting)媒體類型定義transfer-length 。除非寄件者知道接收者能夠解析該類型,否則不能使用該類型。
由伺服器關閉串連確定訊息長度。(注意:關閉串連不能用於確定請求訊息的結束,因為伺服器不能再發響應訊息給用戶端了。)
為了相容HTTP/1.0應用程式,HTTP/1.1的請求訊息體中必須包含一個合法的Content-Length頭欄位,除非知道伺服器相容 HTTP/1.1。一個請求包含訊息體,並且Content-Length欄位沒有給定,如果不能判斷訊息的長度,伺服器應該用用400 (bad request) 來響應;或者伺服器堅持希望收到一個合法的Content-Length欄位,用 411 (length required)來響應。
所有HTTP/1.1的接收者應用程式必須接受“chunked” transfer-coding (傳輸編碼),因此當不能事Crowdsourced Security Testing道訊息的長度,允許使用這種機制來傳輸訊息。訊息不應該夠同時包含 Content-Length頭欄位和non-identity transfer-coding。如果一個訊息同時包含non-identity transfer-coding和Content-Length ,必須忽略Content-Length 。
HTTP Keep-Alive模式