如何解读“连接:保持活着,关闭”?

时间:2012-07-12 00:53:14

标签: http standards

根据我的理解,HTTP连接可以是keep-aliveclose

我向服务器发送了一个HTTP请求:

GET /page1/ HTTP/1.1
Host: server.com
Connection: keep-alive

并回复:

HTTP/1.1 200 OK
Connection: keep-alive, close

基本上,我认为服务器存在问题,因为keep-alive, close之类的响应不明确。

但是,作为接收器,我们应该如何处理这样的消息?我们应该解释此标头值为keep-alive还是close

4 个答案:

答案 0 :(得分:26)

<强> TL; DR:Chrome将此响应标头解释为keep-alive,并在Firefox关闭每个连接时保持持久连接。

当我尝试优化网站的页面加载时间时,我偶然发现了这个问题。

在引用的RFC中,我没有找到任何关于如何正确处理Connection标头中的多个条目的信息。在我看来,实现可能会从两个可能性中选择:

  1. 如果有多个条目,您可以选择最符合您需求的条目
  2. 如果内部有close,则可以在传输后关闭连接
  3. 所以,我需要找出答案。让我们进行更深入的调查:

    我注意到Chrome总是发送带有Connection: keep-alive的HTTP / 1.1请求,而我的Apache默认配置始终使用Connection: close标头进行响应。所以我开始调查并使用Wireshark查看TCP段。

    Chrome必须获取14个元素来显示网站,其中大多数是图片或css文件等静态内容。它完成了14个TCP连接并花费了大量时间(大约1,2秒)。在每次请求图像(例如)之后,出现了一个将FIN标志设置为1的TCP段。

    那么Chrome与Firefox又如何呢? Chrome似乎与一台服务器的并发连接数最多为6. Firefox具有更精细的配置,可以区分持久性(最大值为6,见于about:config)和非持久性(不同来源的最大数量差异很大) )。但是等等...... Chrome和Firefox都在发送带有Connection: keep-alive的HTTP / 1.1请求标头,因此两者都应限制为6(因为这是打开持久连接的请求)。

    我决定尝试一个简单的技巧,并将以下行添加到Web根文件夹中的.htaccess

    <ifModule mod_headers.c>
    Header set Connection keep-alive
    </ifModule>
    

    服务器现在响应:

    Connection: keep-alive, close
    

    现在我再次看一下TCP片段:Chrome现在只有9个连接到我的服务器,只有3个FIN标志设置为1.所以这个技巧似乎有效。但为什么有这三个连接,在数据传输后关闭连接?这些是PHP请求,因为HTTP标头X-Powered-By: PHP/5.4.11已确认。

    那么Firefox呢?还有那14个请求!

    如何解决这个问题并使fcgi进程与keep-alive一起工作?

    我将以下行添加到httpd.conf配置的virtualhost部分:

    KeepAlive On
    KeepAliveTimeout 5
    MaxKeepAliveRequests 100
    

    并删除.htaccess中添加的内容。现在服务器没有发送任何令人困惑的问题 - Connection: keep-alive, close,但只发送Connection: keep-alive,一切正常!

    <强>结论:

    连接字段设置为

    的标头
    HTTP/1.1 200 OK
    Connection: keep-alive, close
    
    Chrome会将{p>解释为keep-alive,而Firefox似乎会关闭每个连接。这似乎取决于实际的实施。

    因此,如果您愿意实现客户端来处理包含Connection: keep-alive, close的响应头,那么如果您需要多个请求,我建议尝试使用keep-alive。可能发生的最糟糕的事情是:服务器将关闭连接,你需要再次连接(这正是你原本应该拥有的另一个选项!)

答案 1 :(得分:3)

这意味着服务器不会执行持久连接,并会在此请求后关闭连接。

答案 2 :(得分:2)

答案是RFC 7230 — 6.1. Connection。它说:

  

Connection头字段的值具有以下语法:

 Connection        = 1#connection-option
 connection-option = token

在Internet RFC用语中,1#connection-option表示至少一个,最多任意数量的connection-option。这意味着可能有多个选项,其中接收者将选择它喜欢的任何人。这不是歧义,这是一种选择。

答案 3 :(得分:2)

您正在使用HTTP/1.1,并且您正在指定Connection: keep-alive

HTTP/1.1下,默认情况下所有连接都是保持活动状态,并且不推荐使用Connection: keep-alive标头,因此您不应发送它。

Connection: keep-alive是在所谓的HTTP/1.0+天中使用的一点点黑客。 (+代表“为了让它发挥作用所必需的黑客”。)

HTTP:权威指南中,作者:Brian Totty,Marjorie Sayer,Sailu Reddy,Anshu Aggarwal,David Gourley by O'Reilly,我们读到:

  

不推荐使用Keep-alive,并且不再记录当前的HTTP / 1.1规范。但是,保持活动握手仍然被浏览器和服务器相对普遍使用,因此HTTP实现者应该准备好与它进行互操作。

服务器可能正在“互操作”并且会拖延您的冗余。