http2 協議協商過程

2021-09-19 23:39:36 字數 2857 閱讀 4540

http/2 協議剛剛發布不久,http1.1的伺服器和客戶端依然大量存在,新老協議必定長期共存一段時間。這樣,瀏覽器和伺服器就需要協商使用何種協議進行通訊。

主流的方法是使用alpn或者npn來做協商。

區別是有的。就在於誰持有會話協議的決定權。alpn是由客戶端給伺服器傳送乙個協議清單,由伺服器來最終選擇乙個。而npn則正好相反。

node 已經在tls模組內實現了npn支援。只要建立tls伺服器(createserver),在options引數內傳遞伺服器支援的協議清單npnprotocols,在客戶端連線(connect)傳遞npnprotocols,這樣建立連線後,就可以在socket.npnprotocol內得到協商的結果。

請看mocha測試用例:

describe('tls', function() , function(socket) ).listen(1111);

//client

process.env.node_tls_reject_unauthorized = "0";

tls.connect(, function() );

tls.connect(, function() );

tls.connect(, function() );

tls.connect(, function() );

})})

輸出結果

s1:http 1.0程式設計師的**常常氣死寫文字的人——因為一堆艱澀文字,變成**常常簡單無比。

理論上來說,http/2 可以架構在tls(加密通道)上,也可以架構在tcp(平文字)上。協議文字也確實沒有限定或者強制使用tls通道。但是,h2的前身是spdy,而spdy是在tls之上的;spdy的主人家google的瀏覽器,chrome也只支援tls;另外一家主流瀏覽器firefox也跟進。這就讓架構於tls之上就成為http/2的事實上的標準。所有協商協議也都支援npn(tls的乙個擴充套件)。

兩家瀏覽器廠商的做法,其實並非強梁,而是基於現實考量:

1. 大量現存的**、中介軟體,都假設80埠上跑的是http1.1,並且基於這個假設,對流經它們的流量做出修改。如果h2繼續使用80,很可能和這些修改發生衝突。使用tls(預設為443埠)就避開了這個衝突的可能性

2. 加密化通道(相比http1.x)對使用者隱私是更好的保護

通過平文字公升級協議到h2,依然可能。採用的是現存的http1.1的公升級機制。

(... http/2 response ...)由 upgrade指定公升級目標協議, http2-settings傳遞base64後的settings。如果伺服器為1.1的,那麼返回1.1的響應。否則,就發101 switching protocols ,隨後公升級為h2。

因為這個做法比npn要做乙個網路往返,這個做法(101 switching protocols )被很多實現忽略。比如,node-http2就沒有實現(請腦補標準機構的臉色:)。在程式設計師友好,客戶友好的柔情面紗下面,遇到核心的效能問題,依然是一片叢林景象。

儘管node-http2**內,把alpn的協議協商也有,並且堂而皇之的也和npn一樣:

options.alpnprotocols = supportedprotocols;

options.npnprotocols = supportedprotocols;

...this._server = https.createserver(options);

但是經過測試,node還沒有支援alpn,有測試用例為證:

describe('tls', function() , function(socket) ).listen(1111);

//client

process.env.node_tls_reject_unauthorized = "0";

tls.connect(, function() );

tls.connect(, function() );

tls.connect(, function() );

tls.connect(, function() );

})})

根本就沒有協商,怎麼樣都是http/1.1 !

s1:http/1.1關於node對alpn的支援,文件也沒有提及,但是在issue內有提到,它們正在等待openssl實現並且穩定。穩!定!openssl這幾年出的糗還少嗎,什麼時候能弄穩定呢。

HTTP2的協議協商機制

http 2 使用和 http 1.1 一樣的 http 和 https 的 url 模式。同時 http 2 和 http 1.1 也共享了相同的預設埠號 http 的 80 埠,https 的 443 埠。字串 h2c 標示執行在明文 tcp 之上的 http 2 協議 http模式 字串 h2...

公升級HTTP 2協議

首先只有使用https協議的站點可以公升級http 2協議 nginx如果想要公升級http 2需要滿足以下要求 nginx版本要高於1.9.5 with http ssl module 跟 with http v2 module 必帶 因為http2.0協議需要使用https協議。yum inst...

Nginx 支援Http2協議

要開啟http 2協議支援,需要在nginx 1.10以上版本並且需要openssl庫的版本在1.0.2以上編譯。http 2.0只支援開啟了https的 檢視當前openssl版本 需要openssl庫的版本在1.0.2以上 openssl version可以看到我這裡的版本正好是1.0.2 滿足...