摘要: 理解HTTP协议...

  • 原文:用了这么久HTTP, 你是否了解Content-Length和Transfer-Encoding ?
  • 作者:朴瑞卿的博客

由Content-Length导致的问题引发的一系列思考: 前段时间开发API网关, 使用postman调试时出现了超时的情况, 经排查确定是请求数据被处理后Content-Length与实际不一致导致的问题, 故有此文.

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 首部在这种情况下不被发送. 在每一个分块的开头需要添加当前分块的长度, 以十六进制的形式表示,后面紧跟着 rn , 之后是分块本身, 后面也是rn. 终止块是一个常规的分块, 不同之处在于其长度为0.

Transfer-Encoding: chunked是如何工作的

接下来我们用一个下载文件的例子, 来探讨Transfer-Encoding: chunked是如何工作的. 服务端代码如下:

使用postman发起请求, wireshark抓包查看, 如图:

在wireshark中可以很清晰地看到chunked的数据, 其结构大致是: 返回的消息被分为多个数据块, 每个数据块有两部分, 长度 + 数据, 这两部分都以CRLF(即rn)结尾. 而终止块是一个特殊的数据块, 其长度为0, 如图:

如此, 即完成了分块编码. 其主要应用于如下场景, 即要传输大量的数据, 但是在请求在没有被处理完之前响应的长度是无法获得的. 例如, 当需要用从数据库中查询获得的数据生成一个大的HTML表格、需要传输大量的图片等.

  • Content-Length如果存在且生效, 必须是正确的, 否则会发生异常.(大于实际值会超时, 小于实际值会截断并可能导致后续的数据解析混乱)
  • 如果报文中包含Transfer-Encoding: chunked首部, 那么Content-Length将被忽略.

参考

  • https://developer.mozilla.org
  • 《HTTP权威指南》

版权声明

本文发布于朴瑞卿的博客, 允许非商业用途转载, 但转载必须保留原作者朴瑞卿 及链接:https://blog.piaoruiqing.com. 如有授权方面的协商或合作, 请联系邮箱: piaoruiqing@gmail.com.

关于Fundebug

Fundebug专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了20亿+错误事件,付费客户有阳光保险、核桃编程、荔枝FM、掌门1对1、微脉、青团社等众多品牌企业。欢迎大家免费试用!

http下载异常_用了这么久HTTP, 你是否了解Content-Length?相关推荐

  1. http下载异常_百度网站抓取异常的原因有哪些?有什么影响和解决方法?

    大纲如下:1.抓取异常是什么?百度抓取异常又是什么?2.百度抓取异常的原因有哪些?3.网站抓取异常的原因有哪些?4.百度抓取异常对网站有什么影响?5.网站出现抓取异常的解决方法抓取异常是什么?百度抓取 ...

  2. minecraftjava下载地址_请问谁有我的世界1.14Java版的下载地址啊?

    Résultats de recherche Résultats Web Minecraft:Java 版下载| | Minecrafthttps://www.minecraft.net/zh-han ...

  3. 爬虫python下载视频_用python做爬虫下载视频

    用python有一段时间了,对python是十二分喜爱,在我看来python是个好工具,可以轻松简洁的帮我完成一些我想要完成的工作.下面和大家分享一下我用python爬取某网站视频的案例.用pytho ...

  4. 腾讯视频下载位置_腾讯视频怎么下视频到手机

    很多人都使用腾讯视频,播放器家园网小编给大家分享一下腾讯视频下载位置_腾讯视频怎么下视频到手机相关内容.作为国内首家,全力打造正版视频平台的腾讯视频,将从流畅的观映体验.高清的视觉效果.贴心的分享感受 ...

  5. 腾讯视频下载官方_腾讯视频评论在哪

    本文给大家整理了腾讯视频下载官方_腾讯视频评论在哪方面的内容.腾讯视频影音是一款界面轻松友好,功能全面完善,方便好用,绿色安全,完全免费的.专注视频播放的客户端软件,您可运行腾讯视频影音,在线享受腾讯 ...

  6. 腾讯视频下载格式_怎么下载腾讯视频

    不管这个腾讯视频好用与否,都有一大批用户,本文播放器家园网小编分享腾讯视频下载格式_怎么下载腾讯视频.腾讯视频时刻为您推荐最新最火的视频,精彩不断随时观看.支持各种画质的下载,没网也能享受高视觉的享受 ...

  7. 腾讯视频下载电脑_腾讯视频如何设置允许腾讯视频驻留功能

    本文给大家整理了腾讯视频下载电脑_腾讯视频如何设置允许腾讯视频驻留功能方面的内容.腾讯视频不断实践"三网合一"的使命,现已覆盖互联网.电视.移动三大终端,兼具影视.综艺.资讯三大内 ...

  8. 腾讯视频真实下载地址_腾讯视频如何多倍速播放视频

    腾讯视频官网版是一款专注视频播放的客户端软件,您可运行腾讯视频,在线享受奇艺网站内全部免费高清正版视频.腾讯视频视频播放器内容丰富,影视更新快,包含腾讯视频所有的视频内容,在线享受腾讯视频站内全部免费 ...

  9. 腾讯视频下载安装_如何上传视频到腾讯视频平台

    播放器软件很多,本文小编给大家推荐腾讯视频.我们可以在腾讯视频播放器上,观看各种电视剧.电影.综艺节目等内容.里面的大部分视频都是免费的,部分独播大剧可能会存在vip收费的情况,这也是无法避免的.腾讯 ...

  10. 腾讯视频如何下载视频_腾讯视频如何做明星装扮

    这篇文章主要说的是腾讯视频如何下载视频_腾讯视频如何做明星装扮,希望可以帮助大家.腾讯视频时刻为您推荐最新最火的视频,精彩不断随时观看.支持各种画质的下载,没网也能享受高视觉的享受,让生活的每一刻都不 ...

最新文章

  1. 配置jdk环境 windows
  2. mysql主从同步linux,linux中部署mysql主从同步示例详解(绝对经典,看了必会)
  3. IOS开发笔记8-C语言基础复习
  4. 链接并执行GitHub上托管的外部JavaScript文件
  5. CSS实现某元素hover时 所有兄弟节点样式改变
  6. 使用OpenCV,Keras和Tensorflow构建Covid19掩模检测器
  7. GitHub的常用命令---终端操作
  8. win7下使用Taste实现协同过滤算法
  9. 《推荐系统实践》项亮 书中程序实现
  10. html字体加载太慢,字体加载CSS @font-face性能优化的常用策略
  11. java基于微信小程序的学习打卡系统 uniapp 小程序
  12. android 视频测试工具,安兔兔视频测试下载3.0 官方版-安卓盒子视频性能检测工具平板西西软件下载...
  13. 海康摄像机3D PTZ功能,拍照功能
  14. mysql 实现异地同步_MySQL 异地同步问题
  15. 电脑屏幕亮度能否自动调节
  16. 中国计算机软件法,计算机软件专利申请中国快律法务攻略.pdf
  17. Android SearchView基本用法
  18. 王者荣耀服务器维修多久,王者荣耀服务器正在维护中,具体维护时间及更新内容可留意官网更新公告_游戏吧...
  19. 史无前例的这个 GitHub 汇总了 300 道 Python 面试题
  20. Typora基础用法:pandoc安装,导入导出word文档,pdf文件。设置图片目录

热门文章

  1. 基于php工程项目管理系统——计算机毕业设计
  2. YS-M8C自助终端主板RK3288详解和说明
  3. 要成为云架构师需要学什么技能?
  4. 老电脑可以安装win11系统吗
  5. 怎么安装光盘并重新启动计算机,如何用光盘重新安装电脑系统
  6. WT2003H语音芯片(模组)是如何让雾化加湿助眠器方案 设计简单化、标准化?
  7. 利用win7漏洞进行系统登录密码破解
  8. word背景图片设置a4纸大小教程
  9. U3D游戏开发效率和UE4相比哪个高?
  10. php rrd 源码,ganalia+php+nginx+rrd 监控hadoop