HTTP/2筆記之鏈接創建

前言

HTTP/2協議在TCP鏈接之初進行協商通訊,只有協商成功,纔會涉及到後續的請求-響應等具體的業務型數據交換。html

HTTP版本標識符

  • h2,基於TLS之上構建的HTTP/2,做爲ALPN的標識符,兩個字節表示,0x68, 0x32,即https
  • h2c,直接在TCP之上構建的HTTP/2,缺少安全保證,即http
  • 在HTTP/2 RFC文檔出現以前,以上版本字段須要添加上草案版本號,相似於h2-11,h2c-17

HTTP/2 請求過程

針對直接創建在標準TCP之上HTTP2,在未知服務器是否提供HTTP/2支持以前,能夠依賴現有HTTP/1.1進行試探。java

HTTP版本的請求內容

  1. 客戶端發起請求,只有請求報頭:
    GET / HTTP/1. 1 Host: server. example. com Connection: Upgrade, HTTP2-Settings Upgrade: h2c HTTP2-Settings: <base64url encoding of HTTP/2 SETTINGS payload> 
  2. 服務器若不支持HTTP/2,直接按照HTTP/1.1響應便可
    HTTP/1. 1 200 OK Content-Length: 243 Content-Type: text/html . . . 
  3. 服務器支持HTTP/2,通知客戶端一塊兒切換到HTTP/2協議下吧安全

    HTTP/1. 1 101 Switching Protocols Connection: Upgrade Upgrade: h2c [ HTTP/2 connection . . . 
  4. 101響應空行以後,服務器必須發送的第一個幀爲SETTINGS幀(其負載可能爲空)做爲鏈接序言
  5. 客戶端接收到101響應後,也必須發送一個序言做爲響應,其邏輯結構:
    PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n // 純字符串表示,翻譯成字節數爲24個字節 SETTINGS幀 // 其負載可能爲空 
    服務器端和客戶端所發送的鏈接序言有所不一樣。
  6. 客戶端能夠立刻發送請求幀或其它幀過去,不用等待來自服務器端的SETTINGS幀
  7. 任一端接收到SETTINGS幀以後,都須要返回一個包含確認標誌位SETTIGN做爲確認
  8. 其它幀的正常傳輸

HTTP/2的直接鏈接

客戶端預先知道服務器提供HTTP/2支持,能夠免去101協議切換的流程開銷。 具體流程:服務器

  1. 客戶端必須首先發送一個鏈接序言,其邏輯結構:
    PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n // 純字符串表示,翻譯成字節數爲24個字節 SETTINGS幀 // 其負載可能爲空 
  2. 發送完畢序言以後,客戶端能夠不用等待來自服務器端響應,立刻發送HTTP/2其它幀
  3. 服務器端接收到客戶端的鏈接序言以後,須要發送一個SETTINGS幀做爲鏈接序言
  4. 任一端接收到SETTINGS幀以後,都須要返回一個包含確認標誌位SETTIGN做爲確認
  5. 其它幀的正常傳輸

HTTPS版本創建鏈接

HTTP/2安全版本在TLS上構建,協商採用的ALPN擴展協議,採用「h2」做爲協議標識符(http版本則是「h2c」)。必定程度上可認爲不存在試探是否支持或直接鏈接的煩惱,由於這個過程直接在TLS層協商而成。網絡

流程以下:url

  1. 客戶端和服務器端TLS層協商
  2. 客戶端發送鏈接序言(同上表示,PRI + SETTINGS)
  3. 接收到客戶端鏈接序言以後,服務器端發送鏈接序言
  4. 雙方各自確認SETTINGS幀
  5. 其它幀的正常傳輸

HTTPS和HTTP Upgrade方式協商

HTTPS協商是強制,封裝在TLS之上ALPN擴展實現,HTTP只有非直接鏈接方式纔會存在經過101 協議切換方式進行升級。spa

這裏有一張圖形象說明其流程。.net

統一的鏈接過程

這裏不管是HTTP仍是HTTPS,在兩端成功協商以後(或HTTP的直接鏈接),其鏈接過程都是同樣的翻譯

注意事項

  1. 客戶端發起的HTTP/1.1請求,其流標識符爲1,默認優先級;半關閉「half closed」狀態,一旦完成HTTP/2的鏈接,將被應用於響應
  2. 文檔提到的客戶端能夠經過HTTP Alternative Services(簡稱爲[ALT-SVC],相似於CNAME機制)得到通知服務器是否支持HTTP/2,但目前看來僅僅是草案建議而已
  3. 鏈接序言用於最後兩端協商確認雙方要使用HTTP/2協議,創建初始化的HTTP/2鏈接環境
  4. 客戶端若知服務器支持HTTP/2,可免去經過HTTP/1.1 101協議切換方式進行升級,在創建鏈接後便可發送序言,不然只能在接收到服務器端101響應後發送序言
  5. 創建在TLS上的HTTP/2經過ALPN擴展協商機制取代101協議切換
  6. 鏈接序言所包含的SETTINGS幀其負載能夠爲空
  7. 針對一個TCP鏈接,服務器第一個要發送的幀必須是SETTINGS幀
  8. 爲了不沒必要要延遲,客戶端能夠在發送完畢序言以後發送幀數據,不用等待來自服務器端的序言SETTINGS幀
  9. 客戶端接收到服務器端做爲序言的SETTINGS幀,須要遵照其設定
  10. 在一些環境下須要提供一個順序機制,容許服務器在客戶端發送業務幀以前發送SETTINGS,這須要客戶端配合
  11. 客戶端和服務器端任何一方接收到無效鏈接序言須要拋出PROTOCOL_ERROR類型鏈接錯誤,若收到GOAWAY幀,可忽略

小結

HTTP/2鏈接的創建協商機制比HTTP/1.1稍微複雜了一些。code

對比明文版的HTTP/1.1和HTTP/2完成一次請求-響應:

  1. HTTP/1.1在創建創建以後,只須要發送請求報文數據
  2. HTTP/2客戶端須要在鏈接創建之初立刻發送一個鏈接序言過去,而後纔是正常請求
  3. 兩端(客戶端+服務器端)的兩次完整的鏈接序言+確認的交互流程,多了兩次往返過程

在弱網絡環境下,會不會加劇網絡負載,只能拭目一看了。

引用

  1. 《Implementing HTTP/2 client in 60 minutes》

原文 http://www.blogjava.net/yongboy/archive/2015/03/18/423570.html

相關文章
相關標籤/搜索