一文看完HTTP3的演化歷程

HTTP協議爲Web的發展提供了驅動力,它始於1991年的HTTP/0.9,在1999年演變爲HTTP/1.1,並由IETF(互聯網工程任務組)負責進行標準化。HTTP/1.1存在了很長一段時間,但Web不斷變化的需求要求推出更好的協議,於是HTTP/2在2015年出現了。IETF最近宣佈要推出新的版本,即HTTP/3。對於有些人來說,這是一個驚喜,但也會讓他們感到有一點點困惑。如果你沒有密切關注IETF的工作,就會覺得HTTP/3出現得很突然。不過,我們可以通過一系列實驗和Web協議的演變史來追溯它的起源,特別是QUIC傳輸協議。

如果你還不熟悉QUIC,可以先看看我的一些同事所寫的文章。John的這篇文章描述了當今HTTP世界的一些惱人之處,Alessandro的這篇文章描述了傳輸層的實際細節,而Nick的這篇文章介紹瞭如何進行測試。我們在https://cloudflare-quic.com收集了更多的資源。如果你喜歡,請務必看一看我們用Rust實現的QUIC協議quiche

HTTP/3是HTTP應用程序到QUIC傳輸層的映射。這個名稱在第17版草案(draft-ietf-quic-http-17)中正式啓用,該草案於2018年10月底提出,在11月於曼谷舉行的IETF 103大會期間進行了討論並達成初步的共識。HTTP/3之前叫作HTTP over QUIC,再往前又叫HTTP/2 over QUIC。在那之前,我們有HTTP/2 over gQUIC,再往前,我們有SPDY over gQUIC。事實上,HTTP/3只是一種基於QUIC(基於UDP的多路複用和安全傳輸)的HTTP新語法。

在這篇文章中,我們將探討HTTP/3舊名稱背後的歷史以及改名背後的動機。我們將回到HTTP的早期階段,介紹一路走來所做的工作。如果你想要獲得一個整體的視圖,可以打開這個非常詳細的SVG版本


HTTP/3協議層

場景設定

在開始介紹HTTP之前,需要注意的是,有兩個協議都使用了QUIC這個名稱。gQUIC通常用來表示谷歌QUIC(原始協議),而QUIC通常用來表示IETF正在進行標準化的版本。

從90年代初期開始,Web的需求已經發生了很大的變化。我們有了新版本的HTTP,並增加了傳輸層安全(TLS)來增強安全性。

爲了更好地解釋HTTP和TLS的歷史,我整理了協議規範和日期的細節。這些信息通常以文本形式呈現出來,例如按日期排序的項目列表。但因爲存在標準分支,它們在時間上有所重疊,簡單的列表無法表達出這種複雜的關係。而且,在HTTP方面還存在一些並行的工作,這些工作通過重構核心協議來簡化使用,通過擴展協議來增加新的用途,以及通過重新定義數據交換方式來提高性能。要想跨越近30年的互聯網發展史和不同的工作流分支,並把它們串起來,需要對它們進行可視化。於是,我製作了Cloudflare Secure Web Timeline。

接下來,我將按照這個時間表來解釋HTTP歷史的關鍵篇章。爲了更好地理解本文的內容,最好先知道爲什麼要進行協議標準化以及IETF是如何實現的。因此,在回到時間表之前,我們先簡要介紹這個主題。如果你已經很熟悉IETF,可以跳過下面的部分。

互聯網標準的類型

通常,標準定義了共同的引用術語、範圍、約束、適用性和其他考慮事項。標準可以以多種形式存在,可以是非正式的(也就是所謂的“事實上的標準”)或正式的(由標準定義組織——例如IETF、ISO或MPEG——同意或發佈)。標準被用在很多領域,甚至連茶葉都有一個正式的標準——英國製茶標準BS 6008。

早期Web使用的是在IETF外部發布的HTTP和SSL協議,這些在Secure Web Timeline上被標記爲紅線。客戶端和服務器對這些協議的採用使它們成爲事實上的標準。

到了某個時刻,人們決定將這些協議正式化(後面部分將描述其背後的動機)。互聯網標準通常由IETF負責定義,IETF的指導原則是“粗略共識和可運行的代碼”。這個原則以互聯網的開發和部署經驗爲基礎,與嘗試在真空中開發完美方案的“clean room”方法是不一樣的。

IETF互聯網標準被稱爲RFC。這個解釋起來很複雜,所以我建議你閱讀由QUIC工作組聯合主席Mark Nottingham撰寫的博文“如何閱讀RFC”。這裏所謂的工作組(或WG)一般是指郵件列表。

IETF每年都會召開三次會議,爲所有工作組提供時間和設施,如果他們願意,可以親自參加會議。會議期間的議程可能安排得非常緊湊,只有非常有限的時間可用於深入討論技術領域的問題。爲了解決這個問題,一些工作組還選擇在IETF常規會議中間的幾個月召開臨時會議。自2017年以來,QUIC工作組已經召開了幾次臨時會議,會議主頁上提供了完整的會議清單

IETF會議還爲其他與IETF相關的人員提供了會面的機會,例如互聯網架構委員會(Internet Architecture Board)或互聯網研究工作組(Internet Research Task Force)。近年來,在IETF會議之前的週末都會舉行IETF Hackathon。這爲社區提供了開發可運行代碼的機會,更重要的是,可以與其他人在同一個房間裏進行互操作性測試,這樣有助於找出規範中存在的問題。

本文要強調的一點是,RFC不是突然間出現的,它們一般會經歷一個過程,通常從IETF互聯網草案(I-D)開始。如果規範已經存在,那麼要準備一個I-D就很簡單,只需要進行簡單的重新格式化。I-D從發佈之日起有6個月的有效期。要保持I-D的活躍狀態,就要發佈新版本。在實際當中,一個I-D的消失並不會產生多大後果,而且這種事情經常發生。這些文件會繼續託管在IETF文檔網站上,任何想要閱讀它們的人都可以繼續訪問它們。

I-D在Secure Web Timeline中使用紫色線條表示。每條線都有一個唯一的名稱,格式爲draft-{作者姓名}-{工作組}-{主題}-{版本}。工作組字段是可選的,有時會發生變化。如果一個I-D被IETF採納,或者直接由IETF內部發起,名字則爲draft-ietf-{工作組}-{主題}-{版本}。I-D可能會有分支,會發生合併,或者分支直接停止發展。版本從00開始,每次發佈新草案時增加1。例如,I-D第4稿的版本爲03。如果I-D名稱發生變化,版本將重置爲00。

需要注意的是,任何人都可以向IETF提交I-D,但你不應該把它們當作標準來看待。如果IETF的標準化流程針對某個I-D達成了共識,並且最終文檔通過了評審,我們最終會得到一個RFC。在這個階段名稱會再次發生變化。每個RFC都會獲得一個唯一的編號,例如RFC 7230。這些在Secure Web Timeline上使用藍線表示。

RFC是不可變文檔,這意味着修改RFC後需要一個全新的編號。修改RFC可能是爲了合併勘誤(編輯方面或技術方面的錯誤)或爲了改進規範的佈局。RFC可能會淘汰舊版本(完全替換),或者更新它們(實質性變更)。

所有IETF文檔均可在http://tools.ietf.org上公開獲得。我個人認爲IETF Datatracker對用戶更加友好,因爲它提供了文檔的進度可視化。

下面是一個例子,顯示了RFC 1945(HTTP/1.0)的開發過程,很顯然,它是Secure Web Timeline的靈感來源。

有趣的是,在我創建Secure Web Timeline的過程中,我發現上面的可視化其實是不對的。由於某種原因,它缺少了draft-ietf-http-v10-spec-05。由於I-D的生命週期是6個月,因此在成爲RFC之前似乎存在一個空白,實際上,草案05在1996年8月之前仍然有效。

Secure Web Timeline

在稍微瞭解了互聯網標準文檔的實現方式之後,現在可以開始介紹Secure Web Timeline了。接下來將展示一些圖表,它們顯示了整個時間表的重要部分。每個點代表文檔或功能的可用日期。對於IETF文檔,爲清晰起見,省略了草案編號。如果你想查看所有詳細信息,請參看完整的時間表

HTTP從1991年的HTTP/0.9協議開始,在1994年發佈了draft-fielding-http-spec-00,這個I-D很快被IETF採用,改名爲draft-ietf-http-v10-spec-00。這個I-D在1996年成爲RFC 1945(HTTP/1.0)之前經歷了6個草案版本。

但是,在HTTP/1.0相關工作完成之前,另一項與HTTP/1.1相關的工作就已啓動。draft-ietf-http-v11-spec-00於1995年11月發佈,並於1997年正式作爲RFC 2068。你們可能已經發現Secure Web Timeline中並未完全捕獲這一系列事件,這是可視化工具的問題。

1997年中期,HTTP/1.1的修訂工作啓動了,對應的I-D爲draft-ietf-http-v11-spec-rev-00。這項工作於1999年完成,並作爲RFC 2616發佈。2007年之前,IETF的HTTP世界都很平靜。

SSL和TLS簡史

SSL 2.0規範在1995年左右發佈,而SSL 3.0則在1996年11月發佈。有趣的是,SSL 3.0對應的RFC 6101於2011年8月發佈。根據IETF的說法,這屬於“Historic”,即“通常是爲了記錄那些被考慮過但又被放棄的想法,或者在決定記錄它們時就已經是Historic的協議”。對於這種情況,擁有一個描述SSL 3.0的IETF文檔是有好處的,因爲它可以作爲規範在其他地方被引用。

我們更感興趣的是SSL是如何激發了TLS的開發,TLS從1996年11月開始,I-D爲draft-ietf-tls-protocol-00。它經歷了6個草案版本,並在1999年初作爲RFC 2246(TLS 1.0)發佈。

在1995年到1999年期間,SSL和TLS協議被用於保護HTTP通信。作爲一種事實上的標準,這種方式運作得很好。直到1998年1月,隨着draft-ietf-tls-https-00的發佈,HTTPS的正式標準化過程纔開始。這項工作在2000年5月結束,發佈了RFC 2616(HTTP over TLS)。

TLS在2000年至2007年期間繼續演化,出現了TLS 1.1和TLS 1.2。TLS的下一個版本於2014年4月被採用,即draft-ietf-tls-tls13-00。在經歷了28個草案之後,於2018年8月成爲RFC 8446(TLS 1.3)。

互聯網標準化進程

我希望你能夠通過仔細觀察時間表瞭解IETF的工作原理。互聯網標準的形成大致是這樣的:研究人員或工程師設計適合特定用例的實驗性協議,然後在不同規模水平公開或私下對協議進行實驗。實驗數據有助於識別或改進問題。相關工作可能被公開,用於向公衆作出解釋,收集更廣泛的意見,或找到其他實現者。那些採用了早期工作成果的人讓實驗協議成爲了事實上的標準,對實驗協議成爲正式標準起到了促進作用。

對於正在考慮實現、部署或以某種方式使用協議的組織而言,協議的狀態是一個重要的考慮因素。正式的標準化過程會讓事實上的標準更具吸引力,因爲它會帶來更高的穩定性。但需要注意的是,並非所有正式標準化都能獲得成功。

確定最終標準的過程幾乎與標準本身一樣重要。以最初的想法爲基礎,邀請人們一起來貢獻想法,這些人擁有更廣泛知識和經驗,可以爲更廣泛的人羣帶來更有用的東西。但是,標準化過程並不總是那麼容易,陷阱和障礙總是存在的。有時候,這個過程需要很長時間,以至於最終得到的結果已經變得不那麼重要了。

Cloudflare的可運行代碼

Cloudflare很自豪能夠成爲不斷髮展的新協議的早期採用者。我們很早就開始採用新標準,如HTTP/2,我們還嘗試使用實驗性或尚未最終確定的功能,如TLS 1.3和SPDY。

在IETF標準化過程中,將可運行的代碼部署在跨不同網站的真實網絡上可以幫助我們瞭解協議在真實環境中的運行情況。我們將現有的專業知識和從實驗中獲得的信息結合起來,用以改進可運行的代碼,並向正在標準化協議的工作組反饋有意義的問題和改進意見。

測試新的東西並不是唯一的優先事項。創新者應該知道什麼時候該前進,什麼時候該把舊的創新拋在腦後。有時候這與面向安全的協議有關,例如,由於POODLE漏洞,Cloudflare默認禁用了SSLv3。在其他情況下,舊協議會被更先進的新協議所取代,Cloudflare就使用HTTP/2替換了SPDY。

相關協議的引入和棄用在Secure Web Timeline上使用橙色線表示。虛線豎線有助於將Cloudflare事件與相關的IETF文檔關聯起來。例如,Cloudflare在2016年9月引入了TLS 1.3支持,而RFC 8446最終版在兩年後的2018年8月發佈。

HTTP重構

HTTP/1.1是一個非常成功的協議。時間表顯示,在1999年之後,IETF就沒有太多的動作。然而,真實的情況是,多年的使用經驗發現了RFC 2616中潛在的問題,這些問題導致了一些互操作性問題。此外,其他RFC(如2817和2818)擴展了RFC 2616。2007年,IETF決定啓動一項新工作,以改進HTTP協議規範。這項工作被稱爲HTTPbis(“bis”源於拉丁語,意爲“兩個”、“兩次”或“重複”),併成立了新的工作組。原始章程描述了他們試圖解決的問題。

簡單地說就是HTTPbis決定重構RFC 2616。它將合併勘誤修復,並借鑑在此期間發佈的其他一些規範的某些方面。他們將文檔分成了幾個部分,於2007年12月發佈了6個I-D:

  • draft-ietf-httpbis-p1-messaging
  • draft-ietf-httpbis-p2-semantics
  • draft-ietf-httpbis-p4-conditional
  • draft-ietf-httpbis-p5-range
  • draft-ietf-httpbis-p6-cache
  • draft-ietf-httpbis-p7-auth

上圖顯示了在最終標準化之前,這項工作如何通過長達7年的起草過程,發佈了27個草案版本。2014年6月,發佈了所謂的RFC 723x系列(其中x的範圍爲從0到5)。HTTPbis工作組主席用“RFC2616已死”來慶祝這一成就,也就是說這些新文件將使舊的RFC 2616作廢。

這與HTTP/3有什麼關係?

當IETF正忙於RFC 723x系列時,這個世界並沒有停下發展的腳步。人們繼續在互聯網上增強、擴展和試驗HTTP。其中就包括谷歌,谷歌已經開始試驗一種叫作SPDY(發音爲speedy)的協議。谷歌宣稱,這個協議旨在提高Web瀏覽的性能。2009年底,SPDY v1發佈,很快又在2010年推出SPDY v2。

我不打算深入解釋SPDY的技術細節,關鍵的是要知道,SPDY採用了HTTP的核心範式,並對數據交換格式稍作修改。事後看來,HTTP明確劃分了語義和語法。語義描述了請求和響應交換的概念,包括:方法、狀態碼、標頭(元數據)和正文(有效載荷),語法則描述瞭如何將語義映射到在網絡上傳輸的字節。

HTTP/0.9、1.0和1.1共享了很多語義,還以字符串形式共享了一些語法。SPDY採用了HTTP/1.1語義,並將語法從字符串改爲二進制形式。

谷歌的SPDY實驗表明,他們想要改變HTTP語法,但會保留現有的HTTP語義。例如,保留https://格式的URL可以避免很多可能會影響到採用率的問題

在看到了一些積極的結果後,IETF認爲是時候看看HTTP/2.0的效果了。於2012年3月舉行的IETF 83大會的一份幻燈片展示了HTTP/2.0的需求、目標和成功的衡量標準。它還明確指出“HTTP/2.0只在傳輸格式方面與HTTP/1.x不兼容”。

在那次會議期間,社區成員被邀請分享他們的提案。提交審議的I-D包括draft-mbelshe-httpbis-spdy-00、draft-montenegro-httpbis-speed-mobility-00和draft-tarreau-httpbis-network-friendly-00。最終,SPDY草案獲得通過,並於2012年11月啓動draft-ietf-httpbis-http2-00相關工作。在短短兩年多的時間內完成了18次草案,並於2015年發佈了RFC 7540(HTTP/2)。在這期間,HTTP/2的語法分散到足以使HTTP/2和SPDY不兼容。

這些年,IETF一直忙於與HTTP相關的工作,HTTP/1.1重構和HTTP/2標準化同時進行。這與21世紀初多年的平靜形成鮮明對比。

儘管HTTP/2正處於標準化階段,但使用SPDY和試驗SPDY仍然是有好處的。Cloudflare從2012年8月起開始支持SPDY,但在2018年2月就棄用了。當時的統計數據顯示,不到4%的Web客戶想要使用SPDY。2015年12月,我們又推出了HTTP/2支持,也就是在RFC發佈後不久,我們的數據分析表明,有相當一部分Web客戶端可以使用它。

支持SPDY和HTTP/2協議的Web客戶端傾向於使用TLS。2014年9月推出的通用SSL可以確保所有註冊到Cloudflare的網站都能夠在我們引入這些新協議時使用它們。

gQUIC

谷歌在2012年至2015年期間繼續進行實驗,併發布了SPDY v3和v3.1。他們也開始研究gQUIC(當時發音爲quick),並於2012年初推出初始版本的規範。

gQUIC的早期版本使用了SPDY v3形式的HTTP語法,因爲當時HTTP/2規範還沒有完成。SPDY二進制語法被打包成可以在UDP數據報中發送的Q​​UIC數據包,與HTTP使用的TCP傳輸有所不同。


SPDY over gQUIC協議層

gQUIC使用了一些巧妙的技巧來提升性能,其中之一就是打破應用程序和傳輸之間的分層界限。這意味着gQUIC只支持HTTP。因此,當時被稱爲“QUIC”的gQUIC被當作HTTP的下一個候選版本。儘管QUIC在過去幾年中不斷髮生變化,直到今天,人們還是將QUIC理解爲最初的HTTP變體。

有關gQUIC的實驗繼續進行,並最終切換到更接近HTTP/2的語法,以至於大多數人直接將其稱爲“HTTP/2 over QUIC”。但是,由於技術方面的限制,它們之間存在一些非常微妙的差異,比如HTTP標頭的序列化和交互方式。雖然這是一個很小的差異,但卻意味着HTTP/2 over gQUIC與IETF的HTTP/2是不兼容的。

最後,我們始終需要考慮互聯網協議的安全性問題。gQUIC沒有使用TLS,相反,谷歌開發了一種叫作QUIC Crypto的方法,可以加快安全握手過程。已經與服務器建立了安全會話的客戶端可以重用會話信息來執行“零往返時間”或0-RTT握手(0-RTT後來被TLS 1.3採用)。

那麼HTTP/3到底是什麼?

到目前爲止,我們應該已經熟悉了標準化過程,也知道了gQUIC是什麼。2015年6月,谷歌提交了題爲“QUIC: A UDP-based Secure and Reliable Transport for HTTP/2”的draft-tsvwg-quic-protocol-00。它的語法幾乎與HTTP/2相同。

簡單地說,與IETF合作的結果就是,QUIC在傳輸層似乎提供了很多優勢,應該與HTTP解耦,因此有必要重新引入分層。此外,有人傾向於返回到基於TLS的握手機制(由於在這個時候有關TLS 1.3的工作正在進行中,同時也正在整合0-RTT,所以並沒有那麼糟糕)。

大約一年後,也就是在2016年,提交了一系列新的I-D:

  • draft-hamilton-quic-transport-protocol-00
  • draft-thomson-quic-tls-00
  • draft-iyengar-quic-loss-recovery-00
  • draft-shade-quic-http2-mapping-00

這是另一個HTTP和QUIC令人感到混淆的地方。draft-shade-quic-http2-mapping-00的標題是“HTTP/2 Semantics Using The QUIC Transport Protocol”,並將自己描述爲“基於QUIC的HTTP/2語義映射”。但其實這種說法不是很恰當。HTTP/2在保持語義的同時也在改變語法。此外,“HTTP/2 over gQUIC”已經不能用來準確地描述語法了,至於原因,之前已經提到過了。

IETF版本的QUIC是一個全新的傳輸協議。這是一個巨大的承諾,在做出這個承諾之前,IETF希望先看看成員的實際興趣。爲此,2016年在柏林舉行的IETF 96大會上召開了正式的“Birds of a Feather”會議。我很幸運能夠親自參加這次會議,還有其他數百人也參加了會議。在會議結束時達成了共識,QUIC將被IETF採用並標準化。

用於將HTTP映射到QUIC的第一個IETF QUIC I-D(draft-ietf-quic-http-00)採用了Ronseal方法,並將其名稱簡化爲“HTTP over QUIC”。不幸的是,這項工作並沒有完全完成,而且在正文中出現了很多次“HTTP/2”。I-D新編輯Mike Bishop發現了這一點,並開始修復HTTP/2的命名錯誤。在01草案中,描述被改爲“基於QUIC的HTTP語義映射”。

隨着時間的推移和版本的增加,“HTTP/2”一詞的使用在逐漸減少。往後推兩年,也就是在2018年10月,I-D到了第16版。雖然HTTP over QUIC與HTTP/2很相似,但它終究是一個獨立的、不向後兼容的HTTP語法。對於那些沒有密切關注IETF開發的人(佔了大多數)來說,文檔名稱並沒有體現出這種差異。標準化的要點之一是促進交流和互操作性,然而,像命名這樣簡單的事情是造成社區混亂的主要原因。

回想一下2012年所說的“HTTP/2.0只在傳輸格式方面與HTTP/1.x不兼容”。IETF遵循了現有的線索。在IETF 103召開之前和召開期間,經過深思熟慮,各方一致同意將“HTTP over QUIC”重命名爲HTTP/3。

但RFC 7230和7231不同意你對語義和語法的定義!

有時候,文檔的標題也會令人感到混淆。描述語法和語義的HTTP文檔是:

  • RFC 7230——超文本傳輸​​協議(HTTP/1.1):消息語法和路由
  • RFC 7231——超文本傳輸​​協議(HTTP/1.1):語義和內容

我們可能會對這些名稱進行過多的解讀,認爲基本的HTTP語義是特定於HTTP版本的,即HTTP/1.1。好在HTTPbis工作組正在努力解決這個問題。一些成員正在進行另一輪文件修訂工作。這項工作現在正在進行當中,被稱爲HTTP核心活動。它將把六份草案壓縮成三份:

  • HTTP語義(draft-ietf-httpbis-semantics)
  • HTTP緩存(draft-ietf-httpbis-caching)
  • HTTP/1.1消息語法和路由(draft-ietf-httpbis-messaging)

基於這種新的結構,HTTP/2和HTTP/3成爲了通用HTTP語義的語法定義。這並不意味着它們除了語法之外就沒有自己的特性,但這應該有助於今後的討論。

總結

這篇文章簡要介紹了HTTP在過去三十年的標準化過程。我試着在不涉及很多技術細節的情況下解釋我們是如何發展到達今天的HTTP/3的。如果你想要跳過中間的部分,希望用一句話來概括,那麼應該是這樣:HTTP/3只是一種基於IETF QUIC(一種基於UDP的多路複用和安全傳輸)的新HTTP語法。

在這篇文章中,我們介紹了HTTP和TLS發展過程的重要篇章。我們將全部內容整合到下面的這張Secure Web Timeline中。對於喜歡一探究竟的人,請務必查看完整版本,其中包含了草案編號。

英文原文:https://blog.cloudflare.com/http-3-from-root-to-tip/

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