Ένας μεσολαβητής 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 που μεταφέρει ήδη ο μεσολαβητής αντί να ανοίξει άλλο άμεσο socket. Το servername του προορισμού παρέχει SNI και ταυτότητα πιστοποιητικού, με την επαλήθευση ενεργή. Ο έλεγχος ALPN απορρίπτει προορισμό που δεν διαπραγματεύτηκε h2.

Το failRoute πρέπει να καθαρίσει τη διαδρομή· το useSession κατέχει τα αιτήματα και το κλείσιμο της συνεδρίας. Εφαρμόστε προθεσμίες σύνδεσης και λειτουργίας γύρω από αυτό το τμήμα.

Ο εξωτερικός συνδετήρας εξακολουθεί να κατέχει τη στόχευση CONNECT host:port, την αυθεντικοποίηση προς τον μεσολαβητή, τον χειρισμό απορρίψεων και τα byte που αποθηκεύονται μετά τις κεφαλίδες. Ολοκληρώστε τα πριν δώσετε το socket στο TLS· ένα πρόλογο HTTP/2 που στέλνεται απευθείας σε ακροατή μεσολαβητή HTTP/1.1 ξεκινά στο λάθος επίπεδο.

Σχετικά άρθρα