Tunele Java Socket HTTP CONNECT w OpenJDK 25
Użyj ścieżki gniazda przez serwer proxy HTTP w OpenJDK 25, aby dotrzeć do dozwolonej usługi TCP, zachowując osobno punkt końcowy proxy i cel.
Własny protokół TCP może podróżować przez serwer proxy HTTP, gdy ten proxy zezwala na CONNECT do celu. Protokół aplikacji nie musi stawać się HTTP: HTTP ustanawia tunel, a następnie aplikacja wymienia w nim własne bajty.
OpenJDK 25 udostępnia ścieżkę przez proxy HTTP w Socket(Proxy). Jego implementacja wykonuje wymianę CONNECT i zwraca połączone gniazdo do użytku przez aplikację.
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();
}Ten fragment używa klas z java.net i java.io. Zastąp oba punkty końcowe i wykonaj wymianę protokołu przed opuszczeniem bloku try. Dla dozwolonego publicznego celu TCP wybieraj kandydatów HTTP z listy proxy HTTP dopiero po sprawdzeniu pozwolenia CONNECT dla portu tego celu. Adres proxy to miejsce, do którego Java łączy się najpierw; adres przekazany do connect identyfikuje usługę, do której proxy ma dotrzeć.
Nierozwiązany cel zachowuje swoją nazwę hosta na potrzeby żądania CONNECT tej implementacji. Rozwiązany InetSocketAddress zamiast tego przekazuje temu żądaniu swój rozwiązany adres IP. Ta różnica ma znaczenie, gdy proxy musi rozwiązać nazwę usługi lub zastosować politykę opartą na nazwie hosta.
Co pozostawia udane połączenie
Otrzymane strumienie przenoszą dane tunelowanej usługi. Nie ujawniają osobnej odpowiedzi HTTP, którą aplikacja powinna odczytać i odrzucić. Dodanie drugiej wymiany CONNECT wysłałoby tekst HTTP do usługi po tym, jak JDK już ustanowił tunel.
Przykład ustawia limit czasu połączenia i limit czasu odczytu gniazda; to osobne mechanizmy sterowania, a nie jeden ogólny termin sesji aplikacji.
Pozwolenie CONNECT nadal należy do proxy. Punkt końcowy, który przekazuje zwykłe żądania sieciowe, może odrzucić port usługi lub wymagać uwierzytelnienia przed otwarciem tunelu. Trzymaj te niepowodzenia osobno od serwera, który akceptuje tunel, ale później odrzuca protokół aplikacji.
Jeśli ten protokół wymaga TLS, wynegocjuj TLS przez połączone gniazdo z zamierzoną nazwą hosta usługi i zwykłymi kontrolami certyfikatu. Samo CONNECT nie szyfruje strumienia. Dla prawdziwego HTTP API klient HTTP pozostaje wygodniejszym interfejsem, ponieważ obsługuje także komunikaty HTTP.