Espere pela linha em branco após CONNECT
Leia a resposta HTTP/1 CONNECT completa antes de entregar o socket ao TLS, mesmo quando a linha de status chega primeiro.
O cliente vê 200 Connection Established, inicia TLS e logo relata disparates onde deveria haver um registro TLS. Procure uma resposta HTTP inacabada antes de culpar as configurações de cifra do destino.
Num intercâmbio HTTP/1 CONNECT, a linha de status é apenas o começo da resposta. Campos de cabeçalho podem vir depois. A linha em branco que encerra a seção de cabeçalhos marca a passagem para o túnel após uma resposta CONNECT bem-sucedida.
HTTP/1.1 200 Connection Established\r\n
Proxy-Agent: example\r\n
\r\n
Esses bytes podem chegar numa leitura, em várias leituras ou numa leitura que também contenha bytes seguintes. O TCP não preserva os limites de escrita do servidor.
Faça da entrega um estado explícito do analisador
- Recolha e analise a linha de status. Use o status numérico em vez de uma frase de motivo em inglês exata.
- Continue até chegar o terminador completo da seção de cabeçalhos. Uma linha de status bem-sucedida não faz os campos restantes desaparecerem.
- Ante uma resposta CONNECT bem-sucedida, identifique o byte imediatamente após esse terminador como o início dos dados do túnel. Ante outras respostas, siga o tratamento adequado de resposta HTTP e autenticação.
- Transfira a conexão e os bytes não consumidos pela interface de E/S com buffer suportada pelo protocolo seguinte.
O último passo importa mesmo com uma boa busca de delimitador. Um leitor com buffer pode ter consumido mais do socket do que o analisador pediu. Iniciar TLS no socket nu enquanto se abandona esse leitor pode deixar bytes presos no buffer privado do leitor.
Use um prazo de configuração e um limite de tamanho de cabeçalho. Um EOF antes do terminador é uma resposta de proxy incompleta, não um convite a esperar para sempre ou tentar TLS de qualquer maneira.
Raciocine sobre vários limites
Imagine uma leitura que termina logo depois de Proxy-Agent:. O analisador ainda precisa de mais bytes de cabeçalho HTTP. Imagine outra que termina no meio da sequência CRLF final. Isso ainda não é uma seção de cabeçalhos completa. Agora imagine uma seção de cabeçalhos completa e bem-sucedida seguida de bytes de túnel no mesmo buffer: esses bytes extras precisam sobreviver à entrega.
Um 407 é um desfecho diferente. Exige tratamento de autenticação; não autoriza nenhum TLS ClientHello para um túnel que nunca foi aberto.
Prefira um conector mantido, a menos que implementar o handshake seja a tarefa. Este limite é específico do intercâmbio HTTP/1 mostrado aqui. Um proxy HTTP/2 transporta CONNECT num fluxo com enquadramento diferente.