• 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的代码,所以没有去找到底是哪个版本开始做了修改了。

  • 相关阅读:
    c#添加托盘图标右键后显示菜单选项
    mysql workbench修改字段报错
    mysql增删改查语句
    连接win7的mysql很慢解决方法
    uvm_cmdline_processor
    cadence help文件库调出指令 :cdnshelp
    设置开机自动运行vncserver
    Vector bit-select and part-select addressing verilog片选写法
    Verilog三段式状态机描述
    同步FIFO学习
  • 原文地址:https://www.cnblogs.com/skyaccross/p/2828986.html
Copyright © 2020-2023  润新知