iOS9 ATS HTTP/2 NSURLSession

本文主要是看了

  • WWDC 2015 - Session 711 - Networking with NSURLSession
  • WWDC 2016 - Session 711 - NSURLSession: New Features and Best Practices

做出的翻譯和總結, 文字/視頻鏈接如下 :

  • wwdc2015/711 : Networking with NSURLSession
  • wwdc2016/711 : NSURLSession: New Features and Best Practices

App Transfer Security


iOS9新特性. 核心是防止用戶的個人隱私數(shù)據(jù)被意外泄漏. 加強默認Configuration的安全性.

HTTP

以前HTTP請求是明文傳輸(clearText)的, 別人攔截請求之后就能獲取所有信息.

HTTPS

HTTPS通過在TCP于HTTP層之間加入一層SSL/TLS層, 能做到 :

  • Encryption : 信息加密傳輸, 別人看不懂
  • Integrity : 保證數(shù)據(jù)完整性, 即第三方篡改后能檢測出來
  • Authentication : 身份驗證, 防止第三方偽造通信

HTTPS in iOS

蘋果希望所有所有請求都使用HTTPS來加強安全性, 但是也有以下幾種例外(以下全部可以在info.plist文件中配置) :

  • 全局HTTPS請求, 但是某個域名采用HTTP請求
    NSAppTransportSecurity
    NSAllowsArbitraryLoads = NO // 默認為NO, 這一行不要也行
    NSExceptionDomains
    "media.example.com"
    NSExceptionAllowsInsecureHTTPLoads = YES
  • 全局HTTP請求, 但是某個域名采用HTTPS請求
    NSAppTransportSecurity
    NSAllowsArbitraryLoads = YES
    NSExceptionDomains
    "secure.example.com"
    NSExceptionAllowsInsecureHTTPLoads = NO
  • 全局HTTP/HTTPS(任意)請求
    NSAppTransportSecurity
    NSAllowsArbitraryLoads = YES

使用NSAllowsArbitraryLoads可以檢測app中加載失敗是不是因為ATS的原因.

CFNetwork中用于網(wǎng)絡診斷的環(huán)境變量CFNETWORK_DIAGNOStICS = 1 : 所有加載失敗的URL都能被確定是URL錯誤還是底層TLS錯誤. 這樣能進一步排查錯誤.

下面為ATS新增的屬性

  • NSAllowsArbitraryLoadsInWebContent : UIWebView會無視app的其他協(xié)議, 加載HTTP的內(nèi)容. 僅限于UIWebVie對象, 其他對象還是對遵循安全協(xié)議.

  • NSRequiresCertificateTransparency : 保證證書的合法性.

NSURLSession新特性


NSURLSession將全面支持HTTP/2 !

為什么需要HTTP/2

由于HTTP/1.1存在許多問題 :

  • 單路連接 請求低效

    • 每個TCP連接只能對應一個HTTP請求, 每個HTTP請求只請求一個資源, 瀏覽器只能通過建立多個TCP連接來解決, 但是由于文本協(xié)議開銷, 缺乏頭壓縮, 意味著對客戶端和服務器的要求更高且性能更低下
    HTTP/1.1 without pipelining
    • 使用HTTP管道, 但是HTTP管道并不適用于所有的服務器或網(wǎng)絡, 實際上在很多瀏覽器上是被禁止的. 事實上效率并不高.
    HTTP/1.1 with pipelining
  • HTTP只允許由客戶端主動發(fā)起請求
    • 意味著缺少預加載的功能
  • HTTP頭冗余
    • 每次發(fā)送HTTP請求都有一堆重復的header value

了解HTTP/2

between HTTP/1.1 and HTTP/2

HTTP/2 有什么改進 :

  • 一個TCP連接能發(fā)起多個HTTP請求
  • 實現(xiàn)完全多路復用, 意味著一個新的請求不用等到上一個請求得到響應之后再發(fā)出
  • 有請求優(yōu)先級, 所以能把重要的資源優(yōu)先提供給擁有更高權限的客戶端.
  • 使用二進制分幀, 使得數(shù)據(jù)的處理和解析速度更快.
  • 使用HPACK頭壓縮技術
    • 使用一個靜態(tài)表和一個動態(tài)表
    • 靜態(tài)表包含最常用的HTTP信息頭, 并且不可修改
    • 包含在靜態(tài)表中的信息頭可以動態(tài)添加到動態(tài)表中, 動態(tài)表中的信息頭通過指針引用靜態(tài)表中的信息
  • HTTP/2自動支持HTTPS, 意味著HTTP/2是安全的
  • 支持服務器自推送

HTTP/2 多路復用

Q : HTTP/2多路復用是如何隊首阻塞的問題的?

A : 在HTTP/1.1的時候曾試過采用HTTP pipelining (HTTP 管道/流水線 技術)能實現(xiàn)同一TCP連接中不用等待舊請求的響應就可以發(fā)送新請求. 但是HTTP pipelining有個致命的缺點 : HTTP響應仍然是按照請求的順序依次收到.

HTTP/2 多路復用+請求優(yōu)先級, 發(fā)送的時候還是依次發(fā)送請求, 但是與此同時我們同時得到了回復, 同時, 更高優(yōu)先級的請求我們得到以及發(fā)送給客戶端的速度更快, 如下圖所示 :

HTTP/2 Multiplexing

服務器自推送

在HTTP/1.1時代, 我們沒有服務器自推送, 只能發(fā)一個請求, 得到響應之后再發(fā)第二個請求... 延遲可想而知 :

HTTP/1.1 without Server Push

而在HTTP/2時代, 我們有了服務器自推送, 服務器會把相關聯(lián)的數(shù)據(jù)全部push給我們 :

HTTP/2 with Server Push

性能馬上強了一大截, 我們再也不用像以前那樣苦苦等待了.

并且這功能已經(jīng)內(nèi)嵌在NSURLSession中, 我們不需要寫任何一行代碼來支持其實現(xiàn).

iOS中適配HTTP/2

NSURLSession已經(jīng)自動支持HTTP/2, 客戶端不需要額外寫任何代碼. 只需要一臺支持HTTP/2通信的服務器即可. 哎呀, 要是沒有怎么辦, 也沒關系, 看下面 :

  • 服務器支持HTTP/2
    • NSURLSession自動使用HTTP/2進行通信
  • 服務器不支持HTTP/2
    • NSURLSession自動使用HTTP/1.1或其他更優(yōu)的協(xié)議

我們一句代碼, 判斷都不用寫, 省事又省心.

SPDY

這里說句題外話, 雖然SPDY并不在該Session中提及, 但是與HTTP/2有異曲同工之處, SPDY在之前被認為是未來的HTTP/2, 所以這里說一下.

SPDY是Google開發(fā)的基于TCP的應用層協(xié)議, 通過頭部壓縮, 多路復用和優(yōu)先級來縮短網(wǎng)頁的加載時間和提高安全性. 可以說是HTTP/1.1的一個優(yōu)化版.

  • 多路復用, 請求優(yōu)化
  • 支持服務器推送技術
  • SPDY壓縮了HTTP頭
  • 強制使用SSL傳輸協(xié)議

更多有關SPDY的詳情請見這里


驚 ! iOS9開始蘋果棄用NSURLConnection, 不再維護NSURLConnection, 所有有關Networking的新API只會在NSURLSession上更新.

NSURLSession replace NSURLConnection

NSURLSession的新功能


cookie 共享

增加sessionCookieGroup以實現(xiàn)app與其擴展(例如通知中心等等)之間cookie的共享.

let ident = "group.mycompany.mygroupname" 
let cookieStorage = NSHTTPCookieStorage.sharedCookieStorageForGroupContainerIdentifier(
    identifier: ident)
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
config.HTTPCookieStorage = cookieStorage
let session = NSURLSession(configuration: config)

NSURLSessionStreamTask

以前我們使用NSInputStream/NSOutputStream來進行一些非HTTP的連接, 例如利用TCP連接一臺遠程的服務器等等, 現(xiàn)在我們有了NSURLSessionStreamTask讓我們更簡單地實現(xiàn)以上功能.

NSURLSessionStreamTask的特性 :

  • 更輕松地使用TCP進行通信
  • 替代NSInputStream/NSOutputStream, 提供更優(yōu)的API
    • 異步讀寫API
    • 內(nèi)置強大的支持功能, 能自動通過HTTP代理, 連接一個遠程服務器.
    • 輕松轉換成NSStream

NSURLSessionTaskMetrics

對發(fā)送請求/DNS查詢/TLS握手/請求響應等各種環(huán)節(jié)時間上的統(tǒng)計. 更易于我們檢測, 分析我們的請求緩慢到底是發(fā)生在哪個環(huán)節(jié), 并對此進行優(yōu)化提升我們APP的性能.

下面開始介紹NSURLSessionTaskMetrics的屬性

Property

  • taskInterval : 任務從開始到結束總共用的時間

  • redirectCount : 任務重定向的次數(shù)

  • transactionMetrics : 在任務執(zhí)行期間產(chǎn)生的每個請求/響應事務, 它是一個裝著許多NSURLSessionTaskTransactionMetrics對象的數(shù)組

NSURLSessionTaskTransactionMetrics

property

  • request and response : 請求和響應

  • networkProtocolName : 網(wǎng)絡協(xié)議名稱

    • http/1.1
    • http/2
    • spdy/3, spdy/3.1
  • isProxyConnection : 是否連接代理服務器

  • isReusedConnection : 是否允許重連

  • resourceFetchType : 描述本次加載的類型, 枚舉類型

    • networkLoad : 網(wǎng)絡加載
    • localCache : 本地緩存
    • serverPush : 服務器自推送
  • Connection Establishment and Transmission

    transmissions
    • fetchStart : 開始發(fā)起請求.

    • domainLookupStart : 發(fā)送DNS請求, 域名->IP地址

    • domainLookupEnd : DNS請求完成, 拿到IP地址

    • connectStart : 與遠程服務器開始建立TCP連接

      • secureConnectionStart : HTTPS的TLS握手開始
      • secureConnectionEnd : HTTPS的TLS握手完成
    • connectEnd : 與服務器建立起了TCP連接

    • requestStart : 開始傳輸HTTP header第一個字節(jié)的時間(遠程/緩存)

    • requestEnd : HTTP最后一個字節(jié)傳輸完成的時間(遠程/緩存)

    • responseStart : 從服務器得到數(shù)據(jù)(遠程/緩存)

    • responseEnd : 從服務器接受完最后一個字節(jié)的數(shù)據(jù)(遠程/緩存)

另外, 需要注意的是, 如果請求命中了cache, 上述很多值會為nil.

API

NSURLSessionTaskDelegate代理中新增一個方法- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didFinishCollectingMetrics:(NSURLSessionTaskMetrics *)metrics, 當收集完成的時候就會調用該方法.

我們只需要實現(xiàn)代理的這個方法就能在這里做統(tǒng)計, 輸出等等操作.

Something else

蘋果不再支持RC4加密.


以上圖片均來自官方WWDC中的PDF.

參考資料 :
HTTP/2
NSURLSession
NSURLSessionTaskMetrics

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容