Преобразование запроса SOCKS5 в туннель HTTP
Завершите обмен CONNECT с родителем, верните клиенту ответ SOCKS и только затем передавайте байты приложения.
Фронтенд SOCKS5 может использовать HTTP-прокси как свой дальнейший транспорт. Он выступает как сервер SOCKS по отношению к клиенту и как клиент HTTP CONNECT по отношению к родителю. Оба управляющих обмена завершаются до начала потока приложения.
Запрос SOCKS CONNECT уже содержит хост или адрес назначения и порт. Для иллюстративного обмена HTTP/1.1 с родителем:
client → adapter: SOCKS5 CONNECT service.example.net:443
adapter → parent:
CONNECT service.example.net:443 HTTP/1.1
Host: service.example.net:443
parent → adapter: HTTP/1.1 200 Connection Established
[end of headers]
adapter → client: SOCKS5 success reply
client ↔ adapter ↔ parent ↔ service: application bytes
Переведите результат на границе
Адаптер выполняет любую требуемую аутентификацию у родителя и ждёт результата CONNECT. Успешный ответ 2xx устанавливает родительский туннель. Только после этого он должен вернуть соответствующий ответ об успехе SOCKS нижестоящему клиенту.
Если родитель отклоняет операцию, отправьте определённый ответ об ошибке SOCKS и затем немедленно закройте соединение с клиентом. SOCKS5 требует такого закрытия в течение десяти секунд после обнаружения сбоя. Сохраняйте HTTP-статус родителя как диагностическую информацию для адаптера. Передача этой строки состояния как данных приложения поместила бы управляющее сообщение HTTP в поток, клиент которого ожидает кадрирование SOCKS.
До успешного результата CONNECT родитель всё ещё говорит на HTTP, включая кадрирование любого ответа с запросом аутентификации или ошибкой. После разделителя заголовков успешного результата соединение становится туннелем; тела ответа HTTP, которое нужно было бы сначала потребить, нет.
Сохраните байты после заголовков
Одно чтение может содержать конец заголовков родителя и байты от назначения вместе. Сохраните эти дополнительные байты для нижестоящего приложения. Протоколы, в которых сервер говорит первым, могут приветствовать сразу после открытия соединения.
После отправки ответа об успехе SOCKS передавайте поток приложения в обоих направлениях. Адаптеру не нужно чередовать одно сообщение клиента с одним сообщением сервера, и ему не нужно понимать записи TLS, чтобы их передавать. Его протокольная работа состояла в установлении и преобразовании двух туннельных согласований.