根据我的理解,HTTP连接可以是keep-alive
或close
。
我向服务器发送了一个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
?
答案 0 :(得分:26)
<强> TL; DR:Chrome将此响应标头解释为keep-alive
,并在Firefox关闭每个连接时保持持久连接。
当我尝试优化网站的页面加载时间时,我偶然发现了这个问题。
在引用的RFC中,我没有找到任何关于如何正确处理Connection
标头中的多个条目的信息。在我看来,实现可能会从两个可能性中选择:
close
,则可以在传输后关闭连接所以,我需要找出答案。让我们进行更深入的调查:
我注意到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实现者应该准备好与它进行互操作。
服务器可能正在“互操作”并且会拖延您的冗余。