URLConnection從HTTP重定向到HTTPS
也不知什么原因,公司項(xiàng)目的服務(wù)端一直在吸引著大波攻擊,于是服務(wù)端的同學(xué)打算把所有HTTP的請(qǐng)求都換為HTTPS,他們決定兼容舊版本于是就將之前的所有HTTP請(qǐng)求全部重定向到另一個(gè)HTTPS請(qǐng)求。
項(xiàng)目請(qǐng)求框架搭建初期,考慮到應(yīng)用也不會(huì)使用太復(fù)雜的請(qǐng)求模式,于是就簡單使用URLConnection完成服務(wù)端交互。服務(wù)端一修改,全部請(qǐng)求都失敗了。雖然URLConnection有是否遵循重定向開關(guān)(setInstanceFollowRedirects),其默認(rèn)就是開啟的,即便你再強(qiáng)制其打開,也是沒有用,問題依舊。找了大量資料,其實(shí)問題的關(guān)鍵點(diǎn)不是重定向而是從HTTP重定向到HTTPS,關(guān)鍵點(diǎn)就在URLConnection的兩個(gè)子類上。
HttpURLConnection與HttpsURLConnection
HttpURLConnection為URLConnection的子類,而HttpsURLConnection為HttpURLConnection的子類,在HttpURLConnection基礎(chǔ)上對(duì)HTTPS進(jìn)行支持。
URLConnection通常使用URL的openConnection()方法獲得,而URL是根據(jù)其是否為Https開頭來打開一個(gè)HttpURLConnection還是HttpsURLConnection。
而當(dāng)URLConnection進(jìn)行connect()時(shí),遇到了重定向,如果打開了遵循重定向,那么其會(huì)獲取重定向的地址,然后嘗試連接這個(gè)地址。值得注意的是,這時(shí)候并不是使用新的鏈接地址重新openConnection()一個(gè)URLConnection,而是直接嘗試連接這個(gè)重定向的地址,否則也就不存在以上的Bug了。
于是理論上分析,HTTP重定向到HTTP是不存在問題的,HTTPS重定向到HTTPS也是不存在問題的,而HTTP與HTTPS之間的重定向,那么就很可能會(huì)有問題了。HTTP重定向到HTTPS,URLConnection會(huì)將重定向的HTTPS以HTTP方式繼續(xù)提交,那么服務(wù)端肯定是認(rèn)為你是錯(cuò)誤的提交方式;同理,HTTPS重定向HTTP也一樣。
問題解決
- 使用URLConnection抓取到重定向,就使用重定向的地址重新人為openConnection()一個(gè)新的URLConnection重新請(qǐng)求。
- 使用第三方請(qǐng)求框架,如OKHttp。
具體項(xiàng)目具體分析,方法一是可行的,但是處理起來就很麻煩了。而方案二則更可選,因?yàn)閁RLConnection與OKHttp用法其實(shí)差不了多遠(yuǎn)。