Sačekajte prazan red nakon CONNECT
Pročitajte kompletan HTTP/1 CONNECT odgovor prije nego što socket predate TLS-u, čak i kada statusna linija stigne prva.
Klijent vidi 200 Connection Established, pokrene TLS i odmah prijavi besmislice tamo gdje bi trebao biti TLS zapis. Tražite nedovršen HTTP odgovor prije nego okrivite postavke šifri odredišta.
U HTTP/1 CONNECT razmjeni statusna linija je samo početak odgovora. Nakon nje mogu slijediti polja zaglavlja. Prazan red koji završava dio zaglavlja označava prelazak u tunel nakon uspješnog CONNECT odgovora.
HTTP/1.1 200 Connection Established\r\n
Proxy-Agent: example\r\n
\r\n
Ti bajtovi mogu stići u jednom čitanju, u nekoliko čitanja ili u čitanju koje sadrži i naredne bajtove. TCP ne čuva granice pisanja servera.
Učinite primopredaju eksplicitnim stanjem parsera
- Prikupljajte i parsirajte statusnu liniju. Koristite numerički status umjesto tačne engleske reason phrase.
- Nastavite dok ne stigne kompletan terminator dijela zaglavlja. Uspješna statusna linija ne čini preostala polja nestalima.
- Za uspješan CONNECT odgovor, bajt odmah nakon tog terminatora smatrajte početkom podataka tunela. Za ostale odgovore slijedite odgovarajuću obradu HTTP odgovora i autentifikacije.
- Prenesite vezu i sve nepotrošene bajtove kroz baferirani I/O interfejs koji podržava sljedeći protokol.
Posljednji korak je važan čak i uz dobru pretragu graničnika. Baferirani čitač je mogao potrošiti više socketa nego što je parser zatražio. Pokretanje TLS-a na golom socketu uz napuštanje tog čitača može ostaviti bajtove u privatnom baferu čitača.
Koristite rok za postavljanje i ograničenje veličine zaglavlja. EOF prije terminatora je nepotpun proxy odgovor, a ne poziv da čekate zauvijek ili ipak pokušate TLS.
Promislite nekoliko granica
Zamislite čitanje koje završava nakon Proxy-Agent:. Parseru još trebaju dodatni HTTP bajtovi zaglavlja. Zamislite drugo koje završava na pola završne CRLF sekvence. To još nije kompletan dio zaglavlja. A sada zamislite kompletan uspješan dio zaglavlja iza kojeg u istom baferu slijede bajtovi tunela: ti dodatni bajtovi moraju preživjeti primopredaju.
407 je drugačiji ishod. Zahtijeva obradu autentifikacije; ne dopušta TLS ClientHello u tunel koji nikada nije otvoren.
Preferirajte održavani konektor osim ako je implementacija rukovanja zadatak. Ova granica je specifična za ovdje prikazanu HTTP/1 razmjenu. HTTP/2 proxy nosi CONNECT na streamu s drugačijim uokvirenjem.