HTTP簡史

高性能瀏覽器網絡 --> 第三部分 HTTP --> 第9章 HTTP簡史


    HTTP是因特網上最廣泛和普遍採用的應用協議之一:它是客戶端與服務器之間共同的語言,造就了今天的web網絡。HTTP誕生之初,只是簡單作爲一種關鍵字導航路徑,現在它不僅僅用於瀏覽器,而是幾乎被所有連網軟件和硬件應用所採用。
本章,我們將對HTTP協議的進化史做一個簡要概括。關於各種各樣的HTTP語義的完整討論超出了本書的範圍,但對HTTP關鍵設計的變化,以及每一個變化之後的動機的理解,將給與我們討論HTTP性能的必要的背景知識,特別是在HTTP 2.0的許多改進即將到來的背景下。

HTTP 0.9: 單行協議(The One-Line Protocol)


最初的HTTP協議由Tim Berners-Lee提出,當初設計時就儘量考慮簡單性,以幫助實現他的一個新想法:萬維網。該策略似乎已經奏效了。
在1991年,Berners-Lee概述了新協議的設計動機,並列出了幾個高層設計目標:文件傳輸功能,能夠請求搜索超文本文檔,格式協商,能夠把一個客戶轉介到另一個服務器。爲了用行動證明這些理論,他創建了一個簡單的原型,實現了部分規劃功能:
  • 客戶端請求是一個單一的ASCII字符串
  • 客戶端請求由一個回車符號結束
  • 服務器響應是一個ASCII字符流
  • 服務器響應是一個HTML
  • 文檔傳輸完成後連接即終止
聽起來好像很複雜,其實很簡單。一個相當簡單的,Telnet友好協議實現了這些規則。

          


這個請求由一個單行組成:GET 方法和請求文檔的路徑。響應是一個超文本文檔 -- 沒有頭部信息和其它元數據,只有HTML。再簡單不過了。此外,因爲前面提到的交互只是 the intended protocol的一個子集,所以非正式的被稱爲HTTP 0.9。
HTTP誕生於1991年,並後面的幾年迅速進化。讓我們簡明扼要概述HTTP 0.9的功能:
  • C-S,請求響應協議
  • ASCII協議,運行在TCP/IP鏈路上
  • 用戶傳輸超文本
  • 每個請求之後關閉服務器與客戶端之間的連接
一些流行的web服務器,比如Apache, Nginx,仍然部分支持HTTP 0.9協議,因爲與現在的版本相比沒有多大不同!你可以打開一個Telnet會話並試着通過HTTP 0.9 訪問google.com,或者你喜歡的站點,以堅持這一早期協議的行爲和限制。

HTTP 1.0: 快速增長以及非正式RFC(Rapid Growth and Informational RFC)


1991年到1995年這段時間,是HTML規範,一種新的被稱爲“web browser”的軟件趨同進化時期,面向消費者的公共因特網基礎設施也在這段時間出現並快速發展。
對這個新誕生的Web, 我們想要的功能越來越多,而且隨着它的迅速普及,許多HTTP 0.9的侷限被暴露出來:我們需要一個能做得更多的協議,不僅僅服務於超文本,還要能提供更豐富的關於請求和響應的元數據,允許內容協商,等等。In turn, 新生的web開發者社區對此作出了迴應,他們通過一個特殊的過程,生產大量實驗性的HTTP服務器和客戶端實現:實現,部署,看其它人是否採用。
在這個快速試驗區間,一套最佳實踐和通用模式開始出現,1996年5月,HTTP工作組(HTTP -WG)發佈了RFC 1945,該文檔記錄了坊間流傳的許多HTTP 1.0實現的”常見用法“。注意這只是一個指導性的RFC:我們知道,HTTP 1.0不是一個正式的規範或因特網標準。
但話說回來,一個HTTP1.0請求應該與此類似:

                          

  帶HTTP版本號的請求行,後面跟着請求頭
 響應狀態,後面跟着響應頭
前面所述的這個交換並沒有戰士HTTP 1.0的所有功能,不過它體現了協議的一些關鍵變化:
  • 請求可能包括多行,每一行是一個頭域
  • 響應對象以一個響應狀態行開始
  • 響應對象有它自己的由換行符分割的頭域
  • 響應對象不只限於超文本
  • 在每個請求之後端口服務器與客戶端連接
請求和響應頭均以ASCII編碼,但響應對象可以是任何類型:一個HTML文件,一個普通文本文件,一張圖片,或其它任何類型的內容。因此,HTTP的”超文本傳輸“部分在引入不久之後就成爲了一個誤稱。現實中,HTTP進化很快,已經成爲超媒體(hypermedia transport),但原來的名字一直流傳下來。
除了媒體類型協商,這個RFC也記錄了許多其它通用實現能力:內容編碼,字符集支持,multi-part types,權限控制,緩存,代理行爲,日期格式,等等。

HTTP 1.1:因特網標準


推動HTTP成爲一個官方 IETF因特網標準的工作與圍繞HTTP 1.0的文檔工作並行進行已有大約四年之久:在1995和1999年間。事實上,第一個官方HTTP 1.1標準是在RFC 2068中定義的,該RFC正式發佈於1997年1月,大約在HTTP 1.0發佈之後六個月。兩年半之後,1999年的六月,許多改進和更新被集成進標準中,並作爲RFC 2616發佈。

HTTP 1.1標準解決了之前的版本中一些含糊不清的地方,並引入了許多關鍵性能優化:keepalive連接,chunked編碼傳輸,字節範圍請求,額外的緩存機制,傳輸編碼,還有請求流水線。
瞭解這些功能後,現在我們我們來看看一個由現代HTTP瀏覽器和客戶端執行的一個典型的HTTP 1.1會話是怎麼樣的。

$> telnet website.org 80
Connected to xxx.xxx.xxx.xxx

GET /index.html HTTP/1.1 
Host: website.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4)... (snip)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: __qca=P0-800083390... (snip)

HTTP/1.1 200 OK 
Server: nginx/1.0.11
Connection: keep-alive
Content-Type: text/html; charset=utf-8
Via: HTTP/1.1 GWA
Date: Wed, 25 Jul 2012 20:23:35 GMT
Expires: Wed, 25 Jul 2012 20:23:35 GMT
Cache-Control: max-age=0, no-cache
Transfer-Encoding: chunked

100 
<!doctype html>
(snip)

100
(snip)

0 

GET /favicon.ico HTTP/1.1 
Host: www.website.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4)... (snip)
Accept: */*
Referer: http://website.org/
Connection: close 
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: __qca=P0-800083390... (snip)

HTTP/1.1 200 OK 
Server: nginx/1.0.11
Content-Type: image/x-icon
Content-Length: 3638
Connection: close
Last-Modified: Thu, 19 Jul 2012 17:51:44 GMT
Cache-Control: max-age=315360000
Accept-Ranges: bytes
Via: HTTP/1.1 GWA
Date: Sat, 21 Jul 2012 21:35:22 GMT
Expires: Thu, 31 Dec 2037 23:55:55 GMT
Etag: W/PSA-GAu26oXbDi

(icon data)
(connection closed)

1

請求HTML文件, 並指明編碼,字符集以及cookie元數據

2

以Chunked方式響應之前的HTML請求

3

一個16進制字符數字表示的chuank字節數

4

chunked流響應結束

5

通過同一個TCP連接請求一個icon文件

6

通知服務器不重用連接

7

響應icon文件,接着關閉連接

唷,信息量很大啊!第一個也是最明顯的差異是,我們有兩個請求對象,一個用於請求HTML網頁,一個用於請求一副圖像,兩者通過同一個連接發送。這是連接keepalive在起作用,它允許我們重用已存在的HTTP連接,發送到同一個主機的多個請求,以提供快得多的端用戶體驗。 see “Optimizing for TCP”.
要終止持久連接,通知第二個客戶端請求通過連接頭髮送一個顯示的 close 字串給服務器。類似的,一旦響應傳輸完成,服務器也可以通知客戶關閉當前連接。技術上,即使沒有這樣的信號,任意一邊都能夠終止TCP連接,但客戶端和服務器應該儘可能的提供它,以使雙方能夠採用更好的重用策略。

HTTP 1.1改變了HTTP協議的語義,默認使用連接keepalive。意思是,除非說明(通過Connection:close頭),服務器應該默認保持連接打開。
然而,這個功能是向後兼容HTTP 1.0的,即通過Connection: Keep-Alive頭。因此,如果你正在使用HTTP 1.1,技術上你不需要Connection: Keep-Alive頭,儘管如此,許多客戶端仍然選擇提供它。

另外,HTTP 1.1協議添加了內容, 編碼,字符集,甚至語言協商,傳輸編碼,緩存目錄,客戶端cookies,加上其它十幾種功能都能夠在每個請求上進行協商。
我們不是詳述每一個HTTP 1.1功能的語義。這要夠寫一本專門書籍了,而且已經有不少這樣的書籍了。前面的例子很好的展示了HTTP的進步和進化,以及每個客戶端-服務器交換的錯綜複雜的步驟。體現了很多東西!


原文:http://chimera.labs.oreilly.com/books/1230000000545/ch09.html


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章