Избегайте кругового перенаправления с использованием HttpClient 4.1.1 - PullRequest
16 голосов
/ 14 июля 2011

Как мне избежать кругового перенаправления с помощью HttpClient 4.1.1.Как я получаю ошибку, как это: -

executing requestGET http://home.somehost.com/Mynet/pages/cHome.xhtml HTTP/1.1
org.apache.http.client.ClientProtocolException
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:822)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:754)
    at edu.uci.ics.crawler4j.url.WebURL.setURL(WebURL.java:122)
    at edu.uci.ics.crawler4j.crawler.CrawlController.addSeed(CrawlController.java:207)
    at edu.uci.ics.crawler4j.example.advanced.Controller.main(Controller.java:31)
Caused by: org.apache.http.client.CircularRedirectException: Circular redirect to 'http://home.somehost.com/Mynet/pages/Home.xhtml'
    at org.apache.http.impl.client.DefaultRedirectStrategy.getLocationURI(DefaultRedirectStrategy.java:168)
    at org.apache.http.impl.client.DefaultRedirectStrategy.getRedirect(DefaultRedirectStrategy.java:193)
    at org.apache.http.impl.client.DefaultRequestDirector.handleResponse(DefaultRequestDirector.java:1021)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:482)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:820)

Это мой код ...

DefaultHttpClient client = null;

        try
        {
            // Set url
            //URI uri = new URI(url.toString());

            client = new DefaultHttpClient();

            client.getCredentialsProvider().setCredentials(
                    new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM),
                    new UsernamePasswordCredentials("test", "test"));


            URL url1 = new URL (url);
            HttpURLConnection connection = (HttpURLConnection) url1.openConnection();
            connection.setFollowRedirects(false);

            HttpGet request = new HttpGet(url);
            final HttpParams params = new BasicHttpParams();
            HttpClientParams.setRedirecting(params, false);
            HttpContext context = new BasicHttpContext();

            System.out.println("----------------------------------------");
            System.out.println("executing request" + request.getRequestLine());
            HttpResponse response = client.execute(request, context);
            HttpEntity entity = response.getEntity();


            System.out.println(response.getStatusLine());
                    InputStream content = entity.getContent();
                    BufferedReader in   = 
                        new BufferedReader (new InputStreamReader (content));
                    String line;
                    while ((line = in.readLine()) != null) {
                       // System.out.println(line);
                    }
                } catch(Exception e) {
                    e.printStackTrace();
                }

Ответы [ 5 ]

32 голосов
/ 15 июля 2011

Вы можете установить для ClientPNames.ALLOW_CIRCULAR_REDIRECTS значение true, это позволит перенаправлять в то же место.

  client.getParams().setParameter(ClientPNames.ALLOW_CIRCULAR_REDIRECTS, true); 

Подробнее здесь

2 голосов
/ 11 октября 2013

Существует ошибка, которая вызывает циклическое перенаправление в Apache HttpClient начиная с 4.0, она не была исправлена ​​даже в последней версии.

В DefaultRequestDirector.java он создает HttpRedirect для выполнения перенаправления, и онбудет повторно использовать все заголовки в вашем исходном HttpGet, проблема здесь в том, что он также будет повторно использовать заголовок Host , что означает, что сервер все равно получит исходный хост после попытки перенаправления на новый URI.

Я исправил это, переопределив DefaultRequestDirector:

public class RedirectRequestDirector extends DefaultRequestDirector
{
    RedirectRequestDirector(
            final HttpRequestExecutor requestExec,
            final ClientConnectionManager conman,
            final ConnectionReuseStrategy reustrat,
            final ConnectionKeepAliveStrategy kastrat,
            final HttpRoutePlanner rouplan,
            final HttpProcessor httpProcessor,
            final HttpRequestRetryHandler retryHandler,
            final RedirectHandler redirectHandler,
            final AuthenticationHandler targetAuthHandler,
            final AuthenticationHandler proxyAuthHandler,
            final UserTokenHandler userTokenHandler,
            final HttpParams params) 
    {
        super(requestExec, conman, reustrat, kastrat, rouplan, httpProcessor, retryHandler, redirectHandler, targetAuthHandler, proxyAuthHandler, userTokenHandler, params);

    }
    @Override
    protected RoutedRequest handleResponse(RoutedRequest roureq,
            HttpResponse response,
            HttpContext context)
                    throws HttpException, IOException
    {
        RoutedRequest req = super.handleResponse(roureq, response, context);
        if(req != null)
        {
            String redirectTarget = req.getRoute().getTargetHost().getHostName();
            req.getRequest().getOriginal().setHeader("Host", redirectTarget);
        }
        return req;
    }

}

и DefaultHttpClient:

public class RedirectHttpClient extends DefaultHttpClient
{
    @Override
    protected RequestDirector createClientRequestDirector(
            final HttpRequestExecutor requestExec,
            final ClientConnectionManager conman,
            final ConnectionReuseStrategy reustrat,
            final ConnectionKeepAliveStrategy kastrat,
            final HttpRoutePlanner rouplan,
            final HttpProcessor httpProcessor,
            final HttpRequestRetryHandler retryHandler,
            final RedirectHandler redirectHandler,
            final AuthenticationHandler targetAuthHandler,
            final AuthenticationHandler proxyAuthHandler,
            final UserTokenHandler stateHandler,
            final HttpParams params) {
        return new RedirectRequestDirector(
                requestExec,
                conman,
                reustrat,
                kastrat,
                rouplan,
                httpProcessor,
                retryHandler,
                redirectHandler,
                targetAuthHandler,
                proxyAuthHandler,
                stateHandler,
                params);
    }
}

Теперь я не буду жаловаться на Circular Redirect.

2 голосов
/ 14 июля 2011

Вы просто избежали этого. HttpClient обнаружил циклическое перенаправление и выдал исключение. Если бы его не «избегали», он продолжал бы перенаправлять навсегда (пока вы не решили убить процесс). Существует не так много других вариантов, если сервер отвечает.

Единственный способ по-настоящему избежать циклического перенаправления - это исправить сервер.

Если вам интересно, что происходит (например, почему он работает в браузере, а не в вашей программе), попробуйте включить некоторые дополнительные журналы HttpClient. В частности, убедитесь, что вы видите все заголовки HTTP, отправляемые туда и обратно. Затем вы можете посмотреть на разговор, происходящий, когда вы делаете тот же запрос в вашем браузере, отмечая различия. Это может быть отсутствующий файл cookie, сумасшедшее обнаружение браузера и т. Д. *

Существует несколько способов отслеживания сообщений вашего браузера. Вот несколько способов, которыми я часто пользуюсь, от самых простых до самых сложных (ИМХО):

  • Firefox + HttpFox (или LiveHttpHeaders, Firebug и т. Д ...)
  • Скрипач (только для Windows)
  • Wireshark / ТСРйитр

Для низкоуровневого тестирования попробуйте использовать telnet (если только вы не используете Windows, в этом случае вам может быть лучше что-то вроде PuTTY / plink ) и укажите, какие изменения вызывают круговые перенаправления .

0 голосов
/ 21 октября 2016

Вы можете попробовать:

RequestConfig requestConfig = RequestConfig.custom()
                              .setCircularRedirectsAllowed(true)
                              .build();

HttpClient httpClient = HttpClients.custom()
                        .setDefaultRequestConfig(requestConfig)
                        .setRedirectStrategy(new LaxRedirectStrategy())
                        .build();

HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
0 голосов
/ 16 января 2014

Убедитесь, что ваш запрос не отправлен прокси-серверу, прежде чем отправлять его по URL-адресу, который вы запросили.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...