HttpURLConnection 設定Host 頭部無效
阿新 • • 發佈:2018-12-25
最近做了一個服務,對外提供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的原始碼
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的程式碼,所以沒有去找到底是哪個版本開始做了修改了。