0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

HTTP标头有什么问题?

LiveVideoStack 来源:LiveVideoStack 作者:Mark Nottingham 2020-08-10 16:41 次阅读

在过去的十年中,HTTP社区一直忙于对Web协议现代化,对核心规范进行了多次修订与扩展,从HTTP/2以及现在的 HTTP/3。不幸的是,从最初到现在我们定义和使用HTTP header的方式并没有什么大的改变,由于未指定的Headers(以及处理方式的多样性)引起的互通性问题,为开发人员带来很多痛苦,甚至引发安全问题。

●HTTP标头有什么问题?●

大多数Web开发人员都熟悉HTTP标头;如Content-Length、Cache-Control和Cookie之类。它们会携带请求和响应的元数据,通常,这部分数据是消息发送者由于某种原因无法放入正文内容的信息,或者是消息接收者无需查看正文内容即可获得的信息。 因为标头需要由许多不同的客户端和服务器,代理服务和CDN处理(通常在消息的生存期内不止一次),所以大家希望它们易于处理,高效解析并且定义明确句法。 HTTP将头值(更恰当的说是字段值,因为它们也可能出现在主体后面的尾部字段中)定义为一个约束很少的“八进制序列”(即字节),尽管建议是ASCII字节。它还建议在ABNF中定义标题,如果用逗号分隔字段的值,则可以将同名的多个字段组合在同一行上。 因此,每个标题字段都有自己的唯一定义,需要知道它才能解析值。一些领域作者使用ABNF来做到这一点;另一些人使用示例。有些只是让你根据你以前看到的价值观来猜测。 例如,考虑年龄年限标题。它是核心HTTP规范的一部分,所以它应该是定义明确的,而且它只是一个简单的整数。

Age: 42

由此ABNF指定:

Age = delta-secondsdelta-seconds = 1*DIGITDIGIT = %x30-39 ; 0-9

起初这似乎很简单——0到9之间数字的一个到多个实例。但在实际考虑中,如果一个实现遇到这些现实标题中的任何一个,它应该做什么:

Age: 0, 60Age: 60, 0Age: 50mAge: abc234Age: 60;ms=212

它不是那么简单,因为测试真正的缓存需要用年限显示。 因此,当同一个人正在编写生成和消耗消息头的代码而没有其他人时,示例或ABNF可能是一个足够的定义,但如果有多个实现生成和解析值,则互操作性是很糟的。 每个标题作者都必须记住要解决一个问题列表,这些问题涉及如何处理重复值、案例规范化、无论是单个项目还是列表等等。通常,他们不会处理这些问题,这意味着开发者通常以不同的方式自行选择。 未充分指定的消息头也是安全问题的来源;如果实现解析消息头的方式不同,它们的行为可能会不同,从而导致Response Splitting这类的攻击。 浏览器供应商已经足够关注这些问题,开始像CSP算法那样定义头。也就是说,他们费力地定义解析和序列化算法,然后创建测试用例。这种方法对字段语法的模糊性较小,实现之间的差异较小。然而,它仍然是一次性的;它只有助于澄清特定标题的算法。对于规范的作者来说,去努力并确保它是正确的也是很累的-所以大多数标题作者都不会费心。它还为实现者创建了大量繁忙的工作,因为他们需要分别实现每个新的头的解析器

●引入结构化领域●

HTTP工作组已经非常清楚了这类问题,几年前我们开始尝试定义一些更好的方法,使人们可以使用这些东西来创建新的字段。经过几次尝试后,我们确定了一种最初称为结构化标题的方法,但我们现在(更正确地)称之为“结构化字段”。 结构化字段是一个定义良好的数据类型库,在HTTP头和拖车中可能有用,包括字符串、Tokens、布尔值、整数、小数和字节序列作为原子“Item”类型,以及这些项的列表和字典。重要的是,它定义了每种类型的精确解析和序列化算法,以及错误处理和详细的测试套件-所有这些都有助于确保互操作性。 这允许新头字段的作者根据这些类型定义它。例如,他们可以说“这是一个字符串列表”,人们将知道如何使用一个现成的库来明确地解析和生成标头,而不是编写特定于头的代码。

Example-Header: "blue", "sort of red", "green"每个项目也可以有参数,或键/值对的额外信息。参数是一种重要的可扩展性机制,它允许消息头随着时间的推移而演变。

Example-Header: "blue"; websafe, "sort of red"; author="sue", "green"

递归的形式也很有限;列表和字典值也可以包含列表,例如:

Example-Header: people=(joanna stacy), places=("new york" "rome") 内部列表中的每个项目以及内部列表本身都可以进行参数化。 你可能会注意到,这些消息头看起来很像许多现有的HTTP字段。这是通过设计实现的;不仅对开发人员来说是舒适的,它还允许通过结构化字段实现生成许多现有字段,并且通常它们也可以被解析。例如,许多Cache-Control报头都是有效的“结构化字段”,即使它没有定义为一个:

Cache-Control: max-age=3600, immutable

很不幸你还不能将结构化字段用于现有的标头,也无法仅通过查看它来判断给定字段是否是结构化字段;你必须知道它的定义值,因为结构化字段至少在现在才用于新字段。

●使用结构化字段获得更好的性能●

指定新字段更容易,并使它们更安全和更可互操作,这对HTTP来说是一个显著的改进。如果结构化字段也能帮助HTTP性能呢?他们有两种方法可以帮助你。显然,这些都是投机性的好处,但它们仍然是有趣的谈论。 首先是解析效率。由于传统的HTTP消息头是文本形式的,解析器必须接触字符串中的每个字节,有时需要多次,有时会将其复制并重新复制到内存的不同部分。这是一个固有的低效过程,HTTP/2和HTTP/3是二进制协议而不是文本协议的原因之一。 在结构化字段之前,我们对此无能为力,因为HTTP消息头的定义非常松散。结构化字段中定义良好的数据类型会改变这一点。现在,我们可以定义一个新的,二进制序列化的任何头使用他们。 二元结构化字段是定义这种序列化的草案建议,以定义这样的序列化。它使用HTTP/2(和/3)SETTINGS机制来协商对替代序列化的支持,并利用结构化字段与许多现有标题字段的语法的相似性将其返回到一组已经广泛使用的标题字段上,如果它们无法解析,则返回到不透明的文本。 二进制序列化将帮助性能多少?由于预期会减少CPU负载,因此它应该减少请求处理的延迟并提高可伸缩性。我们还没有真实的统计,但是如果你考虑许多标题所采取的路径-从JavaScript到浏览器,然后再到CDN,通过多个CDN节点到源服务器,再到应用程序代码本身。累积节省的潜力是有吸引力的。 结构化字段可能有助于性能的第二种方法是通过提高压缩效。HTTP/2为头和拖车字段引入了HPACK压缩。虽然它的前身SPDY使用GZIP,但由于CRIME攻击,它被发现是不安全的。因此,HPACK(及其继承者QPACK)通过引用整个字段值来压缩字段;如果它的任何一部分发生变化,它就不能使用以前的引用(有时会对压缩效率产生令人惊人的影响)。 之所以选择整值粒度,是因为通用解析器无法理解字段值的结构;为了安全起见,我们必须确保攻击者无法通过猜测部分字段值来探测加密。 对于结构化字段,现在有一种潜在的方法可以使压缩算法对字段中的单个数据类型而不是整个值进行操作。

Cache-Control: max-age=3600, s-maxage=7200, must-revalidate

例如,考虑以下Cache-Control字段: 使用HPACK和QPACK,整个字段值存储在动态表中,并且只能由具有完全相同值的未来消息引用。如果我们将其解析为结构化字段并存储单个数据类型,我们可以存储:

lmax-age

l3600

ls-maxage

l7200

lmust-revalidate

这些变量中的每一个都可以在将来的标头中出现时分别引用,从而使压缩算法更精细,而且效率更高。 早期的原型表明,使用这种技术的提升对于Web浏览器连接来说效率非常低的,因为它们的标题往往是高度重复的,用多个字节(字段值中的每种类型都有一个字节)替换HPACK中的1字节引用实际上会造成伤害。 对于从多个客户端携带流量的连接——例如反向代理和源服务器上游的CDN所看到的流量——好处可能更明显;需要更多的实验。

●长期改善HTTP●

如果上面描述的反向导入技术被捕获,未来版本的HTTP(或HTTP/2和HTTP/3的扩展)可以大大减少使用中的非结构化消息头的数量。 二进制结构化字段草案描述了两种实现方法。如果字段的语法与结构化字段兼容-至少在大多数情况下-它可以作为一个发送,当失败时返回到明文标题。 没有兼容语法的标题需要另一种方法。例如,Date、Last-Modified、Expires和类似的消息头永远不可能是有效的结构化字段。但是,可以将日期表示为整数,结构化字段可以传递整数。 所以,就有这样的标题:

Date: Thu, 09 Apr 2020 09:06:50 GMT

可能会在适当的转译跳点上表示为:

SF-Date: 1586423210

这为我们提供了一种方法,可以将所有通用消息头和额外的元信息作为结构化字段发送。

●立即使用结构化字段●

结构化字段规范正处于标准化的最后阶段,这意味着它很快会成为一个RFC。目前我们已经有多个实例,包括在Chrome中,许多新的安全头(例如Fetch元数据)都是结构化的。 同时,可以通过具体实现来了解它们是如何工作的。例如,Python http_sfv库允许从命令行解析它们。 如果你定义了新的消息头(无论它们是针对整个的Web还是仅针对HTTP API)都可以在RFC发布后开始使用结构化字段。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 服务器
    +关注

    关注

    12

    文章

    8106

    浏览量

    82485
  • HTTP
    +关注

    关注

    0

    文章

    464

    浏览量

    30310
  • 结构化
    +关注

    关注

    0

    文章

    26

    浏览量

    10264

原文标题:使用结构化的标头字段改善HTTP

文章出处:【微信号:livevideostack,微信公众号:LiveVideoStack】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    鸿蒙原生应用开发-网络管理HTTP数据请求

    @ohos.net.http.d.ts中导入http命名空间。 2.调用createHttp()方法,创建一个HttpRequest对象。 3.调用该对象的on()方法,订阅http响应
    发表于 03-29 17:51

    为什么变频电机铭牌了额定频率,变频范围,却不额定转速?

    请教各位老师: 为什么变频电机铭牌了额定频率,变频范围,却不额定转速?要用50*60/P去算吗?可是极对数也没啊。。吗变频器里的额定转速怎么填呢?灰常激动的等待各位老师解答! 我那台
    发表于 12-13 07:04

    HTTP 中GET 和 POST 的区别

    一、概述 HTTP 的请求报文 GET 方法的特点 POST 方法的特点 GET 和 POST 的区别 二、HTTP 的请求报文 首先我们要解决的第一个问题是:GET 和 POST 是什么? GET
    的头像 发表于 11-11 14:40 590次阅读
    <b class='flag-5'>HTTP</b> 中GET 和 POST 的区别

    稳压二极管并联使用什么问题

    稳压二极管并联使用,什么问题
    发表于 10-17 07:18

    23张图带你弄懂HTTP协议!

    HTTP 协议发明到现在,经过了几次版本修改,分别是HTTP/0.9,HTTP/1.0,HTTP/1.1以及HTTP/2。现在市面上主要
    发表于 10-16 15:57 534次阅读
    23张图带你弄懂<b class='flag-5'>HTTP</b>协议!

    功放老是跳掉保护是什么问题

    功放老是跳掉保护是什么问题? 功放作为一种常见的音响设备,主要是用于放大电子音乐信号,使其产生更强的音响效果。然而在使用过程中,有些用户可能会遇到功放老是跳掉保护的问题,这会影响到音响的正常
    的头像 发表于 09-13 15:29 4606次阅读

    pcb仿真能解决什么问题

    pcb仿真能解决什么问题?  PCB(Printed Circuit Board,印刷电路板)是一种在电气和电子设备中应用广泛的基础元件。随着技术的不断发展,PCB设计也进入了数字化和智能化的时代
    的头像 发表于 08-29 16:40 1065次阅读

    什么是HTTP?什么是HTTPS?HTTP与HTTPS的区别在哪?

    每天都在上网,在搜索东西的时候,你有发现网址有什么不同吗?本文就来谈谈HTTP与HTTPS有什么不同。
    的头像 发表于 08-27 09:15 1487次阅读
    什么是<b class='flag-5'>HTTP</b>?什么是HTTPS?<b class='flag-5'>HTTP</b>与HTTPS的区别在哪?

    老电工都看不出的配电箱有什么问题

    小编看到有电友在网上分享一张他接好的配电箱,不仅乱,还有很多问题,我们一起来帮他找找他接的配电箱有些什么问题吧!能找到3个错误以上的,都是老电工!
    发表于 08-20 12:06 264次阅读
    老电工都看不出的配电箱有<b class='flag-5'>什么问题</b>

    33.033 HTTP协议 初识HTTP协议

    编程HTTP
    充八万
    发布于 :2023年07月19日 14:28:59

    esptool.FatalError无法连接到ESP8266,等待数据包超时怎么解决?

    的工作......并且不再可能上传,我总是得到 “esptool.FatalError:无法连接到 ESP8266:等待数据包超时” 我的猜测是因为串行连接第一张草图,现在很忙……不知道。 我尝试
    发表于 05-25 12:13

    如何通过AT命令向ESP8266-01发出HTTP或HTTPS请求?

    : NodeMCU\\r\\nConnection: close\\r\\n\\r\\n 但它不起作用,有时会出现像波特率这样的错误输出,但仍然不是,我只收到 HTML 2.0 BAD 请求的或什么都没有... 有人可以帮我吗?
    发表于 05-19 08:33

    HTTP的状态消息

     HTTP状态消息是指HTTP服务器在响应客户端请求时返回的状态信息。状态消息由数字状态码和可选的文本描述组成,主要有以下几种类型
    发表于 05-06 16:01 292次阅读

    如何获得完整的execute-from-flash和驱动程序集?

    描述文件中的填充物。应用程序按预期链接(从闪存运行)。 问题:申请/项目(附件)问题吗?如何获得完整的 execute-from-flash 和驱动程序集?为什么 MCUXpresso 创建了一个不运行的项目?
    发表于 04-28 07:04

    如何对Google Cloud IoT Core Pub/Sub的http POST发送请求?

    我正在 lua 中开发一个项目,使用 ESPlorer IDE,它需要 ESP8266 通过 http 客户端 POST 请求将遥测事件发送到谷歌云物联网核心,该请求必须具有与以下类似的格式
    发表于 04-27 07:17