Установите CONNECT до начала TLS-рукопожатия Asio
Используйте нижележащий слой SSL-потока Asio для обмена с обычным HTTP-прокси, а затем запустите TLS через принятый туннель.
Для ssl::stream<tcp::socket> через обычный HTTP-прокси сначала используйте его необработанный транспорт, а затем поручите ему TLS до места назначения:
auto& transport = tlsStream.next_layer();
- Подключите этот транспорт к хосту и порту прокси. Если целевой публичный HTTPS-адрес разрешён и учётные данные прокси не заданы, список HTTP-прокси предлагает подходящие конечные точки; убедитесь, что выбранный прокси разрешает нужный туннель.
- Отправьте CONNECT с указанием authority назначения, например
api.example:443, и разберите полные заголовки ответа на простом транспорте. Успешный ответ 2xx открывает туннель; отказ остаётся ответом HTTP-прокси. - Настройте имя хоста назначения, требуемый SNI, доверенные корневые сертификаты и проверку узла, затем запустите рукопожатие клиента на
tlsStream. - После успешного TLS используйте для чтения и записи приложения SSL-поток. Прямое чтение нижележащего слоя на этом этапе обходит обработку TLS.
Перенесите остаток буфера HTTP-парсера на следующий этап. В Asio есть перегрузки рукопожатия с буфером; отбрасывание хвоста, которым владеет парсер, может потерять байты, уже прочитанные из сокета.
В этом простом типе next_layer и lowest_layer оба ведут к TCP. При большем числе обёрток они могут различаться, поэтому выбирайте интерфейс, который несёт фактический протокол прокси. HTTPS-прокси добавляет ещё один этап TLS и не входит в эту последовательность CONNECT в открытом виде.