iOS HTTPDNS集成般哼,結(jié)合AFNetwork進行“ip直連”

????????本期是通過NSURLProtocol攔截的方式替換ip,包括SNI的處理钞楼。后期有時間會有一章通過hook網(wǎng)絡(luò)框架AFN的方式喇闸,這種方式也無需改變AFN源碼,包括在HTTPS證書校驗的過程询件。而本文主要針對HTTPS協(xié)議進行說明燃乍,HTTP協(xié)議沒有SSL/TLS的證書驗證的過程,處理起來比較簡單宛琅,也無需用到CFNetwork刻蟹,所以暫時不做講解。還有一篇結(jié)合SDWebImage對HTTP協(xié)議進行"ip直連"的文章嘿辟。無論是HTTP還是HTTPS都可結(jié)合AFNetwork和SDWebImage進行"ip直連"座咆,其中原理都是相通的痢艺。若有不足或誤區(qū)仓洼,盼請指正介陶。

? ? ? ? 大概說一下本章內(nèi)容:本文對HTTPDNS做一個較為詳細的講解,在看本文之前色建,您需要對系統(tǒng)偏底層的CFNetwork網(wǎng)絡(luò)框架有一個比較基礎(chǔ)的認知哺呜。整體總結(jié)為以下幾點。

一箕戳、什么是HTTPDNS?

? ? ? ? 首先某残,DNS解析的目的就是通過某個域名:host(www.xxx.com)找到ip地址(111.111.1.1)。對于HTTPDNS的含義陵吸,用通俗簡單一點語言解釋玻墅。就是跳過運營商的DNS解析,通過ip地址直接精準對目標服務器進行連接壮虫“南幔可避免被劫持,并大大縮短DNS解析時間囚似,這也是對網(wǎng)絡(luò)請求的一個重要優(yōu)化環(huán)節(jié)(DNS優(yōu)化)剩拢。

? ? ? ? 我們都知道一般的request發(fā)出去之后的第一步就是對請求域名進行解析,而一般情況下我們的解析都是走運營商的LocalDNS饶唤,首先LocalDNS會對請求過的數(shù)據(jù)做緩存徐伐,因為緩存的時效性,我們想拿到最新最準確的數(shù)據(jù)時就會受限募狂。其次办素,在這個DNS解析的過程中容易被外界劫持,注入一些未知的內(nèi)容(像廣告一類)后返回祸穷,甚至返回一個全新的ip給用戶性穿,可能危及到用戶的個人隱私。而HTTPDNS是讓用戶繞過LocalDNS粱哼,在發(fā)送請求之前在本地就把host換成ip季二,直接對準目標服務器,這樣就無需去問運營商服務器索要ip了揭措,本來耗時不短的DNS的解析過程耗已在本地客戶端完成了胯舷,所以DNS解析的時間就大大縮短了。? ?

? ? ? ? 至于怎么拿到host對應的ip呢绊含,因為客戶端沒法拿到當前host對應的最優(yōu)ip(比如根據(jù)發(fā)送請求的地域不同等原因桑嘶,對應的最優(yōu)ip也可能不同),所以最好不要寫死在客戶端躬充,而是通過外界拿到逃顶。兩種方案:1讨便、服務器直接下發(fā),此種情況也是比較復雜以政,因為涉及的很多容災的處理霸褒,比如在ip鏈接失敗的時候,需要用LocalDNS做兜底盈蛮,并向服務器上傳錯誤日志废菱,詢問是否需要更新本地ip集合等等一系列復雜的操作。2抖誉、通過三方拿到殊轴,比如DNSPOD,阿里等袒炉。個人建議選擇支持預處理的三方旁理,在啟動app的時候,預先拿到需要的ip集合我磁,比如阿里孽文。


二、結(jié)合AFNetwork的普通網(wǎng)絡(luò)請十性,通過NSURLProtocol對網(wǎng)絡(luò)進行攔截叛溢,然后進行"ip直連"。

? ? ? ? 此文主要通過NSURLProtocol攔截請求的方式進行“ip直連”劲适,以及post請求時楷掉,body“丟失”問題處理,SNI場景處理霞势,利用CFNetwork對SNI的處理烹植。先簡單介紹一下NSURLProtocol,NSURLProtocol是蘋果提供給開發(fā)者們專門用來劫持網(wǎng)絡(luò)請求的一個抽象類愕贡,所以一般用到的時候選擇用繼承NSURLProtocol的方式草雕,本文中的WYCustomURLProtocol就只這樣一個子類。先了解幾個重要的api:? ? ? ?

1固以、+ (BOOL)canInitWithRequest:(NSURLRequest *)request墩虹;// 通過協(xié)議或是域名判斷哪些域名的請求需要攔截的就返YES,反之返NO憨琳。? ?

2诫钓、+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request;? // 上面方法的返YES時,會走到這個方法篙螟,你可以直接返回request菌湃,也可以重定向一個request返回。

3遍略、- (void)startLoading惧所;// 重定向的request就是從此發(fā)出去的

4骤坐、- (void)stopLoading; //? 當cancel請求的時候,會調(diào)用此方法下愈。

接下來就開始附上code了纽绍,要用UrlProtocol之前需要對之進行注冊。

第1步驰唬、在初始化AFHTTPSessionManager的時候顶岸,對其進行注冊:如圖 1

圖 1

第2步、若你使用到了YTK框架叫编,那么可以這樣初始化,此處為了便于理解所以引用了YTK霹抛,實際操作的時候搓逾,建議對外提供一個注冊接口,不要直接用此種直接依賴TYK的方式杯拐,以免污染HTTPDNS部分霞篡。 圖 2

圖 2

第3步、對于要過濾攔截的域名需在此方法判斷 圖 3

圖 3

第4步端逼、請求ip替換host的過程朗兵,并給header添加host, 如圖 4顶滩。此處只要能正確替換余掖,大家可以各顯神通。

圖 4

其中的wy_bodyForPost目的是為了取回body礁鲁,方法體如圖 5?

圖 5

????????此處需要說明一下盐欺,通過NSURLProtocol攔截的post請求的body并非真的丟失了,只是body數(shù)據(jù)在URL loading system中到達這里之前就已被轉(zhuǎn)成stream了仅醇∪呙溃可以在request.HTTPBodyStream中解析它。

第5步析二、利用CFNetwork重新構(gòu)建C語言的request粉洼,并發(fā)送。如圖 6和 圖7

圖 6
圖 7

三叶摄、SNI場景属韧。

????????什么是SNI場景呢,SNI全稱 Server Name Indication准谚,是TLS的擴展挫剑。我們知道一個服務器可能對應了多個域名的情況,客戶端與服務端在建立HTTPS連接的過程中要進行SSL/TLS握手柱衔。整個握手過程步驟分5步:

1樊破、客戶端發(fā)起握手請求愉棱,攜帶隨機數(shù)、支持算法列表等參數(shù)哲戚。

2奔滑、服務端收到請求,選擇合適的算法顺少,下發(fā)公鑰證書和隨機數(shù)朋其。

3、客戶端對服務端證書進行校驗脆炎,并發(fā)送隨機數(shù)信息梅猿,該信息使用公鑰加密。

4秒裕、服務端通過私鑰獲取隨機數(shù)信息袱蚓。

5、雙方根據(jù)以上交互的信息生成session ticket几蜻,用作該連接后續(xù)數(shù)據(jù)傳輸?shù)募用苊荑€喇潘。

而握手失敗就發(fā)生在第3步,客戶端驗證后端給的證書過程如下:

1梭稚、客戶端用本地的根證書解開證書鏈颖低,確認服務端下發(fā)的證書是由可信任機構(gòu)頒發(fā)。

2弧烤、客戶端檢查證書的domain域和擴展域忱屑,驗證是否包含本次請求的host。

若是在握手過程中客戶端要是沒有指定需要訪問的目標域名扼褪,這就會導致一個問題:如果一臺服務機對應了多個域名想幻,每個域名對應的證書也不一樣,那服務端也不知道該返回給客戶端哪一套證書進行校驗话浇,導致第3步的校驗失敗脏毯,以至握手失敗。但若是我們指定該SSL/TLS的目標域名幔崖,那服務端就知道該返回那一套證書了食店,即可通過證書驗證,握手成功赏寇。

那么如何指定目標域名呢吉嫩?我們可以為SNI擴展字段添加一個host。而iOS的上層網(wǎng)絡(luò)庫NSURLConnection/NSURLSession沒有提供對SNI字段進行配置的接口嗅定,所以要用到Socket層級的底層網(wǎng)絡(luò)庫CFNetwork自娩,對SNI字段進行配置。如圖 8

圖 8

補充:1渠退、為什么要在SNI的擴展里面添加傳host忙迁,我不是在header傳了host了嗎脐彩?此處做一個簡要說明:由于HTTP的host字段在header中。而SSL/TLS的握手以及證書驗證都是在HTTP開始之前姊扔,所以header里面的host對于如何判斷選取證書是沒有關(guān)系的惠奸。這個時候,SSL/TLS協(xié)議的HELLO中增加了一個server name字段(SNI擴展字段)恰梢,讓HTTP的客戶端可以提前設(shè)置host佛南,從而使服務端在SSL/TLS的握手階段可以選擇正確的證書。在SSL/TLS握手過程中嵌言,若不是SNI的情況嗅回,意味著服務器只對應了一個域名,一套證書呀页,所以可以直接返回即為正確的證書妈拌,這也是為什么不是SNI的情況下無需配置SNI的原因。前面我們說了SNI呢是一對多的情況蓬蝶,在拿不到host的時候不知道返回哪一套證書,就會返回默認的一套或不返回猜惋,這個時候我們就需要在配置SNI了丸氛,添加server name字段,對應的value即為host值著摔。(比如:若是你需要通過HTTPS訪問CDN節(jié)點資源缓窜,而CDN的節(jié)點往往服務了多個域名,所以需要通過SNI指定具體的域名證書進行通信谍咆。)

四禾锤、證書校驗

? ? ? ? 在證書校驗的過程中解決了SNI的問題之后呢,服務端會返回給客戶端一個與請求域名相匹配的證書摹察,在客戶端驗證的時候若是默認取的請求地址中的host恩掷,而此時默認host早被我們換成了ip地址了,與證書是不匹配的供嚎,所以我們需要將header中的host取出進行證書驗證黄娘。數(shù)據(jù)處理過程如圖9 ;證書驗證過程如圖 10克滴,一般SecTrustResultType的值為kSecTrustResultProceed或kSecTrustResultUnspecified表明驗證通過逼争。

圖 9
圖 10

下面主要是一些讀取數(shù)據(jù)過程中對數(shù)據(jù)的處理,細節(jié)就不多說了劝赔,基本都是更CFNetwork相關(guān)部分誓焦。 如圖 11

圖 11
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市着帽,隨后出現(xiàn)的幾起案子杂伟,更是在濱河造成了極大的恐慌移层,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件稿壁,死亡現(xiàn)場離奇詭異幽钢,居然都是意外死亡,警方通過查閱死者的電腦和手機傅是,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門匪燕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人喧笔,你說我怎么就攤上這事帽驯。” “怎么了书闸?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵尼变,是天一觀的道長。 經(jīng)常有香客問我浆劲,道長嫌术,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任牌借,我火速辦了婚禮度气,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘膨报。我一直安慰自己磷籍,他們只是感情好,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布现柠。 她就那樣靜靜地躺著院领,像睡著了一般。 火紅的嫁衣襯著肌膚如雪够吩。 梳的紋絲不亂的頭發(fā)上比然,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機與錄音废恋,去河邊找鬼谈秫。 笑死,一個胖子當著我的面吹牛鱼鼓,可吹牛的內(nèi)容都是我干的拟烫。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼迄本,長吁一口氣:“原來是場噩夢啊……” “哼硕淑!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤置媳,失蹤者是張志新(化名)和其女友劉穎于樟,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拇囊,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡迂曲,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了寥袭。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片路捧。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖传黄,靈堂內(nèi)的尸體忽然破棺而出杰扫,到底是詐尸還是另有隱情,我是刑警寧澤膘掰,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布章姓,位于F島的核電站,受9級特大地震影響识埋,放射性物質(zhì)發(fā)生泄漏凡伊。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一窒舟、第九天 我趴在偏房一處隱蔽的房頂上張望窗声。 院中可真熱鬧,春花似錦辜纲、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至杀糯,卻和暖如春扫俺,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背固翰。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工狼纬, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人骂际。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓疗琉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親歉铝。 傳聞我的和親對象是個殘疾皇子盈简,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容