Node.js HTTP/2 праз HTTP CONNECT з createConnection
Завяршыце CONNECT, узгадніце TLS прызначэння з h2, затым выкарыстайце createConnection, каб трымаць http2.connect на гэтым патоку.
Проксі HTTP/1.1 можа пераносіць кадры HTTP/2 прызначэння ўнутры CONNECT. Проксі не абавязаны рэалізоўваць гэтыя ўнутраныя кадры, але кліент павінен выконваць перадачу пратаколаў па парадку.
Пасля праверкі поўнага адказу CONNECT і захавання tunnelSocket дадайце TLS прызначэння і перадайце ўсталяваны паток у HTTP/2:
import tls from 'node:tls';
import http2 from 'node:http2';
const secureSocket = tls.connect({
socket: tunnelSocket,
servername: 'api.example',
ALPNProtocols: ['h2'],
});
secureSocket.once('error', failRoute);
secureSocket.once('secureConnect', () => {
if (secureSocket.alpnProtocol !== 'h2') {
secureSocket.destroy();
failRoute(new Error('Destination did not negotiate h2'));
return;
}
const session = http2.connect('https://api.example', {
createConnection: () => secureSocket,
});
session.on('error', failRoute);
useSession(session);
});createConnection вяртае паток TLS, які ўжо пераносіць проксі, замест адкрыцця чарговага прамога сокета. servername прызначэння дае SNI і ідэнтычнасць сертыфіката пры ўключанай праверцы. Праверка ALPN адхіляе прызначэнне, якое не ўзгадніла h2.
failRoute павінен ачысціць маршрут; useSession валодае запытамі і закрыццём сесіі. Ужывайце тэрміны злучэння і аперацый вакол гэтага фрагмента.
Знешні канэктар па-ранейшаму адказвае за мэтавы host:port CONNECT, аўтэнтыфікацыю проксі, апрацоўку адмоў і байты, буфераваныя пасля загалоўкаў. Завяршыце гэта перад перадачай сокета ў TLS; прэамбула HTTP/2, адпраўленая проста ў слухач проксі HTTP/1.1, пачынаецца на няправільным узроўні.