Un protocolo TCP personalizado puede viajar a través de un proxy HTTP cuando ese proxy permite CONNECT hacia el destino. El protocolo de la aplicación no tiene que convertirse en HTTP: HTTP establece el túnel y después la aplicación intercambia sus propios bytes dentro de él.

OpenJDK 25 ofrece una ruta de proxy HTTP en Socket(Proxy). Su implementación realiza el intercambio CONNECT y devuelve un socket conectado para que lo use la aplicación.

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 fragmento utiliza clases de java.net y java.io. Sustituya los dos extremos y realice el intercambio de protocolo antes de salir del bloque try. Para un destino TCP público permitido, elija candidatos HTTP de la lista de proxies HTTP solo después de comprobar el permiso CONNECT para el puerto de ese destino. La dirección del proxy es donde Java se conecta primero; la dirección que se pasa a connect identifica el servicio que el proxy debe alcanzar.

El destino sin resolver conserva su nombre de host para la solicitud CONNECT de esta implementación. Un InetSocketAddress resuelto, en cambio, aporta su dirección IP resuelta a esa solicitud. Esa distinción importa cuando el proxy debe resolver el nombre del servicio o aplicar una política basada en el nombre de host.

Qué le deja una conexión correcta

Los flujos resultantes transportan los datos del servicio tunelizado. No exponen una respuesta HTTP separada que su aplicación deba leer y descartar. Añadir un segundo intercambio CONNECT enviaría texto HTTP al servicio después de que el JDK ya haya establecido el túnel.

El ejemplo proporciona un tiempo de espera de conexión y un tiempo de espera de lectura del socket; son controles separados, no un único plazo global para la sesión de la aplicación.

El permiso CONNECT sigue perteneciendo al proxy. Un extremo que reenvía solicitudes web ordinarias puede rechazar el puerto del servicio o exigir autenticación antes de abrir un túnel. Mantenga esos fallos separados de un servidor que acepta el túnel pero luego rechaza el protocolo de su aplicación.

Si ese protocolo necesita TLS, negocie TLS a través del socket conectado con el nombre de host previsto del servicio y las comprobaciones habituales de certificados. CONNECT por sí solo no cifra el flujo. Para una API HTTP real, un cliente HTTP sigue siendo la interfaz más cómoda porque también gestiona los mensajes HTTP.

Artículos relacionados