Для ssl::stream<tcp::socket> через обычный HTTP-прокси сначала используйте его необработанный транспорт, а затем поручите ему TLS до места назначения:

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

Перенесите остаток буфера HTTP-парсера на следующий этап. В Asio есть перегрузки рукопожатия с буфером; отбрасывание хвоста, которым владеет парсер, может потерять байты, уже прочитанные из сокета.

В этом простом типе next_layer и lowest_layer оба ведут к TCP. При большем числе обёрток они могут различаться, поэтому выбирайте интерфейс, который несёт фактический протокол прокси. HTTPS-прокси добавляет ещё один этап TLS и не входит в эту последовательность CONNECT в открытом виде.

Похожие статьи