Attendez la ligne vide après CONNECT
Lisez la réponse HTTP/1 CONNECT complète avant de remettre la socket à TLS, même lorsque la ligne de statut arrive en premier.
Le client voit 200 Connection Established, démarre TLS et signale aussitôt des absurdités là où un enregistrement TLS devrait se trouver. Cherchez une réponse HTTP inachevée avant d'accuser les réglages de chiffrement de la destination.
Dans un échange HTTP/1 CONNECT, la ligne de statut n'est que le début de la réponse. Des champs d'en-tête peuvent suivre. La ligne vide qui termine la section d'en-tête marque le passage au tunnel après une réponse CONNECT réussie.
HTTP/1.1 200 Connection Established\r\n
Proxy-Agent: example\r\n
\r\n
Ces octets peuvent arriver en une lecture, en plusieurs lectures, ou dans une lecture qui contient aussi les octets suivants. TCP ne préserve pas les frontières d'écriture du serveur.
Faites de la remise un état explicite de l'analyseur
- Collectez et analysez la ligne de statut. Utilisez le code numérique plutôt qu'une phrase de raison anglaise exacte.
- Continuez jusqu'à ce que le terminateur complet de la section d'en-tête soit arrivé. Une ligne de statut réussie ne fait pas disparaître les champs restants.
- Pour une réponse CONNECT réussie, considérez l'octet juste après ce terminateur comme le début des données du tunnel. Pour les autres réponses, suivez le traitement approprié de la réponse HTTP et de l'authentification.
- Transférez la connexion et les octets non consommés via l'interface d'E/S tamponnée prise en charge par le protocole suivant.
La dernière étape compte même avec une bonne recherche de délimiteur. Un lecteur tamponné a pu consommer plus de la socket que l'analyseur n'en a demandé. Démarrer TLS sur la socket nue tout en abandonnant ce lecteur risque de laisser des octets dans le tampon privé du lecteur.
Utilisez un délai de configuration et une limite de taille d'en-tête. Une EOF avant le terminateur est une réponse de proxy incomplète, pas une invitation à attendre indéfiniment ni à tenter TLS quand même.
Raisonnez sur plusieurs frontières
Imaginez une lecture qui se termine après Proxy-Agent:. L'analyseur a encore besoin d'octets d'en-tête HTTP. Imaginez-en une autre qui se termine au milieu de la séquence CRLF finale. Ce n'est toujours pas une section d'en-tête complète. Imaginez maintenant une section d'en-tête complète et réussie suivie d'octets de tunnel dans le même tampon : ces octets supplémentaires doivent survivre à la remise.
Un 407 est une autre issue. Il exige un traitement d'authentification ; il n'autorise pas un TLS ClientHello dans un tunnel qui n'a jamais été ouvert.
Préférez un connecteur maintenu, sauf si implémenter la poignée de main est la tâche. Cette frontière est propre à l'échange HTTP/1 montré ici. Un proxy HTTP/2 porte CONNECT sur un flux au tramage différent.