Een HTTP/1.1-proxy kan HTTP/2-frames van de bestemming binnen CONNECT vervoeren. De proxy hoeft die binnenste frames niet te implementeren, maar de client moet de protocoloverdrachten in volgorde uitvoeren.

Nadat je het volledige CONNECT-antwoord hebt gevalideerd en tunnelSocket hebt behouden, voeg je doel-TLS toe en geef je de opgezette stream aan 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 geeft de TLS-stream terug die de proxy al draagt in plaats van nog een directe socket te openen. De servername van de bestemming levert SNI en certificaatidentiteit, met verificatie ingeschakeld. De ALPN-controle weigert een bestemming die h2 niet heeft onderhandeld.

failRoute moet de route opruimen; useSession bezit verzoeken en het sluiten van de sessie. Pas verbindings- en operatietermijnen toe rond dit fragment.

De buitenste connector bezit nog steeds de host:port CONNECT-doelwit, proxyauthenticatie, afhandeling van weigeringen en de bytes die na de headers zijn gebufferd. Rond die af voordat de socket naar TLS gaat; een HTTP/2-preambule die rechtstreeks naar een HTTP/1.1-proxylistener wordt gestuurd, begint op de verkeerde laag.

Gerelateerde artikelen