منتظر خط خالی پس از CONNECT بمانید
پاسخ کامل HTTP/1 CONNECT را پیش از سپردن سوکت به TLS بخوانید، حتی اگر خط وضعیت اول برسد.
کلاینت 200 Connection Established را میبیند، TLS را آغاز میکند و بیدرنگ جایی که باید یک رکورد TLS باشد چیزهای بیمعنی گزارش میدهد. پیش از متهم کردن تنظیمات رمزنگاری مقصد، دنبال پاسخ HTTP ناتمام بگردید.
در تبادل HTTP/1 CONNECT، خط وضعیت تنها آغاز پاسخ است. پس از آن ممکن است فیلدهای سرآیند بیایند. خط خالی که بخش سرآیند را پایان میدهد، نشانه گذار به تونل است پس از یک پاسخ موفق CONNECT.
HTTP/1.1 200 Connection Established\r\n
Proxy-Agent: example\r\n
\r\n
این بایتها میتوانند در یک خواندن، در چند خواندن، یا در خواندنی برسند که بایتهای بعدی را هم در بر دارد. TCP مرزهای نوشتن سرور را حفظ نمیکند.
تحویل را به یک حالت صریح در تجزیهگر تبدیل کنید
- خط وضعیت را جمعآوری و تجزیه کنید. از کد عددی وضعیت استفاده کنید، نه از عبارت دلیل انگلیسی دقیق.
- ادامه دهید تا پایانبخش کامل سرآیند برسد. خط وضعیت موفق باعث ناپدید شدن فیلدهای باقیمانده نمیشود.
- در پاسخ موفق CONNECT، بایت بلافاصله پس از آن پایانبخش را آغاز دادههای تونل بدانید. در پاسخهای دیگر، پردازش مناسب پاسخ HTTP و احراز هویت را دنبال کنید.
- اتصال و هر بایت مصرفنشده را از طریق واسط I/O بافرشدهای که پروتکل بعدی پشتیبانی میکند منتقل کنید.
قدم آخر حتی با جستوجوی خوب جداکننده اهمیت دارد. یک خواننده بافرشده ممکن است بیش از آنچه تجزیهگر خواسته از سوکت مصرف کرده باشد. آغاز TLS روی سوکت خام در حالی که آن خواننده رها میشود میتواند بایتها را در بافر خصوصی خواننده گرفتار کند.
از مهلت راهاندازی و محدودیت اندازه سرآیند استفاده کنید. EOF پیش از پایانبخش یعنی پاسخ پروکسی ناقص، نه دعوتی برای انتظار بیپایان یا امتحان کردن TLS به هر حال.
چند مرز را بررسی کنید
خواندنی را تصور کنید که پس از Proxy-Agent: پایان مییابد. تجزیهگر هنوز به بایتهای سرآیند HTTP بیشتری نیاز دارد. خواندن دیگری را تصور کنید که در میانه دنباله CRLF پایانی تمام میشود. آن هنوز بخش سرآیند کامل نیست. حالا بخش سرآیند کامل و موفق را تصور کنید که بایتهای تونل در همان بافر پس از آن میآیند: آن بایتهای اضافی باید از تحویل جان سالم به در ببرند.
407 نتیجه دیگری است. به پردازش احراز هویت نیاز دارد؛ به TLS ClientHello اجازه ورود به تونلی را نمیدهد که هرگز باز نشده است.
مگر آنکه پیادهسازی دستدهی خودِ کار باشد، یک کانکتور نگهداریشده را ترجیح دهید. این مرز مخصوص تبادل HTTP/1 نشاندادهشده در اینجاست. پروکسی HTTP/2، CONNECT را روی جریانی با قاببندی متفاوت حمل میکند.