web-dev-qa-db-ja.com

HttpClient4.1.1を使用した循環リダイレクトを回避する

HttpClient4.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();
                }
16
arsenal

ClientPNames.ALLOW_CIRCULAR_REDIRECTSをtrueに設定できます。これにより、同じ場所へのリダイレクトが可能になります。

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

詳細を見る ここ

32
nos

あなたはそれを避けました。 HttpClientが循環リダイレクトを検出し、例外をスローしました。それが「回避」されていなければ、(プロセスを強制終了することを決定するまで)永久にリダイレクトし続けます。サーバーが応答するのであれば、他のオプションはそれほど多くありません。

循環リダイレクトループを本当に回避する唯一の方法は、サーバーを修正することです。

何が起こっているのか疑問に思っている場合(ブラウザでは機能しているように見えるが、プログラムからは機能していないように見える)、追加のHttpClientログのいくつかをオンにしてみてください。特に、すべてのHTTPヘッダーが送受信されていることを確認してください。次に、ブラウザで同じリクエストを行ったときに行われている会話を確認し、違いに注意してください。クッキーの欠落、ブラウザの異常検出などである可能性があります...

ブラウザの通信を追跡する方法はいくつかあります。最も簡単なものから最も難しいもの(IMHO)の順に、私がよく使用するいくつかの方法を次に示します。

  • Firefox + HttpFox (またはLiveHttpHeaders、Firebugなど...)
  • フィドラー (Windowsのみ)
  • Wireshark/tcpdump

低レベルのテストでは、telnetを使用してみてください(Windowsを使用している場合を除きます。その場合は、 PuTTY/plink のようなものを使用したほうがよい場合があります)、循環リダイレクトの原因となる変更を除外します。

2
Adam Batkin

4.0以降のApacheHttpClientで循環リダイレクトを引き起こすバグがあり、最新バージョンでも修正されていません。

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

これで、CircularRedirectについて文句を言うことはありません。

2
lex chou

あなたは試すことができます:

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

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

HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
2
Provat

リクエストしたURLに送信する前に、リクエストがプロキシに送信されていないことを確認してください。

0
Chris