有的时候服务器生成HTTP回应是无法确定信息大小的,这时用Content-Length就无法事先写入长度,而需要实时生成消息长度,这时服务器一般采用Chunked编码。

在进行Chunked编码传输时,在回复消息的头部有transfer-coding并定义为Chunked,表示将用Chunked编码传输内容。

Chunked编码使用若干个Chunk串连而成,由一个标明长度为0的chunk标示结束。每个Chunk分为头部和正文两部分,头部内容指定下一段正文的字符总数(十六进制的数字)和数量单位(一般不写),正文部分就是指定长度的实际内容,两部分之间用回车换行(CRLF)隔开。在最后一个长度为0的Chunk中的内容是称为footer的内容,是一些附加的Header信息(通常可以直接忽略)。

我们来模拟一下数据结构:
[Chunk大小][回车][Chunk数据体][回车][Chunk大小][回车][Chunk数据体][回车][0][回车][footer内容(有的话)][回车]

注意chunk-size是以十六进制的ASCII码表示的,比如86AE(实际的十六进制应该是:38366165),计算成长度应该是:34478,表示从回车之后有连续的34478字节的数据。
跟踪了www.yahoo.com的返回数据,发现在chunk-size中,还会多一些空格。可能是固定长度为7个字节,不满7个字节的,就以空格补足,空格的ASCII码是0x20。

解码流程:
    对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这个标记

Sample

Encoded response

HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked 25
This is the data in the first chunk 1A
and this is the second one
0

same as above, raw bytes in hex

0000-000F   48 54 54 50 2f 31 2e 31 20 32 30 30 20 4f 4b 0d   HTTP/1.1 200 OK.
0010-001F 0a 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 74 .Content-Type: t
0020-002F 65 78 74 2f 70 6c 61 69 6e 0d 0a 54 72 61 6e 73 ext/plain..Trans
0030-003F 66 65 72 2d 45 6e 63 6f 64 69 6e 67 3a 20 63 68 fer-Encoding: ch
0040-004F 75 6e 6b 65 64 0d 0a 0d 0a 32 35 0d 0a 54 68 69 unked....25..Thi
0050-005F 73 20 69 73 20 74 68 65 20 64 61 74 61 20 69 6e s is the data in
0060-006F 20 74 68 65 20 66 69 72 73 74 20 63 68 75 6e 6b the first chunk
0070-007F 0d 0a 0d 0a 31 41 0d 0a 61 6e 64 20 74 68 69 73 ....1A..and this
0080-008F 20 69 73 20 74 68 65 20 73 65 63 6f 6e 64 20 6f is the second o
0090-009F 6e 65 0d 0a 30 0d 0a 0d 0a ne..0....

same as above, in Java code

public static final byte[] CHUNKED_RESPONSE;
static {
StringBuilder sb = new StringBuilder();
sb.append("HTTP/1.1 200 OK/r/n");
sb.append("Content-Type: text/plain/r/n");
sb.append("Transfer-Encoding: chunked/r/n/r/n");
sb.append("25/r/n");
sb.append("This is the data in the first chunk/r/n"); // 37 bytes of payload
// (conveniently consisting of ASCII characters only)
sb.append("/r/n1A/r/n");
sb.append("and this is the second one"); // 26 bytes of payload
// (conveniently consisting of ASCII characters only)
sb.append("/r/n0/r/n/r/n");
CHUNKED_RESPONSE = sb.toString().getBytes(java.nio.charset.Charset.forName("US-ASCII"));
}

Decoded data

This is the data in the first chunk
and this is the second one

基本上checked的编码方式。

http响应chunked格式分析的更多相关文章

  1. HTTP POST请求报文格式分析与Java实现文件上传

    时间 2014-12-11 12:41:43  CSDN博客 原文  http://blog.csdn.net/bboyfeiyu/article/details/41863951 主题 HTTPHt ...

  2. http请求报文格式和响应报文格式

    转载 出处 超文本传输协议(Hypertext Transfer Protocol,简称HTTP)是应用层协议.HTTP 是一种请求/响应式的协议,即一个客户端与服务器建立连接后,向服务器发送一个请求 ...

  3. http请求报文格式(请求行、请求头、空行 和 请求包体)和响应报文格式(状态行、响应头部、空行 和 响应包体)

    转载 出处 超文本传输协议(Hypertext Transfer Protocol,简称HTTP)是应用层协议.HTTP 是一种请求/响应式的协议,即一个客户端与服务器建立连接后,向服务器发送一个请求 ...

  4. application/x-www-form-urlencoded multipart/form-data text/plain 后台返回的数据响应的格式类型

    application/x-www-form-urlencoded multipart/form-data text/plain 为什么上传文件的表单里要加个属性 enctype  后台返回的数据响应 ...

  5. AAC 格式分析

    一直在做一个语音项目,到了测试阶段,近来不是很忙,想把之前做的内容整理一下. 关于AAC音频格式基本情况,可参考维基百科http://en.wikipedia.org/wiki/Advanced_Au ...

  6. AAC ADTS AAC LATM 格式分析

    http://blog.csdn.net/tx3344/article/details/7414543# 目录(?)[-] ADTS是个啥 ADTS内容及结构 将AAC打包成ADTS格式 1.ADTS ...

  7. HTTP请求、响应报文格式

    HTTP请求报文格式: HTTP请求报文主要由请求行.请求头部.空行以及请求正文4部分组成 1,请求行由3部分组成,分别为:请求方式,URI(注意这里不是URL)以及协议版本组成,之间由空格分隔 请求 ...

  8. Google的Protocol Buffer格式分析

    [转]转自:序列化笔记之一:Google的Protocol Buffer格式分析 从公开介绍来看,ProtocolBuffer(PB)是google 的一种数据交换的格式,它独立于语言,独立于平台.作 ...

  9. .net下二进制序列化的格式分析[转]

    .net下二进制序列化的格式分析[转] -- 综合应用 (http://www.Host01.Com/article/Net/00020003/) --- .net下二进制序列化的格式分析 (http ...

随机推荐

  1. python---迭代器与生成器(一)

    迭代器与生成器 迭代器 迭代是Python最强大的功能之一,是访问集合元素的一种方式.. 迭代器是一个可以记住遍历的位置的对象. 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代 ...

  2. 【C#】Socket中的ssl通信

    引言    有个项目中用到了Socket ssl通信,在此记录一下. 证书 Socket ssl需要用到证书用来校验身份,而作为调试,我们只需用测试证书即可. 有个工具可以很方便地制作测试证书,下载地 ...

  3. 兄弟ifream的方法调用

    兄弟ifream A var ifreamId = window.frameElement && window.frameElement.id || ''; var url = 'ur ...

  4. Week2《Java程序设计》第二周学习总结

    Week02-Java学习笔记2 1. 本周学习总结 本周学习了java的基本语法与类库,其中介绍了基本数据类型和引用类型,介绍了String类,String对象的拼接以及String的一些常用方法: ...

  5. 读书笔记-Ribbon源码分析

    @LoadBalanced注解用来给RestTemplate做标记,以使用负载均衡的客户端来配置. 通过搜索LoadBalancerClient可以发现,LoadBalancerClient是Spri ...

  6. QWidget类参考

    QWidget类是所有用户界面对象的基类. 详情请见…… #include <qwidget.h> 继承QObject和QPaintDevice. 被QButton.QFrame.QDia ...

  7. Https与SSL介绍

    参考资料: http://www.ruanyifeng.com/blog/2014/02/ssl_tls.html http://www.ruanyifeng.com/blog/2014/09/ill ...

  8. Android 进阶10:进程通信之 Messenger 使用与解析

    读完本文你将了解: Messenger 简介 Messenger 的使用 服务端 客户端 运行效果 使用小结 总结 代码地址 Thanks 前面我们介绍了 AIDL 的使用与原理,这篇文章来介绍下 A ...

  9. (四)java基本语法

    关键字 被java赋予了特殊意义的单词: class,new,private,protected,public,static,final,abstract,interface,this,super,I ...

  10. 修改Sublime Text3 的侧边栏字体大小

    修改Sublime Text3 的侧边栏字体大小 1. 安装”Package Control Package Control”,建议使用官方安装命令:https://sublime.wbond.net ...