http请求中的Content-Length作用机制与分块chunked
httpclient-4.5.9.jar
org.apache.http:
auth 身份
client 端
conn 连接
cookie 本地
impl: 实现
execchain 异常
httpcore-4.4.11.jar
org.apache.http.entity;
AbstractHttpEntity
http请求体包报文格式:
Content-Type: 报文类型:application/json;charset=utf-8
Content-Encoding: 编码方式:gzip或deflate
Content-Length: 报文长度:
Chunked: 是否分块传输
Content-Length
, HTTP消息长度, 用十进制数字表示的八位字节的数目. 一般情况下, 很多工作都被框架完成, 我们很少去关注这部分内容, 但少数情况下发生了Content-Length
与实际消息长度不一致, 程序可能会发生比较奇怪的异常, 如:
- 无响应直到超时.
- 请求被截断, 而且下一个请求解析出现错乱.
Content-Length
是HTTP消息长度, 用十进制数字表示的八位字节的数目, 是Headers中常见的一个字段. Content-Length
应该是精确的, 否则就会导致异常 (特别地, HTTP1.0中这个字段可有可无).
Content-Length
首部指示出报文中实体主体的字节大小. 这个大小是包含了所有内容编码的, 比如, 对文本文件进行了gzip
压缩的话, Content-Length
首部指的就是压缩后的大小而不是原始大小.
Content-Length是如何工作的
Content-Length
使用十进制的数字表示了消息的长度, 服务端/客户端通过它来得知后续要读取消息的长度.
如果这个长度不正确, 会发生如下情况:
Content-Length > 实际长度
如果Content-Length比实际的长度大, 服务端/客户端读取到消息结尾后, 会等待下一个字节, 自然会无响应直到超时.
同样地, 在响应消息中Content-Length
超过实际长度也是一样的效果:
Content-Length < 实际长度
如果这个长度小于实际长度, 首次请求的消息会被截取, 比如参数为param=piaoruiqing
, Content-Length
为10, 那么这次请求的消息会被截取为: param=piao
, 如图所示:
但, 仅仅是如此吗, 当然不, 我们再来看看第二次请求会发生什么让人意外的事情, 如图:
连续的两次请求, 第一次消息被截断, 而第二次没有发生预期的截断, 而是服务端抛出了异常: Request method 'ruiqingPOST' not supported
.刺不刺激 (ノ)゚Д゚( )
那 ruiqingPOST
是个什么神仙方法??? 此时, 凭着多年开发(DEBUG)经验练就的敏感度, 我们大致可以猜出, 上一次请求被截取剩下的消息, 在这次请求出现了. 掏出wireshark来验证一下, 如图:
导致这种情况的原因就是开启了Connection:keep-alive
, 如果使用Connection:close
, 所产生的现象就是每一次的请求都被截断, 但不会产生解析混乱(如将上一次剩下的消息拼接到后续的请求消息中).
不确定Content-Length的值怎么办
Content-Length首部指示出报文中实体主体的字节大小. 但如在请求处理完成前无法获取消息长度, 我们就无法明确指定
Content-Length, 此时应该使用
Transfer-Encoding: chunked
什么是Transfer-Encoding: chunked
数据以一系列分块的形式进行发送. Content-Length
首部在这种情况下不被发送. 在每一个分块的开头需要添加当前分块的长度, 以十六进制的形式表示,后面紧跟着 \r\n
, 之后是分块本身, 后面也是\r\n
. 终止块是一个常规的分块, 不同之处在于其长度为0.
Transfer-Encoding: chunked是如何工作的
接下来我们用一个下载文件的例子, 来探讨Transfer-Encoding: chunked
是如何工作的. 服务端代码如下:
使用postman发起请求, wireshark抓包查看, 如图:
在wireshark中可以很清晰地看到chunked的数据, 其结构大致是: 返回的消息被分为多个数据块, 每个数据块有两部分, 长度
+ 数据
, 这两部分都以CRLF(即\r\n
)结尾. 而终止块是一个特殊的数据块, 其长度为0, 如图:
如此, 即完成了分块编码. 其主要应用于如下场景, 即要传输大量的数据, 但是在请求在没有被处理完之前响应的长度是无法获得的. 例如, 当需要用从数据库中查询获得的数据生成一个大的HTML表格、需要传输大量的图片等.
Content-Length
如果存在且生效, 必须是正确的, 否则会发生异常.(大于实际值会超时, 小于实际值会截断并可能导致后续的数据解析混乱)- 如果报文中包含
Transfer-Encoding: chunked
首部, 那么Content-Length
将被忽略. - @转自:https://blog.piaoruiqing.com.
http请求中的Content-Length作用机制与分块chunked的更多相关文章
- SSM项目中用ajax尝试实现controller请求中重定向不起作用的问题
首先我在controller中有一个添加数据的方法: @RequestMapping(value="/emp",method=RequestMethod.POST) public ...
- HTTP请求中浏览器的缓存机制
摘要:在Web开发过程中,我们可能会经常遇到浏览器缓存的问题.本文作者详细解释了浏览器缓存的机制,帮助读者更深层次的认识浏览器的缓存. 流程 当资源第一次被访问的时候,HTTP头部如下 (Reques ...
- HTTP请求中的缓存(cache)机制
http://www.chaorenmao.com/blog/?p=79 流程 当资源第一次被访问的时候,HTTP头部如下 (Request-Line) GET /a.html HTTP/1.1Ho ...
- Ajax请求中的async:false/true的作用【转载】
[Ajax请求中的async:false/true的作用] 作者:https://www.cnblogs.com/mmzuo-798/p/7098979.html 前言: 昨天在做倒计时修改的时候,发 ...
- [翻译] Python 3.5中async/await的工作机制
Python 3.5中async/await的工作机制 多处翻译出于自己理解,如有疑惑请参考原文 原文链接 身为Python核心开发组的成员,我对于这门语言的各种细节充满好奇.尽管我很清楚自己不可能对 ...
- Http请求中Content-Type讲解以及在Spring MVC中的应用
引言: 在Http请求中,我们每天都在使用Content-type来指定不同格式的请求信息,但是却很少有人去全面了解content-type中允许的值有多少,这里将讲解Content-Type的可用值 ...
- URL中“#” “?” &“”号的作用
URL中"#" "?" &""号的作用 阅读目录 1. # 2. ? 3. & 回到顶部 1. # 10年9月,twit ...
- RL中“#” “?” &“”号的作用
阅读目录 1. # 2. ? 3. & 回到顶部 1. # 10年9月,twitter改版.一个显著变化,就是URL加入了"#!"符号.比如,改版前的用户主页网址为http ...
- HTTP请求中的Body构建——.NET客户端调用JAVA服务进行文件上传
PS:今日的第二篇,当日事还要当日毕:) http的POST请求发送的内容在Body中,因此有时候会有我们自己构建body的情况. JAVA使用http—post上传file时,spring框架中 ...
随机推荐
- LeetCode--064--最小路径和
给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小. 说明:每次只能向下或者向右移动一步. 示例: 输入:[ [1,3,1], [1,5,1], ...
- 链接收藏:bullet物理引擎不完全指南
这个也是博客园的文章,编辑得也很好,就不copy了,结尾还有PDF: https://www.cnblogs.com/skyofbitbit/p/4128347.html 完结
- JavaScript自增和自减
一.自增++ 通过自增运算符可以使变量在自身的基础上加一: 对于一个变量自增以后,原变量的值会立即自增一: 自增符号:++ 自增分为两种:1.后++(a++):2.前++(++a): 共同点:a++ ...
- 放一道比较基础的LCA 的题目把 :CODEVS 2370 小机房的树
题目描述 Description 小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上.有一天,他们想爬到一个节点上去搞基,但是作为两只虫子, ...
- Python_015(面向对象(接口类,抽象类,多态,封装)
一.抽象类与接口类 1.抽象类:抽象即类似或者说比较像的部分,继承描述的是父类与子类的一种关系,要找出这种关系,必须先抽象再继承; a:抽象分成两个层次: 1)由对象->类:将两个有相似地方的对 ...
- [BZOJ3262]:陌上花开(CDQ分治)
题目传送门 题目描述 有$n$朵花,每朵花有三个属性:花形$(s)$.颜色$(c)$.气味$(m)$,用三个整数表示.现在要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花$A$比 ...
- 分类汇总统计mysql数据库一个字段中不同的记录的总和
方法1.用 if 语句,如下例. 方法2.用case when then else 语句,用法如同if. mysql> select sum(if(id<500,1,0)),sum(if( ...
- SIEM中心日志节点WEF搭建说明
https://www.freebuf.com/articles/es/197812.html
- GMM demo
# GMM model # // library(mvtnorm) ) n1 = n2 = mu1 = c(,) mu2 = c(-,-) sigma1 = matrix(c(,.,.,),nrow= ...
- 阶段1 语言基础+高级_1-3-Java语言高级_04-集合_05 List集合_2_Arraylist集合
数组查询快,增删慢. 不是同步的就是多线程的 ArrayList其实就是一个数组 这是add方法 它在添加元素的时候会创建新的数组,然后把元素复制过来.这就是为什么查询快,增删们的原因. 每次增加元素 ...