De client ziet 200 Connection Established, start TLS en meldt meteen onzin waar een TLS-record hoort te staan. Zoek naar een onvoltooide HTTP-respons voordat je de cipher-instellingen van de bestemming de schuld geeft.

Bij een HTTP/1 CONNECT-uitwisseling is de statusregel alleen het begin van de respons. Daarna kunnen headervelden volgen. De lege regel die de headersectie afsluit, markeert de overgang naar de tunnel na een geslaagde CONNECT-respons.

HTTP/1.1 200 Connection Established\r\n
Proxy-Agent: example\r\n
\r\n

Die bytes kunnen in één leesactie binnenkomen, in meerdere leesacties, of in een leesactie die ook volgende bytes bevat. TCP bewaart de schrijfgrenzen van de server niet.

Maak van de overdracht een expliciete parserstatus

  1. Verzamel en parseer de statusregel. Gebruik de numerieke status in plaats van een exacte Engelse reason phrase.
  2. Ga door tot de volledige terminator van de headersectie is aangekomen. Een geslaagde statusregel laat de overige velden niet verdwijnen.
  3. Beschouw bij een geslaagde CONNECT-respons de byte direct na die terminator als het begin van tunneldata. Volg bij andere responsen de passende afhandeling van HTTP-respons en authenticatie.
  4. Draag de verbinding en alle ongebruikte bytes over via de gebufferde I/O-interface die het volgende protocol ondersteunt.

De laatste stap is belangrijk, ook met een goede zoekactie naar het scheidingsteken. Een gebufferde lezer kan meer van de socket hebben verbruikt dan de parser vroeg. TLS starten op de kale socket terwijl je die lezer laat vallen, kan bytes achterlaten in de privébuffer van de lezer.

Gebruik een deadline voor het opzetten en een limiet voor de headergrootte. EOF vóór de terminator is een onvolledige proxyrespons, geen uitnodiging om eindeloos te wachten of TLS toch te proberen.

Redeneer over meerdere grenzen

Stel je een leesactie voor die eindigt na Proxy-Agent:. De parser heeft nog meer HTTP-headerbytes nodig. Stel je een andere voor die halverwege de laatste CRLF-reeks eindigt. Dat is nog geen volledige headersectie. Stel je nu een volledige geslaagde headersectie voor, gevolgd door tunnelbytes in dezelfde buffer: die extra bytes moeten de overdracht overleven.

Een 407 is een andere uitkomst. Die vraagt om authenticatieafhandeling; die staat geen TLS ClientHello toe in een tunnel die nooit is geopend.

Geef de voorkeur aan een onderhouden connector, tenzij het implementeren van de handshake de taak is. Deze grens is specifiek voor de hier getoonde HTTP/1-uitwisseling. Een HTTP/2-proxy draagt CONNECT op een stream met een andere framing.

Gerelateerde artikelen