Компоненты Apache Http - Как тайм-аут запроса CONNECT на прокси? - PullRequest
0 голосов
/ 22 июня 2019

Тайм-аут без использования прокси

Я запускаю netcat на своем локальном компьютере следующим образом, который в основном прослушивает соединения через порт 9090:

netcat -l -p 9090

И используя Apache HttpComponents , я создаю соединение с ним с таймаутом в 4 секунды ..

RequestConfig requestConfig = RequestConfig.custom()
        .setSocketTimeout(4000)
        .setConnectTimeout(4000)
        .setConnectionRequestTimeout(4000)
        .build();

HttpGet httpget = new HttpGet("http://127.0.0.1:9090");
httpget.setConfig(requestConfig);

try (CloseableHttpResponse response = HttpClients.createDefault().execute(httpget)) {}

В терминале (где у меня работает netcat) я вижу:

??]?D???;#???9?Mۡ?NR?w?{)?V?$?(=?&?*kj?
?5??98?#?'<?%?)g@?  ?/??32?,?+?0??.?2???/??-?1???D

<!-- 4 seconds later -->
read(net): Connection reset by peer

На стороне клиента я вижу:

Exception in thread "main" org.apache.http.conn.ConnectTimeoutException: 
Connect to 127.0.0.1:9090 [/127.0.0.1] failed: Read timed out

Это все ожидаемо.

Тайм-аут с использованием прокси

Я немного изменяю код клиента и настраиваю прокси, следуя документам здесь .

RequestConfig requestConfig = RequestConfig.custom()
         .setSocketTimeout(4000)
         .setConnectTimeout(4000)
         .setConnectionRequestTimeout(4000)
         .build();

HttpHost proxy = new HttpHost("127.0.0.1", 9090);
DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy);
CloseableHttpClient httpclient = HttpClients.custom()
        .setRoutePlanner(routePlanner)
        .build();

HttpGet httpget = new HttpGet("https://127.0.0.1:9090");
httpget.setConfig(requestConfig);

try (CloseableHttpResponse response = httpclient.execute(httpget)) {}

И снова запустите netcat, и на этот раз на стороне сервера

CONNECT 127.0.0.1:9090 HTTP/1.1
Host: 127.0.0.1:9090
User-Agent: Apache-HttpClient/4.4.1 (Java/1.8.0_212)

Но тайм-аут не работает для CONNECT. Я просто жду вечно ..

Как настроить httpclient на тайм-аут на 4 секунды, как в первом случае, который я описал?

Ответы [ 2 ]

0 голосов
/ 23 июня 2019

RequestConfig вступают в силу только после полного установления соединения с целью по определенному маршруту.Они не применяются к рукопожатию SSL или любым запросам CONNECT, которые выполняются до основного обмена сообщениями.

Настройка времени ожидания сокета на уровне ConnectionManager, чтобы обеспечить время ожидания операций на уровне соединения после определенного периода бездействия.

0 голосов
/ 22 июня 2019

Одна возможность:

// This part is the same..
httpget.setConfig(requestConfig);

ExecutorService executorService = Executors.newSingleThreadExecutor();
Callable<CloseableHttpResponse> callable = () -> {
    try (CloseableHttpResponse response = httpclient.execute(httpget)) {
        return response;
    }
};

Future<CloseableHttpResponse> future = executorService.submit(callable);
try {
    future.get(4, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
    httpget.abort();
    executorService.shutdownNow();
}

Но я открыт для других предложений ..

...