HTTP封包概覽
本文主要對封包的流動及其内容的了解做了介紹。包括以下内容:
- 封包的流動
- 封包的組成部分(起始行、首部和實體的主體部分)
- 封包的差別(響應封包和請求封包之間)
- 方法介紹
- 狀态碼介紹
- HTTP首部作用
這裡要強調的是,這個最多是我抄書的了解,并不全面。請大家看的時候還需要用慧眼進行鑒别。
一、封包的流動
HTTP封包是指在HTTP應用程式之間收發的資料塊。其以文本形式的元資訊開頭,描述封包的内容和含義,而後接續可選部分。這裡有三個術語:
- 流入(inbound)
- 流出(outbound)
- 事務處理(transaction)
流入是指從用戶端到伺服器的事務處理方向;而流出則是從伺服器到用戶端的事務處理方向。但不管是哪種流動,所有封包都向下(downstream)流動,而封包的發送者都在接受者的上遊(upstream)。注意,這裡的上遊和下遊都隻和發送者、接受者有關,而伺服器和用戶端都是下遊節點,是以我們無法差別封包的發送方向。
二、封包的組成部分
HTTP封包分請求封包和響應封包兩種,它們都由三個部分組成:
- 起始行:對封包進行描述。
- 首部:包含屬性
- 主體:可選的,包含資料。
起始行和首部是由行分隔的ASCII文本,都包括了一個回車符和一個換行符,可寫作CRLF。但是,由于部分HTTP應用程式不總是發送CRLF,是以一個HTTP應用程式應該接受單個換行符作為終止。主體可以包含文本或者二進制資料,也可以為空。
1.文法
HTTP封包分為兩類,而文法不同。請求封包的格式為:
<method> <request-URL> <version>
<headers>
<entity-body>
而響應封包在格式上,隻有起始行有别:
<version> <status> <reason-phrase>
接下來将對其中的大部分内容進行詳細介紹,而實體則在日後詳談。這裡簡述下實體
<entity-body>
:包含一個由任意資料組成的資料塊,是可選的。
2.起始行
起始行分為請求行和響應行。
2.1.請求行
請求封包的起始行,包含一個方法和一個請求URL。方法描述需要執行的操作,而請求URL則描述操作對象。請求行還包含用戶端的HTTP協定版本。這些字段使用空格符" "分隔。注意,在HTTP/0.9不要求請求中包含HTTP版本号。
2.2.響應行
響應封包的起始行,包含響應封包使用的HTTP協定版本、數字狀态碼和原因短語。所有字段使用空格符" "分隔。
2.3.方法
告知伺服器要進行的操作。HTTP規範中描述了一組方法,而在HTTP規範之外的方法,則是擴充方法,是HTTP規範的拓展。常用HTTP方法有:
方法 | 描述 | 是否包含主體 |
---|---|---|
GET | 從伺服器中擷取文檔 | 否 |
HEAD | 從伺服器擷取文檔首部 | 否 |
POST | 向伺服器發送需要處理的資料 | 是 |
PUT | 将請求的主體存儲在伺服器上 | 是 |
TRACE | 對可能經過代理服務傳送到伺服器上的封包進行追蹤 | 否 |
OPTIONS | 查詢伺服器支援的方法 | 否 |
DELETE | 從伺服器上删除文檔 | 否 |
2.4.狀态碼
伺服器對用戶端操作結果的回應。狀态碼有五種分類,而目前HTTP版本隻規定了其中一部分。如果接收到拓展的狀态碼,則會按照其所屬範圍進行分類,而後按照該分類中的普通成員處理。狀态碼分類如下:
整體範圍 | 已定義範圍 | 分類 |
---|---|---|
100~199 | 100、101 | 資訊提示 |
200~299 | 200~206 | 成功 |
300~399 | 300~305 | 重定向 |
400~499 | 400~415 | 用戶端錯誤 |
500~599 | 500~505 | 伺服器錯誤 |
後面會解釋目前使用的所有狀态碼,這裡按下不表。
2.5.原因短語
與狀态碼同時出現,是其文本形式,但是HTTP規範對此并沒有任何規定,但是有推薦的文本内容。
2.6.版本号
以HTTPx.y出現,使得HTTP用戶端和伺服器可以了解雙方的能力和封包。注意,其版本号不會被當作小數處理,每一個數字都會單獨比較。
3.首部
其作用是向封包添加附加資訊,本質上是名/值對的清單,用冒号":"分開名與值,可以分為五種:通用首部、請求首部、響應首部、實體首部和擴充首部。首部的文法如下:
<headers>: (可選的空格)<value>\r\n
首部可以有多行,為了增強可讀性,從第二行開始要在前面加一個空格或者制表符。
4.實體的主體部分
是HTTP封包的符合,即其要傳輸的内容。HTTP封包可以承載多種類型的數字資料,包括HTML文檔、圖檔、視訊等。
5.HTTP0.9的封包
這是HTTP協定早期版本,由請求和響應構成,但是請求中隻包含方法和請求URL,而響應中隻包含實體。由于其卻放靈活性,不能使用大部分提到的方法,但是在部分應用上仍舊使用,開發者應該清楚其局限。
三、方法
這部分是對前面的基本方法的深入探讨。有以下幾點要注意:
- 并不是每個伺服器實作了所有方法
- 伺服器中部分方法的使用可能是受限的,而限制則在伺服器的配置中進行設定。
1.安全方法
這是由HTTP協定定義的,其中包括GET和HEAD方法。安全方法意味着不産生動作,但這由Web開發者決定。相對應的,使用不安全的方法時,會允許HTTP應用開發者通知使用者,這才是目的。
2.GET方法
常用方法,用于請求伺服器發送某個資源,在HTTP/1.1中,要求伺服器實作該方法。
3.HEAD方法
類似GET方法,但是響應隻傳回首部。目的是允許用戶端對資源的首部進行檢查。該方法有以下作用:
- 不擷取資源的前提下了解資源情況
- 檢視對象是否存在
- 測試資源是否被修改
規範要求其傳回的首部于GET方法獲得的相同。
4.PUT方法
向伺服器寫入文檔,其方法的語義即讓伺服器用請求的主體部分(body)建立或者覆寫所請求的URL命名的新文檔。由于其允許使用者修改檔案,通常要求進行密碼認證。該方法需要存儲資源。
5.POST方法
起初用來輸入資料,現多用來支援HTTP表單。表單體拿到的資料發送給伺服器,再由伺服器決定去向。該方法不需要存儲資源。
6.TRACE方法
在用戶端發起請求以後,當它穿過其他應用程式的中間節點時可能被修改。而TRACE方法允許用戶端最後将請求發送給伺服器。
該請求會進行“環回”診斷,即在伺服器彈回一條攜帶收到的封包的TRACE響應,使得用戶端能檢視原始封包的修改情況。TRACE方法用于診斷,驗證請求是否穿過了請求/響應鍊,但由于其假設中間應用程式對各種不同類型的請求的處理相同,是以其不能差別HTTP程式對不同方法的處理機制的差異。
TRACE請求中不能帶有實體的主體部分。響應主體則包含收到的請求主體的精确副本。
7.OPTIONS方法
請求Web伺服器告知其支援的所有方法,這些方法是通用于伺服器上所有資源的。這使得用戶端可以判定請求資源的最優方法。(就是優化)
8.DELETE方法
請求伺服器删除請求URL指定的資源,但是用戶端程式不保證删除操作被執行。
9.拓展方法
由于HTTP被設計為字段可拓展的,新舊特性可以相容。而拓展方法指的是:沒有在HTTP/1.1規範中定義的方法。常見拓展方法執行個體如下:
方法 | 描述 |
---|---|
LOCK | 允許使用者“鎖定”資源,以防編輯時被其他人修改。 |
MKCOL | 允許使用者建立資源 |
COPY | 複制伺服器上的資源 |
MOVE | 移動伺服器的資源 |
上面的拓展方法是在WebDAV HTTP拓展中定義的拓展方法。要注意的是,并非所有拓展方法都可以被了解或者應用,是以,最好對拓展方法寬容以待,隻要不破壞端到端行為,可以傳遞給下遊伺服器;如果可能破壞,則傳遞501 Not Implemented進行響應。慣例是:“對發送的内容要求嚴格,對接受的内容要求寬松”。
四、狀态碼
目的是便利用戶端了解事務處理的結果,分為五大類,而五大類中的每個狀态碼都有一個HTTP/1.1推薦使用的原因短語。
1.資訊性狀态碼100~199
在HTTP/1.1中引入,存在争論,受到限制。其主要内容如下:
狀态碼 | 原因短語 | 含義 |
---|---|---|
100 | Continue | 說明收到請求的初始部分,請用戶端繼續。發送了這個狀态碼以後,伺服器在收到請求之後必須響應。 |
101 | Switching Protocol | 說明伺服器正在根據用戶端的指定,将協定切換成Update首部所列的協定 |
在這裡,要對100狀态碼進行一個解釋。其針對的情境是:用戶端需要發送一個實體給伺服器,但要在發送之前檢查一下伺服器是否會接受該實體。而它在用戶端、伺服器和代理之間是這樣通信的:
用戶端與100狀态碼
用戶端可以發送一個攜帶了值為100Continue的Expect請求首部,進而可以在發送實體之前等待100Continue的響應。這用于避免向伺服器發送一個無法處理的大實體。注意,如果等待逾時,則用戶端應該直接發送實體;要應對非預期的響應。
伺服器與100狀态碼
伺服器在收到帶有值為100Continue的Expect首部的請求時,應該用100Continue或者其他錯誤狀态碼進行響應。但是,如果用戶端沒有要求,則伺服器不應該發送該響應。
如果伺服器在發送100Continue之前就收到部分實體,即用戶端已經逾時了,伺服器就不需要發送100狀态碼,但是讀完請求以後,應該發送一個最終狀态碼(可跳過100狀态碼)。
代理與100狀态碼
代理收到一個100Continue的Expect請求,則能做的分以下幾種情況:
- 知道下一跳伺服器是HTTP/1.1相容(或者不知道),則将Except首部向下轉發
- 知道下一跳伺服器隻與HTTP/1.1之前相容,則應該響應417Exception Failed錯誤(或者是先向用戶端傳回100Continue,而後在向伺服器轉發請求的時候,删除Except首部)。
-
代理代表與HTTP/1.0或之前的版本相容的用戶端,則可以向請求中放入Except首部與100Continue值,但是不能向用戶端轉發該狀态碼。
是以,代理維護下一跳伺服器及其版本資訊有優點:更好地處理100Continue期望的請求。
2.成功狀态碼200~299
成功的請求有不同類型,是以下面有不同的表示成功的狀态碼。
狀态碼 | 原因短語 | 含義 |
---|---|---|
200 | OK | 請求沒問題,實體的主體部分包含請求的資源。 |
201 | Created | 對用于建立伺服器對象的請求的響應。其實體的主體部分應該包含各種引用了已建立資源的URL,Location首部包含的是最具體的引用。 |
202 | Accepeted | 請求已被接受,但是未執行并不保證執行請求。伺服器應該在實體的主體部分包含對請求狀态的描述,以及完成請求的時間的估算(或者可以獲得此資訊位置的指針)。 |
203 | Non-authoritative Information | 實體首部包含的資訊來自資源的副本(而非伺服器)。在中間節點有資源副本,但是無法或者沒有對它發送的與資源有關的首部進行驗證時,出現的情況。 |
204 | Not Content | 響應封包包含首部和狀态行,但是沒有實體的主體部分。用于在浏覽器不轉為顯示新文檔的情況下,對其進行更新。 |
205 | Reset Content | 用于浏覽器,告知浏覽器清楚目前頁面中所有HTML表單元素。 |
206 | Partial Content | 成功執行一個部分或者Range請求。其必須包含Content-Range\Date或者Content-Location首部。 |
3.重定向狀态碼300~399
告知使用者使用替代位置來通路資源,或者提供一個替代的響應而不是資源内容。如果資源已移動,則可以發送重定向狀态碼以及一個可選的Location首部來告知用戶端資源已被移動,以及目前位置。這樣浏覽器可以透明轉入新的位置。
也可以通過重定向狀态碼驗證本地資源與伺服器資源,用于檢視伺服器資源的修改,以及保持本地副本的及時性。
對包含了重定向狀态碼的非HEAD請求進行響應,則包含一個實體,并在實體中描述資訊和指向(多個)重定向URL的連接配接。
狀态碼 | 原因短語 | 含義 |
---|---|---|
300 | Multiple Choices | 用戶端請求一個實際上指向多個資源的URL時傳回。伺服器在傳回時,可以在Location首部包含首選URL |
301 | Moved Permanently | 在請求的URL已經移除時使用。響應的Location首部則包含資源的現URL |
302 | Found | 類似301,但是Location首部給出的URL隻能臨時定位資源,之後的請求應使用舊URL |
303 | See Other | 告知用戶端應使用另一個URL擷取資源。新URL位于Location首部,目的是允許POST請求的響應将用戶端重定向到某個資源上 |
304 | Not Modified | 用戶端可以通過包含的請求首部,使其變為有條件的。條件首部的内容可以在後面看到。帶有該狀态碼的響應不包含實體的主體部分。 |
305 | Use Proxy | 說明該資源必須通過代理通路。代理位置由Location首部指出。用戶端是相對某個特定資源解析該響應,而不是指定所有資源通過該代理進行。 |
307 | Temporary Redirect | 類似301。但是Location首部給出的URL隻能臨時定位資源,之後的請求應使用舊URL |
狀态碼302、303、307之間存在交叉和細微的差别,而其源于HTTP/1.0和HTTP/1.1應用程式之間的差别。
對于HTTP/1.0用戶端,發起POST請求并收到302響應時,會接受Location首部的重定向URL,并發送GET請求。
對HTTP/1.0伺服器,要求用戶端像上面一樣做。
但是HTTP/1.1使用303狀态碼實作相同行為,是以,對于HTTP/1.1用戶端,使用307狀态碼來代理302狀态碼,以避免302狀态碼被覆寫。
4.用戶端錯誤狀态碼400~499
伺服器收到無法處理的内容時的響應。
狀态碼 | 原因短語 | 含義 |
---|---|---|
401 | Bad Request | 告知用戶端發送了一個錯誤請求。 |
402 | Unauthorized | 與适當的首部一同傳回,請求用戶端在擷取資源的通路權以前,對自己進行認證。 |
403 | Payment Required | 未使用,但是保留到未來使用。 |
404 | Not Found | 伺服器無法找到請求的URl,通常包含一個實體,顯示給用戶端。 |
405 | Method Not Allowed | 發送的請求中帶有URl不支援的方法。其在響應中應該包含Allow首部,告知該資源可以使用的方法。 |
406 | Not Acceptable | 在沒有用戶端可接受的URL相比對的資源時使用,用戶端可以指定參數來說明它們願意接受的實體類型。 |
407 | Proxy Authentication Required | 類似401,但是用于對要求對資源進行認證的代理伺服器。 |
408 | Request Timeout | 用戶端完成請求的時間逾時,伺服器發送此狀态碼并關閉連接配接。 |
409 | Conflict | 說明請求可能在資源上引發的沖突。在伺服器擔心請求可能會引發沖突時,發送此狀态碼。響應中應包含描述沖突的主體。 |
410 | Gone | 類似404,隻是伺服器曾經擁有該資源,用于站點的維護,可以在伺服器的資源被移除時通知用戶端。 |
411 | Length Required | 伺服器的要求 |
412 | Precondition Failed | 發起條件請求,但是其中一個條件失敗時使用。 |
413 | Request Entity Too Large | 用戶端發送的實體主體部分大于伺服器能處理的内容。 |
414 | Request URI Too Long | URL實在太長。 |
415 | Unsupported Media Type | 伺服器無法了解或者無法支援用戶端所發送的實體的内容類型時使用。 |
416 | Requested Range Not Satisfiable | 請求封包請求的是指定資源的某個範圍,但是該範圍無效或者無法滿足。 |
417 | Expectation Failed | 包含期望的請求無法由伺服器滿足。如果代理或者中間程式有确切證據說明伺服器必然會産生一個失敗的期望,則可以發送這個響應狀态碼。 |
有一個403Forbidden,好像是伺服器拒絕處理請求,并且不說明原因。
5.伺服器錯誤狀态碼500~599
用戶端的請求有效,但是伺服器出錯時,可以使用,這是通常是代理與伺服器交流的結果。
狀态碼 | 原因短語 | 含義 |
---|---|---|
500 | Internal Server Error | 伺服器遇到一個妨礙它為請求提供服務的時候使用。 |
501 | Not Implemented | 用戶端發起的請求超過伺服器能力時使用 |
502 | Bad Gateway | 作為代理或者網關使用的伺服器從請求響應鍊的下一條鍊路上收到了一條僞響應時使用 |
503 | Sevice Unavailable | 用來說明伺服器現在無法為請求提供服務,但是将來可以啊(有種備胎的感覺) |
504 | Gateway Timeout | 類似408,但是該響應來自一個網關或者代理 |
505 | HTTP Version Not Supported | 收到的請求的版本不符。 |
五、首部
首部與方法配合使用,決定伺服器和用戶端的動作。其有五種首部,在下面進行詳細論述。
1.通用首部
提供與封包相關的最基本的資訊,可以由兩種封包使用。資訊性首部有:
首部 | 描述 |
---|---|
Connection | 允許用戶端和伺服器指定與請求/響應連接配接相關的選項 |
Date | 提供日期和時間标志,說明封包建立的時間 |
MIME-Version | 給出發送端使用的MIME版本 |
Trailer | 封包采用了分塊傳輸編碼時,使用該首部列出位于封包拖挂(trailer)部分的首部集合。 |
Transfer-Encoding | 告知封包采用的編碼方式 |
Update | 給出發送端可能想要“更新”使用的新版本或者協定 |
Via | 顯示封包經過的中間節點 |
而通用緩存首部則是在HTTP/1.0中引入的,允許HTTP應用程式快取區域副本的首部,而不用直接從伺服器中擷取。基本的緩存首部如下:
首部 | 描述 |
---|---|
Cache-Control | 用于随封包傳送緩存指令 |
Pragma | 另一種随封包傳送指令的方式,但是非專門用于緩存 |
2.請求首部
在請求封包中特有的内容。對伺服器提供更詳細的有關用戶端的資訊。其資訊性首部有:
首部 | 描述 |
---|---|
Client-IP | 運作用戶端的機器的IP |
From | 用戶端使用者的郵箱位址 |
Host | 請求的伺服器主機名和端口号 |
Referer | 包含目前請求URL的文檔的URL |
UA-Color | 提供了與用戶端顯示器對顔色的支援的有關資訊 |
UA-CPU | 提供了用戶端的CPU類型或制造商 |
UA-Disp | 提供用戶端顯示器能力相關資訊 |
UA-OS | 提供用戶端作業系統資訊——名稱及其版本 |
UA-Pixels | 提供用戶端顯示器像素 |
User-Agent | 将發起請求的應用程式名告知伺服器 |
2.1.Accept首部
為用戶端提供将器喜好和能力告知伺服器的方式,進而使得連接配接的兩端都得益。主要的Accept首部如下:
首部 | 描述 |
---|---|
Accept | 告訴伺服器能夠發送那些媒體類型 |
Accept-Charset | ...能夠發送的字元集 |
Accept-Encoding | ...能夠接受的編碼方式 |
Accept-Language | ...能夠發送的語言 |
TE | 能使用那些擴充傳輸編碼 |
2.2.條件請求首部
為請求加上限制,要求伺服器在響應之前,確定條件為真。
首部 | 描述 |
---|---|
Expect | 允許用戶端列出某請求所要求的伺服器行為 |
If-Match | 如果實體标記與文檔目前的實體标記比對,則擷取文檔 |
If-Modfied-Since | 除非在指定日期之後資源被修改,否則限制該請求 |
If-None-match | 如果實體标記與文檔目前的實體标記不比對,則擷取文檔 |
If-Range | 允許對文檔的某個範圍進行條件請求 |
If-Unmodified-Since | 除非在指定日期之後資源沒被修改,否則限制該請求 |
Range | 如果伺服器支援範圍請求,請求資源的指定範圍 |
2.3.安全請求首部
對請求進行質詢後者響應認證。要求用戶端在擷取特定資源之前,對自身進行認證,進而提高事務安全性。
首部 | 描述 |
---|---|
Authorization | 包含用戶端提供給伺服器,以便對其自身進行認證的資料 |
Cookie | 傳遞給伺服器的一個令牌,隐含安全功能 |
Cookie2 | 用來說明請求端支援的Cookie版本 |
2.4.代理請求首部
由于代理的普遍應用而來。
首部 | 描述 |
---|---|
Max-Forward | 在通往源伺服器的路徑上,将請求轉發給其他代理(網關)的最大次數,與TRACE一同使用 |
Proxy-Authorization | 與同名首部功能相同,但是用于代理 |
Proxy-Connection | 與同名首部功能相同,但是用于代理 |
3.響應首部
由響應封包使用,為用戶端提供額外的資訊,包括資訊性首部、協商首部和安全響應首部。資訊性首部如下:
首部 | 描述 |
---|---|
Age | 響應持續時間 |
Public | 伺服器為資源提供的方法清單 |
Retry-After | 資源不可用則在該日期或者時間重試 |
Server | 伺服器應用的名稱和版本 |
Title | HTML源端給定的标題 |
Warning | 比原因短語詳細的警告封包 |
而協商首部則是用來傳遞與可協商資源有關的資訊。
首部 | 描述 |
---|---|
Accept-Range | 對該資源來說,伺服器可以接受的範圍類型 |
Vary | 伺服器檢視的其他首部的清單,可能使響應變化。即由伺服器決定最适合的資源版本發送給用戶端 |
安全響應首部則是HTTP的質詢/響應認證機制的響應側。安全響應首部如下:
首部 | 描述 |
---|---|
Procy-Authenticate | 來自代理對用戶端的質詢清單 |
Set-Cookie | 在用戶端設定令牌,辨別用戶端 |
Set-Cookie2 | 類似上面 |
WWW-Authenticate | 來自伺服器的對用戶端的質詢清單 |
4.實體首部
可以出現在兩種封包中,提供有關實體及其内容的大量資訊,其資訊性首部有:
首部 | 描述 |
---|---|
Allow | 列出對該實體可以執行的請求方法 |
Location | 告知用戶端實體的位置,用于定向到資源的位置 |
内容首部包含的是與實體内容有關的特定資訊。
首部 | 描述 |
---|---|
Content-Base | 解析主體中相對URL時使用的基礎URL |
Content-Encoding | 對主體執行的編碼方式 |
Content-Language | 了解主體适合的自然語言 |
Content-Length | 長度 |
Content-Location | 位置 |
Content-MD5 | MD5校驗碼 |
Content-Range | 該實體表示的位元組範圍 |
Content-Type | 對象類型 |
緩存首部則說明了被緩存的主體的資訊。
首部 | 描述 |
---|---|
ETag | 與實體相關的實體标記 |
Expires | 實體不再有效,要從原始的源端中再次擷取該實體的日期和時間 |
Last-Modified | 實體最後一次被修改的日期和時間 |
這裡就是本章的全部内容,雖然有一些圖有所缺漏,但是至少看懂HTTP封包大概是怎麼回事應該沒問題了。