当不能预先确定报文体的长度时,不可能在头中包含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发送的缓存大小。
分享到:
相关推荐
如果您在研究中使用此功能,请引用他们的工作并检查许可证。 引用 如果你觉得这个项目有用,请把它引用为: @misc{saeed2020recognition, author = {Saeed, Aaqib}, title = {On-device Learning of Act
默认情况下,模块可以作为普通CSS文件导入到项目中。 项目结构允许(有一定要求)构建自己的定制专业项目。 所有功能部件和组件都使用类作为样式方式。图书馆cUI样式已经以最小化形式作为CSS文件构建,可以导入到...
Tranfer PEP是用matlab编程语言实现的。 输入是Mascot(*。dat)标识。 输出是三个PEP估计结果:组合PEP,单独的PEP和传输的PEP。 这是主要功能说明。 选择算法案例并指定FDR阈值: 四种不同情况分别对应于转移PEP...
旋转测试简单的REST API在Revolut Java测试的帐户之间转移资金要求此API是使用和一起,用于JSON解析。 测试套件使用JUnit进行断言,并使用进行模拟。 它与Mac系统使用的IntelliJ IDEA社区版devolopeing 使用安装,但...
TCP(Tranfer Control Protocal)传输控制协议是一个面向连接的协议,当使用这个协议 时,网络可以保证客户端和服务器端的连接是可靠的、安全的。 UDP(User Datagram Protocal)用户数据报协议是一种非面向连接的...
FSBB30CH60伺服电机驱动模块ALTIUM设计硬件原理图PCB+AD集成封装库文件,硬件4层板设计,大小为188mmx135mm,ALTIUM设计的工程文件,包括完整的...Tranfer EI33变压器 Trans 共模电感 ULN2003 ULN2003 Volt Reg LM7805
a book on heat and mass transfer
专业英语翻译,对从事这个行业的同事很有好处,特别是刚刚走出校园的莘莘学子们
TCP(Tranfer Control Protocol): 一种面向连接(可靠)的传输控制协议。通过TCP协议传输,得到的是一个顺序、无差错的 数据流。发送方和接收方成对的两个socket之间必须建立连接,以便在TCP协议的基础上 进行通信,当...
/*tranfer to Greenwich time*/ } 【程序92】 题目:时间函数举例2 1.程序分析: 2.程序源代码: /*calculate time*/ #include "time.h" #include "stdio.h" main() { time_t start,end; int i; start...
将球面坐标转换为地心坐标,测试无误,自带数据集,具体应用修改参数即可
用户可将多个 Java applet 及其所需组件(.class 文件、图像和声音)绑定到 JAR 文件中,而后作为单个的简单 HTTP(Hypertext Tranfer Protocal,超文本传输协议)事务下载到浏览器中,从而大大提高下载速度。...
FTP传输-Tranfer FTP S 型链块-S chain S型链块统计-Statistic S chains A 按比例改变花宽-By change ratio 按不同纱线拷贝-According to yarns 按不同梳栉拷贝-According to guide bars 按设定拷贝-According to ...
1.程序分析: 2.程序源代码: #include "stdio.h" #include "conio.h" #include "time.h" void main() { time_t lt /*define a longint ... printf(asctime(gmtime(<))) /*tranfer to Greenwich time*/ getch() }
使用神经网络进行风格迁移,采用预训练的vgg提取图片特征,采取下采样(编码)结合上采样(解码)的方式转换图片,尽可能最小化生成图片的内容损失和风格损失 使用imagenet作为训练数据集 文件说明 model.py 为神经...
Filetranfer 用MFC编写的文件传输 Filetranfer 用MFC编写的文件传输Filetranfer 用MFC编写的文件传输 Filetranfer 用MFC编写的文件传输
RLC serial oscilation,tranfer curve.
文件信息存储在 DynamoDB 中。 将文件上传到端点。 它将被上传到 S3。 将向预订时使用的地址发送一封电子邮件。 电子邮件包含一个 url,用户可以从那里下载文件。 如何在本地机器上运行 安装 Node.js 0.11.9 或...
【程序91】 题目:时间函数举例1 1.程序分析: 2.程序源代码: #include "stdio.h" #include "conio.h" #include "time.h" void main() { time_t lt;... /*tranfer to Greenwich time*/ getch(); }
一个简单的没有技术含量的方法