Чакайце пусты радок пасля 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 і аўтэнтыфікацыі.
- Перадайце злучэнне і ўсе невыкарыстаныя байты праз буфераваны інтэрфейс уводу-вываду, які падтрымлівае наступны пратакол.
Апошні крок важны нават пры добрым пошуку раздзяляльніка. Буфераваны чытач мог спажыць з сокета больш, чым запытаў парсер. Запуск TLS на голым сокеце з адмовай ад гэтага чытача можа пакінуць байты ў прыватным буферы чытача.
Выкарыстоўвайце крайні тэрмін наладкі і абмежаванне памеру загалоўка. EOF перад тэрмінатарам — гэта няпоўны адказ проксі, а не запрашэнне чакаць бясконца ці ўсё ж паспрабаваць TLS.
Разгледзьце некалькі межаў
Уявіце чытанне, якое сканчаецца пасля Proxy-Agent:. Парсеру ўсё яшчэ патрэбны байты загалоўка HTTP. Уявіце іншае чытанне, якое сканчаецца пасярэдзіне апошняй паслядоўнасці CRLF. Гэта ўсё яшчэ не поўны раздзел загалоўка. А цяпер уявіце поўны паспяховы раздзел загалоўка, за якім у тым жа буферы ідуць байты тунеля: гэтыя лішнія байты павінны перажыць перадачу.
407 — іншы вынік. Ён патрабуе апрацоўкі аўтэнтыфікацыі; ён не дазваляе TLS ClientHello у тунель, які ніколі не адкрываўся.
Аддавайце перавагу суправаджаемаму канэктару, калі рэалізацыя рукапаціскання не з'яўляецца задачай. Гэтая мяжа тычыцца менавіта паказанага тут абмену HTTP/1. Проксі HTTP/2 пераносіць CONNECT у патоку з іншай кадраваннем.