Власний протокол TCP може проходити через HTTP-проксі, коли цей проксі дозволяє CONNECT до призначення. Протокол застосунку не мусить ставати HTTP: HTTP встановлює тунель, а потім застосунок обмінюється власними байтами всередині нього.

OpenJDK 25 надає шлях через HTTP-проксі в Socket(Proxy). Його реалізація виконує обмін CONNECT і повертає підключений сокет для використання застосунком.

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();
}

Цей фрагмент використовує класи з java.net і java.io. Замініть обидві кінцеві точки та виконайте обмін протоколом до виходу з блоку try. Для дозволеної публічної цілі TCP вибирайте HTTP-кандидатів зі списку HTTP-проксі лише після перевірки дозволу CONNECT для порту цієї цілі. Адреса проксі — це місце, куди Java підключається першою; адреса, передана в connect, визначає службу, якої проксі має досягти.

Невизначене призначення зберігає своє ім'я хоста для запиту CONNECT у цій реалізації. Визначений InetSocketAddress натомість передає цьому запиту свою визначену IP-адресу. Ця різниця важлива, коли проксі має визначити ім'я служби або застосувати політику на основі імені хоста.

Що залишає успішне з'єднання

Отримані потоки несуть дані служби, що проходить через тунель. Вони не розкривають окремої відповіді HTTP, яку ваш застосунок мав би прочитати й відкинути. Додавання другого обміну CONNECT надіслало б службі текст HTTP після того, як JDK уже встановив тунель.

Приклад задає час очікування з'єднання та час очікування читання із сокета; це окремі засоби керування, а не один спільний строк для сеансу застосунку.

Дозвіл CONNECT усе ще належить проксі. Кінцева точка, що пересилає звичайні веб-запити, може відхилити порт служби або вимагати автентифікації перед відкриттям тунелю. Тримайте ці відмови окремо від сервера, який приймає тунель, але згодом відхиляє протокол вашого застосунку.

Якщо цьому протоколу потрібен TLS, узгодьте TLS через підключений сокет із передбаченим іменем хоста служби та звичайними перевірками сертифіката. Сам CONNECT не шифрує потік. Для справжнього HTTP API HTTP-клієнт залишається зручнішим інтерфейсом, бо він також обробляє повідомлення HTTP.

Схожі статті