Nginx 忽略客户端的 HTTP 1.0 请求并以 HTTP 1.1 响应

Nginx 忽略客户端的 HTTP 1.0 请求并以 HTTP 1.1 响应

我正在使用nginx/php5-fpm代码进行测试

<?php

header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found"); 
// also tested: header("Status: 404 Not Found");

echo $_SERVER["SERVER_PROTOCOL"];

并强制使用HTTP 1.0使用curl命令。

curl -0 -v 'http://www.example.com/test.php'


> GET /test.php HTTP/1.0

< HTTP/1.1 404 Not Found
< Server: nginx
< Date: Sat, 27 Oct 2012 08:51:27 GMT
< Content-Type: text/html
< Connection: close
< 
* Closing connection #0
HTTP/1.0

正如你所见,我已经使用 发出请求HTTP 1.0,但 nginx 回复我HTTP 1.1

赏金

@MaximDounin、@MichaelHampton 已经提供了对规范的答案,谢谢。我为未来的读者稍微扩展了这个问题:

Q. 当客户端请求 HTTP 1.0 时,响应 HTTP 1.1 有什么好处?Google 的做法不是更合理吗,即当客户端请求 1.0 时,响应 1.0?

答案1

这是正常且预期的行为,根据 RFC 2616

至少有条件地符合此规范的应用程序应在其消息中使用 HTTP 版本“HTTP/1.1”,并且必须对任何与 HTTP/1.0 不兼容的消息这样做。有关何时发送特定 HTTP 版本值的更多详细信息,请参阅 RFC 2145。

RFC 2145 对此进行了扩展

HTTP 服务器应发送一个响应版本,该版本等于该服务器至少有条件兼容的最高版本,并且其主版本小于或等于请求中收到的版本。HTTP 服务器不得发送它至少有条件不兼容的版本。如果无法使用客户端请求中使用的主版本发送响应,服务器可以发送 505(不支持 HTTP 版本)响应。

如果已知或怀疑客户端错误地实现了 HTTP 规范,则 HTTP 服务器可以发送较低的响应版本,但这不应该是默认设置,并且如果请求版本是 HTTP/1.1 或更高版本,则不应该这样做。

用英语来说,这意味着:如果客户端发送 HTTP/1.0 请求,则可以接受 HTTP/1.0 响应或 HTTP/1.1,但优先考虑 HTTP/1.1。

这样做的原因是,一端可以通告其可以支持的最高版本的 HTTP,这样另一端就可以选择升级其协议支持(如果可能)。然后两端将决定它们都可以使用哪个协议版本。如 RFC 2145 所述,这种设计还有助于处理有缺陷的实现。

当时还设想 HTTP 协议可能会有更多版本,包括次要版本和主要版本,这些规则旨在帮助确保互操作性。谷歌对 RFC 一无所知的做法可能会失败一次HTTP/2.0已完成。(您知道它的草案形式是快闪记忆体

答案2

问:客户端请求HTTP 1.0时响应HTTP 1.1有什么好处?

它实际上会向您发送符合 HTTP/1.0 的响应。它不会使用任何需要 HTTP/1.1 的功能(例如 keepalive)。

这样做的原因是因为这对服务器来说是一种廉价的方式来表达:

“嘿,我知道你用 HTTP/1.0 给我发了一个请求,但我只是想让你知道我能够 HTTP/1.1. 以下是对您原始请求的回复:[...]

(注意:如果服务器支持虚构的 HTTP/1.8,它将会响应该 HTTP/1.8。)

在某些情况下,这可以为您节省额外的请求。如果您需要从服务器获取 3 个不同的 URI,则可以将第一个 URI 发送为 HTTP/1.0,然后升级到您和服务器都支持的最高版本以进行后续请求。

相关内容