Пасля таго як 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.

Падобныя артыкулы