@(StuRep)前端
來自百度FEX前端團隊
HTTP/1.0只容許在一個鏈接上創建一個當前未完成的請求。HTTP/1.1管道只部分處理了請求併發和報頭阻塞的問題。所以客戶端須要發起屢次請求經過數次鏈接服務器來減小延遲。web
此外,HTTP/1.1的報頭字段常常重複和冗長。在產生更多或更大的網絡數據包時,可能致使小的初始TCP堵塞窗口被快速填充。這可能在多個請求創建在一個新的TCP鏈接時致使過分的延遲。算法
本協議經過定義一個優化的基礎鏈接的HTTP語義映射來解決這些問題。 具體地,它容許在同一鏈接上交錯地創建請求和響應消息,並使用高效率編碼的HTTP報頭字段。 它還容許請求的優先級,讓更多的重要的請求更快速的完成,進一步提高了性能。緩存
最終協議設計爲對網絡更友好,由於它相對HTTP/1.x減小了TCP鏈接。 這意味着與其餘流更少的競爭以及更長時間的鏈接,從而更有效地利用可用的網絡容量。安全
最後,這種封裝也經過使用二進制消息幀使信息處理更具擴展性。
_服務器
HTTP/2中基本的協議單位是幀。每一個幀都有不一樣的類型和用途。例如,報頭(HEADERS)和數據(DATA)幀組成了基本的HTTP 請求和響應;其餘幀例如 設置(SETTINGS)、窗口更新(WINDOW_UPDATE)和推送承諾(PUSH_PROMISE)是用來實現HTTP/2的其餘功能。網絡
HTTP/2添加了一種新的交互模式,即服務器能推送消息給客戶端。服務器推送容許服務端預測客戶端須要來發送數據給客戶端,交換網絡使用以阻止潛在的延遲增加。服務器經過複用一個以PUSH_PROMISE幀發送的請求來實現推送,而後服務端能夠在一個單獨的流裏面發送響應給這個合成的請求。併發
幀包含的HTTP報頭字段是壓縮的。HTTP請求有多是高度冗餘的,所以壓縮能顯著減小請求和響應的大小。
_性能
一個HTTP/2鏈接是運行在TCP鏈接上的應用層協議。客戶端是TCP鏈接的發起者。優化
HTTP/2使用與HTTP/1.1相同的"http"和"https" 資源標識符(URI)。使用相同的默認端口:"http" 的80端口及「https」的443端口。所以,實現對例如http://example.org/foo或https://example.com/bar目標資源的URI請求處理須要首先肯定上游服務端(當前客戶端但願創建鏈接的對等端)是否支持HTTP/2。
這意味着檢測「http」 及「https」 的URIs是否支持HTTP/2的方法是不同的。檢測"http"URIs在章節3.2中描述。檢測"https"URIs 在章節3.3中描述。
客戶端沒法預知服務端是否支持HTTP/2.0 的狀況下使用HTTP升級機制發起「http」 URI請求([RFC7230] 章節6.7)。客戶端發起一個http1.1請求,其中包含識別HTTP/2的升級報頭字段與h2c token。HTTP/1.1必須包含一個確切的HTTP2-Settings中的報頭字段。
客戶端在不瞭解服務端是否支持HTTP/2的時候,會使用TSL [TLS12] 於其應用層協議協商擴展 [TLSALPN]。
使用TLS的HTTP/2 使用"h2"程序token。「h2c」token絕對不能由客戶端或者選定的服務端發送。
TSL協商一旦完成,客戶端和服務端均可以發送鏈接序言。
在創建TCP鏈接而且檢測到HTTP/2會被各個對等端使用後,每一個端點必須發送一個鏈接序言最終確認並做爲創建HTTP/2鏈接的初始設置參數。
若是任何一個端點沒有以一個有效的鏈接序言開頭,客戶端和服務端必須終止TCP鏈接。若是端點並無使用HTTP/2此時能夠省略超時(GOAWAY)幀(章節6.8)。
_
TTP/2鏈接一旦創建,端點之間能夠立刻交換數據幀。
幀報頭字段定義是:
HTTP/2報文報頭字段是包含一個或多個相關的鍵值對。他們在HTTP請求響應消息及服務器推送操做(見章節8.2)中使用。
報頭集合是0個或多個報頭字段的集合。當他經過鏈接傳輸的時候,報頭集合將使用HTTP報頭壓縮序列化到報文報頭塊中。序列化的報頭塊被分割成一個或多個的字節序列,稱爲報頭分區,並在報頭(章節6.2)、推送承諾(章節6.6)及延續幀(章節6.10)的載體中傳送。
HTTP報文頭壓縮並不保留報頭字段的相關順序。具備多個值的報頭字段使用特定的分割器被編碼分割到一個單獨的報頭區域(見 章節8.1.2.3 HeaderOrdering),這保留了該報頭字段中各類值的對應順序。
_
流是一個獨立的,客戶端和服務端在HTTP/2鏈接下交換幀的雙向序列。流有一下幾個重要特色:
流由31位字節的無符號整數標識。客戶端發起的流必須以奇數標示;服務器發起的流必須使用偶數來標示。0(0x0)用來標識鏈接控制信息流,且絕對不能用來創建一個新流。
HTTP/1.1升級到HTTP/2的請求將收到一個1(0x1)標識的流的響應。升級完成後,0x1流將對客戶端處於「半封閉(本地)」狀態。所以,0x1流不能被從HTTP/1.1升級的客戶端用來做爲一個新的流的標識符。
流標識符不能被重複使用。生存期長的鏈接可能致使流標識符可用範圍耗盡。客戶端不能新建流標識符時能夠針對新流創建一個新的鏈接。服務端不能新建流標識符時能夠發送一個超時幀(GOAWAY)強制客戶端對新的流使用新的鏈接。
對等端可使用設置幀裏面的SETTINGS_MAX_CONCURRENT_STREAMS參數來限制流的併發量。最大併發流設置(章節6.5.2)僅適用於終端而且只對接收到此設置的對等端有效。也就是說:客戶端能夠指定服務端能啓動的流最大併發量,並且服務端能指定客戶端能啓動的流最大併發量。終端絕對不能超過對等端設置的限制。
終端絕對不能超過對等端設定的設置。終端接收到報頭幀致使他們廣播的併發流超過限制的必須將這做爲流錯誤(章節5.4.2)處理。終端但願將SETTINGS_MAX_CONCURRENT_STREAMS的值減小到比當前打開的流更小時能夠關閉超過新的設置值的流或者容許流結束。
使用複用流介紹了針對TCP鏈接的資源爭奪致使的流阻塞。流量控制方案等確保同一鏈接上的流相互之間不會形成破壞性的干擾。流量控制在單個流及整個鏈接過程當中使用。
HTTP/2 經過使用WINDOW_UPDATE幀類型來提供流量控制(章節6.9)。
HTTP/2流流量控制目標在於容許不須要協議改動的狀況下改進流量控制算法。HTTP/2中的流量控制有如下特色:
流量控制的定義是用來保護端點在資源約束條件下的操做。例如,一個代理須要在不少鏈接之間共享內存,也有可能有緩慢的上游鏈接和快速的下游鏈接。流量控制解決的狀況是接收端在一個流上處理數據的同時一樣想繼續處理同個鏈接上的其餘流。
新建流的終端能夠在報頭幀(章節6.2)中包含優先級信息來對流標記優先級。對於已存在的流,優先級幀(章節6.3)能夠用來改變流優先級。
優先級的目的是容許終端表達它如何讓對等端管理併發流時分配資源。更重要的是,在發送容量有限時優先級能用來選擇流來傳輸幀。
流的優先級明確設置將輸入到優先級處理過程當中。它並不能保證能至關其餘相關流有特殊的處理或者傳輸順序。終端並不能使用優先級強制要求對等端按照特定順序處理併發流。所以優先級的表達僅僅是一個建議。
優先級信息能夠像它們被建立同樣使用報頭幀或者使用優先級幀來明確指定或者改變。提供優先級信息是可選的,沒有明確指定時使用默認值(章節5.3.5)。
_
錯誤碼是32位字段,用在RST_STREAM和超時幀中用來標識流或者連接錯誤的緣由。
定義瞭如下錯誤碼:
_
HTTP/2容許服務端針對客戶端一個單獨的請求,主動的發送(或推送)一個或者多個相關的響應。這種特定在服務端知道客戶端須要這些響應來完整的處理最初的請求的時候特別有用。
_
這段概況了HTTP協議的屬性,包括提升互操做性、減小暴露已知的安全漏洞,或者減小執行變更的可能。
HTTP/2鏈接是永久性的。爲了最佳的性能,它期待直到肯定與服務端的進一步溝通再也不必要的時候,客戶端纔會關閉鏈接(例如,當用戶導航到其餘特定的網頁),或者直到服務端關閉鏈接。
_
客戶端只有通過權限驗證才能獲取HTTP/2響應的資源。這在服務器推送中(章節8.2)尤其重要,客戶端在接收響應前驗證PUSH_PROMISE幀。
HTTP/2依據HTTP/1.1權限定義來檢測服務端是否有權限提供給定的響應,見RFC2818 章節3.這依賴於本地「HTTP」URI方案的域名解析,以及服務端提供的「https」方案驗證。
客戶端絕對不能以任何形式使用服務端提供的客戶端沒有權限的資源。
在跨協議攻擊中,攻擊者使客戶端在一種協議中向解析另外一種協議的服務器啓動一個交易。攻擊者可能可以使交易看起來在第二種協議中是合法的。結合對web上下文的利用,這個能夠針對保護不力的服務器在祕密網絡下進行互動。
HTTP/2報頭名稱和值編碼成帶有長度前綴的字節序列。這使得HTTP/2可以攜帶任何字符串的字節做爲報頭字段的名稱或值。中介端直接轉換HTTP/2請求或響應到HTTP/1.1時能夠容許HTTP/1.1消息建立的損壞。攻擊者能夠利用這個行爲讓中介端建立HTTP/1.1消息時帶有非法報頭字段、額外報頭字段,甚至是徹底僞造的新消息。
推送響應並無一個來自客戶端的明確請求;請求是服務端從PUSH_PROMISE幀中提供的。
緩存響應推送多是基於原始服務器的緩存控制報頭字段的指導。然而,若是服務端主機包含多個用戶可能會致使問題。例如,服務端可能爲多個用戶每一個提供小部分的URI空間。