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

  1. Recolha e analise a linha de status. Use o status numérico em vez de uma frase de motivo em inglês exata.
  2. 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.
  3. 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.
  4. 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.

Artigos relacionados