Perkelkite Beast CONNECT buferį į TLS rankos paspaudimą
Perduokite po CONNECT atsakymo likusius baitus Asio buferiniam TLS rankos paspaudimui, tada suvartokite tiksliai tiek, kiek jis sunaudojo.
Kai Beast perskaito proksio CONNECT atsakymo antraštę, patikrinkite ir atsakymo būseną, ir dinaminį buferį. Skaitymo operacija gali paimti baitus už antraštės pabaigos ir juos palikti pateiktame buferyje. Jei TLS paleisite su perkrova, kuri skaito tik lizdą, tie likę baitai atsidurs už TLS įvesties kelio.
WebSocket srautui, kurio kitas sluoksnis yra SSL srautas, naudokite buferinę rankos paspaudimo perkrovą. Esamoje yield_context sesijoje, visų operacijų metu išlaikant gyvą 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);
Ankstyvieji grąžinimai yra sesijos gedimo išėjimai; ten prijunkite įprastą klaidų ataskaitą ir valymą. Tunelį sukuria tik sėkmingas CONNECT atsakymas. Atmetimo puslapis neturi tapti TLS įvestimi.
Buferinė perkrova baigiasi klaidos kodu ir baitų skaičiumi. Šis skaičius nurodo, kiek baitų ji suvartojo iš pateiktų buferių. Baigus pašalinkite būtent tą priešdėlį naudodami consume(used). Neišvalykite buferio prieš operacijos pradžią, nekeiskite jo saugyklos, kol rankos paspaudimas laukia, ir nemanokite, kad operacija suvartojo kiekvieną pateiktą baitą.
Įprasto kliento iš karto po CONNECT pradėto TLS atveju buferis gali būti tuščias. Perkrova apdoroja ir šį atvejį. Jos tikslas – išsaugoti srauto ribas; ji nepaverčia savavališkų vėlesnių proksio duomenų galiojančiu TLS. Prieš rankos paspaudimą SSL sluoksnyje palikite paskirties hosto vardo tikrinimą ir SNI konfigūraciją, o WebSocket atnaujinimą pradėkite tik po sėkmingo TLS.