httpwtf.

2021-03-07 11:08:30

HTTP是现代发展的基础,从前端前后到移动。但像任何广泛的成熟标准一样,它'在壁橱里有一些时髦的骷髅。

这些骷髅中的一些是众所周知的,但真正的有用功能,其中一些是遗产奇怪依赖于每天数十亿的连接,而其中一些真的应该是' t存在。让'看看窗帘后面:

缓存从未容易容易,但HTTP缓存标题可能特别令人困惑。最糟糕的例子是没有缓存和私人的。以下响应标题是多少?

实际上,这意味着"请在所有浏览器缓存中存储此响应,但在使用它时重新验证它"实际上,这使得响应更加可缓存,因为这甚至适用于默认情况下通常可以缓存的响应。

具体而言,无缓存意味着您的内容明确可缓存,但只要浏览器或CDN想要使用它,它们应该使用If-Match或If-Formified发送请求,以便从询问所述服务器仍然响起日期首先。与此同时,私人意味着此内容是可缓存的,但仅在最终客户端浏览器中,而不是CDN或代理。

如果您尝试禁用缓存,因为响应包含安全或隐私敏感数据,而且在其他地方存放,您现在遇到了大麻烦。实际上,你可能想要没有商店。

如果您发送一个响应,包括缓存控制:No-Store标题,没有人会缓存响应,它每次都从服务器新鲜。唯一的边缘案例是如果您发送了客户端已经拥有缓存的响应时,则此赢得返回。如果要执行此操作并清除现有的高速缓存,请添加max-age = 0。

Twitter显着打这个问题。它们使用pragma:No-Cache(同一标题的传统版本)应该使用缓存控制:无存储,并意外持续所有用户'在浏览器缓存中的私有直接邮件。那个'如果您在某处分享计算机或在公共计算机上使用Twitter,您现在留下了所有私人信息,那么如果您在某处使用Twitter。可读在硬盘上。哎呀。

你'重新了解HTTP标头。 HTTP消息以包含该方法&amp的第一行开始。 URL(对于请求)或状态代码&消息(用于响应),然后它具有一系列键/值对,用于元数据,称为标头,然后它有一个主体。

你知道你还可以发送预告片,在消息正文之后追加元数据吗?

这些没有被广泛使用,但它们'重复完全标准化,理论上一切都应该支持它们,或者至少忽略它们。如果您有最初可用的元数据,它们可以很有用,并且您在发送身体之前需要等待它。

它们在一些API协议中使用,如GRPC,它们' RE主要是关于整体响应本身的元数据的价值,例如,您可以使用预告片来包括服务器时序元数据,以便在请求期间为服务器处理提供客户端性能度量。 ,附加答案完全完成后。它们'重复特别有用,例如,在长时间运行的HTTP流之后包含最终状态元数据。

它&#39仍然很少见到你' ll需要这个,但它'当你这样做时它很酷。有一些要求:

对于服务器响应预告片,客户端必须在初始请求中使用TE:预告片标题进行通告。

初始标题应指定稍后将使用的预告片字段,带有预告片:<字段名称&gt ;.

非允许某些标题作为拖车,包括内容长度,缓存控制,授权,主机和类似标准标题,这些标题通常需要解析,认证或路由请求。

要在HTTP / 1.1中发送拖车,您' LL也需要使用CHUNDED编码。 HTTP / 2同时使用单独的框架&标题,所以这是必要的。

您是否知道HTTP请求可以接收多个响应状态代码?服务器可以在最终状态(200,404或其任何内容)之前发送无限数量的1xx代码。这些充当临时答复,并且都可以包括自己的独立标题。

有一些不同的1xx代码可用:100,101,102和103.它们没有广泛使用,但在一些利基用例中,他们有一些酷炫的力量:

HTTP 100是从到目前为止请求确定的服务器的响应,并且客户端应该继续。

大多数时候,这是一个禁忌。如果你开始发送请求,你可能会继续继续,尽管它总是很高兴拥有服务器' s支持&鼓励。

虽然发送包括预期的请求,但这会变得有用:1​​00继续标题。该标题告诉服务器您希望100次响应,而且您'重新发送完整的请求身体,直到您收到它。

发送期望:100 - 继续允许服务器决定它是否需要接收整个机构,这可能需要大量的时间/带宽。如果URL&标题足以让它已经发送响应(例如,拒绝文件上传)这是一种快速有效的方法。如果服务器确实希望接收全身,则会发送临时100响应,客户端继续,然后服务器在完成时将完整请求处理完整请求。

HTTP 101用于切换协议。它说"我派你一个URL和标题,现在我想用这个连接完全不同的事情"不仅仅是不同的要求,而是完全不同的协议。

主要用例是设置WebSocket。为此,客户端发送包括这两个标题的请求:

然后从那里停止说出HTTP,并开始在此连接上交换原始的WebSocket数据。

此状态还用于在同一连接中从HTTP / 1.1升级到HTTP / 2,您可以使用它来将HTTP连接转换为基于其他TCP的各种协议。

也就是说,这个状态是HTTP / 2支持的,它使用不同的协议协商机制和一个完全不同的机制来设置WebSockets(基本上是Anywhere的支持,WebSockets始终是HTTP / 1.1现在)。

HTTP 102告诉客户端,服务器仍在处理请求,它' LL很快回复。这与100的不同之处在于现在已收到整个请求,并且所有操作现在都在服务器端发生,同时使用客户端等待。

这不是我可以辨别的'它似乎主要存在,以确保客户没有认为服务器已经简单地死亡。它在原始的HTTP规范中' s'已从许多新版本中删除。

仍然是支持和amp;在野外的真实地方使用,所以如果它很适合您的需要,那么它就可以在您的应用程序中使用它。

HTTP 103同时是一个新的&时尚状态旨在部分地取代HTTP / 2' S服务器推送功能(现在正在从Chrome中删除)。

使用HTTP 103,服务器可以早期发送一些标题,然后在完全处理请求并发送其余响应。这主要是为提供链接标题而设计的,如链接:< /style.css& gt ;; rel =预加载; AS =样式,告诉客户对其他内容,它可能希望早期加载(如样式表,JS&图像,用于网页请求)并行与完整响应。

当服务器收到需要一点处理的请求时,它通常可以' t完全发送响应标题,直到处理完成。 HTTP 103允许服务器立即轻动客户端并行下载其他内容,而不等待所请求的资源数据准备就绪。

HTTP推荐标题告诉服务器前面来自哪个页面,或者将哪个网址触发资源负载。这有一些隐私挑战,但它陷入了困境,它在大多数请求中发送,而且在您浏览互联网时发送。

特别是,它'拼写错误。这是在Web的早期添加的,而Unix拼写检查当时' t认识到推荐或引用者(正确的拼写)。当任何人注意到时,它都在在基础设施和工具中的严重用途,所以没有什么可以改变,我们必须与每个浏览器请求一起生活,每个浏览器请求都有一个拼写标题。

除非你和#39;重新编写代码来阅读这个标题,否则不是特别重要的,但对于网络兼容性的挑战,这是一个很大的比喻。

为了获得最大的混淆和损坏潜力,与此类似的新的隐私/安全标题如推荐人策略确实使用了正确的拼写。

我们讨论了HTTP 101如何使用HTTP 101请求以前设置WebSockets。完整请求所以可能如下所示:

这里的sec-websocket-accept键是有趣的。这旨在停止缓存代理意外重用WebSocket响应,以通过要求响应包含与客户端标题匹配的标题来' t理解的WebSocket响应。具体来说:

服务器哈希结果字符串,在base64中编码散列,并发送回来

这很奇怪。单个固定的随机uuid,它永远用于每个WebSocket的设置中?将字符串附加到Base64字符串而不解码,然后再次base64-ing结果?

这个想法是这种逻辑ISN' t的东西可能是偶然发生的事情,或者可以在其他地方使用的东西,以保证双方是有意开始的WebSocket连接。这确实证实了服务器或代理商在不了解它的情况下使用缓存的数据,而客户端HASN' t已被欺骗,以打开它并不了解的WebSocket连接。

这完全有效,它'广泛使用和快速&易于实施,这都是很棒的,但它疯狂地'世界上每个WebSocket连接都依赖于一个魔术UUID。

虽然我们谈论websockets:你知道websockets有效地忽略了通常适用于HTTP请求的所有COR和单一原始策略限制吗?

CORS确保在A.com上运行的JavaScript' T来自B.com的数据读取数据,除非后者明确选择在其响应标题中。

这对于许多原因非常重要,特别是包括网络 - 本地服务器(公共网页应该与您的路由器交谈)和浏览器状态(从一个域的请求应该使用cookie。来自另一个)。

不幸的是,WebSockets完全忽略了Cors,假设所有WebSocket服务器都是现代的&足以正确检查原产地标题。许多服务器没有,大多数开发人员我' ve提到这是为了Weren' t意识到这一点。

简而言之:如果您有WebSocket API,请在信任任何传入连接之前检查原始标题和/或使用CSRF令牌。

曾几何时(1982)RFC建议使用X-Prefix for消息标题是将自定义扩展与标准名称分区的好方法。

当这与电子邮件元数据相关时,这次稍后推广在HTTP标头中的用法。

这仍然是一个常见的模式,如果你浏览你浏览Web的HTTP请求,那么它会看到相当多的问题:

X-Shenanigans:无 - 这出现在Twilio' s api的每个响应中。我不知道为什么,但是在那里知道那里是安慰的。这次肯定没有神圣的人。

X-Clacks-overhead:GNU Terry Pratchett - 根据自己的书籍内的消息协议向Terry Pratchett致敬。

X-Requested-with:xmlhttproquest - 由各种js框架附加,包括jQuery,以清楚地区分Ajax请求从资源请求(它可以' t包括如此自定义标题)。

X-Recruiting:<俗气的音高,让您申请工作> - 相当多的公司将这些公司添加为尝试和雇用那种读取HTTP标题的人以获得乐趣的那种人。

X-Power-by:<框架> - 用于宣传服务器正在使用的框架或技术(通常是坏主意)。

x-http-method-override - 用于设置' t的方法,因为某种原因是要求的真实方法,通常是客户或网络限制。大多数是现在一个坏主意,但仍然很受欢迎和amp;由相当多的框架支持。

X转发 - 用于:< ip> - 许多代理&amp使用的缺勤标准;负载均衡器在上游请求中包含原始请求者' IP。

每个人都是奇怪而精彩的方式,但一般的模式大多是一个坏主意,新的(2011)RFC现在正式阻止了它的使用。

问题是许多非标准标题最终确实成为标准。如果发生这种情况,如果您使用了X-prefix,则现在必须更改名称(打破所有现有实现)或标准化X-prefix(完全击败前缀的点,并将令人讨厌的噪音添加到名称中的令人讨厌的噪音) 。

互联网上几乎所有的网络形式都以不必要的混淆和amp提交数据;长缠绕的内容型:应用程序/ X-WWW-Form-Form-URL编码标题。

在1997年的RFC for HTTP中定义了用于内容编码的解析规则,它需要所有实现来处理X-GZIP和X-COMPRESS等同于GZIP和压缩。

用于配置Web页面框架的标准标题现在是Forever X-Frame-Options,而不仅仅是框架选项 同样,我们有X-Content-Type-Options,X-DNS预取控制,X-XS-Protection和各种X-Forwarded- * CDN /代理标题,所有这些都被广泛实现,并且已成为正式或 Fefacto标准标题在广泛使用中。 如果要使用自定义标题,只需使用自定义标题名称,' s未标准化为其他人。 如果您真的想避免碰撞,请考虑命名为它,但是如果您的谷歌在30秒后出现的标准标题,则通常相当安全地&#39。 标准化很难,当你仔细看时,HTTP充满了奇怪的角落和奇怪的细节。 让我知道你对Twitter的看法。