Кліент бачыць 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 не захоўвае межы запісу сервера.

Зрабіце перадачу яўным станам парсера

  1. Сабярыце і разабярыце радок статусу. Выкарыстоўвайце лікавы статус, а не дакладную англійскую фразу прычыны.
  2. Працягвайце, пакуль не прыйдзе поўны тэрмінатар раздзела загалоўка. Паспяховы радок статусу не робіць астатнія палі нябачнымі.
  3. Для паспяховага адказу CONNECT лічыце байт адразу пасля гэтага тэрмінатара пачаткам даных тунеля. Для іншых адказаў прытрымлівайцеся адпаведнай апрацоўкі адказу HTTP і аўтэнтыфікацыі.
  4. Перадайце злучэнне і ўсе невыкарыстаныя байты праз буфераваны інтэрфейс уводу-вываду, які падтрымлівае наступны пратакол.

Апошні крок важны нават пры добрым пошуку раздзяляльніка. Буфераваны чытач мог спажыць з сокета больш, чым запытаў парсер. Запуск TLS на голым сокеце з адмовай ад гэтага чытача можа пакінуць байты ў прыватным буферы чытача.

Выкарыстоўвайце крайні тэрмін наладкі і абмежаванне памеру загалоўка. EOF перад тэрмінатарам — гэта няпоўны адказ проксі, а не запрашэнне чакаць бясконца ці ўсё ж паспрабаваць TLS.

Разгледзьце некалькі межаў

Уявіце чытанне, якое сканчаецца пасля Proxy-Agent:. Парсеру ўсё яшчэ патрэбны байты загалоўка HTTP. Уявіце іншае чытанне, якое сканчаецца пасярэдзіне апошняй паслядоўнасці CRLF. Гэта ўсё яшчэ не поўны раздзел загалоўка. А цяпер уявіце поўны паспяховы раздзел загалоўка, за якім у тым жа буферы ідуць байты тунеля: гэтыя лішнія байты павінны перажыць перадачу.

407 — іншы вынік. Ён патрабуе апрацоўкі аўтэнтыфікацыі; ён не дазваляе TLS ClientHello у тунель, які ніколі не адкрываўся.

Аддавайце перавагу суправаджаемаму канэктару, калі рэалізацыя рукапаціскання не з'яўляецца задачай. Гэтая мяжа тычыцца менавіта паказанага тут абмену HTTP/1. Проксі HTTP/2 пераносіць CONNECT у патоку з іншай кадраваннем.

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