我正在从头开始构建一个 Web 服务器以获取乐趣,并且我注意到 Chrome 的一些奇怪行为。我从 Chrome 收到的对
/
的 GET 请求的请求如下所示:
GET / HTTP/1.1
Host: localhost:8000
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.75 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
DNT: 1
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
没什么特别的,但它也向我的服务器发出另一个请求,但它不发送任何内容,这导致我的服务器永远等待传入消息。
Safari 中未发现此行为。我已将服务器设置为对每个请求响应 403,但持久连接仍然存在。此连接的目的是什么以及我应该如何处理它?我是否遗漏了 HTTP 协议中的某些内容?
HTTP/1.1 浏览器倾向于打开多个 TCP 连接。如果您的服务器一次只能对一个连接进行操作,那么您可能会陷入死锁。当每个连接准备好请求时,您应该使用线程或非阻塞 IO (
select
) 来处理每个连接。
Chrome 可能会打开一个额外的套接字,以便在第一个套接字关闭时它已准备好,但我不确定。 HTTP/1.1 没有办法取消请求/响应,除了关闭套接字之外,服务器也有可能在完成响应后发送
Connection: close
,因此浏览器正在为将来的请求做好准备。
不是答案,而是要重现的更多细节;-同样的问题,即使在第一个连接关闭后也没有 GET 请求。
设置
观察结果
需要明确的是,这种行为并不一致,有时没有额外的请求,通常有一个,有时有两个。
所以问题依然存在;这个连接是做什么用的?我们该如何应对?