由淺入深看HTTP


一. HTTP協議的應用簡單概況

 

HTTP協議的主要特點可概括如下:


1.支持客戶/服務器模式。
2.簡單快速:客戶向服務器請求服務時,只需傳送請求方法和路徑。請求方法常用的有GET、HEAD、POST。每種方法規定了客戶與服務器聯系的類型不同。由於HTTP協議簡單,使得HTTP服務器的程序規模小,因而通信速度很快。
3.靈活:HTTP允許傳輸任意類型的數據對象。正在傳輸的類型由Content-Type加以標記。
4.無連接:無連接的含義是限制每次連接只處理一個請求。服務器處理完客戶的請求,並收到客戶的應答后,即斷開連接。采用這種方式可以節省傳輸時間。
5.無狀態:HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺少狀態意味着如果后續處理需要前面的信息,則它必須重傳,這樣可能導致每次連接傳送的數據量增大。另一方面,在服務器不需要先前信息時它的應答就較快。

 

HTTP協議對其用戶來講其實是透明的,不同於如SMTP等協議的是,HTTP的報文並非是直接交付給用戶去看的,最常見的場合是HTTP協議將超文本交付給瀏覽器或者其他超文本解析的軟件來進行處理,超文本可以使用任意的標簽語言如HTML,XSL,XML,XHTML。

 

(1)靜態超文本

客戶端直接通過URL請求到服務端相對應的資源,服務端直接將部署在數據庫或者文件系統中的標簽語言文件返還給客戶端,其中可以包括其他的URL來使得客戶端再次和網絡中的其他主機發送HTTP請求來遞歸地完成超文本的解析,如HTML中的img標簽。

 

(2)動態超文本

動態超文本需要通過軟件技術來實現創建和處理動態文本,例如CGI,JavaServlet等技術,將URL中‘?’之后的動態部分做解析並生成動態文檔,並且可以嵌入腳本語言交付給瀏覽器中的解析引擎來提高動態文檔的效率,使文檔中不必要的重復的部分獨立解析完成,甚至可以實現活動文檔,直接在文檔上運行字節碼形式的java程序或者javascript腳本。

 

二. HTTP運行事務

 

(1)HTTP報文分組

 

如下兩圖所示,為通用的HTTP請求和響應報文模型

          請求報文                       響應報文

 

 

 

1.請求報文

一個HTTP的完整請求報文的具體格式如下:

 

 

 

A.請求行--方法:

 

GET:請求服務器的文檔

HEAD:請求關於文檔的信息,但不是這個文檔本身

POST:從客戶向服務器發送一些信息

PUT:從服務器向客戶發送文檔

TRACE:把到達的請求回送

CONNECT:保留

DELETE:刪除Web網頁

OPTIONs:詢問關於可用的選項

 

 

 

B.請求行--URL:

 

URL:統一資源定位符,是在因特網上知名任何種類的信息的標准,URL定義的是四樣東西:

 

協議 :// 主機 : 端口 / 路徑

 

具體詳細不屬於HTTP內容范疇,暫且不贅述。

 

 

 

C.請求行--版本:

 

目前HTTP的最新版本是1.1,舊版本還有1.0等,具體相關定義在對應RFC中可以查找。

 

 

 

D.請求報文的首部行:(個別書上也把這個叫做頭域)

 

首部行是客戶向服務器發送信息時的附加信息,數量為零到多個,如上圖所示的格式,每個首部行占有一個首部名,一個冒號,一個空格和一個首部值。在RFC中完整的首部值列表及分類如下所示:(其中上顏色的為較常用首部名稱)

 

a.通用首部:既可以出現在請求報文中,也可以出現在響應報文中。這些是客戶端和服務器都可以使用的通用首部。可以在客戶端、服務器和其他應用程序之間提供一些非常有用的通用功能。不論報文是何種類型,都為其提供一些有用的信息。例如不管是構建請求報文還是響應報文,創建報文的日期時間都是同一個意思,因此提供這類信息的首部對這兩種類型的報文來說都是通用的。下面用表格的形式給出通用的信息性首部。

通用的信息性首部:

首部           描述
Connection        允許客戶端和服務器指定與請求/響應連接有關的選項
Date            提供日期和時間標志,說明報文是什么時間創建的
MIME-Version       給出了發送端使用的MIME版本
Trailer          如果報文采用了分塊傳輸編碼(chunked transfer encoding)方式,就可以用這個首部列出位於報文拖鞋 (trailer)部分的首部集合。
Transfer-Encoding     告知接收端為了保證報文的可靠傳輸,對報文采用了什么編碼方式。
Update          給出了發送端可能想要"升級"使用的新版本或協議
Via            顯示了報文經過的中間節點(代理、網關)

通用緩存首部:

首部           描述
Cache-Control       用於隨報文傳送緩存指示
Pragma          另一種隨報文傳送指示的方式,但並不專用於緩存

b.請求首部:提供更多有關請求的信息。請求首部是在請求報文中有意義的首部。用於說明是誰或什么在發送請求,請求源自何處,或者客戶端的喜好及能力。服務器可以根據請求首部給出的客戶端的信息,試着為客戶端提供更好的響應。

首部              描述
Client-IP           提供了運行客戶端的機器的IP地址
From              提供了客戶端用戶的E-mail地址
Host               給出了接收請求的服務器的主機名和端口號
Referer             提供了包含當前請求URI的文檔的URL
UA-Color            提供了與客戶端顯示器的顯示顏色有關的信息
UA-CPU            給出了客戶端CPU的類型或制造商
US-Disp           提供了與客戶端顯示器(屏幕)能力有關的信息
US-OS             給出了客戶端顯示器的像素信息
UA-Pixels           提供了客戶端顯示器的像素信息
User-Agent          將發起請求的應用程序名稱告知服務器(User-Agent)用戶代理

Accept首部為客戶端提供了一種將其喜好和能力告知服務器的方式,包括他們想要什么,可以使用什么,以及最重要的,他們不想要什么。這樣服務器就可以根據這些額外信息,對要發送的內容做出更明智的決定。Accept首部會使連接的兩端都受益。客戶端會得到他們想要的內容,服務器則不會浪費其時間和帶寬來發送客戶端無法使用的東西。

首部            描述
Accept            告訴服務器能夠發送哪些媒體類型
Accept-Charset       告訴服務器能夠發送哪些字符集
Accept-Encoding     告訴服務器能夠發送哪些編碼方式
Accept-Language      告訴服務器能夠發送哪些語言
TE             告訴服務器可以使用哪些擴展傳輸編碼

 

條件請求首部:有時客戶端希望為請求加上某些限制。比如客戶端已經有了一份副本,就希望只在服務器上的文檔與客戶端擁有的副本有所區別時,才請求服務器傳輸文檔。通過條件請求首部,客戶端就可以加上這種限制,要求服務器在對請求進行相應之前,確保某個請求為真。

首部            描述
Expect           允許客戶端列出某請求所要求的服務器行為
If-Match         如果實體標記與文檔當前的實體標記相匹配,就或者這份文檔
If-Modified-Since     除非在某個指定的日期之后資源被修改過,否則就限制這個請求
If-Range         允許對文檔的某個范圍進行條件請求
If-Unmodified-Since    除非在某個指定的日期之后資源沒有被修改過,否則就限制這個請求
Range          如果服務器支持范圍請求,就請求資源的指定范圍

 

安全請求首部:HTTP本身就支持一種簡單的機制,可以對請求進行質詢/響應認證。這種機制要求客戶端在獲取特定的資源之前,先對自身進行認證,這樣就可以使事務稍微安全一些。

首部            描述
Authorization        包含了客戶端提供給服務器,以便對其自身進行認證的數據
Cookie           客戶端用它想服務器傳送一個令牌-他並不是真正的安全首部,但卻是隱含了安全功能
Cookie2           用來說明請求端支持的cookie版本

 

代理請求首部:隨着因特網上代理的普遍應用,人們定義了幾個首部來協助其更好地工作。

首部            描述
Max-Forword       在通往源端服務器的路徑上,將請求轉發給其他代理或網關的最大次數-與TRACE方法一同使用
Proxy-Authorization   與Authorization首部相同,但這個首部是在與代理進行認證時使用的
Proxy-Connection    與Connection首部相同,但這個首部是在於代理建立連接時使用的

c.響應首部:提供更多有關響應的信息。響應報文由自己的響應首部集。響應首部為客戶端提供了一些額外的信息,比如誰在發送響應、響應者的功能,甚至與響應相關的一些特殊指令。這些首部有助於客     戶端處理響應,並在將來發起更好的請求。

首部          描述
Age          (從最初創建開始)響應持續時間
Public          服務器為其資源支持的請求方法列表
Retry-After       如果資源不可用的話,再次日期或時間重試
Server         服務器應用程序軟件的名稱和版本
Title          對HTML文檔來說,就是HTML文檔的源端給出的標題
Warning        比原因短語中更詳細的一些警告報文

 

協商首部:如果資源有多種表示方法-比如,如果服務器上有某文檔的法語和德語譯稿,HTTP/1.1可以為服務器和客戶端提供對資源進行協商的能力。

首部         描述
Accept-Ranges    對此資源來說,服務器可接受的范圍類型
Vary          服務器查看的其他首部的列表,可能會使響應發生變化;也就是說,這是一個首部列表,服務器會根據這些首部的內容挑選出最合適的資源版本發送給客戶端。

 

安全響應首部:

我們已經看到過安全請求首部了,本質上這里說的就是HTTP的質詢/響應認證機制的響應側。

首部          描述

Proxy-Authenticate 來自代理的對客戶端的質詢列表
Set-Cookie       不是真正的安全首部,但隱含有安全功能;可以在客戶端設置一個令牌,以便服務器對客戶端進行標識。
Set-Cookie2     與Set-Cookie類似。
WWW-Authenticate 來自服務器的對客戶端的質詢列表

 

d、實體首部:描述主體的長度和內容,或者資源自身。有很多首部可以用來描述HTTP報文的負荷。由於請求和響應文本中都可能包含實體部分,所以在這兩種類型的報文中都可能出現這些首部。實體首部提供了有關實體及其內容的大量信息,從有關對象類型的信息,到能夠對資源使用的各種有效的請求方法。總之,實體首部可以告知報文的接收者它在對什么進行處理。

首部        描述
Allow        列出了可以對此實體執行的請求方法
Location       告知客戶端實體實際上位於何處;用於將接收端定向到資源的位置上去

 

內容首部:內容首部提供了與實體內容有關的特定信息,說明了其類型、尺寸以及處理它所需的其他有用信息。比如,Web瀏覽器可以通過查看返回的內容類型,得知如何顯示對象。

首部              描述
Content-Base         解析主體中的相對URL時使用的基礎URL
Content-Encoding       對主體執行的任意編碼方式
Content-Language      理解主體時最適宜使用的自然語言
Content-Length        主體的長度或尺寸
Content-Location      資源實際所處的位置
Content-MD5        主體的MD5校驗
Content-Range       在整個資源中此實體表示的字節范圍
Content-Type         這個主體的對象模型

 

實體緩存首部:通用的緩存首部說明了如何或什么時候進行緩存。實體的緩存首部提供了與被緩存實體有關的信息,比如驗證已緩存的資源副本是否仍然有效所需的信息,以及更好地估計已緩存資源合適失效所需的線索。

首部        描述
ETag        與此實體有關的實體標記
Expires      實體不在有效,要從原始的源端再次獲取此實體的日期和時間
Last-Modified   這個實體最后一次被修改的日期和時間

 

首部行有的時候為了提高可讀性會被分為多行來提高可讀性,將其值划分為多個延續行,每個延續行的前面至少要有一個空格或者一個制表符。請求報文的實體是一些需要發送的備注性信息。

 

2.響應報文

一個HTTP的完整響應報文的具體格式如下:

 

 

A.狀態行--版本:同請求行--版本

 

 

B.狀態行--狀態碼:

大致分類如下所示:

100-199 用於指定客戶端應相應的某些動作。 
200-299 用於表示請求成功。 
300-399 用於已經移動的文件並且常被包含在定位頭信息中指定新的地址信息。 
400-499 用於指出客戶端的錯誤。 
500-599 用於支持服務器錯誤。 

具體的狀態碼參見:http://www.cnblogs.com/lxinxuan/archive/2009/10/22/1588053.html

 

 

C.狀態行--短語:所謂的短語是和狀態碼相對應的,如常見的404狀態碼對應Not found,403對應Forbidden

 

 

D.響應報文的首部行:參見請求報文的首部行

 

響應報文的實體與請求報文不同,主要存放的是服務端向客戶端發送的文檔,如果響應不是錯誤報文,則實體出現在響應報文中。

 

 

 

 

 

(2)連接模型

 

 

如上圖所示,盡管服務端使用了80號端口作為TCP連接的接收端,但HTTP本身是個無狀態的協議,服務端不會保留關於客戶端的信息,每次HTTP永遠是客戶端先發起請求,然后服務端回送響應。

 

 

關於長連接和短連接:

 

從HTTP1.1之后默認使用了長連接,在HTTP1.0中使用的是HTTP首部Connection:Keep-alive來進行長連接的實驗性拓展。長連接使數據傳輸完成之后保持TCP連接不斷開,等待在同域名下繼續使用這個通道傳輸數據,與之相對應的就是短連接,從HTTP1.1開始要在HTTP請求報文中使用Connection:close來通知不希望使用長連接。在短連接中,對每一個請求/響應都要建立一次TCP連接,舉個例子如某一個超文本文檔上有N個位於同一個服務器的圖片時,那么就要先后對該圖片所在的服務器打開和關閉N+1次TCP連接,短鏈接會給服務器帶來巨大的不必要的開銷,也減慢了連接建立和關閉的過程。在使用了長連接之后,服務器允許TCP連接的保持已減少握手過程,服務器也可以在客戶端請求時或者請求超時時關閉這個連接,在某些情況下,服務器並不知道要發送的文檔的長度,那么服務器就要把長度未知這個首部通知客戶,並在發送數據后關閉這個連接,因此客戶就可以知道數據結束的地方就要到了。另外在首部中可以通過定義Keep-Alive首部來定義TCP連接的最長使用限時。實際上頭部有了Connection: Keep-alive這個首部並不代表服務器一定就會使用長連接,客戶端和服務端都可以忽略這個首部的定義。如下所示為長連接的連接模式圖:

長連接模式下。當客戶端向服務器發生請求之后,客戶端如何判斷服務器的數據已經發生完成?除了通過服務器關閉連接來被動的關閉HTTP的TCP連接之外,可以通過消息首部字段Content-Length來判斷數據傳輸是否完畢,單位為字節,另外也可以通過使用消息首部字段Transfer-Encoding來協助完成判斷,Transfer-Encoding:clunk或者Transfer-Encoding:clunked模式可以將數據分為一塊一塊的傳輸,clunk編碼的具體格式這里暫不贅述。

 

 

關於HTTP中的Cookie:

Cookie的實質就是一個鍵值對,當一個客戶端向服務端發送請求的時候,瀏覽器就查找在Cookie目錄中是否有那個服務器發送的Cookie,如果有的話就會把相應的Cookie包含對請求之中,當這個Cookie包含在請求之中的時候服務端就可以知道這個客戶是一個老客戶,cookie的使用者和消費者都是服務端,這對於瀏覽器和消費者都是透明的。在HTTP報文分組中,與其功能相關的首部是Cookie首部和Set-Cookie首部。具體格式如下所示:

 

Set-Cookie:value [ ;expires=date][ ;domain=domain][ ;path=path][ ;secure]

Cookie : value

Cookie:value1 ; value2 ; name1=value1

 

在Set-Cookie中,可以通過定義選項的值來進一步確定Cookie的功能。

 

1.有效期選項(The expires  option)

 

緊跟cookie值后面的每個選項都以分號和空格分割,並且每個選項都指定cookie何時應該被發送到服務器。第一個選項是expires,其指定了cookie何時不會再被發送到服務器端的,因此該cookie可能會被瀏覽器刪掉。例如:

1 Set-Cookie:name=Nicholas;expires=Sat, 02 May 2009 23:38:25 GMT

在沒有expires選項時,cookie的壽命僅限於單一的會話中。瀏覽器的關閉意味這一次會話的結束,所以會話cookie只存在於瀏覽器保持打開的狀態之下。這就是為什么當你登錄到一個web應用時經常看到一個checkbox,詢問你是否選擇存儲你的登錄信息:如果你選擇是的話,那么一個expires選項會被附加到登錄的cookie中。如果expires選項設置了一個過去的時間點,那么這個cookie會被立即刪除。

 

2.域選項(The domain option)

 

下一個選項是domain,指示cookie將要發送到哪個域或那些域中。默認情況下,domain會被設置為創建該cookie的頁面所在的域名。例如本站中的cookie的domain屬性的默認值為www.nczonline.com。domain選項被用來擴展cookie值所要發送域的數量。例如:

1 Set-Cookie:name=Nicholas;domain=nczonline.net

domain設置的值必須是發送Set-Cookie消息頭的域名。例如,我無法向google.com發送一個cookie,因為這個產生安全問題。不合法的domain選項只要簡單的忽略即可。

 

3.Path選項(The path option)

另一個控制何時發送Cookie消息頭的方式是指定path選項。與domain選項相同的是,path指明了在發Cookie消息頭之前必須在請求資源中存在一個URL路徑。這個比較是通過將path屬性值與請求的URL從頭開始逐字符串比較完成的。如果字符匹配,則發送Cookie消息頭,例如:

1 Set-Cookie:name=Nicholas;path=/blog

 

 在這個例子中,path選項值會與/blog,/blogrool等等相匹配;任何以/blog開頭的選項都是合法的。要注意的是只有在domain選項核實完畢之后才會對path屬性進行比較。path屬性的默認值是發送Set-Cookie消息頭所對應的URL中的path部分。

4.secure選項(The  secure  option)

最后一個選項是secure。不像其它選項,該選項只是一個標記並且沒有其它的值。一個secure cookie只有當請求是通過SSL和HTTPS創建時,才會發送到服務器端。這種cookie的內容意指具有很高的價值並且可能潛在的被破解以純文本形式傳輸。例如

1 Set-Cookie:name=Nicholas;secure

現實中,機密且敏感的信息絕不應該在cookies中存儲或傳輸,因為cookies的整個機制都是原本不安全的。默認情況下,在HTTPS鏈接上傳輸的cookies都會被自動添加上secure選項。

 

關於HTTP的安全:

 

HTTP本身並不提供安全,然而通過在傳輸層和應用層中使用安全套接層(SSL)可以使HTTP運行在安全的環境下,即HTTPS,HTTPS可以提供保密性,客戶和服務器鑒別以及數據的完整性。

SSL的設計時為了給應用層生成的數據提供安全以及壓縮服務,一般來說SSL能接收來自任何應用層協議的數據,但最多情況下這個應用層的協議就是HTTP,SSL對應用層傳來的數據提供多種服務:

 

分片:SSL把數據划分為長度小於或者等於2的14次字節的數據分片

壓縮:數據分片通過使用一種由客戶端和服務器協商好的無損壓縮方式進行壓縮,這個服務是可選的。

報文完整性:為了保護數據的完整性,SSL使用密鑰散列函數來創建MAC。

保密:為了提供保密性,原始的數據和MAC一起用對稱密鑰加密技術來加密。

組幀:先在被加密的有效載荷上添加一個首部,然后再把這個惡有效載荷傳遞給可靠的運輸層協議。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM