2011-07-14 16 views
15

¿Cómo puedo evitar la redirección circular utilizando HttpClient 4.1.1. Como estoy consiguiendo el error como este: -Evite la redirección circular utilizando 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) 

Este es mi código ...

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

¿Seguro que se puede evitar? Si realmente hay una redifección circular, lanzar una excepción parece una forma razonable de indicar eso. – nos

+0

@nos Gracias por responder de nuevo. Estoy recibiendo la misma URL para la redirección circular. Pero si escribo esa url en el navegador, recibo tres respuestas del servidor con la misma URL. Primero es 302 tempo movido. el segundo es 302 encontrado, el tercero es 200 correcto ... con la misma URL ... Y quiero capturar el contenido de esta url. – ferhan

Respuesta

31

Puede establecer ClientPNames.ALLOW_CIRCULAR_REDIRECTS en true, esto permitirá redirigir a la misma ubicación.

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

Ver más información here

+0

El enlace está roto. – Youngjae

+8

Esto está en desuso para la versión actual. Use RequestConfig.custom(). SetCircularRedirectsAllowed (true) .build() en su lugar. – keiki

+0

En realidad, esto no es solo para evitar que HttpClient arroje un error de redirección. Eso significa que la redirección todavía está sucediendo? Como Adam ha mencionado, ¿no necesita una solución permanente en el servidor? –

2

Sólo lo evitó. HttpClient detectó la redirección circular y lanzó una excepción. Si no se hubiera "evitado", continuaría redirigiendo para siempre (hasta que haya decidido matar el proceso). No hay muchas otras opciones, si eso es lo que el servidor responde.

La única manera de evitar realmente un bucle de redirección circular es reparar el servidor.

Si se está preguntando qué está sucediendo (como por qué parece que funciona buscar en un navegador pero no en su programa), intente encender algunos de los registros adicionales de HttpClient. En particular, asegúrese de poder ver todos los encabezados HTTP que se envían de un lado a otro. Luego puede ver la conversación que tiene lugar cuando realiza la misma solicitud en su navegador, anotando las diferencias. Puede ser una cookie faltante, detección de navegador loca, etc.

Existen varias maneras de rastrear las comunicaciones de su navegador. Aquí hay algunas maneras que utilizo a menudo, con el fin de menor a mayor dificultad (en mi humilde opinión):

  • Firefox + HttpFox (o LiveHTTPHeaders, Firebug, etc ...)
  • Fiddler (sólo Windows)
  • Wireshark/tcpdump

Para las pruebas de bajo nivel, trate de usar telnet (a menos que se utiliza Windows, en cuyo caso puede ser mejor con algo así como PuTTY/plink) y la decisión de entrada/salida qué cambios hacen que las redirecciones circulares.

+0

Gracias por responder de nuevo. Estoy recibiendo la misma URL para la redirección circular. Pero si escribo esa url en el navegador, recibo tres respuestas del servidor con la misma URL. Primero es 302 tempo movido. el segundo es 302 encontrado, el tercero es 200 correcto ... con la misma URL ... Y quiero capturar el contenido de esta url. – ferhan

+0

He actualizado mi respuesta con algunas sugerencias para diagnosticar el problema –

+0

Estoy usando firebug en mi firefox ... Entonces en el firebug cuando veo la respuesta ... Veo 302 Encontrado, 302 Movido temporalmente, luego atlast 200 OK para la misma url en mi firebug. – ferhan

2

Hay un error que hará que redirección circular en Apache HttpClient desde 4.0, no se fijó incluso en la versión más reciente.

En DefaultRequestDirector.java, se crea un HTTPRedirect realizar la redirección, y se volverá a utilizar todos los encabezados en su HttpGet original, el problema aquí es que también reutilizar cabecera Host, lo que significa que el servidor todavía obtendrá el original host después de intentar redireccionar al nuevo URI.

He arreglado esto reimplantado el 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; 
    } 

} 

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

Ahora bien, no se quejará de la Circular de redireccionamiento.

0

Compruebe que su solicitud no se envíe a un proxy antes de ser enviada a la url que ha solicitado.

0

puede intentar:

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

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

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