一、什麼是HTTP?
超文本傳輸協定(英文:HyperText Transfer Protocol,縮寫:HTTP)是網際網路上應用最為廣泛的一種網絡協定。設計HTTP最初的目的是為了提供一種釋出和接收HTML頁面的方法。通過HTTP或者HTTPS協定請求的資源由統一資源辨別符(Uniform Resource Identifiers,URI)來辨別。
HTTP的發展是網際網路協會(World Wide Web Consortium)和Internet工作小組(Internet Engineering Task Force)合作的結果,(他們)最終釋出了一系列的RFC,其中最著名的RFC 2616,定義了HTTP協定中現今廣泛使用的一個版本—HTTP 1.1。
二、協定概述
HTTP協定(HyperText Transfer Protocol,超文本轉移協定)是用于從WWW伺服器傳輸超文本到本地浏覽器的傳送協定。它可以使浏覽器更加高效,使網絡傳輸減少。它不僅保證計算機正确快速地傳輸超文本文檔,還确定傳輸文檔中的哪一部分,以及哪部分内容首先顯示(如文本先于圖形)等
HTTP是一個應用層協定,由請求和響應構成,是一個标準的用戶端伺服器模型。HTTP是一個無狀态的協定。
通常,一次Web請求的基本過程:
建立連接配接→接收請求→處理請求→通路資源→建構響應→發送響應→記錄日志
由HTTP用戶端發起一個請求,建立一個到伺服器指定端口(預設是80端口)的TCP連接配接。HTTP伺服器則在那個端口監聽用戶端的請求。一旦收到請 求,伺服器會向用戶端傳回一個狀态,比如"HTTP/1.1 200 OK",以及傳回的内容,如請求的檔案、錯誤消息、或者其它資訊。
HTTP協定的主要特點可概括如下:
1)支援客戶/伺服器模式。支援基本認證和安全認證。
2)簡單快速:客戶向伺服器請求服務時,隻需傳送請求方法和路徑。請求方法常用的有GET、HEAD、POST。每種方法規定了客戶與伺服器聯系的類型不同。由于HTTP協定簡單,使得HTTP伺服器的程式規模小,因而通信速度很快。
3)無狀态:HTTP協定是無狀态協定。無狀态是指協定對于事務處理沒有記憶能力。缺少狀态意味着如果後續處理需要前面的資訊,則它必須重傳,這樣可能導緻每次連接配接傳送的資料量增大。
三、HTTP協定版本
超文本傳輸協定已經演化出了很多版本,它們中的大部分都是向下相容的。在RFC 2145中描述了HTTP版本号的用法。用戶端在請求的開始告訴伺服器它采用的協定版本号,而後者則在響應中采用相同或者更早的協定版本。
HTTP/0.9
誕生于1991,僅用于傳輸html文檔,已過時。隻接受GET一種請求方法,沒有在通訊中指定版本号,且不支援請求頭。由于該版本不支援POST方法,是以用戶端無法向伺服器傳遞太多資訊
HTTP/1.0
這是第一個在通訊中指定版本号的HTTP協定版本,至今仍被廣泛采用,特别是在代理伺服器中。支援多媒體資料的處理,keep-alive(保持連接配接),有緩存功能
HTTP/1.1
目前版本。持久連接配接被預設采用,并能很好地配合代理伺服器工作。還支援以管道方式在同時發送多個請求,以便降低線路負載,提高傳輸速度。更多的請求方法,更精細的緩存控制,持久連接配接
HTTP/1.1相較于HTTP/1.0協定的差別主要展現在:
·緩存處理
·帶寬優化及網絡連接配接的使用
·錯誤通知的管理
·消息在網絡中的發送
·網際網路位址的維護
·安全性及完整性
MIME: Multipurpose Internet Mail Extension
base64: 将二進制資料編碼成文本發送,并能夠讓接收方還原回原來的格式;
四、HTTP封包:
HTTP事務:一次請求以及與其對應的響應的過程
HTTP請求:request
HTTP請求封包
封包格式:
<method> <request-URL> <version>
<headers>
<entity-body>
HTTP響應:response
HTTP響應封包
<version> <status> <reason-phrase>
<entity-body>
其中:
<method>: 請求方法,希望伺服器端執行的動作,如GET、HEAD、POST等
<request-url>: 請求的資源,可以是相對路徑,也是完整的URL
<version>:協定版本,格式HTTP/<major>.<minor>,如http/1.0
<headers>:HTTP首部
<status>: 狀态碼
<reason-phrase>:原因短語,數字狀态碼易讀資訊
<entity-body>: 主體部分
請求方法<method>
HTTP/1.1協定中共定義了八種方法(也叫“動作”)來以不同方式操作指定的資源:
GET:向指定的資源發出“顯示”請求;需要伺服器發送;
HEAD:跟GET相似,但其不需要服務發送資源而僅傳回響應首部
POST:向指定資源送出資料,支援HTML表單送出,表單中有使用者填入的資料,這些資料會發送到伺服器端,由伺服器存儲至某位置(例如發送處理程式)。
PUT:與GET相反,向服務寫入文檔;例如釋出系統
DELETE:請求伺服器删除Request-URI所辨別的資源。
OPTIONS:探測伺服器端對某資源所支援的請求方法
TRACE:回顯伺服器收到的請求,主要用于測試或診斷。
CONNECT:HTTP/1.1協定中預留給能夠将連接配接改為管道方式的代理伺服器。通常用于SSL加密伺服器的連結(經由非加密的HTTP代理伺服器)。
方法名稱是區分大小寫的。當某個請求所針對的資源不支援對應的請求方法的時候,伺服器應當傳回狀态碼405(Method Not Allowed),當伺服器不認識或者不支援對應的請求方法的時候,應當傳回狀态碼501(Not Implemented)。
HTTP伺服器至少應該實作GET和HEAD方法,其他方法都是可選的。當然,所有的方法支援的實作都應當符合下述的方法各自的語義定義。此外,除了上述方法,特定的HTTP伺服器還能夠擴充自定義的方法。例如:
PATCH(由RFC5789指定的方法):用于将局部修改應用到資源。
除了以上八種方法外還有其他擴充方法:LOCK、MKCOL、COPY、MOVE
HTTP狀态碼<status>:
狀态碼
狀态碼英文名稱
中文描述
1XX:資訊性狀态碼
100
Continue
繼續。用戶端應繼續其請求
101
Switching Protocols
切換協定。伺服器根據用戶端的請求切換協定。隻能切換到更進階的協定,例如,切換到HTTP的新版本協定
2xx:成功狀态碼
200
OK
請求成功。一般用于GET與POST請求
201
Created
已建立。成功請求并建立了新的資源
202
Accepted
已接受。已經接受請求,但未處理完成
203
Non-Authoritative Information
非授權資訊。請求成功。但傳回的meta資訊不在原始的伺服器,而是一個副本
204
No Content
無内容。伺服器成功處理,但未傳回内容。在未更新網頁的情況下,可確定浏覽器繼續顯示目前文檔
205
Reset Content
重置内容。伺服器處理成功,使用者終端(例如:浏覽器)應重置文檔視圖。可通過此傳回碼清除浏覽器的表單域
206
Partial Content
部分内容。伺服器成功處理了部分GET請求
3XX:重定向狀态碼
300
Multiple Choices
多種選擇。請求的資源可包括多個位置,相應可傳回一個資源特征與位址的清單用于使用者終端(例如:浏覽器)選擇
301
Moved Permanently
永久移動。請求的資源已被永久的移動到新URI,傳回資訊會包括新的URI,浏覽器會自動定向到新URI。今後任何新的請求都應使用新的URI代替
302
Found
臨時移動。與301類似。但資源隻是臨時被移動。用戶端應繼續使用原有URI
303
See Other
檢視其它位址。與301類似。使用GET和POST請求檢視
304
Not Modified
未修改。所請求的資源未修改,伺服器傳回此狀态碼時,不會傳回任何資源。用戶端通常會緩存通路過的資源,通過提供一個頭資訊指出用戶端希望隻傳回在指定日期之後修改的資源
305
Use Proxy
使用代理。所請求的資源必須通過代理通路
306
Unused
已經被廢棄的HTTP狀态碼
307
Temporary Redirect
臨時重定向。與302類似。使用GET請求重定向
4XX:用戶端類的錯誤
400
Bad Request
用戶端請求的文法錯誤,伺服器無法了解
401
Unauthorized
請求要求使用者的身份認證
402
Payment Required
保留,将來使用
403
Forbidden
伺服器了解請求用戶端的請求,但是拒絕執行此請求
404
Not Found
伺服器無法根據用戶端的請求找到資源(網頁)。通過此代碼,網站設計人員可設定"您所請求的資源無法找到"的個性頁面
405
Method Not Allowed
用戶端請求中的方法被禁止
406
Not Acceptable
伺服器無法根據用戶端請求的内容特性完成請求
407
Proxy Authentication Required
請求要求代理的身份認證,與401類似,但請求者應當使用代理進行授權
408
Request Time-out
伺服器等待用戶端發送的請求時間過長,逾時
409
Conflict
伺服器完成用戶端的PUT請求時可能傳回此代碼,伺服器處理請求時發生了沖突
410
Gone
用戶端請求的資源已經不存在。410不同于404,如果資源以前有現在被永久删除了可使用410代碼,網站設計人員可通過301代碼指定資源的新位置
411
Length Required
伺服器無法處理用戶端發送的不帶Content-Length的請求資訊
412
Precondition Failed
用戶端請求資訊的先決條件錯誤
413
Request Entity Too Large
由于請求的實體過大,伺服器無法處理,是以拒絕請求。為防止用戶端的連續請求,伺服器可能會關閉連接配接。如果隻是伺服器暫時無法處理,則會包含一個Retry-After的響應資訊
414
Request-URI Too Large
請求的URI過長(URI通常為網址),伺服器無法處理
415
Unsupported Media Type
伺服器無法處理請求附帶的媒體格式
416
Requested range not satisfiable
用戶端請求的範圍無效
417
Expectation Failed
伺服器無法滿足Expect的請求頭資訊
5XX:伺服器類的錯誤
500
Internal Server Error
伺服器内部錯誤,無法完成請求
501
Not Implemented
伺服器不支援請求的功能,無法完成請求
502
Bad Gateway
充當網關或代理的伺服器,從遠端伺服器接收到了一個無效的請求
503
Service Unavailable
由于超載或系統維護,伺服器暫時的無法處理用戶端的請求。延時的長度可包含在伺服器的Retry-After頭資訊中
504
Gateway Time-out
充當網關或代理的伺服器,未及時從遠端伺服器擷取請求
505
HTTP Version not supported
伺服器不支援請求的HTTP協定的版本,無法完成處理
HTTP首部:<headers>:
Name: Value
如:Content-type: images/gif
分為以下幾類:
通用首部:請求和響應都可以使用的;
請求首部:
響應首部:
實體首部:用于指定實體屬性
擴充首部:非标準首部,可能是由程式開發者建立的,例如X-Forward-For
通用首部:
Connection:定義C/S之間關于請求/響應的有關選項
對于http/1.0, Connection: keep-alive
Via: 顯示了封包經過的中間節點
Cache-Control: 緩存訓示
Pragma
Client-IP:
Host: 請求的主機名和端口号,虛拟主機環境下用于不同的虛拟主機
Referer:指明了請求目前資源的原始資源的URL
User-Agent: 使用者代理,使用什麼工具發出的請求
Accept首部:使用者标明客戶自己更傾向于支援的能力
Accept: 指明伺服器能發送的媒體類型
Accept-Charset: 支援使用的字元集
Accept-Encoding: 支援使用的編碼方式
Accept-Language: 支援使用語言
條件請求首部:
Expect:
If-Modified-Since: 是否在指定時間以來修改過此資源
If-None-Match
跟安全相關的請求首部:
Authorization: 用戶端送出給服務端的認證資料,如帳号和密碼
Cookie: 用戶端發送給伺服器端身份辨別
Cookie2
Age:
Server: 向用戶端标明伺服器程式名稱和版本
協商首部:
Accept-Ranges: 對目前資源來講,伺服器所能夠接受的範圍類型
Vary: 首部清單,伺服器會根據清單中的内容挑選出最适合的版本發送給用戶端
跟安全相關的響應首部:
Set-Cookie: 伺服器端在某用戶端第一次請求時發給令牌
Set-Cookie2:
WWW-Authentication: 質詢,即要求客戶提供帳号和密碼
實體首部:
Location: 資源的新位置
Allow: 允許對此資源使用的請求方法
内容首部:
Content-Encoding
Content-Language
Content-Length
Content-Location
Content-Range
Content-Type
緩存首部:
ETag: 實體标簽
Expires: 過期期限
Last-Modified: 上一次的修改時間
五、HTTPS
目前有兩種方法來建立安全超文本協定連接配接:HTTPS URI方案和HTTP 1.1請求頭(由RFC2817引入)。由于浏覽器對後者的幾乎沒有任何支援,是以HTTPS URI方案仍是建立安全超文本協定連接配接的主要手段。安全超文本連接配接協定使用https://代替http://
安全方法
對于GET和HEAD方法而言,除了進行擷取資源資訊外,這些請求不應當再有其他意義。也就是說,這些方法應當被認為是“安全的”。用戶端可能會使用其他“非安全”方法,例如POST,PUT及DELETE,應該以特殊的方式(通常是按鈕而不是超連結)告知客戶可能的後果(例如一個按鈕控制的資金交易),或請求的操作可能是不安全的(例如某個檔案将被上傳或删除)。
但是,不能想當然地認為伺服器在處理某個GET請求時不會産生任何副作用。事實上,很多動态資源會把這作為其特性。這裡重要的差別在于使用者并沒有請求這一副作用,是以不應由使用者為這些副作用承擔責任。
副作用
假如在不考慮諸如錯誤或者過期等問題的情況下,若幹次請求的副作用與單次請求相同或者根本沒有副作用,那麼這些請求方法就能夠被視作“幂等”的。 GET,HEAD,PUT和DELETE方法都有這樣的幂等屬性,同樣由于根據協定,OPTIONS,TRACE都不應有副作用,是以也理所當然也是幂等 的。
假 如某個由若幹個請求做成的請求串行産生的結果在重複執行這個請求串行或者其中任何一個或多個請求後仍沒有發生變化,則這個請求串行便是“幂等”的。但是,可能出現若幹個請求做成的請求串行是“非幂等”的,即使這個請求串行中所有執行的請求方法都是幂等的。例如,這個請求串行的結果依賴于某個會在下次執行這 個串行的過程中被修改的變量。
六、持續連接配接
在 HTTP 0.9和1.0使用非持續連接配接,在非持續連接配接下,每個tcp隻連接配接一個web對象,連接配接在每個請求-回應對後都會關閉,一個連接配接可被多個請求重 複利用的保持連接配接機制被引入。這種連接配接持續化顯著地減少了請求延遲,因為客戶不用在首次請求後再次進行TCP互動确認建立連接配接。現在在HTTP 1.1使用持續連接配接,不必為每個web對象建立一個新的連接配接,一個連接配接可以傳送多個對象。 HTTP1.1還進行了帶寬優化,例如1.1引入了分塊傳輸編碼來允許流化傳輸持續連接配接上發送的内容,取代原先的buffer式傳輸。HTTP管道允許客戶在上一個回應被收到前發送多重請求進而進一步減少了延遲時間。
另一項協定的改進是byte serving(位元組服務),允許伺服器根據客戶的請求僅僅傳輸資源的一部分。
七、HTTP協定例子:
下面是一個我通過浏覽器自帶的開發工具HTTP用戶端與伺服器之間會話的例子,運作于www.google.com,端口80
用戶端請求封包:
<code>GET / HTTP</code><code>/1</code><code>.1</code>
<code>Host: www.google.com.hk</code>
<code>User-Agent: Mozilla</code><code>/5</code><code>.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko</code><code>/20100101</code> <code>Firefox</code><code>/27</code><code>.0</code>
<code>Accept: text</code><code>/html</code><code>,application</code><code>/xhtml</code><code>+xml,application</code><code>/xml</code><code>;q=0.9,*/*;q=0.8</code>
<code>Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3</code>
<code>Accept-Encoding: </code><code>gzip</code><code>, deflate</code>
<code>Cookie: PREF=ID=1737e66a16d71100:U=18298c26ad246c7f:FF=1:LD=zh-CN:NW=1:TM=1392034889:LM=1395146306:GM=1:S=oDsIzDBU1QId5BJy; NID=67=q2AFerfuDoSCSUYh8cLAHL3bJTcwBl0TF9COVot2bYGOUdauofGqlCr9eVtH68IOhIsggtl9bYk2k4O94fqhAW3pCSKTqA5aGqowV0u9ymWksMy8Fjd0KIsvEgXaroa7; OGPC=270001-1:</code>
<code>Connection: keep-alive</code>
伺服器應答封包:
<code>HTTP</code><code>/1</code><code>.1 200 OK</code>
<code>Alternate-Protocol: 443:quic</code>
<code>Cache-Control: private, max-age=0</code>
<code>Content-Encoding: </code><code>gzip</code>
<code>Content-Type: text</code><code>/html</code><code>; charset=UTF-8</code>
<code>Date: Wed, 19 Mar 2014 05:35:06 GMT</code>
<code>Expires: -1</code>
<code>Server: gws</code>
<code>X-Frame-Options: SAMEORIGIN</code>
<code>X-XSS-Protection: 1; mode=block</code>
<code>X-Firefox-Spdy: 3.1</code>
在HTTP1.0,單一TCP連接配接内僅執行一個“用戶端發送請求—伺服器發送應答”周期,之後釋放TCP連接配接。在HTTP1.1優化支援持續活躍連接配接:用戶端連續多次發送請求、接收應答;批量多請求時,同一TCP連接配接在活躍(Keep-Live)間期内複用,避免重複TCP初始握手活動,減少網絡負荷和響應周期。此外支援應答到達前繼續發送請求(通常是兩個),稱為“流線化”(stream)。
<a href="http://blog.51cto.com/search/result?q=Linux%E7%BD%91%E7%BB%9C%E6%9C%8D%E5%8A%A1-Web+Servic" target="_blank">Linux網絡服務-Web Servic</a>
本文轉自 鵬愛 51CTO部落格,原文連結:http://blog.51cto.com/pengai/1903470