Изчакайте празния ред след 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 отговор и удостоверяване.
- Предайте връзката и всички неконсумирани байтове през буферирания I/O интерфейс, поддържан от следващия протокол.
Последната стъпка е важна дори при добро търсене на разделител. Буфериран четец може да е изразходвал повече от сокета, отколкото парсерът е поискал. Стартирането на TLS върху гол сокет, докато изоставяте този четец, може да остави байтове в личния буфер на четеца.
Използвайте краен срок за настройка и ограничение за размера на заглавката. EOF преди терминатора е непълен отговор на прокси, а не покана да чакате вечно или да опитате TLS въпреки това.
Обмислете няколко граници
Представете си четене, което завършва след Proxy-Agent:. Парсерът все още се нуждае от още HTTP байтове на заглавката. Представете си друго, което завършва по средата на последната CRLF последователност. Това все още не е пълна секция на заглавката. А сега си представете пълна успешна секция на заглавката, следвана от тунелни байтове в същия буфер: тези допълнителни байтове трябва да оцелеят при предаването.
407 е различен изход. Той изисква обработка на удостоверяване; не разрешава TLS ClientHello в тунел, който никога не е бил отварян.
Предпочитайте поддържан конектор, освен ако реализирането на ръкостискането не е задачата. Тази граница е специфична за показания тук обмен HTTP/1. Прокси HTTP/2 носи CONNECT в поток с различна рамка.