Um protocolo TCP personalizado pode viajar por um proxy HTTP quando esse proxy permite CONNECT até o destino. O protocolo da aplicação não precisa se tornar HTTP: o HTTP estabelece o túnel e depois a aplicação troca seus próprios bytes dentro dele.

O OpenJDK 25 oferece um caminho por proxy HTTP em Socket(Proxy). Sua implementação realiza a troca CONNECT e devolve um socket conectado para a aplicação usar.

Proxy route = new Proxy(
    Proxy.Type.HTTP,
    new InetSocketAddress("proxy.example", 8080));

try (Socket socket = new Socket(route)) {
    socket.setSoTimeout(10000);
    socket.connect(
        InetSocketAddress.createUnresolved("tcp-service.example", 8443),
        5000);
    InputStream input = socket.getInputStream();
    OutputStream output = socket.getOutputStream();
}

Este trecho usa classes de java.net e java.io. Substitua os dois pontos de extremidade e faça a troca de protocolo antes de sair do bloco try. Para um destino TCP público permitido, escolha candidatos HTTP na lista de proxies HTTP somente depois de verificar a permissão CONNECT para a porta desse destino. O endereço do proxy é onde o Java se conecta primeiro; o endereço passado para connect identifica o serviço que o proxy deve alcançar.

O destino não resolvido preserva seu nome de host para a requisição CONNECT desta implementação. Um InetSocketAddress resolvido, em vez disso, fornece seu endereço IP resolvido a essa requisição. Essa distinção importa quando o proxy precisa resolver o nome do serviço ou aplicar uma política baseada no nome de host.

O que uma conexão bem-sucedida deixa para você

Os fluxos resultantes transportam os dados do serviço tunelizado. Eles não expõem uma resposta HTTP separada que sua aplicação deva ler e descartar. Adicionar uma segunda troca CONNECT enviaria texto HTTP ao serviço depois que o JDK já estabeleceu o túnel.

O exemplo define um tempo limite de conexão e um tempo limite de leitura do socket; são controles separados, não um único prazo geral para a sessão da aplicação.

A permissão CONNECT continua pertencendo ao proxy. Um ponto de extremidade que encaminha requisições web comuns pode rejeitar a porta do serviço ou exigir autenticação antes de abrir um túnel. Mantenha essas falhas separadas de um servidor que aceita o túnel mas depois rejeita o protocolo da sua aplicação.

Se esse protocolo precisar de TLS, negocie TLS pelo socket conectado com o nome de host pretendido do serviço e as verificações normais de certificado. O CONNECT sozinho não criptografa o fluxo. Para uma API HTTP real, um cliente HTTP continua sendo a interface mais conveniente porque também trata mensagens HTTP.

Artigos relacionados