[譯] HTTP 的進化 - 0.九、1.0、1.一、Keep-Alive、Upgrade 和 HTTPS

HTTP 的進化 - 理解真實的 HTTP 是如何工做的html

原文: https://medium.com/platform-engineer/evolution-of-http-69cfe6531ba0web


自從在 1989-1991 年間被 CERN(譯註:即「歐洲核子研究組織」的原稱 - Conseil Européen pour la Recherche Nucléaire)的 Tim Berners-Lee 發明出來之後,HTTP(超文本傳輸協議) 就一直是萬維網的基礎傳輸協議。在 C/S 計算模型中,HTTP 起到了一個「請求/響應」協議的做用。HTTP 標準由 IETF(因特網工程任務組) 和 W3C(萬維網聯盟)負責開發,並以一系列註釋請求(RFCs - Requests for Comments)的形式被髮布。HTTP 有 4 個版本:HTTP/0.九、HTTP/1.0、HTTP/1.1 以及 HTTP/2.0。當前一般使用 HTTP/1.1 版本,將來會是 HTTP/2.0。瀏覽器

HTTP/0.9 — 單行協議

  • HTTP 的首個版本 — 一個簡單的 客戶端/服務器、請求/響應、對 telenet 友好的協議
  • 請求: 單行 (method + 所請求文檔的 path)
  • 支持的方法: 僅 GET
  • 響應類型: 僅 超文本
  • 響應後立刻結束的鏈接
  • 沒有 HTTP headers (沒法傳輸其餘內容類型的文件), 沒有 status/error 代碼, 沒有 URLs, 沒有版本控制
$> telnet ashenlive.com 80

(鏈接1創建 - TCP 三次握手)
Connected to xxx.xxx.xxx.xxx

(請求)
GET /my-page.html

(超文本響應)
<HTML>
A very simple HTML page
</HTML>

(鏈接1關閉 - 斷掉 TCP)
複製代碼

流行的 web 服務器(Apache, Nginx)始終支持 HTTP/0.9。能夠打開一個 Telnet 會話訪問 google.com 試試。緩存

HTTP/1.0 — 構建可擴展性

  • 對瀏覽器友好的協議
  • 提供了對請求和響應都包含豐富元數據的 header 域 (HTTP 版本號、status code 和 content type)
  • 響應:再也不只限於超文本 (Content-Type 頭部提供了傳輸 HTML 以外文件的能力 — 如腳本、樣式或媒體文件)
  • 支持的方法: GET , HEAD , POST
  • 響應後立刻結束的鏈接
(鏈接1創建 - TCP 三次握手)
Connected to xxx.xxx.xxx.xxx

(請求)
GET /my-page.html HTTP/1.0 
User-Agent: NCSA_Mosaic/2.0 (Windows 3.1)

(響應)
HTTP/1.0 200 OK 
Content-Type: text/html 
Content-Length: 137582
Expires: Thu, 01 Dec 1997 16:00:00 GMT
Last-Modified: Wed, 1 May 1996 12:45:26 GMT
Server: Apache 0.84

<HTML> 
A page with an image
  <IMG SRC="/myimage.gif">
</HTML>

(鏈接1關閉 - 斷掉 TCP)

------------------------------------------

(鏈接2創建 - TCP 三次握手)
Connected to xxx.xxx.xxx.xxx

(請求)
GET /myimage.gif HTTP/1.0
User-Agent: NCSA_Mosaic/2.0 (Windows 3.1)

(響應)
HTTP/1.0 200 OK 
Content-Type: text/gif 
Content-Length: 137582
Expires: Thu, 01 Dec 1997 16:00:00 GMT
Last-Modified: Wed, 1 May 1996 12:45:26 GMT
Server: Apache 0.84

[image content]

(鏈接2關閉 - 斷掉 TCP)
複製代碼

HTTP/0.9 和 HTTP/1.0 的主要問題 — 爲每一個請求創建一個新鏈接

HTTP/0.9 和 HTTP/1.0 都須要爲每次請求創建一個新的鏈接(並在收到對應的響應後當即關閉該鏈接)。每次新鏈接創建時,都要經歷一遍 TCP 三次握手。考慮到更好的性能,應該着重減小這些 C/S 之間的往返通訊。HTTP/1.1 用持久化鏈接解決了這個問題。安全

典型的 TCP 三次握手(觀察一下 TCP 狀態機是如何改變其狀態的吧)

HTTP/1.1 — 標準化的協議

  • 這是當前廣泛使用的 HTTP 版本
  • 進行了重大的性能優化和特性加強,分塊傳輸、壓縮/解壓、內容緩存磋商、虛擬主機(有單個 IP 地址的主機具備多個域名)、更快的響應,以及經過增長緩存節省了更多的帶寬
  • 支持的方法: GET , HEAD , POST , PUT , DELETE , TRACE , OPTIONS
  • 長久的鏈接
(鏈接1創建 - TCP 三次握手)
Connected to xxx.xxx.xxx.xxx

(請求1)
GET /en-US/docs/Glossary/Simple_header HTTP/1.1
Host: developer.mozilla.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://developer.mozilla.org/en-US/docs/Glossary/Simple_header

(響應1)
HTTP/1.1 200 OK
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
Date: Wed, 20 Jul 2016 10:55:30 GMT
Etag: "547fa7e369ef56031dd3bff2ace9fc0832eb251a"
Keep-Alive: timeout=5, max=1000
Last-Modified: Tue, 19 Jul 2016 00:59:33 GMT
Server: Apache
Transfer-Encoding: chunked
Vary: Cookie, Accept-Encoding

[content]

(請求2)
GET /static/img/header-background.png HTTP/1.1
Host: developer.cdn.mozilla.net
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://developer.mozilla.org/en-US/docs/Glossary/Simple_header

(響應2)
HTTP/1.1 200 OK
Age: 9578461
Cache-Control: public, max-age=315360000
Connection: keep-alive
Content-Length: 3077
Content-Type: image/png
Date: Thu, 31 Mar 2016 13:34:46 GMT
Last-Modified: Wed, 21 Oct 2015 18:27:50 GMT
Server: Apache

[image content of 3077 bytes]

(鏈接1關閉 - 斷掉 TCP)
複製代碼

TCP 三次握手會在任何鏈接被創建以前發生一次。最終,當發送了全部數據以後,服務器發送一個消息,表示不會再有更多數據向客戶端發送了;則客戶端纔會關閉鏈接(斷開 TCP)。HTTP/1.0 存在的問題是,對於每一個 請求/響應 輪迴,也要創建並關閉一個鏈接。而改用 HTTP/1.1 後的優勢則在於,能夠複用同一個鏈接,來完成屢次 請求/響應 輪迴

Keep-Alive 和 Upgrade 頭部

Keep-Alive 頭部

  • Connection: Keep-Alive 頭部在 HTTP/1.1 以前就存在,但在 HTTP/1.1 中該頭部被廢棄了,由於持久化鏈接變成了默認的行爲(譯註:除非用Connection: Close顯式關閉)。Keep-Alive 頭部能夠被用於在主機之間定義持久鏈接通訊策略(好比使一個鏈接在某個事件發生以前都保持激活)。這奠基了持久化、鏈接複用、管道化及其餘不少現代 web 通訊協議中被增強能力的基礎。
  • 能夠對客戶端、服務器,或任何中間人分別設置獨立的 Keep-Alive 頭部。同時,主機能夠增長 timeout 參數以設置一個超時,或用 max 參數限制每一個鏈接的最大請求數。
HTTP/1.1 200 OK
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
Date: Thu, 11 Aug 2016 15:23:13 GMT
Keep-Alive: timeout=5, max=1000
Last-Modified: Mon, 25 Jul 2016 04:32:39 GMT
Server: Apache

[body] 
複製代碼

`Keep-Alive` 頭部的用法。全部鏈接都是獨立協商的
  • 受益於 Keep-Alive 頭部,HTTP 管道化實現了多個鏈接,以及其餘更多改進。

HTTP 管道化和多個並行鏈接

Upgrade 頭部

  • 藉助 HTTP/1.1 帶來的 Upgrade 頭部,即可用一個經常使用的協議起步,好比 HTTP/1.1,而後讓該鏈接切換到加強的協議類型,如 HTTP/2.0 或 WebSockets。
  • 在一個升級過的鏈接中,再也不有 max 參數了。升級後的協議爲 timeout 參數提供了新的策略(若是沒有特別定義,使用基礎協議默認的 timeout 值)。

由 HTTP/1.1 升級到 WebSocket[RFC6455]

HTTPS

  • 加密超文本傳輸協議(HTTPS)是 HTTP 的安全版本,使用 SSL/TLS 完成安全加密通訊。
  • 最初由網景公司在 90 年代中期開發,SSL(安全套接字層)是一種加強 HTTP 的密碼學協議,定義了客戶端和服務器之間如何安全的互相通訊。TLS(安全傳輸層協議)是 SSL 的繼承者。
  • 由於在客戶端和服務器間提供了雙向加密,HTTPS 鏈接能夠在數據傳輸中防止中間人攻擊和常見的安全威脅。

訪問 msdn.microsoft.com 站點時的 SSL 握手過程 — TCP 鏈接 -> SSL/TLS 客戶端 Hello -> SSL/TLS 服務器 Hello -> SSL/TLS 認證 -> SSL/TLS 客戶端交換祕鑰 -> SSL/TLS 新會話 Ticket -> HTTPS 加密數據傳輸

SSL/TLS 握手 — HTTPS 中的主要問題

  • 儘管 HTTPS 設計上是安全的,但 SSL/TLS 握手過程在 HTTPS 鏈接以前消耗了顯著的時間;一般會耗費 1 至 2 秒,極大影響了網站啓動性能。

HTTP/2.0 和將來

全部以上說起的特性,當今都已經被主要的服務器和瀏覽器所使用了。但像 HTTP/2.0、Server Side Events (SSE) 以及 WebSocket 這樣的現代加強功能,則改變了傳統 HTTP 的工做方式。性能優化

參考:

  1. https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Evolution_of_HTTP
  2. https://tools.ietf.org/id/draft-thomson-hybi-http-timeout-01.html
  3. https://developer.mozilla.org/en-US/docs/Web/HTTP/Protocol_upgrade_mechanism
  4. https://hpbn.co/brief-history-of-http/
----------------------------------------

長按二維碼或搜索 fewelife 關注咱們哦bash

相關文章
相關標籤/搜索