Tunnels HTTP CONNECT avec Java Socket dans OpenJDK 25
Utilisez le chemin de socket via proxy HTTP d’OpenJDK 25 pour joindre un service TCP autorisé, tout en gardant distincts le point de terminaison du proxy et la destination.
Un protocole TCP personnalisé peut traverser un proxy HTTP lorsque ce proxy autorise CONNECT vers la destination. Le protocole applicatif n’a pas besoin de devenir HTTP : HTTP établit le tunnel, puis l’application échange ses propres octets à l’intérieur.
OpenJDK 25 fournit un chemin via proxy HTTP dans Socket(Proxy). Son implémentation effectue l’échange CONNECT et renvoie un socket connecté que l’application peut utiliser.
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();
}Cet extrait utilise des classes de java.net et java.io. Remplacez les deux points de terminaison et effectuez l’échange de protocole avant de quitter le bloc try. Pour une cible TCP publique autorisée, choisissez des candidats HTTP dans la liste de proxys HTTP seulement après avoir vérifié l’autorisation CONNECT pour le port de cette cible. L’adresse du proxy est l’endroit où Java se connecte d’abord ; l’adresse transmise à connect identifie le service que le proxy doit atteindre.
La destination non résolue conserve son nom d’hôte pour la requête CONNECT de cette implémentation. Une InetSocketAddress résolue fournit au contraire son adresse IP résolue à cette requête. Cette distinction compte lorsque le proxy doit résoudre le nom du service ou appliquer une politique fondée sur le nom d’hôte.
Ce qu’une connexion réussie vous laisse
Les flux obtenus transportent les données du service tunnelisé. Ils n’exposent pas de réponse HTTP distincte que votre application devrait lire puis jeter. Ajouter un second échange CONNECT enverrait du texte HTTP au service alors que le JDK a déjà établi le tunnel.
L’exemple définit un délai de connexion et un délai de lecture du socket ; ce sont des contrôles distincts, et non une échéance globale unique pour la session applicative.
L’autorisation CONNECT appartient toujours au proxy. Un point de terminaison qui relaie des requêtes web ordinaires peut refuser le port du service ou exiger une authentification avant d’ouvrir un tunnel. Gardez ces échecs distincts d’un serveur qui accepte le tunnel mais rejette ensuite votre protocole applicatif.
Si ce protocole nécessite TLS, négociez TLS via le socket connecté avec le nom d’hôte prévu du service et les vérifications habituelles du certificat. CONNECT seul ne chiffre pas le flux. Pour une véritable API HTTP, un client HTTP reste l’interface la plus commode, car il gère aussi les messages HTTP.