转载请注明出处 http://blog.csdn.net/yankai0219/article/details/8269922

0.序
1.http/1.1协议中与chunked编码的相关字段
1)Entity Body
2)Content-length
3)Message Length
4)content-length字段的作用 
2.chunked编码
1)定义
2)说明:
3)格式:
4)chunked编码的程序化表示
0.序
在研究百度云盘的响应过程中,发现其响应采用chunked编码形式,并且没有Content-length字段,因为项目需要,就需要研究一下http/1.1协议中的chunked编码。
首先介绍与chunked编码相关的几个概念,从而引出chunked编码
1.http/1.1协议中与chunked编码的相关字段
1)Entity Body: entity-body只有在message-body出现时才会出现。通过对message-body的解码获得entity-body。transfer-encoding用于确保安全和信息的恰当传输。
     Entity-length:在应用任何transfer-encoding之前的message-body的长度。即没有编码之前message-body的长度。
2)Content-length:用于描述HTTP消息实体的传输长度。(the
transfer-length of the message-body)
消息实体长度:即Entity-length,压缩之前的message-body的长度
消息实体的传输长度:Content-length,压缩后的message-body的长度。
3)Message Length:这部分的解释必须得看看大牛的解释 http://blog.xiuwz.com/tag/content-length/
在具体的HTTP交互中,客户端是如何获取消息长度的呢,主要基于以下几个规则:
  • 响应为1xx,204,304相应或者head请求,则直接忽视掉消息实体内容。
  • 如果有Transfer-Encoding,则优先采用Transfer-Encoding里面的方法来找到对应的长度。比如说Chunked模式。
  • “如果head中有Content-Length,那么这个Content-Length既表
    示实体长度,又表示传输长度。如果实体长度和传输长度不相等(比如说设置了Transfer-Encoding),那么则不能设置Content-
    Length。如果设置了Transfer-Encoding,那么Content-Length将被忽视”。这句话翻译的优点饶,其实关键就一点:有了Transfer-Encoding,则不能有Content-Length。
  • Range传输。不关注,没详细看了:)
  • 通过服务器关闭连接能确定消息的传输长度。(请求端不能通过关闭连接来指明请求消息体的结束,因为这样可以让服务器没有机会继续给予响应)。这种情况主要对应为短连接,即非keep-alive模式。
  • HTTP1.1必须支持chunk模式。因为当不确定消息长度的时候,可以通过chunk机制来处理这种情况。
  • 在包含消息内容的header中,如果有content-length字段,那么该字段对应的值必须完全和消息主题里面的长度匹配。
    “The entity-length of a message is the length of the message-body before any transfer-codings have been applied”
    也就是有chunk就不能有content-length 。
  • 其实后面几条几乎可以忽视,简单总结后如下:
  • 1、Content-Length如果存在并且有效的话,则必须和消息内容的传输长度完全一致。(经过测试,如果过短则会截断,过长则会导致超时。)

    2、如果存在Transfer-Encoding(重点是chunked),则在header中不能有Content-Length,有也会被忽视。

    3、如果采用短连接,则直接可以通过服务器关闭连接来确定消息的传输长度。(这个很容易懂)

    结合HTTP协议其他的特点,比如说Http1.1之前的不支持keep alive。那么可以得出以下结论:

    1、在Http 1.0及之前版本中,content-length字段可有可无。

    2、在http1.1及之后版本。如果是keep alive,则content-length和chunk必然是二选一。若是非keep alive,则和http1.0一样。content-length可有可无。

其中比较重要的一点如下所述:
          如果存在Transfer-encoding存在,则在header中不能由content-length,有也会被忽略。
          如果Content-length存在并且有效的话,则必须和消息内容的传输长度完全一致。
4)content-length字段的作用   
     Conent-Length表示实体内容长度,客户端(服务器)可以根据这个值来判断数据是否接收完成。但是如果消息中没有Conent-Length,那该如何来判断呢?又在什么情况下会没有Conent-Length呢?
没有Content-length时,客户端如何来判断数据是否接收完成呢?
1)静态页面或者图片:当客户端向服务器请求一个静态页面或者一张图片时,服务器可以很清楚的知道内容大小,然后通过Content-length消息首部字段告诉客户端 需要接收多少数据。
2)动态页面:
如果是动态页面等时,服务器是不可能预先知道内容大小,这时就可以使用Transfer-Encoding:chunk模式来传输
数据了。即如果要一边产生数据,一边发给客户端,服务器就需要使用”Transfer-Encoding:
chunked”这样的方式来代替Content-Length。
采用Transfer-encoding的目的
     一边产生数据,一边发给客户端。
1)定义
     分块传输编码(Chunked
transfer encoding)是超文本传输协议(HTTP)中的一种数据传输机制,允许HTTP由网页服务器发送给客户端应用(
通常是网页浏览器)的数据可以分成多个部分。分块传输编码只在HTTP协议1.1版本(HTTP/1.1)中提供。
2)说明:
     通常,HTTP应答消息中发送的数据是整
个发送的,Content-Length消息头字段表示数据的长度。数据的长度很重要,因为客户端需要知道哪里是应答消息的结束,以及后续应答消息的开
始。然而,使用分块传输编码,数据分解成一系列数据块,并以一个或多个块发送,这样服务器可以发送数据而不需要预先知道发送内容的总大小。
3)格式:
     如果一个HTTP消息(请求消息或应答消息)的Transfer-Encoding消息头的值为chunked,那么,消息体由数量未定的块组成,并以最后一个大小为0的块为结束。
每一个非空的块都以该块包含数据的字节数(字节数以十六进制表示)开始,跟随一个CRLF (回车及换行),然后是数据本身,最后块CRLF结束。在一些实现中,块大小和CRLF之间填充有白空格(0x20)。
最后一块是单行,由块大小(0),一些可选的填充白空格,以及CRLF。最后一块不再包含任何数据,但是可以发送可选的尾部,包括消息头字段。
消息最后以CRLF结尾。
     chunk编码将数据分成一块一块的发生。Chunked编码将使用若干个Chunk串连而成,由一个标明长度为0 的chunk标示结束。每个Chunk分为头部和正文两部分,头部内容指定正文的字符总数(十六进制的数字 )和数量单位(一般不写),正文部分就是指定长度的实际内容,两部分之间用回车换行(CRLF) 隔开。在最后一个长度为0的Chunk中的内容是称为footer的内容,是一些附加的Header信息(通常可以直接忽略)。

Chunk编码的格式如下:

Chunked-Body = *chunk 
“0″ CRLF
footer
CRLF
chunk = chunk-size [ chunk-ext ] CRLF
chunk-data CRLF

hex-no-zero = <HEX excluding “0″>

chunk-size = hex-no-zero *HEX
chunk-ext = *( “;” chunk-ext-name [ "=" chunk-ext-value ] )
chunk-ext-name = token
chunk-ext-val = token | quoted-string
chunk-data = chunk-size(OCTET)

footer = *entity-header

即Chunk编码由四部分组成: 1、0至多个chunk块 ,2、“0″ CRLF ,3、footer ,4、CRLF . 而每个chunk块由:chunk-size、chunk-ext(可选)、CRLF、chunk-data、CRLF组成。

4)chunked编码的程序化表示

     (1)c++ 详见http://wuhua.iteye.com/blog/673841
     (2)c语言
char * chunkpart1 = "42\r\n" ;
char * chunkpart2 =
tmpuchar_body_data ;
char * chunkpart3 = "\r\n0\r\n\r\n" ;
int chunklen = 0;
 chunklen = strlen(chunkpart1)
strlen(chunkpart2) + strlen(chunkpart3);
char * chunk = (char*)ngx_pcalloc(r->pool,chunklen+1);
strncpy(chunk,chunkpart1,strlen(chunkpart1));
strncpy((chunk+strlen(chunkpart1)),chunkpart2, strlen(chunkpart2)
);
strncpy((chunk+strlen(chunkpart1)
strlen(chunkpart2) ),chunkpart3, strlen(chunkpart3));
参考文章
1)http://zh.wikipedia.org/wiki/%E5%88%86%E5%9D%97%E4%BC%A0%E8%BE%93%E7%BC%96%E7%A0%81
2)http://blog.xiuwz.com/tag/content-length/
3)http://wuhua.iteye.com/blog/673841

http协议中content-length 以及chunked编码分析的更多相关文章

  1. HTTP协议中的chunked编码解析

    \r\n\r\n"了. chunked编码很简单,是不是? 不过,在协议还原的实现过程中,如何高效高性能地对chunked进行解码,是一件值得挑战的事哦.毕竟,HTTP的流量占比不小的. 长 ...

  2. HTTP1.1中CHUNKED编码解析

    一般HTTP通信时,会使用Content-Length头信息性来通知用户代理(通常意义上是浏览器)服务器发送的文档内容长度,该头信息定义于HTTP1.0协议RFC  1945  10.4章节中.浏览器 ...

  3. HTTP1.1中CHUNKED编码解析(转载)

    HTTP1.1中CHUNKED编码解析 一般HTTP通信时,会使用Content-Length头信息性来通知用户代理(通常意义上是浏览器)服务器发送的文档内容长度,该头信息定义于HTTP1.0协议RF ...

  4. HTTP 协议中的 Content-Encoding 和 Transfer-Encoding(内容编码和传输编码)

    转自:http://network.51cto.com/art/201509/491335.htm Transfer-Encoding,是一个 HTTP 头部字段,字面意思是「传输编码」.实际上,HT ...

  5. HTTP协议的chunked编码

    一般情况HTTP的Header包含Content-Length域来指明报文体的长度.如: 有时候服务生成HTTP回应是无法确定消息大小的,比如大文件的下载,或者后台需要复杂的逻辑才能全部处理页面的请求 ...

  6. 说说http协议中的编码和解码

    http://www.csdn1 2 3.com/html/itweb/20130730/29422_29378_29408.htm ****************************** 一. ...

  7. PHP header函数设置http报文头示例详解以及解决http返回头中content-length与Transfer-Encoding: chunked的问题

    最近在服务器上,多媒体与设备(摄像头)对接的时候,总是发生错误导致设备崩溃,抓包发现响应头不对,没有返回length,使得摄像头立即崩溃.找了一下资料,改了一下响应头就好了. //定义编码 heade ...

  8. HTTP协议中状态码的应用

    HTTP状态码(HTTP Status Code)是用以表示网页服务器HTTP响应状态的3位数字代码. 所有状态码的第一个数字代表了响应的五种状态之一.   Mark from 维基百科     消息 ...

  9. HTTP协议中的长连接和短连接(keep-alive状态)

    什么是长连接 HTTP1.1规定了默认保持长连接(HTTP persistent connection ,也有翻译为持久连接),数据传输完成了保持TCP连接不断开(不发RST包.不四次握手),等待在同 ...

随机推荐

  1. 苹果内存取证工具volafox

    苹果内存取证工具volafox volafox是一款针对苹果内存取证的专用工具.该工具使用Python语言编写.该工具内置了overlay data数据,用户可以直接分析苹果10.6-10.11的各种 ...

  2. Vim的一些补充

    查看当前路径 :pwd 切换当前路径到当前打开文件所在路径 :cd %:p:h 解释: %表示当前文件名,%:p表示包含文件名的全部路径,%:p:h表示文件所在路径(head of the full ...

  3. set集合玩法、三目运算

    set是无序的,无法用下标获取值 创建set二种方式 1.第一种 s1=set()   #创建一个空的set,看下面就知道为什么要这么创建一个空的集合 2.第二种 s2={11,22,33,44} # ...

  4. 深入理解javascript函数系列第三篇

    前面的话 函数是javascript中特殊的对象,可以拥有属性和方法,就像普通的对象拥有属性和方法一样.甚至可以用Function()构造函数来创建新的函数对象.本文是深入理解javascript函数 ...

  5. 网络流小结+[jzyzoj p1320] patrol

    一个不能更清楚的网络流介绍 ↑虽然不是我写的但是观摩一下总是没问题的嗯   看到晗神学的是神奇的ek算法. 但是看起来还是Ford-Fulkerson比较简单..所以我就学了这个...嗯其他的先看看. ...

  6. 【概率】【找规律】hdu6229 Wandering Robots

    题意:一个机器人在正方形迷宫的左上角,迷宫里有些格子有障碍物,每一步机器人会等概率地向能走的格子转移(包含自身).问你无限长的时间之后,机器人处于矩形对角线的右下方的概率. 无限长时间意味着,起点没有 ...

  7. 安卓中AsyncTask的基本使用

    安卓中AsyncTask的基本使用 使用场景介绍 在安卓开发中,我们经常需要访问互联网资源,这些访问是都需要在后台线程中去完成的,因为安卓的UI线程不允许执行耗时任务.然而,后台线程是不可以修改安卓的 ...

  8. Educational Codeforces Round 12 E. Beautiful Subarrays 字典树

    E. Beautiful Subarrays 题目连接: http://www.codeforces.com/contest/665/problem/E Description One day, ZS ...

  9. hdu 4027 Can you answer these queries? 线段树区间开根号,区间求和

    Can you answer these queries? Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/sho ...

  10. 《python学习手册》第35章 异常的设计

    嵌套异常处理器 其实我们主要需要搞清楚的问题应该是这样的,当异常发生的时候,无论是简单的异常处理还是复杂的异常处理,我们都应该能够清楚的了解到异常运行到哪里,被谁捕获了,现在控制权到了哪里了,下面我们 ...