一种解析HTTP chunked编码数据的方法
【专利摘要】本发明涉及解析HTTP?chunked编码数据的方法,包括:针对所接收的某一HTTP报文,设定一个数值,使用PEEK操作读取该数值长度的字节数据;确定HTTP报文头部的长度,根据该长度值使用READ操作读取报文头部的数据;设定另一个数值,使用PEEK操作读取该数值长度的字节数据;确定chunk-size字段的实际长度及其表示的值,如果chunk-size字段表示的值为零,则解析结束;否则,使用READ操作读取等于chunk-size字段长度的字节数,然后使用READ操作读取等于chunk-size表示的值的字节数。
【专利说明】—种解析HTTP chunked编码数据的方法
【技术领域】
[0001]本发明涉及网络通信领域,特别涉及一种解析HTTP chunked编码数据的方法。
【背景技术】
[0002]HTTP协议的消息格式包含消息首部和消息体。消息首部部分定义了一些属性字段,这些属性字段向报文接收者提供了重要的信息。其中,Content-Length属性字段表示消息体的长度,该字段有利于数据接收过程的编程实现。然而,对于某些动态生成的数据,消息生成者可能无法立即知悉消息体的总长度,从而不能及时计算Content-Length字段值。使用chunked编码可以回避这一问题。Chunked是HTTP/1.1协议的一种传输编码方式,它将待传输数据切割为多个部分,报文只需提供每个部分的长度。编码后的消息体是一组连续的编码块(chunk),每个编码块包含了传输数据块(chunk-data)及其长度(chunk-size),其格式定义如下:
[0003]chunk=chunk_size[chunk-extension]CRLF chunk-data CRLF
[0004]其中,chunk-size是chunk-data的长度,为十六进制字符串。CRLF为双字节换行符,其ASCII码值为OxOdOxOa。可选的chunk-extension格式用一组“name=value”字段组成,但RFC2616未对这些字段进行定义,并规定接收者忽略不能识别的字段。
[0005]流媒体业务的分发和传输过程使用了 HTTP协议,对节目内容进行chunked编码。流服务器通过TCP协议接收报文,解码后,以UDP方式推送给IPQAM,进而发送给终端用户。由于流媒体具有数据量大、传输时间长的特点,流服务器将会对大量数据进行chunked解码操作,因此,chunked解码过程的效率对于流服务器的整体性能至关重要。选择不同的chunked编码解析方式,能够给系统的开发效率、运行性能都能带来相当大的影响。
[0006]作为对chunked解析的一种最简单的实现,离线解析方法先将一个完整的HTTP报文通过网络编程技术复制到本地一个连续、单一的应用层缓冲区,再基于这个连续缓冲区根据chunked编码规则提取有效数据,将解析出的数据拷贝到有效内容缓冲区。HTTPchunked编码离线解析法导致解码过程中会产生两次内存拷贝,造成内存占用多、处理延迟高的问题。且离线解析法适合于原型系统开发,并不适合产品开发环境。
【发明内容】
[0007]本发明的目的在于克服现有的HTTP chunked编码离线解析法内存占用多、处理延迟高的问题,从而提供一种延迟小、内存占用少的解析HTTP chunked编码数据的方法。
[0008]为了实现上述目的,本发明提供了一种解析HTTP chunked编码数据的方法,包括:
[0009]步骤I)、针对所接收的某一 HTTP报文,设定一个数值,使得该数值的大小不小于该HTTP报文头部的长度,然后从所述HTTP报文的起始位置起,使用PEEK操作读取该数值长度的字节数据;
[0010]步骤2)、分析步骤I)所读取的数据,确定HTTP报文头部的长度,根据该长度值使用READ操作读取报文头部的数据;
[0011]步骤3)、设定另一个数值,使得该数值的大小不小于当前chunk的chunk-size字段的长度,使用PEEK操作读取该数值长度的字节数据;
[0012]步骤4)、对步骤3)所读取的数据进行分析,确定chunk-size字段的实际长度及其表示的值,如果chunk-size字段表示的值为零,则解析结束;否则,使用READ操作读取等于chunk-size字段长度的字节数,然后执行下一步;
[0013]步骤5)、使用READ操作读取等于chunk-size表示的值的字节数,然后重新执行步骤3);
[0014]其中,所述PEEK操作用于从协议栈缓冲区中获取数据但不将该数据从协议栈缓冲区中删除,使其能够被后续的READ操作或PEEK操作获取;所述READ操作用于从协议栈缓冲区中获取数据并将该数据从协议栈缓冲区中删除,使其不能被后续的READ或PEEK操作获取。
[0015]上述技术方案中,所述chunk-size字段为RFC2612所述chunk-size字段,连同该字段前面与后面的回车换行符。
[0016]本发明的优点在于:
[0017]1、本发明的方法不需要一个完整的应用层缓冲区存放HTTP报文,降低内存占用。
[0018]2、本发明的方法减少了一次内存拷贝,减小处理延迟。
【专利附图】
【附图说明】
[0019]图1为本发明提出的一种解析HTTP chunked编码数据的方法的流程图;
[0020]图2为要实现本发明方法所需外部环境的示意图;
[0021]图3—图9为在一个实施例中所实现的本发明的解析HTTP chunked编码数据的方法的工作过程示意图。
【具体实施方式】
[0022]现结合附图对本发明作进一步的描述。
[0023]在对本发明做详细说明前,首先对本发明中所涉及的相关概念做统一说明。
[0024]chunk-size字段:与RFC2616中所描述的chunk-size字段相同,还包括该字段之前与之后的回车换行符(即CRLF)。
[0025]PEEK操作:通过操作系统提供的SocketAPI或网络编程框架,从协议栈缓冲区中获取一定的数据但不从协议栈缓冲区中删除,使其会被后续的READ或PEEK操作获取。
[0026]READ操作:通过操作系统提供的Socket API或网络编程框架,从协议栈缓冲区中获取一定的数据并从协议栈缓冲区中删除,使其不会被后续的READ或PEEK操作获取。
[0027]下面对实现本发明方法所需要的外部环境做一简要介绍。
[0028]要实现本发明方法,参考图2,应当具有协议栈软件模块、协议栈缓冲区、有效数据存放模块、临时缓存模块。
[0029]协议栈软件模块,用于接收网络数据,并维护一定量的协议栈缓冲区,将已经从网络接收到但尚未被其他模块读取的网络数据缓存于该协议栈缓冲区,以及提供接口供其他模块顺序读取该内存缓冲区内的数据。其他模块会请求从协议栈缓冲区读取若干字节,但实际得到的字节数可能会小于请求的字节数。
[0030]协议栈缓冲区,用于存放尚未被应用层READ操作读取的数据。一般认为所有数据在解析开始时均已存放在了协议栈缓冲区中。
[0031]有效数据存放模块,用于维护一定量的缓冲区(即有效数据存放区),该有效数据存放区用于存放chunked编码的数据经解析后的HTTP报文有效内容。
[0032]临时缓存模块,用于维护一定量的临时缓冲区,该临时缓冲区存放PEEK操作读取的内容和部分READ操作读取的内容。
[0033]如图1所示,本发明的方法包括以下步骤:
[0034]步骤I)、针对所接收的某一 HTTP报文,设定一个数值,使得该数值的大小不小于该HTTP报文头部的长度,然后从所述HTTP报文的起始位置起,使用PEEK操作读取该数值长度的字节数据;
[0035]步骤2)、分析步骤I)所读取的数据,确定HTTP报文头部的长度,根据该长度值使用READ操作读取报文头部的数据;
[0036]经过本步骤后,HTTP报文的报文头部数据被读取并移走。
[0037]步骤3)、设定另一个数值,使得该数值的大小不小于当前chunk的chunk-size字段的长度,使用PEEK操作读取该数值长度的字节数据;
[0038]在本步骤中,所述数值的大小例如是16字节。
[0039]步骤4)、对步骤3)所读取的数据进行分析,确定chunk-size字段的实际长度及其表示的值,如果chunk-size字段表示的值为零,则解析结束;否则,使用READ操作读取等于chunk-size字段长度的字节数,然后执行下一步;
[0040]步骤5)、使用READ操作读取等于chunk-size表示的值的字节数,然后重新执行步骤3)。
[0041]以上是对本发明方法的基本步骤的描述。需要说明的是,在开始解析时,网络报文可能没有被完全传送到网络协议栈,以至于读取操作返回的字节数可能少于所要求读取的字节数。如果发生这种情况,应做如下处理:
[0042](a)对于PEEK操作,当实际读到的字节数M少于所要求读取的字节数N时,重新执行PEEK操作,要求读取N字节,直至读取到的字节数等于N ;
[0043](b)对于READ操作,当实际读到的字节数M少于所要求读取的字节数N时,取N等于N-M,重新执行READ操作,要求读取N字节,直至读取到的字节数等于所要求读取的字节数。
[0044]为了便于理解,下面结合一个具体的实施例,参考图3-图9,对本发明方法的应用做详细说明。
[0045](I)假设输入的HTTP报文头部长度为190字节,用H*190表示,chunked编码报文(不包含HTTP报头)用C语言风格的字串可表示为“\r\nl0\r\n0123456789abcdef\r\n0\r\n”,报文只有I个长度非零的chunk,该chunk包含16字节有效数据。如图3所示,该报文被协议栈接收。
[0046](2)找到一个大于HTTP报文头部长度的数值193,如图4所示,使用PEEK操作读取193字节,存放在临时缓存模块;
[0047](3)确定HTTP报文头部的实际长度为190,如图5所示,使用READ操作读取190字节,存放于临时缓存区并丢弃;
[0048](4)找到一个大于当前chunk的chunk-size字段长度的数值12,如图6所示,使用PEEK操作读取12字节,存放在临时缓存模块;
[0049](5)分析确定chunk-size字段占用6字节,其表示的数值为是十进制16。如图7所示,使用READ操作读取6字节,存放于临时缓存区并丢弃;
[0050](6)如图8所示,使用READ操作读取16字节,存放于有效数据存放区;
[0051](7)如图9所示,找到一个大于当前chunk的chunk-size字段长度的数值12,使用PEEK操作读取12字节,存放在临时缓存模块;
[0052](8)分析确定chunk-size字段占用5字节,其表示的数值为是O。解析结束。
[0053]最后所应说明的是,以上实施例仅用以说明本发明的技术方案而非限制。尽管参照实施例对本发明进行了详细说明,本领域的普通技术人员应当理解,对本发明的技术方案进行修改或者等同替换,都不脱离本发明技术方案的精神和范围,其均应涵盖在本发明的权利要求范围当中。
【权利要求】
1.一种解析HTTP chunked编码数据的方法,包括: 步骤I)、针对所接收的某一 HTTP报文,设定一个数值,使得该数值的大小不小于该HTTP报文头部的长度,然后从所述HTTP报文的起始位置起,使用PEEK操作读取该数值长度的字节数据; 步骤2)、分析步骤I)所读取的数据,确定HTTP报文头部的长度,根据该长度值使用READ操作读取报文头部的数据; 步骤3)、设定另一个数值,使得该数值的大小不小于当前chunk的chunk_size字段的长度,使用PEEK操作读取该数值长度的字节数据; 步骤4)、对步骤3)所读取的数据进行分析,确定chunk-size字段的实际长度及其表示的值,如果chunk-size字段表示的值为零,则解析结束;否则,使用READ操作读取等于chunk-size字段长度的字节数,然后执行下一步; 步骤5)、使用READ操作读取等于chunk-size表示的值的字节数,然后重新执行步骤3); 其中,所述PEEK操作用于从协议栈缓冲区中获取数据但不将该数据从协议栈缓冲区中删除,使其能够被后续的READ操作或PEEK操作获取;所述READ操作用于从协议栈缓冲区中获取数据并将该数据从协议栈缓冲区中删除,使其不能被后续的READ或PEEK操作获取。
2.根据权利要求1所述的解析HTTPchunked编码数据的方法,其特征在于,所述chunk-size字段为RFC2612所述chunk-size字段,连同该字段前面与后面的回车换行符。
【文档编号】H04L1/00GK103929447SQ201310012071
【公开日】2014年7月16日 申请日期:2013年1月11日 优先权日:2013年1月11日
【发明者】陈君, 李明哲, 李军, 陈晓 申请人:中国科学院声学研究所, 北京中科华影传媒技术有限公司