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.mzph.cn/news/286100.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【遥感物候】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,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。搜索的结果被送到屏幕,不影响原文…

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

介绍: 这是一个用vuejs2.0和element搭建的后台管理界面。 相关技术: vuejs2.0:渐进式JavaScript框架,易用、灵活、高效,似乎任何规模的应用都适用。 element:基于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;其余相关代码正在进…

【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;否…

MAUI 入门教程系列(4.通用主机)

前言对于ASP.NET Core 开发人员而言, 这并不陌生, 当ASP.NET Core应用程序启动时, 会创建默认的应用程序主机, 我们可以为应用程序配置所有的依赖关系、系统设置, 最终启动。如下所示:using IHost host Host.CreateDefaultBuilder(args).ConfigureServices((_, services) >…

【MATLAB统计分析与应用100例】案例012:matlab读取Excel数据,调用robustfit函数作稳健回归

稳健回归效果预览: 文章目录 1. 读取数据2. 调用robustfit函数作稳健回归3 .绘制残差和权重的散点图4. 绘制regress函数和robustfit函数对应的回归直线5. 拟合效果1. 读取数据 ClimateData = xlsread(examp08_01.xls); % 从Excel文件读取数据 x

后台页制作01《ivx低代码签到系统制作》

制作iVX 低代码项目需要进入在线IDE&#xff1a;https://editor.ivx.cn/ 一、签到系统思考 签到系统一般是指公布一个签到链接或者二维码&#xff0c;随后用户扫码后即可完成签到。 那如何制作呢&#xff1f;首先我们可以先不考虑签到页面的制作&#xff0c;既然签到暂时没有…

个人作业-Week2

第一部分 调研&#xff0c; 评测 运行平台 win 8 软件版本&#xff1a;微软必应词典桌面版 3.5.2 BUG标题&#xff1a;必应背单词无法发音 BUG详细描述&#xff1a;如图&#xff0c;左边为必应词典该单词的搜索&#xff0c;可以发音&#xff0c;而右边必应背单词中该单词的发音…

Blazor WebAssembly + Grpc Web=未来?

Blazor WebAssembly是什么首先来说说WebAssembly是什么&#xff0c;WebAssembly是一个可以使C#,Java,Golang等静态强类型编程语言&#xff0c;运行在浏览器中的标准&#xff0c;浏览器厂商基于此标准实现执行引擎。在实现了WebAssembly标准引擎之后&#xff0c;浏览器中可以执行…

Can't create directory 'E:\Repositories\***\db\transactions\138-41.txn':

遇到这种问题应该是迁移SVN库时丢失了文件夹引起的&#xff0c;直接在服务器上找到对应项目的db文件夹&#xff0c;手动创建“transactions”目录和“txn-protorevs”目录即可正常提交。

【MATLAB统计分析与应用100例】案例013:matlab读取Excel数据,调用nlinfit函数作一元非线性回归

1. 一元线性回归分析效果预览 2. matlab完整实现代码 %读取数据,绘制散点图** HeadData = xlsread(examp08_02.xls); %从Excel文