Apache HttpClient中循环重定向的bug详解

 更新时间:2016年1月28日 00:50  点击:1862

在Apache HttpClient 4.0里有个循环重定向的bug,当服务器试图正常的从域名A跳转到B的时候就会发生(我是在 111cn.net 跳 www.111cn.net 的时候发现的),换过最新版也发现还是有这个问题。

跟踪了DefaultRequestDirector.java之后发现,它在内部创建了一个HttpRedirect对象来处理重定向,这个对象会重用你之前的HttpGet对象里的HTTP 头,导致这个bug的根源在于,连Host头也用了,这表示重定向到的新域名如果和老域名如果是同一组集群,那么服务器会试图重新发一个重定向请求,这样就造成了HttpClient抛出CircularRedirectException。

我是派生了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;
    }

}

这里修改了Host头为试图重定向的主机名。
还需要修改 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);
    }
}

现在就能正常处理跳转了。

[!--infotagslink--]

相关文章

  • Java8处理List的双层循环问题

    这篇文章主要介绍了Java8处理List的双层循环问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-19
  • jquery中常用的SET和GET$(”#msg”).html循环介绍

    复制代码 代码如下: $(”#msg”).html(); //返回id为msg的元素节点的html内容。 $(”#msg”).html(”new content“); //将“new content” 作为html串写入id为msg的元素节点内容中,页面显示粗体的new content $(”...2013-10-13
  • 浅谈Java8 的foreach跳出循环break/return

    这篇文章主要介绍了Java8 的foreach跳出循环break/return,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-07-28
  • Spring Boot项目@RestController使用重定向redirect方式

    这篇文章主要介绍了Spring Boot项目@RestController使用重定向redirect方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-02
  • mybatis-plus  mapper中foreach循环操作代码详解(新增或修改)

    这篇文章主要介绍了mybatis-plus mapper中foreach循环操作代码详解(新增或修改),本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-11-17
  • C#的循环语句集锦及案例详解

    这篇文章主要介绍了C#中的基本循环:while循环、for循环和foreach循环,大家都知道循环结构可以简化程序编码,更好地实现理想的效果,并结合案例给大家讲解,需要的朋友可以参考下...2020-06-25
  • python 实现循环定义、赋值多个变量的操作

    这篇文章主要介绍了python 实现循环定义、赋值多个变量的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-09
  • shell中的for循环用法详解

    这篇文章主要介绍了shell中的for循环用法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-07-11
  • 解决vue-router路由拦截造成死循环问题

    这篇文章主要介绍了解决vue-router路由拦截造成死循环问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-05
  • cmd命令的重定向输出 2>&1详解

    这篇文章主要介绍了cmd命令的重定向输出 2>&1详解,需要的朋友可以参考下...2020-08-28
  • c# 循环语句的使用方法

    这篇文章主要介绍了c# 循环语句的使用方法,文中代码非常详细,供大家参考和学习,感兴趣的朋友可以了解下...2020-06-25
  • Apache启动报错No space left on device: AH00023该怎么解决

    Apache启动报错No space left on device: AH00023错误可能是进程导致了,虽然小编不知道什么原因但网上提供的解决办法确实是可以解决我们的问题,下面来看看。对于这类错误是因为linux系统的ipc信号量造成的,apache启动时...2015-10-21
  • JavaScript循环遍历的24个方法,你都知道吗

    这篇文章主要给大家介绍了关于JavaScript循环遍历的24个方法,文中对每种方法都给出了详细的实例代码,方便大家理解学习,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2021-09-15
  • Java8之Stream流代替For循环操作

    这篇文章主要介绍了Java8之Stream流代替For循环操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-19
  • apache配置黑名单和白名单及账户权限控制

    本文我们将分享apache配置黑名单和白名单,apache层的账户权限控制,以及apache黑名单白名单过滤功能,apache rewrite规则实现白名单。 apache配置黑名单和白名单的两...2016-09-14
  • apache实现http重定向到https

    老谢目前做了一个新站,全站采用https协议访问,所以需要http重定向到https,只需要在.htaccess加入下面规则既可: 代码如下 复制代码 RewriteEngine On Rew...2016-01-28
  • Javascript循环删除数组中元素的几种方法示例

    这篇文章主要给大家介绍了关于Javascript循环删除数组中元素的几种方法,文中给出了详细的示例代码供大家参考学习,对大家具有一定的参考学习价值,需要的朋友们下面来一起看看吧。...2017-05-22
  • c#入门之循环语句使用详解(for循环、do/while)

    这篇文章主要介绍了c#入门之循环语句使用详解,有for循环和do/while的示例,需要的朋友可以参考下...2020-06-25
  • 如何检测JavaScript中的死循环示例详解

    这篇文章主要给大家介绍了关于如何检测JavaScript中死循环的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-08-31
  • Python While循环语句实例演示及原理解析

    这篇文章主要介绍了Python While循环语句实例演示及原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-04-30