پس از آنکه 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 آغاز کنید.

مقالات مرتبط