Обробники CONNECT у Node.js повинні зберігати буфер head
Працюйте з сокетом CONNECT і буфером head у Node на межі HTTP і тунелю, зберігаючи байти, уже прочитані за межами заголовків.
HTTP-сервер Node обробляє звичайний проксі-запит через свій callback запиту. CONNECT іде іншим шляхом: сервер видає connect разом із запитом, клієнтським сокетом і буфером head.
Ця подія — передача між розбором HTTP і тунелем. Звичайного об'єкта ServerResponse, який можна було б далі використовувати для тунельного трафіку, немає.
| Аргумент | Що він несе |
|---|---|
req | Запит CONNECT, включно з його цільовим авторитетом і заголовками |
clientSocket | З'єднання назад до клієнта |
head | Дані тунелю, які Node вже прочитав за межами HTTP-заголовків, можливо порожні |
Завершіть рішення HTTP до передавання байтів
Перевірте запитані хост і порт, застосуйте політику доступу й автентифікації проксі та встановіть висхідне з'єднання. CONNECT визначає авторитет на кшталт service.example:443; розбирайте цю форму з огляду на авторитети IPv6, а не діліть наосліп на кожній двокрапці.
Коли тунель прийнято, надішліть успішну відповідь HTTP, а потім завершальний порожній рядок. Після цього передайте будь-які байти head вгору, перш ніж продовжувати з наступними байтами з клієнтського сокета. Приєднання нового обробника даних не може повернути буфер, який уже було окремо доставлено обробнику.
Офіційний приклад тунелювання в Node виконує цю передачу за допомогою serverSocket.write(head) перед з'єднанням двох напрямків потоку. Його невеликий приклад ілюструє перехід; розгорнутому проксі також потрібні обмежені спроби з'єднання, контроль доступу й керування життєвим циклом.
Після успіху байти належать протоколу сервісу
Успішна відповідь CONNECT перетворює з'єднання на потік байтів. Якщо ціль — сайт HTTPS, його обмін TLS відбувається всередині цього потоку. Саме тунелювання не вимагає, щоб проксі видавав замінюючий сертифікат сайту.
До прийняття CONNECT помилка HTTP може пояснити причину відмови. Після прийняття запис HTTP 500 у потік вставив би байти в тунельний протокол. Натомість завершуйте або знищуйте відповідні з'єднання при подальших збоях.
З'єднайте обидва напрямки за допомогою обробка потоку з урахуванням зворотного тиску і вирішіть, як події end, error і close завершують партнера. Зберігайте початковий буфер head як частину тієї самої моделі володіння; це дані застосунку, а не зайві HTTP-заголовки, які можна викинути.