1

我正在检查我的浏览器和谷歌之间的一些 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
4

2 回答 2

1

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

于 2015-04-01T19:00:29.993 回答
0

响应中的 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。

于 2015-04-01T12:14:39.720 回答