`
tiandirensoon
  • 浏览: 595746 次
文章分类
社区版块
存档分类
最新评论

HTTP协议中的Tranfer-Encoding:chunked编码解析

 
阅读更多
当不能预先确定报文体的长度时,不可能在头中包含Content-Length域来指明报文体长度,此时就需要通过Transfer-Encoding域来确定报文体长度。
通常情况下,Transfer-Encoding域的值应当为chunked,表明采用chunked编码方式来进行报文体的传输。chunked编码是HTTP/1.1 RFC里定义的一种编码方式,因此所有的HTTP/1.1应用都应当支持此方式。
chunked编码的基本方法是将大块数据分解成多块小数据,每块都可以自指定长度,其具体格式如下(BNF文法):
Chunked-Body = *chunk //0至多个chunk
last-chunk //最后一个chunk
trailer //尾部
CRLF //结束标记符

chunk = chunk-size [ chunk-extension ] CRLF
chunk-data CRLF
chunk-size = 1*HEX
last-chunk = 1*("0") [ chunk-extension ] CRLF

chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
chunk-ext-name = token
chunk-ext-val = token | quoted-string
chunk-data = chunk-size(OCTET)
trailer = *(entity-header CRLF)

解释:
Chunked-Body表示经过chunked编码后的报文体。报文体可以分为chunk, last-chunk,trailer和结束符四部分。chunk的数量在报文体中最少可以为0,无上限;每个chunk的长度是自指定的,即,起始的数据必然是16进制数字的字符串,代表后面chunk-data的长度(字节数)。这个16进制的字符串第一个字符如果是“0”,则表示chunk- size为0,该chunk为last-chunk,无chunk-data部分。可选的chunk-extension由通信双方自行确定,如果接收者不理解它的意义,可以忽略。
trailer是附加的在尾部的额外头域,通常包含一些元数据(metadata, meta means "about information"),这些头域可以在解码后附加在现有头域之后。
实例分析:
下面分析用ethereal抓包使用Firefox与某网站通信的结果(从头域结束符后开始):
Address 0.......................... f
000c0 31
000d0 66 66 63 0d 0a ............... // ASCII码:1ffc"r"n, chunk-data数据起始地址为000d5
很明显,“1ffc”为第一个chunk的chunk-size,转换为int为8188.由于1ffc后马上就是
CRLF,因此没有chunk-extension.chunk-data的起始地址为000d5, 计算可知下一块chunk的起始
地址为000d5+1ffc + 2=020d3,如下:
020d0 .. 0d 0a 31 66 66 63 0d 0a .... // ASCII码:"r"n1ffc"r"n
前一个0d0a是上一个chunk的结束标记符,后一个0d0a则是chunk-size和chunk-data的分隔符。
此块chunk的长度同样为8188, 依次类推,直到最后一块
100e0 0d 0a 31
100f0 65 61 39 0d 0a...... //ASII码:"r"n"1ea9"r"n
此块长度为0x1ea9 = 7849, 下一块起始为100f5 + 1ea9 + 2 = 11fa0,如下:
100a0 30 0d 0a 0d 0a //ASCII码:0"r"n"r"n
“0”说明当前chunk为last-chunk, 第一个0d 0a为chunk结束符。第二个0d0a说明没有trailer部分,整个Chunk-body结束。
解码流程:
对chunked编码进行解码的目的是将分块的chunk-data整合恢复成一块作为报文体,同时记录此块体的长度。
RFC2616中附带的解码流程如下:(伪代码)
length := 0 //长度计数器置0
read chunk-size, chunk-extension (if any) and CRLF //读取chunk-size, chunk-extension
//和CRLF
while(chunk-size > 0 ) { //表明不是last-chunk
read chunk-data and CRLF //读chunk-size大小的chunk-data,skip CRLF
append chunk-data to entity-body //将此块chunk-data追加到entity-body后
read chunk-size and CRLF //读取新chunk的chunk-size 和 CRLF
}
read entity-header //entity-header的格式为name:valueCRLF,如果为空即只有CRLF
while (entity-header not empty) //即,不是只有CRLF的空行
{
append entity-header to existing header fields
read entity-header
}
Content-Length:=length //将整个解码流程结束后计算得到的新报文体length
//作为Content-Length域的值写入报文中
Remove "chunked" from Transfer-Encoding //同时从Transfer-Encoding中域值去除chunked这个标记
length最后的值实际为所有chunk的chunk-size之和,在上面的抓包实例中,一共有八块chunk-size为0x1ffc(8188)的chunk,剩下一块为0x1ea9(7849),加起来一共73353字节。
注:对于上面例子中前几个chunk的大小都是8188,可能是因为:"1ffc" 4字节,""r"n"2字节,加上块尾一个""r"n"2字节一共8字节,因此一个chunk整体为8196,正好可能是发送端一次TCP发送的缓存大小。
分享到:
评论

相关推荐

    On-device-activity-recognition:智能手机上的个性化机器学习

    如果您在研究中使用此功能,请引用他们的工作并检查许可证。 引用 如果你觉得这个项目有用,请把它引用为: @misc{saeed2020recognition, author = {Saeed, Aaqib}, title = {On-device Learning of Act

    cui-styles:cUI框架CSS样式

    默认情况下,模块可以作为普通CSS文件导入到项目中。 项目结构允许(有一定要求)构建自己的定制专业项目。 所有功能部件和组件都使用类作为样式方式。图书馆cUI样式已经以最小化形式作为CSS文件构建,可以导入到...

    em算法matlab代码-Transfer-PEP:第一组PEP估计算法

    Tranfer PEP是用matlab编程语言实现的。 输入是Mascot(*。dat)标识。 输出是三个PEP估计结果:组合PEP,单独的PEP和传输的PEP。 这是主要功能说明。 选择算法案例并指定FDR阈值: 四种不同情况分别对应于转移PEP...

    RevolutTest:简单的REST API在Revolut Java测试的帐户之间转移资金

    旋转测试简单的REST API在Revolut Java测试的帐户之间转移资金要求此API是使用和一起,用于JSON解析。 测试套件使用JUnit进行断言,并使用进行模拟。 它与Mac系统使用的IntelliJ IDEA社区版devolopeing 使用安装,但...

    网络协议图

    TCP(Tranfer Control Protocal)传输控制协议是一个面向连接的协议,当使用这个协议 时,网络可以保证客户端和服务器端的连接是可靠的、安全的。 UDP(User Datagram Protocal)用户数据报协议是一种非面向连接的...

    FSBB30CH60伺服电机驱动模块ALTIUM设计硬件原理图PCB+AD集成封装库文件.zip

    FSBB30CH60伺服电机驱动模块ALTIUM设计硬件原理图PCB+AD集成封装库文件,硬件4层板设计,大小为188mmx135mm,ALTIUM设计的工程文件,包括完整的...Tranfer EI33变压器 Trans 共模电感 ULN2003 ULN2003 Volt Reg LM7805

    heat and mass tranfer

    a book on heat and mass transfer

    screen tranfer

    专业英语翻译,对从事这个行业的同事很有好处,特别是刚刚走出校园的莘莘学子们

    java网络编程技术课程设计.doc

    TCP(Tranfer Control Protocol): 一种面向连接(可靠)的传输控制协议。通过TCP协议传输,得到的是一个顺序、无差错的 数据流。发送方和接收方成对的两个socket之间必须建立连接,以便在TCP协议的基础上 进行通信,当...

    C语言程序设计实例(200行)

    /*tranfer to Greenwich time*/ } 【程序92】 题目:时间函数举例2 1.程序分析: 2.程序源代码: /*calculate time*/ #include "time.h" #include "stdio.h" main() { time_t start,end; int i; start...

    tranfer.rar_coordinates_地心坐标

    将球面坐标转换为地心坐标,测试无误,自带数据集,具体应用修改参数即可

    hadooplib.zip

    用户可将多个 Java applet 及其所需组件(.class 文件、图像和声音)绑定到 JAR 文件中,而后作为单个的简单 HTTP(Hypertext Tranfer Protocal,超文本传输协议)事务下载到浏览器中,从而大大提高下载速度。...

    经编CAD常用英文词典

    FTP传输-Tranfer FTP S 型链块-S chain S型链块统计-Statistic S chains A 按比例改变花宽-By change ratio 按不同纱线拷贝-According to yarns 按不同梳栉拷贝-According to guide bars 按设定拷贝-According to ...

    time-example.rar_Time_gmtime

    1.程序分析: 2.程序源代码: #include "stdio.h" #include "conio.h" #include "time.h" void main() { time_t lt /*define a longint ... printf(asctime(gmtime(&lt))) /*tranfer to Greenwich time*/ getch() }

    style_tranfer

    使用神经网络进行风格迁移,采用预训练的vgg提取图片特征,采取下采样(编码)结合上采样(解码)的方式转换图片,尽可能最小化生成图片的内容损失和风格损失 使用imagenet作为训练数据集 文件说明 model.py 为神经...

    Filetranfer 用MFC编写的文件传输

    Filetranfer 用MFC编写的文件传输 Filetranfer 用MFC编写的文件传输Filetranfer 用MFC编写的文件传输 Filetranfer 用MFC编写的文件传输

    serial oscilation

    RLC serial oscilation,tranfer curve.

    transfer:简单的文件传输服务

    文件信息存储在 DynamoDB 中。 将文件上传到端点。 它将被上传到 S3。 将向预订时使用的地址发送一封电子邮件。 电子邮件包含一个 url,用户可以从那里下载文件。 如何在本地机器上运行 安装 Node.js 0.11.9 或...

    C语言基础

    【程序91】 题目:时间函数举例1 1.程序分析: 2.程序源代码: #include "stdio.h" #include "conio.h" #include "time.h" void main() { time_t lt;... /*tranfer to Greenwich time*/ getch(); }

    layui 穿梭框transfer右侧数据赋值排序错乱小技巧.doc

    一个简单的没有技术含量的方法

Global site tag (gtag.js) - Google Analytics