HttpURLConnection 设置Host 头部无效

最近做了一个服务,对外提供http接口,采用nginx反代,使用域名访问
但是为了容灾,客户端需要指定ip访问该服务,如果该ip坏掉,客户端就切换到另个一ip(靠dns解析太慢)

nginx上只配置了域名的分发,没有配置ip分发
于是在http请求上做了点处理,url配置ip,同时配置http头部的Host参数为该域名,
HttpURLConnection 有setRequestProperty(key,value)方法来设置http头部
通过ip访问,设置Host头部来让nginx识别,然后分发到相应的处理程序

代码如下

HttpURLConnection urlConn = null;
String url = "http://192.168.1.120/login?platform=xxx&type=account";
URL destURL = new URL(url);
urlConn = (HttpURLConnection) destURL.openConnection();
urlConn.setConnectTimeout(10000);
urlConn.setReadTimeout(10000);
urlConn.setRequestProperty("Host", "auth.xxx.com");

这里我们要访问192.168.1.120这个服务器的一个login服务,配置的域名是 auth.xxx.com
嗯,本地测试ok,就发布到服务器上了。

但是神奇的事情出现了,我们有5台服务器,其中2台可以,另外3台死活不行,总报错说404错误

404说明客户端请求路径不存在,推测估计是Host没有生效。
对比可以和不可以的两种服务器的环境,可以的jdk是 6U18,不可以的是6U24

于是怀疑jdk升级的问题,在网上搜了搜,找了HttpURLConnection的sun的源代码

http://javasourcecode.org/html/open-source/jdk/jdk-6u23/sun/net/www/protocol/http/HttpURLConnection.java.html

发现里面 有一个 allowRestrictedHeaders 这个参数,原来api在设计的时候,可能为了安全,限制了程序能够使用的Http Header
如,下面的都是限制的

private static final String[] restrictedHeaders = {
    /* Restricted by XMLHttpRequest2 */
    //"Accept-Charset",
    //"Accept-Encoding",
    "Access-Control-Request-Headers",
    "Access-Control-Request-Method",
    "Connection", /* close is allowed */
    "Content-Length",
    //"Cookie",
    //"Cookie2",
    "Content-Transfer-Encoding",
    //"Date",
    "Expect",
    "Host",
    "Keep-Alive",
    "Origin",
    // "Referer", 
    // "TE",
    "Trailer",
    "Transfer-Encoding",
    "Upgrade",
    //"User-Agent",
    "Via"
    };

    allowRestrictedHeaders = ((Boolean)java.security.AccessController.doPrivileged(
        new sun.security.action.GetBooleanAction(
            "sun.net.http.allowRestrictedHeaders"))).booleanValue();

里面就有我们要设置的Host,找到原因,就好解决了,只要告诉程序,允许能使用这些限制的头部即可

System.setProperty("sun.net.http.allowRestrictedHeaders", "true");

就ok了,搞定,收工。

【总结】
1.遇到同一份代码有的服务器可以,有的服务器不行的话,多半是环境问题,常见的环境问题有:
  语言环境,字符集编码(如UTF-8/GB2312,虚拟机版本,环境变量路径等

2.没有找到6U18的代码,所以没有去找到底是哪个版本开始做了修改了。

posted on 2012-12-22 13:02  skyaccross  阅读(9205)  评论(0编辑  收藏  举报