یک پروکسی 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 مالک درخواست‌ها و بستن نشست است. مهلت‌های اتصال و عملیات را پیرامون این قطعه اعمال کنید.

اتصال‌دهنده بیرونی هنوز مالک هدف‌گیری CONNECT با host:port، احراز هویت پروکسی، مدیریت رد و بایت‌های بافر‌شده پس از سرآیندها است. آن‌ها را پیش از تحویل سوکت به TLS تمام کنید؛ پیش‌درآمد HTTP/2 که مستقیم به شنونده پروکسی HTTP/1.1 فرستاده شود در لایه اشتباه آغاز می‌شود.

مقالات مرتبط