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

  1. Zbierz i przeanalizuj linię statusu. Użyj statusu liczbowego zamiast dokładnej angielskiej frazy powodu.
  2. Kontynuuj, aż dotrze pełny terminator sekcji nagłówka. Udana linia statusu nie sprawia, że pozostałe pola znikają.
  3. 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.
  4. 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.

Powiązane artykuły