【问题标题】:Multiple Protocols - Correct Implementation多种协议 - 正确实施
【发布时间】:2015-06-05 23:22:28
【问题描述】:

我正在检查我的浏览器和 Google 之间的一些 HTTP 交换,它引发了这个问题。

简而言之,我的浏览器 (Firefox 36.0.4) 正在发出 HTTP/1.1 请求,而 Google 正在响应 HTTP/2.0;在请求的协议中没有尝试响应。我知道大部分 HTTP/2.0 规范已经通过 SPDY 以随意的方式实现了,但这似乎与客户端的协商很糟糕。

我认为在标头中声明协议的目的是服务器将能够确定它应该如何响应客户端,这是通过以下三种方式之一:

1.客户端已经请求了服务器的首选协议,所以服务器继续正常的请求

2. 客户端已请求服务器支持的另一个协议版本,服务器在请求协议中做出响应,但包含指示其首选协议的升级标头。客户端可以请求升级,此时服务器将发送 101 Switching Protocols 响应并切换到首选协议。

3. 客户端请求了不支持或过时的协议,服务器在升级标头中发送 426 Upgrade Required 响应,其中包含支持的协议(按优先级降序排列);客户端必须使用支持的协议重复请求。

4. 客户重新使用了完全不受支持的主要协议版本;例如HTTP/2.x,而服务器只支持 HTTP/1.x。服务器响应 505 HTTP Version Not Supported

与谷歌的交流不是这样做的;这是不好的做法还是我错过了什么?

一个例子,随机选择:

https://plus.google.com/u/0/_/notifications/frame?querystring=blahblahblah

GET /u/0/_/notifications/frame?querystring=blahblahblah HTTP/1.1
Host: plus.google.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-GB,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: https://www.google.co.uk/?gfe_rd=cr&ei=Lc8bVcXFOKbj8we_uIKYDg&gws_rd=ssl
Cookie: NID=67=iZxcMVTvg-6PsQIUpZ5tSPL-7-uJdls3vdci3afLmoLCpD5JOq0NfzhTnnpcCW9ymbXsn3GRGxfSgYlXGEk9XmnbUne0LCPrUc_ahhpc5wV6n-GZ8F7s-JS-JWgZWEwri-GaWXK1vgyRw7jMbqEiAUSRCzs1Fr1K6ZUIH0EpJdlwZD-K26MJNazpyHL_vZ5k4m8NrtFDkAoYPw; OTZ=2759671_52_56_123900_52_436380; SID=DQAAAP0AAAAqKgGz5aFNESd464Z_jUsmTi7JQfEKsuWkGZVJe8QvdbOPTZpL5ZNjKSsSSg9QvJglP-aMNLrgn2b7MsDF_4Z7Ebe1X347Cd3-j3ktLedgmq9nRO92hxEseqf974VNumrst-XqMj9Oq_xf-KDz-CDEJ1XiqWZYVHurV-IrXib5ei7x9dqlLF2NSPYLaCxlrwKdjCQX-FDDB03FWEuE7dIMYs3BQ-_NU5fG9os6I6r6ABy9mkiy84rraZFVthd38VJF5z2WYmgQ55QJPr9EDpSA5VKH1tbW6XyLjZLt5EEEj1xoqRF4EguRkIOiG8IiqRs49GnwqQSCpTw3ROW-jNDI; HSID=A7u8vyQI-v7jJSEbS; SSID=AOojY4hDLYgnSjUrK; APISID=z23KH1a0VsBukvMu/ARaOeOni08HfbGg6R; SAPISID=5iTgyxKDRPP7fNtF/AdiFbKNYN04h7n6cu; PREF=ID=cc54787f58f50d42:U=8e10581450dbe3b5:FF=0:LD=en:TM=1416091562:LM=1418086819:GM=1:S=0KVfl2hqkG8Psvwv; OGP=-5061451:-5061492:; OGPC=4061155-1:
Connection: keep-alive

HTTP/2.0 200 OK
Alternate-Protocol: 443:quic,p=0.5
Cache-Control: private, max-age=0
content-security-policy-report-only: script-src 'unsafe-inline' 'unsafe-eval' 'self' https://*.googleapis.com https://*.gstatic.com https://apis.google.com https://www.google-analytics.com https://www.googletagmanager.com https://*.talkgadget.google.com https://pagead2.googleadservices.com https://pagead2.googlesyndication.com https://tpc.googlesyndication.com https://s.ytimg.com https://www.youtube.com https://clients1.google.com https://www.google.com;report-uri /_/cspreport/es_oz_20150330.18_p0
Content-Type: text/html; charset=utf-8
Date: Wed, 01 Apr 2015 10:57:55 GMT
Expires: Wed, 01 Apr 2015 10:57:55 GMT
Server: GSE
x-content-type-options: nosniff
x-ua-compatible: IE=edge, chrome=1
X-XSS-Protection: 1; mode=block
X-Firefox-Spdy: h2-15

【问题讨论】:

  • Stack Overflow 是一个编程和开发问题的网站。这个问题似乎离题了,因为它与编程或开发无关。请参阅帮助中心的What topics can I ask about here。也许Super UserWeb Applications Stack ExchangeUnix & Linux Stack Exchange 会是一个更好的提问地点。
  • 您能否展示一个显示您描述的行为的示例请求/响应对?
  • @jww 是关于编程和开发的;它是关于如何实现 HTTP 的。如果你宁愿在别处问它,我该和谁争论?
  • @CodeCaster 我在我的问题中添加了一个示例交换

标签: http protocols google-search http2


【解决方案1】:

响应中的 HTTP 版本是服务器功能的广告,而不是响应的实际协议版本。 响应的协议版本是与请求一起发送的版本。

在过去(甚至现在),老客户端发送 HTTP/1.0 请求并让服务器以这种方式响应是很常见的:

GET / HTTP/1.0
User-Agent: Netscape/1.0

HTTP/1.1 200 OK
Content-Length: 0

<connection closed>

服务器宣称它能够使用 HTTP/1.1,但在响应中表现得像 HTTP/1.0(通过关闭连接)。

您的情况也是如此:您发出 HTTP/1.1 请求,服务器宣传它可以使用 HTTP/2.0 并以 HTTP/1.1 响应格式进行响应。

接收该响应的智能客户端可以开始向该服务器发送 HTTP/2.0。

【讨论】:

  • 谢谢,这当然是谷歌正在做的事情。然而,这在规范中并不清楚。 RFC7230 第 3.1.2 节规定响应状态行由“协议版本、空格(SP)、状态码”组成;我将协议版本作为响应使用的版本。但是您似乎表明服务器应该将其用作其首选协议的声明。我说的对吗?
  • 我刚刚检查了升级标头定义,我很确定 Google 不是规范。在这里合规。它说,"A server MAY send an Upgrade header field in any other response to advertise that it implements support for upgrading to the listed protocols, in order of descending preference, when appropriate for a future request." 那么如果升级标头是为了广告能力,那么状态行肯定应该指示响应的协议吗?这是常见做法与规范问题吗?
  • 我的猜测是谷歌服务器没有实现 HTTP/2.0 升级。当通过 TLS 协商时,它们可以使用 HTTP/2.0,但不能使用明文。因此,他们在任何其他响应中发送 Upgrade 标头是错误的(并且为 每个 响应发送它会很浪费),因为他们不支持 upgradeing 到 HTTP/2.0,它们只支持 协商 HTTP/2.0。然而,服务器能够使用 HTTP/2.0,因此它会在响应中说明这一点。
  • 这是有道理的,也是一个可行的理由;虽然我仍然不确定状态行中的协议应该是当前版本还是首选版本。无论如何,这已经足够澄清了,我知道我并没有严重误解任何事情。谢谢
  • 状态行中的协议是客户端/服务器支持的协议。允许服务器回复不同的次要版本,但不能使用不同的主要版本,除非它知道客户端支持此版本。见my response服务器如何知道客户端支持HTTP/2.0。
【解决方案2】:

这是一个 https 请求。客户端宣布在 SSL 握手中支持带有 ALPN(以前称为 NPN)扩展的 HTTP/2.0。因此服务器知道客户端可以做HTTP/2.0。如果未提供此扩展,则不允许服务器回复与客户端请求相比更高的主要 HTTP 版本。

【讨论】:

  • 啊,现在一切都说得通了;谷歌是对的,一切都很好。谢谢。
猜你喜欢
  • 2011-05-13
  • 1970-01-01
  • 1970-01-01
  • 2012-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-22
  • 1970-01-01
相关资源
最近更新 更多