19 Stimmen

Vermeiden Sie zirkuläre Umleitung mit HttpClient 4.1.1

Wie kann ich vermeiden, zirkuläre Umleitung mit HttpClient 4.1.1. Da ich den Fehler wie folgt bekomme:-

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)

Dies ist mein Code...

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

36voto

nos Punkte 214143

Sie können ClientPNames.ALLOW_CIRCULAR_REDIRECTS auf true setzen, dann sind Umleitungen zum gleichen Ort möglich.

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

Mehr Infos sehen aquí

4voto

Provat Punkte 41

Sie können es versuchen:

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

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

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

3voto

Adam Batkin Punkte 49295

Sie haben es einfach vermieden. HttpClient erkannte die zirkuläre Weiterleitung und warf eine Ausnahme. Wäre es nicht "vermieden" worden, hätte es die Umleitung für immer fortgesetzt (bis Sie beschlossen, den Prozess zu beenden). Es gibt nicht viele andere Möglichkeiten, wenn der Server mit dieser Antwort reagiert.

Die einzige Möglichkeit, eine zirkuläre Umleitungsschleife wirklich zu vermeiden, besteht darin, den Server zu reparieren.

Wenn Sie sich fragen, was los ist (z. B. warum es in einem Browser zu funktionieren scheint, aber nicht in Ihrem Programm), versuchen Sie, einige der zusätzlichen HttpClient-Protokolle zu aktivieren. Stellen Sie insbesondere sicher, dass Sie alle HTTP-Header sehen können, die hin und her gesendet werden. Sie können sich dann die Konversation ansehen, die stattfindet, wenn Sie die gleiche Anfrage in Ihrem Browser stellen, und die Unterschiede feststellen. Es könnte sich um ein fehlendes Cookie, eine verrückte Browsererkennung usw. handeln.

Es gibt eine Reihe von Möglichkeiten, die Kommunikation Ihres Browsers nachzuvollziehen. Hier sind ein paar Möglichkeiten, die ich häufig verwende, in der Reihenfolge vom einfachsten zum schwierigsten (IMHO):

  • Firefox + HttpFox (oder LiveHttpHeaders, Firebug, etc...)
  • Fiddler (nur Windows)
  • Wireshark/tcpdump

Für Low-Level-Tests können Sie telnet verwenden (es sei denn, Sie verwenden Windows, in diesem Fall ist es besser, wenn Sie etwas wie PuTTY/Plink ) und zu entscheiden, welche Änderungen die zirkulären Umleitungen verursachen.

2voto

lex chou Punkte 95

Es gibt einen Fehler, der eine zirkuläre Umleitung im Apache HttpClient seit Version 4.0 verursacht, er wurde auch in der neuesten Version nicht behoben.

In DefaultRequestDirector.java wird ein HttpRedirect erstellt, um eine Umleitung durchzuführen, und es werden alle Header in Ihrem ursprünglichen HttpGet wiederverwendet, das Problem hier ist, dass es auch wiederverwendet wird Gastgeber Header, was bedeutet, dass der Server nach dem Versuch, auf einen neuen URI umzuleiten, immer noch den ursprünglichen Host erhält.

Ich habe dies behoben, indem ich den DefaultRequestDirector reimplementiert habe:

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

}

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

Ich werde mich jetzt nicht über die Umleitung beschweren.

0voto

Chris Punkte 4535

Stellen Sie sicher, dass Ihre Anfrage nicht an einen Proxy gesendet wird, bevor sie an die von Ihnen angeforderte Adresse weitergeleitet wird.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X