Перенесите буфер CONNECT из Beast в TLS-рукопожатие
Передайте байты, оставшиеся после ответа CONNECT, в буферизованное TLS-рукопожатие Asio, а затем израсходуйте ровно столько, сколько оно использовало.
После того как Beast прочитает заголовок ответа CONNECT от прокси, проверьте и статус ответа, и динамический буфер. Операция чтения может захватить байты за пределами конца заголовка и сохранить их в переданном буфере. Если запустить TLS перегрузкой, которая читает только сокет, эти сохранённые байты останутся вне пути ввода TLS.
Для потока WebSocket, следующим слоем которого является поток SSL, используйте буферизованную перегрузку рукопожатия. В существующей сессии yield_context, удерживая buffer живым на протяжении всех операций:
http::response_parser<http::empty_body> response;
http::async_read_header(
beast::get_lowest_layer(ws), buffer, response, yield[ec]);
if (ec) return;
auto status = response.get().result_int();
if (status < 200 || status >= 300) return;
std::size_t used = ws.next_layer().async_handshake(
ssl::stream_base::client, buffer.data(), yield[ec]);
if (ec) return;
buffer.consume(used);
Ранние возвраты — это выходы сессии при ошибке; подключите там обычные отчёт об ошибках и очистку. Туннель устанавливает только успешный ответ CONNECT. Страница отказа не должна становиться входом TLS.
Буферизованная перегрузка завершается с кодом ошибки и числом байтов. Это число описывает, сколько байтов она израсходовала из переданных буферов. После завершения удалите ровно этот префикс с помощью consume(used). Не очищайте буфер до начала операции, не изменяйте его хранилище, пока рукопожатие ожидает, и не предполагайте, что операция израсходовала каждый переданный байт.
При обычном TLS, запущенном клиентом сразу после CONNECT, буфер может быть пустым. Перегрузка обрабатывает и этот случай. Её цель — сохранять границы потока; она не делает произвольные последующие данные прокси допустимым TLS. Сохраняйте проверку имени целевого хоста и настройку SNI на уровне SSL до рукопожатия и начинайте обновление до WebSocket только после успешного TLS.