HTTP報文
報文流
HTTP報文是在HTTP引用程序之間發送的數據塊,這些數據塊以一種文本形式的元信息開頭,這些信息描述了報文的內容和含義,后面跟著可選的數據部分,這些報文在客戶端,服務器和代理之間流動。
報文流入源端服務器
HTTP使用屬于流入和流出來描述事務處理的方向,報文流入源端服務器,工作完成之后,會流入用戶的Agent代理中。
報文向下游流動
HTTP報文會像下游流動,所有報文的發送者在接收者的上游。對于請求報文來說,代理1在代理2的上游
報文的組成部分
HTTP報文是簡單的格式化數據塊,每條報文都包含一條來自客戶端的請求,或者一條來自服務器的響應。由三部分組成: 對報文進行描述的起始行,包含屬性的首部塊,已經可選的,包含數據的主體部分。
起始行和首部都是由行分割的ascii文本。每行都以一個或者兩個字符組成的行終止序列作為結束,包括一個回車符和一個換行符。這個行終止序列被寫作crlf。有些老的,或者不完整的HTTP引用程序不會總是發送回車符,又發送換行符。
使用的主體或者報文的主體是一個可選的數據塊,與起始行和首部不同的是,主題中可以包含文本或者二進制數據,也可以為空。
報文的語法
所有的HTTP報文請求可以分為兩類: 請求報文和響應報文。請求報文會向web服務器請求一個動作,響應報文會將請求的結果返回給客戶端,請求和響應報文的基本報文結構都是相同的。
// 請求報文
<method> <request-URL> <version>
<headers>
<entity-body>
// 響應報文
<version> <status> <reason-phrarse>
<headers>
<entity-body>
方法: 客戶端希望服務器對資源執行的動作
請求URL: 命名了請求資源,或者URL路徑組件的完整URL,如果直接和服務器進行對話,只要URL的路徑組件是資源的絕對路徑。
版本: HTTP版本
狀態碼: 每個狀態碼中的第一位都用來描述狀態的一般類別。
原因短語: 數字狀態碼的可讀版本,包含行終止序列之前的所有文本。
首部: 可以有零個或者多個首部,每個首部包含一個名字,后面跟著一個冒號。然后是可選的空格,接著是一個只,最后是一個CRLF。
實體的主體部分: 實體的主體部分包含一個有任意數據組成的數據塊,并不是所有報文都包含實體的組成部分。
起始行
所有的http報文都是以一個其實作為開始,請求報文的起始行說明了要做些什么,響應報文的起始行說明發生了什么
請求行
請求報文請求服務器對資源進行一些操作,請求報文的起始行,或者請求行,包含了一個方法和一個請求URL,這個方法描述了服務器應該執行的操作。請求URL描述了要對那個資源執行這個方法,請求行中包含HTTP的版本。用來告知服務器,客戶端使用的是那種HTTP
響應行
響應報文承載了狀態信息和操作產生的所有結果數據。將其返回給客戶端,響應報文的起始行,或者稱為響應行,包含了響應報文的HTTP版本,數字狀態碼,以及描述操作狀態的文本形式的原因短語
所有這些字符都由空格符進行分割。
方法
請求的起始行以方法作為開始,方法告知服務器要做些什么
狀態碼
方法是用來告訴服務器做什么事情的,狀態碼是告訴客戶端,發生了什么事情,狀態碼位于響應的起始行中。
狀態碼是在每條響應報文的起始行中返回的,會返回一個數字狀態和一個可讀的狀態。數字碼便于沉痼進行差錯管理,而原因短語便于人們理解
通過三位數字代碼對不同的狀態進行分類。200-299之間的狀態碼表示成功,300-399表示資源被遷移走,400-499表示客戶端的請求發生了錯誤,500-599表示服務器出現了錯誤
原因短語
原因短語是響應起始行中的最后一個組件,為狀態碼提供了文本形式的解釋。
版本號
首部
首部分類
HTTP規范定義了首部字段,應用程序也可以隨意發明自己所用的首部
- 通用首部:可以出現在請求報文中,也可以出現在響應報文中
- 請求首部: 提供更多有關請求的信息
- 響應首部: 提供更多有關的響應星系
- 實體首部: 描述主體的長度和內容,或者資源本身
- 拓展首部: 規范中沒有定義過的新首部。
語法:名字:可選空格 字段值 CRLF
首部延續行
將長的首部行為分為多行可以提高可讀性,多出來的每行前面至少有一個空格或者制表符。
HTTP/1.0 200 OK
Content-Type: image/gif
Content-Length: 8572
Server: Test Server
Version 1.0
實體的主體部分
HTTP報文的第三部分就是可選的實體主體部分,實體的主體是HTTP報文的負荷,就是HTTP要傳輸的內容
HTTP報文可以承載很多類型的數字數據: 圖片,視頻, HTML文檔, 軟件應用程序, 信用卡事務, 電子郵件等
版本0.9的報文
HTTP/0.9報文也都是由請求和響應組成,但是請求中只包含方法和請求URL,響應中只包含實體,沒有版本信息,沒有狀態碼或原因短語,也沒有首部。
方法
安全方法
HTTP定義了一組被安全方法的方法。GET方法和HEAD方法都被認為是安全的。
GET
GET是最常用的方法,通常用于請求服務器發送某個資源,HTTP/1.1要求服務器實現此方法。
HEAD
HEAD方法和GET方法的行為很類似,但是服務器在響應中只能返回首部,不會返回實體的主體部分,這就允許客戶端在沒有獲取實際資源的情況下,對資源的首部進行檢查。
- 在不獲取資源的情況下了解資源的情況
- 通過查看響應中的狀態碼,查看對象是否存在
- 查看首部,檢查資源是否被改變
PUT
與GET從服務器中讀取文檔相反,PUT方法會向服務器中寫入文檔。 PUT方法就是讓服務器用請求的主體部分來創建一個由所請求的URL命名的新的文檔,或者,如果URL已經存在的話,就用這個主體代替它。
POST
post方法起初是用來向服務器輸入數據的。
TRACE
客戶端發起一個請求時,這個請求可能要穿過防火墻、代理、網關或其他一些應用程序。每個中間節點都可能會修改原始的HTTP請求。
TRACE 請求會在目的服務器端發起一個“環回”診斷。行程最后一站的服務器會彈回一條 TRACE 響應,并在響應主體中攜帶它收到的原始請求報文。這樣客戶端就可以查看在所有中間 HTTP 應用程序組成的請求/響應鏈上,原始報文是否,以及如何被毀壞或修改過
TRACE的方法主要用于診斷,用于驗證請求是否如愿穿過了請求/響應鏈。可以用來查看代理或者其他應用程序對用戶請求產生的效果
OPTIONS
OPTIONS方法請求對web服務器告知其支持的各種功能,可以詢問服務器支持的方法。
DELETE
DELETE方法所做的事情就是請服務器刪除請求URL所指定的資源。但是客戶端應用程序無法保證刪除操作一定會被執行。HTTP規范允許服務器在不通知客戶端的情況下撤銷請求。
狀態碼
100 —— 199 信息性狀態碼
HTTP/1.1 向協議中引入了信息性狀態碼,這些狀態碼相對較新。
100:HTTP客戶端應用程序中有一個實體的主體部分要發送給服務器,但是希望在發送之前查看一下服務器是否會接受這個實體。
客戶端與100Continue
如果客戶端在向服務器發送一個實體,并且愿意在發送實體之間等待100 continue響應,客戶端發送一個攜帶了100 continue的expect請求首部。如果客戶端不發送實體,就不應該發送100continue expect首部,這樣會使得服務器誤以為客戶端要發送一個實體。
100 continue 是一種優化,客戶端應用程序只有在避免向服務器發送一個服務器無法處理或者使用的大實體的時候,才使用100continue
代理與100continue
如果代理從服務器受到了一條帶有100 continue期望的請求,如果不知道版本,應該將expect首部放在請求中向下轉發。HTTP/1.1 用417 Expectation Failed
代理決定代表http1.0或之前版本兼容的客戶端,在其請求中放入expect首部和100continue值,不會講100 Continue響應轉發給客戶端。
200 ~ 299 ——— 成功狀態碼
300 ~ 399 ——— 重定向狀態碼
如果資源已經被移動,可以發送一個重定向狀態碼和一個可選的Loacation首部來告訴客戶端資源已經被移走,以及現在的位置。
可以通過某些重定向狀態碼對資源的應用程序本地副本和源端服務器上的資源進行驗證。對于那些包含了重定向的非HEAD請求進行響應的時候,需要包含一個實體,并且在實體中包含描述信息和指向多個重定向的URL的連接。
302 303 307狀態碼存在一些交叉,主要源于HTTP/1.0和HTTP/1.1應用程序對這些狀態碼處理方式不同
當HTTP/1.0客戶端發起一個post請求,并且在響應中受到302重定向狀態碼的時候,會接收到Location首部的重定向URL,并且這些URL發起一個GET請求。
HTTP/1.0服務器受到來自HTTP/1.0客戶端的POST請求之后發送302狀態碼,服務器希望客戶端能夠接受重定向URL,并且向重定向的URL發送一個GET請求
對于HTTP/1.1客戶端,用307狀態碼取代302,稱為臨時重定向。服務器可以講302保留起來,為HTTP/1.0進行使用。
400 ~ 499 ——— 客戶端錯誤狀態碼
500 ~ 599 ——— 服務器錯誤狀態碼
代理嘗試代表客戶端與服務器進行交流,代理會發布5XX服務器錯誤狀態碼來描述所遇到的問題。
首部
首部和方法配合工作,決定了客戶端和服務器能做什么事情。
- 通用首部: 客戶端和服務器都可以使用的通用首部
- 請求首部: 請求首部是請求報文中特有的,為服務器提供了一些額外的信息。
- 響應首部: 為客戶端提供信息。
- 實體首部: 實體首部是對實體主體部分的首部
- 擴展首部: 擴展首部是非常標準的首部,未被添加到已批準的HTTP規范中,但是HTTP程序會接受他們并對其進行轉發
通用首部
有些首部提供了與報文相關的最基本的信息,它們被稱為通用首部
通用緩存首部
http/1.0 引入了一個允許http應用程序緩存對象本地副本的首部,這樣不需要從源服務器獲取了,最新的http版本有非常豐富的緩存參數集
請求首部
請求首部只是在請求報文中有意義的首部,用于說明是誰或什么在發送請求,請求源自何處,或者客戶端的喜好以及能力。
Accept首部
Accept首部: 媒體類型, 字符集, 編碼方式, 語言, 拓展傳輸編碼
條件請求首部
為請求加上限制。
安全請求首部
要求客戶端在獲取資源之前,先對自身進行認真,使得事務安全。
代理請求首部
響應首部
為客戶端提供一些額外的信息。
協商首部
HTTP/1.1可以為服務器和客戶端提供對資源進行協商的能力。
安全響應首部
實體首部
由于請求和響應報文中都可能包含實體部分,所以在這兩種類型的報文中都可能出現這些首部
實體首部可以告知報文的接收者它在對什么進行處理