Poczekaj na pustą linię po CONNECT
Przeczytaj całą odpowiedź HTTP/1 CONNECT, zanim przekażesz gniazdo do TLS, nawet gdy linia statusu dotrze pierwsza.
Klient widzi 200 Connection Established, uruchamia TLS i natychmiast zgłasza bzdury tam, gdzie powinien być rekord TLS. Szukaj niedokończonej odpowiedzi HTTP, zanim obwinisz ustawienia szyfrowania celu.
W wymianie HTTP/1 CONNECT linia statusu to tylko początek odpowiedzi. Potem mogą pojawić się pola nagłówka. Pusta linia kończąca sekcję nagłówka oznacza przejście do tunelu po udanej odpowiedzi CONNECT.
HTTP/1.1 200 Connection Established\r\n
Proxy-Agent: example\r\n
\r\n
Te bajty mogą dotrzeć w jednym odczycie, w kilku odczytach albo w odczycie zawierającym też kolejne bajty. TCP nie zachowuje granic zapisu serwera.
Uczyń przekazanie jawnym stanem parsera
- Zbierz i przeanalizuj linię statusu. Użyj statusu liczbowego zamiast dokładnej angielskiej frazy powodu.
- Kontynuuj, aż dotrze pełny terminator sekcji nagłówka. Udana linia statusu nie sprawia, że pozostałe pola znikają.
- Przy udanej odpowiedzi CONNECT uznaj bajt zaraz po tym terminatorze za początek danych tunelu. Przy innych odpowiedziach stosuj odpowiednią obsługę odpowiedzi HTTP i uwierzytelniania.
- Przekaż połączenie i wszystkie niezużyte bajty przez buforowany interfejs wejścia-wyjścia obsługiwany przez następny protokół.
Ostatni krok ma znaczenie nawet przy dobrym wyszukaniu separatora. Buforowany czytnik mógł zużyć więcej gniazda, niż zażądał parser. Uruchomienie TLS na gołym gnieździe i porzucenie tego czytnika może zostawić bajty w prywatnym buforze czytnika.
Użyj terminu na konfigurację i limitu rozmiaru nagłówka. EOF przed terminatorem to niepełna odpowiedź proxy, a nie zaproszenie do czekania wiecznie albo próbowania TLS mimo wszystko.
Przeanalizuj kilka granic
Wyobraź sobie odczyt kończący się po Proxy-Agent:. Parser nadal potrzebuje kolejnych bajtów nagłówka HTTP. Wyobraź sobie inny, kończący się w połowie ostatniej sekwencji CRLF. To wciąż niepełna sekcja nagłówka. Teraz wyobraź sobie pełną udaną sekcję nagłówka, po której w tym samym buforze następują bajty tunelu: te dodatkowe bajty muszą przetrwać przekazanie.
407 to inny wynik. Wymaga obsługi uwierzytelniania; nie zezwala na TLS ClientHello do tunelu, który nigdy nie został otwarty.
Preferuj utrzymywany łącznik, chyba że implementacja uścisku dłoni jest zadaniem. Ta granica dotyczy pokazanej tu wymiany HTTP/1. Proxy HTTP/2 przenosi CONNECT na strumieniu z innym podziałem na ramki.