記錄使用OkHttp庫(kù)時(shí)候遇到的一些小問(wèn)題
1.ssl驗(yàn)證時(shí)出現(xiàn)的相關(guān)錯(cuò)誤
當(dāng)我們使用https來(lái)進(jìn)行數(shù)據(jù)傳輸加密肉康,身份校驗(yàn)的時(shí)候,HTTP 和 TCP 之間額外加了一層 SSL/TLS來(lái)做這部分工作(確定支持的TLS協(xié)議版本魔慷,建立連接并交互證書(shū),驗(yàn)證其有效性,最后通過(guò)非對(duì)稱(chēng)加密的方式和服務(wù)器返回的證書(shū)公鑰生成一個(gè)零時(shí)的秘鑰用作后續(xù)通信時(shí)的對(duì)稱(chēng)加解密通信數(shù)據(jù))记舆。
SSL/TLS具體工作原理可查看此文
可能遇到的相關(guān)錯(cuò)誤:
1.Unable to resolve host "xxx.xxxxxx.com": No address associated with hostname
2.HTTP FAILED: javax.net.ssl.SSLHandshakeException: Connection closed by peer
如果后臺(tái)記錄到類(lèi)似日志,大多數(shù)情況下可通過(guò)上下文相關(guān)輔助日志分析:
1.用戶自身網(wǎng)絡(luò)狀態(tài)是否良好呼巴,ip,country等信息也可以幫助分析
2.用戶是否開(kāi)啟了vpn泽腮,是否使用了第三方代理抓包工具 ,通過(guò)其uuid追蹤他的操作日志衣赶,查詢是否為可疑用戶
3.用戶手機(jī)的型號(hào)與版本诊赊,已知部分低版本手機(jī)/某些特殊的三星手機(jī),并不默認(rèn)支持TLS協(xié)議府瞄,此時(shí)需要額外設(shè)置okhttpclient或相關(guān)容錯(cuò)處理okhttp-issue
4.server端支持的TLS協(xié)議版本是否過(guò)老或者過(guò)新碧磅?
個(gè)人認(rèn)為大多數(shù)情況都是因?yàn)榍皟蓷l原因?qū)е碌拇藛?wèn)題,處理方式也可以仁者見(jiàn)仁智者見(jiàn)智:
1.做好網(wǎng)絡(luò)狀態(tài)判斷后,告知用戶retry即可
2.通過(guò)設(shè)置自定義sslSocketFactory和hostnameVerifier信任所有請(qǐng)求的驗(yàn)證SO上的解決方案
public final class NetworkHelper implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
public static SSLSocketFactory createSSLSocketFactory() {
SSLSocketFactory ssfFactory = null;
try {
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, new TrustManager[]{new NetworkHelper()}, new SecureRandom());
ssfFactory = sc.getSocketFactory();
} catch (Exception e) {
}
return ssfFactory;
}
public static class TrustAllHostnameVerifier implements HostnameVerifier {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
}
2.使用okhttp時(shí)候遵馆,如果手動(dòng)去設(shè)置accept-encoding為gzip/br/deflate等壓縮方式時(shí)鲸郊,其內(nèi)部自動(dòng)解壓縮的邏輯會(huì)失效
類(lèi)似于if (userSettedAcceptEncoding) return else doInternalUncompress,導(dǎo)致返回的response.body()為壓縮過(guò)后的無(wú)意義二進(jìn)制流货邓。此時(shí)的解決方案:
1.去除accept-encoding header即可
2.自己寫(xiě)解壓縮的Interceptor邏輯秆撮,但是非常不推薦此方法,自己有遇到有時(shí)work有時(shí)不work的情況换况,未深究职辨。