ASIHTTPRequest源碼簡單分析

2019獨角獸企業重金招聘Python工程師標準>>> hot3.png

1.前言

? ? ?ASIHttprequest 是基于CFNetwork的,由于CFNetwork是比較底層的http庫,功能比較少,因此,在ASIHttprequest中實現了http協議中比較多的功能,包括代理、gzip、認證、緩存等等。目前,雖然ASIHTTPRequest已經不如前兩年那么流行,但是分析一下其代碼,對掌握CFNetwork庫和HTTP協議還是有好處的,本文將簡單分析一下ASIHTTPRequest中幾個主要函數的流程。

?

2.處理HTTP Request的主要函數

ASIHTTPRequest::main流程如下(只列舉了主要工作):

{

? ? ?(1)若允許后臺運行,則調用beginBackgroundTaskWithExpirationHandler允許程序后臺運行十分鐘

? ? ?(2) 調用buildPostBody函數構造post的body部分,該函數有兩個,一個是基類中的,主要負責壓縮body數據,另一個是派生類ASIFormDataRequest中,分別針對post表單和post文件的方式,分別設置content-type為application/x-www-form-urlencoded和multipart/form-data。

? ? ?(3)根據url和請求的方法來創建CFHTTPMessageRef對象。

? ? ?(4)調用buildRequestHeaders函數來構造header部分,這里只是簡單的將各個header字段放到一個NSDictionary變量中。

? ? ?(5)如果設置了緩存,并且允許從緩存取數據,則從緩存中讀取數據,然后返回。

? ? ?(6)調用applyAuthorizationHeader向header字典中添加HTTP認證相關的字段。

? ? ?(7)調用CFHTTPMessageSetHeaderFieldValue來將header數據添加到CFHTTPMessageRef對象中。

? ? ?(8)調用configureProxies來配置代理。

? ? ?(9)調用startRequest來發送請求。

}

?

ASIHTTPRequest::startRequest

{ ??

? ? ? (1)向主線程發送requestStarted消息

? ? ? (2)如果存在body,且需要post本地文件,則將本地文件讀到postBodyReadStream對象中。然后調用CFReadStreamCreateForStreamedHTTPRequest函數,傳入之前創建的CFHTTPMessageRef對象和postBodyReadStream對象,來創建一個用來讀取response 的CFReadStream對象。

? ? ? ? ? ? ?如果是post數據,則先根據shouldCompressRequestBody的值來判斷是否要壓縮,然后根據postBody的數據來創建一個NSInputStream對象,并賦給postBodyReadStream對象,然后調用CFReadStreamCreateForStreamedHTTPRequest,傳入之前的header和stream對象,來創建NSReadStream對象。

? ? ? ? ? ? ?如果不存在body,則直接通過CFReadStreamCreateForHTTPRequest函數來創建NSReadStream對象。

? ? (3)針對https的情況,調用CFReadStreamSetProperty進行設置

? ? (4)如果請求中設置了代理,則調用CFReadStreamSetProperty對stream進行代理相關的設置

? ? ?(5)處理http持久連接相關的設置

? ? (6)調用scheduleInRunLoop,將readStream對象放入runloop中

? ? (7)調用CFReadStreamSetClient函數來將readStream關聯到一個回調函數ReadStreamClientCallBack中,并使用CFReadStreamOpen打開readStream對象

? (8)調用進度通知相關的函數

? ?(9)創建一個計時器,用來調用updateStatus函數來更新進度,并將計時器放入當前runloop。

}

?

3.處理HTTP Response的主要函數?

ASIHTTPRequest::handleNetworkEvent (該函數用來處理回調事件)

{

? ? (1)當收到kCFStreamEventHasBytesAvailable 事件時 ,調用handleBytesAvailable(此時表示下層已經讀到了response里的數據,這數據可能包含全部的header也可能header尚未讀完)

? ? (2)kCFStreamEventEndEncountered,調用handleStreamComplete,此時表示全部的數據包括header和body都已經讀完,而且對應chunked數據,底層也已經將其合并完。

? ? (3)kCFStreamEventErrorOccurred事件,調用handleStreamError處理錯誤

}

?

ASIHTTPRequest::handleBytesAvailable

{

? ? (1)如果responseHeader對象尚未賦值,則調用readResponseHeaders讀取header

? ? (2)申請一塊buffer,讀取readStream對象里面的數據,此時如果能讀到數據,則表示header已經讀完了,當前讀到的是body里面數據(因為header不是用read方法讀的),如果讀不到數據,則表示還沒有收到body,則返回。

? ? (3)讀取到數據之后,如果header里面顯示數據是壓縮過的,則進行解壓縮

? ? (4)解壓出數據之后有三種處理方式:

? ? ? ? ? ? ?如果用戶設置了didReceiveDataSelector或者dataReceivedBlock,這就表示用戶希望自己處理每次得到的data,則向主線程發送passOnReceivedData消息。

? ? ? ? ? ? ?如果用戶在request中設置了下載路徑,則將數據寫到文件中

? ? ? ? ? ? ?如果以上都不滿足,則將數據append到rawResponseData中。

}

ASIHTTPRequest::readResponseHeaders

{

? ?(1)使用CFReadStreamCopyProperty從readStream對象中讀取header,創建一個CFHTTPMessageRef對象,并且使用CFHTTPMessageIsHeaderComplete檢查該對象,判斷header是否已經讀完,若沒有讀完,則銷毀該對象并返回

? ?(2)?使用CFHTTPMessageCopyAllHeaderFields從CFHTTPMessageRef讀出header到一個dictionary中

? ? (3)如果有緩存,且允許讀取緩存,則從緩存中讀取header并返回。

? ?(4)根據header中的狀態碼來判斷是否需要進行http認證,如果需要則處理認證相關的工作

? ?(5) 從header中content-type,用于對body進行解碼,如沒有該字段,則使用默認的解碼方式對content進行解碼

? ?(6)處理cookie相關的工作

? ?(7)如果不需要重定向,則從header中讀取content-length,然后根據length做相關處理

? ?(8)處理keepalive相關的工作

? ?(9)最后向主線程發送requestReceivedResponseHeaders通知

}

ASIHTTPRequest::handleStreamComplete

{

? ? ?該函數做的事情比較簡單,主要就是設置各種下載結束的標志、設置讀取到的文件大小并發送通知消息、移動下載的臨時文件、保存cache等等。

}


轉載于:https://my.oschina.net/kings0527/blog/591588

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/286100.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/286100.shtml
英文地址,請注明出處:http://en.pswp.cn/news/286100.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Blazor University (28)表單

原文鏈接:https://blazor-university.com/forms/表單源代碼[1]EditForm 組件是 Blazor 管理用戶輸入的方法,這種方法可以輕松地對用戶輸入執行驗證。它還提供了檢查是否滿足所有驗證規則的能力,如果沒有滿足,則向用戶顯示驗證錯誤…

【遙感物候】1983-2012年時間序列中國地區GIMMS 3g NDVI下載(已進行旋轉、格式轉換、投影變換和裁剪)

文章目錄 1. 數據集簡介2. 數據集預覽3. 數據集下載1. 數據集簡介 本數據集為1983-2012年,長時間序列中國地區GIMMS 3g NDVI,空間分辨率為0.08333度,作者已完成了數據預處理:包括旋轉、格式轉換、投影變換和裁剪),作者可以此基礎上直接進行NDVI時空變化趨勢分析、基于NDV…

三、博客首頁完成《iVX低代碼仿CSDN個人博客制作》

制作iVX 低代碼項目需要進入在線IDE:https://editor.ivx.cn/ 一、首頁內容分析 此時我們分析一下首頁內容: 通過以上內容可以得知,這些內容都統一包含在一個塊之內,這個塊之內包含了多個內容,這些內容主要是分為標題…

正則表達式 (grep)

正則表達式 (grep) grep (global search regular expression(RE) and print out the line,全面搜索正則表達式并把行打印出來)是一種強大的文本搜索工具,它能使用正則表達式搜索文本,并把匹配的行打印出來。搜索的結果被送到屏幕,不影響原文…

C語言試題四十九之只刪除字符串前導和尾部的*號,串中字母之間的*號都不刪除。 n 給出了字符串的長度,h字符串中前導*號的個數,e給出了字符串中最后的*個數

??個人主頁:個人主頁 ??系列專欄:C語言試題200例目錄 ??推薦一款刷算法、筆試、面經、拿大公司offer神器 ?? 點擊跳轉進入網站 ?作者簡介:大家好,我是碼莎拉蒂,CSDN博客專家(全站排名Top 50),阿里云博客專家、51CTO博客專家、華為云享專家 1、題目 假定輸入的…

|洛谷|DFS|P1101 單詞方陣

http://www.luogu.org/problem/show?pid1101 循環找到一個y后向8個方向搜索&#xff0c;直到搜到g&#xff0c;然后按照方向反向填充即可 #include<cstdio> #include<algorithm> #include<cstring> #include<queue> #define ms(i,j) memset(i,j, size…

vuejs 和 element 搭建的一個后臺管理界面【收藏】

介紹&#xff1a; 這是一個用vuejs2.0和element搭建的后臺管理界面。 相關技術&#xff1a; vuejs2.0&#xff1a;漸進式JavaScript框架&#xff0c;易用、靈活、高效&#xff0c;似乎任何規模的應用都適用。 element&#xff1a;基于vuejs2.0的ui組件庫。 vue-router&#xff…

【MATLAB統計分析與應用100例】案例010:matlab調用normrnd函數生成正態分布隨機數

效果預覽: 文章目錄 1. 調用normrnd函數生成1000行3列的隨機數矩陣x,其元素服從均值為75,標準差為8的正態分布(1)代碼(2)運行效果2. 調用normrnd函數生成1000行3列的隨機數矩陣x,其各列元素分別服從不同的正態分布(1)代碼(2)運行效果<

四、博客詳情頁完成《iVX低代碼仿CSDN個人博客制作》

制作iVX 低代碼項目需要進入在線IDE&#xff1a;https://editor.ivx.cn/ 一、博客詳情頁分析 博客詳情頁大體分為頂部標題、發布時間、作者信息、博文內容&#xff0c;底部的評論我們在此不必做懸浮內容&#xff0c;咱們直接放到博文之下進行顯示即可&#xff1b;頂部標題需要…

【原創】erlang 模塊之 application

2019獨角獸企業重金招聘Python工程師標準>>> kernel-2.15.2 中的內容 1 2 3 4 5 6 7 8 9 10 11 12 13 14 轉載于:https://my.oschina.net/moooofly/blog/595122

RabbitMQ詳解(三)

一、分發到多Consumer(fanout) 二、Routing路由(Direct) 三、主題路由(Topic)一、分發到多Consumer(fanout)將同一個Message deliver到多個Consumer中。這個模式也被稱為"publish/subscribe" 創建一個日志系統&#xff0c;包含兩部分&#xff1a;第一部分發出log(Pro…

重磅 | Linux內核5.19初步支持LoongArch架構

經過龍芯中科與內核社區一年多的緊密合作&#xff0c;北京時間2022年6月4日清晨&#xff0c;Linux內核社區正式合并LoongArch架構支持代碼。隨著Linux-5.19的rc1版本的正式發布&#xff0c;LoongArch體系結構主體部分的源碼已合并到內核主線之中&#xff0c;其余相關代碼正在進…

C語言試題五十之請編寫一個函數void function(char *ss),其功能時:將字符串ss中所有下標為奇數位置上的字母轉換為大寫(若位置上不是字母,則不轉換)。

??個人主頁:個人主頁 ??系列專欄:C語言試題200例目錄 ??推薦一款刷算法、筆試、面經、拿大公司offer神器 ?? 點擊跳轉進入網站 ?作者簡介:大家好,我是碼莎拉蒂,CSDN博客專家(全站排名Top 50),阿里云博客專家、51CTO博客專家、華為云享專家 1、題目 請編寫一個…

【MATLAB統計分析與應用100例】案例011:matlab讀取Excel數據,調用regress函數作一元線性回歸分析

數據擬合效果預覽: 文章目錄 1. 讀取數據,繪制散點圖2. 計算相關系數3. 繪制回歸直線4. 剔除異常數據,重新調用regress函數作一元線性回歸1. 讀取數據,繪制散點圖 ClimateData = xlsread(examp08_01.xls); % 從Excel文件讀取數據 x &

“*** IS NOT TRANSLATED IN …….. 解決辦法

首先引起提示的原因是因為Lint 代碼檢查工具發現你的項目中&#xff08;或者引用的三方庫&#xff09;有部分string.xml文件內容做了國際化操作&#xff0c;但卻不完整&#xff0c;有些文本內容并沒有相應的國際化翻譯&#xff0c;在android開發中常見于項目引用的Libraries第三…

[轉] ArcEngine 產生專題圖

小生原文 ArcEngine 產生專題圖 ArcEngine提供多個著色對象用于產生專題圖&#xff0c;可以使用標準著色方案&#xff0c;也可以自定義著色方案&#xff0c;ArcEngine提供8中標準著色方案。 一、SimpleRenderer專題圖 是使用單一符號進行著色分類&#xff0c;不涉及對要素的數據…

iVX無代碼挑戰五秒游戲制作

一、五秒挑戰游戲簡介及思考 制作iVX 低代碼項目需要進入在線IDE&#xff1a;https://editor.ivx.cn/ 五秒挑戰游戲指的是點擊一個按鈕開始計時&#xff0c;隨后需要用戶再次點擊計時按鈕&#xff0c;將會停止計時&#xff0c;當計時的時間等于五秒時將挑戰成功&#xff0c;否…

C語言試題五十一之已知學生的記錄是由學號和學習成績構成,n名學生的數據已存入s結構體數組中。請編寫函數fun,該函數的功能是:找出成績最高的學生記錄,通過形參返回主函數(規定只有一個最高分)。

??個人主頁:個人主頁 ??系列專欄:C語言試題200例目錄 ??推薦一款刷算法、筆試、面經、拿大公司offer神器 ?? 點擊跳轉進入網站 ?作者簡介:大家好,我是碼莎拉蒂,CSDN博客專家(全站排名Top 50),阿里云博客專家、51CTO博客專家、華為云享專家 1、題目 請編寫一個…

CSS 巧用 :before和:after

前幾天的晚上較全面的去看了下css的一些文檔和資料&#xff0c;大部分的樣式運用都沒什么大問題了&#xff0c;只是有些許較陌生&#xff0c;但是也知道他們的存在和實現的是什么樣式。今天主要想在這篇學習筆記中寫的也不多&#xff0c;主要是針對:before和:after寫一些內容&a…

MAUI 入門教程系列(4.通用主機)

前言對于ASP.NET Core 開發人員而言, 這并不陌生, 當ASP.NET Core應用程序啟動時, 會創建默認的應用程序主機, 我們可以為應用程序配置所有的依賴關系、系統設置, 最終啟動。如下所示:using IHost host Host.CreateDefaultBuilder(args).ConfigureServices((_, services) >…