Apache HTTP Components. Получить ответ на запрос подключения


Я использую Apache htpp Components (версия-4.5.2) и пытаюсь запросить страницу HTTPS через прокси-сервер.

Редактировать:

Моя главная проблема заключается в том, что мне нужно знать, как отличить сбои прокси-сервера от сбоев запрашиваемых URI (как для HTTP, так и для HTTPS). У меня много прокси и они не надежны на 100%, поэтому в случае сбоя прокси мне нужно повторить запрос с другого прокси сервера.

Например (в случае HTTPS), NoHttpResponseException может быть возвращается в обоих случаях, т. е. при сбое прокси или при сбое целевого URL. Как я могу узнать корень проблемы? Откуда взялся этот NoHttpResponseException? От прокси из целевого Ури?

Я подумал, что могу попробовать прочитать ответ на запрос CONNECT к прокси-серверу,и если это 200, то я это означает, что прокси хорош и следующий NoHttpResponseException приходит с целевого URL. Но если я получаю NoHttpResponseException немедленно (до того, как прокси вернул мне код состояния 200 для подключения), это означает, что проблема с самим прокси, и мне нужно повторить попытку запрос с другого прокси-сервера. Но я не смог найти никаких документов, как получить доступ к ответу на запрос CONNECT, возвращенный прокси-сервером.

Кроме того, иногда я получаю HttpHostConnectException и ConnectTimeoutException. Я рассматриваю это исключение как проблему с прокси (как для HTTP, так и для HTTPS) - это правильный путь? Или это 2 исключения могут произойти даже для целевого URL?
1 2

1 ответ:

Это не будет красиво, но это должно сделать трюк

HttpHost myproxy = new HttpHost("myproxy", 8080)
CloseableHttpClient client = HttpClientBuilder.create()
        .setProxy(myproxy)
        .setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy() {

            @Override
            public boolean isAuthenticationRequested(HttpHost authhost, HttpResponse response, HttpContext context) {

                if (myproxy.equals(authhost)) {
                    context.setAttribute("proxy.status", response.getStatusLine());
                }
                return super.isAuthenticationRequested(authhost, response, context);
            }
        })
        .build();

HttpClientContext context = HttpClientContext.create();
HttpGet get = new HttpGet("https://httpbin.org/");
try (CloseableHttpResponse response = client.execute(get, context)) {
    EntityUtils.consume(response.getEntity());
}
StatusLine proxyStatus = context.getAttribute("proxy.status", StatusLine.class);
System.out.println("Proxy said " + proxyStatus);

PS: HttpHostConnectException и ConnectTimeoutException исключения могут быть брошены только на первом прыжке, то есть при подключении к прокси. Если прокси-сервер не сможет подключиться к целевому серверу по какой-либо причине, он, скорее всего, ответит статусом 5xx в ответ на метод CONNECT.