Safari无法连接基于SBCL+usocket搭建的极简Web服务器
我正在使用usocket在SBCL中测试一个极简Web服务器,代码如下:
(defun create-server (port) (let* ((socket (usocket:socket-listen *hostname* port)) (connection (usocket:socket-accept socket :element-type 'character))) (unwind-protect (with-open-stream (stream (usocket:socket-stream connection)) (progn (format stream *htmlstring*) (finish-output stream))) (progn (format t "Closing sockets~%") (usocket:socket-close connection) (usocket:socket-close socket)))))
该服务器接收指定端口的任意GET请求(未做处理),并返回如下响应:
HTTP/1.1 200 OK Content-Type: text/html Connection: close Content-Length: 64 <!DOCTYPE HTML><html><body><h1>Valid Response</h1></body></html>
我承认这种实现存在协议滥用,但理论上应该可行——它在远程服务器和本地环境中,能被curl、wget等命令行工具,以及MacOS的Firefox、Chrome、Windows的Edge正常访问,唯独Safari不行,报错:
Safari Can’t Connect to the Server
Safari无法打开页面“mysite.net:8080”,因为无法连接到服务器“mysite.net”。
我尝试将*hostname*绑定到域名、IPv4地址及所有IPv4/IPv6接口,Safari Technology Preview曾成功加载一次远程服务器响应,但后续失败。我怀疑Safari发送多个请求(可能先尝试HTTPS,而服务器仅支持HTTP),导致服务器在Safari准备好处理响应前就关闭了连接,但不确定具体原因。我的问题是:让Safari能处理Web服务器响应的最低要求是什么?它似乎比其他工具和浏览器更敏感、限制更多。
更新1
我对Chrome(正常)、Firefox(正常)和Safari(异常)分别执行了tcpdump port 8080,虽未发现明显错误,但似乎支持“连接过早关闭”的推测。同时注意到Safari未发送GET请求,而Chrome和Firefox有。为清晰起见,我将时间戳重命名为ts,客户端和服务器名称分别改为client和host。
Chrome
ts IP client > host: Flags [SEW], seq 534012909, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 1451219412 ecr 0,sackOK,eol], length 0 ts IP host > client: Flags [S.E], seq 657848768, ack 534012910, win 65160, options [mss 1460,sackOK,TS val 3784271166 ecr 1451219412,nop,wscale 7], length 0 ts IP client > host: Flags [.], ack 1, win 2058, options [nop,nop,TS val 1451219440 ecr 3784271166], length 0 ts IP client > host: Flags [P.], seq 1:524, ack 1, win 2058, options [nop,nop,TS val 1451219440 ecr 3784271166], length 523: HTTP: GET / HTTP/1.1 ts IP host > client: Flags [P.], seq 1:150, ack 1, win 510, options [nop,nop,TS val 3784271195 ecr 1451219440], length 149: HTTP: HTTP/1.1 200 OK ts IP host > client: Flags [F.], seq 150, ack 1, win 510, options [nop,nop,TS val 3784271195 ecr 1451219440], length 0 ts IP client > host: Flags [.], ack 150, win 2056, options [nop,nop,TS val 1451219468 ecr 3784271195], length 0 ts IP client > host: Flags [.], ack 151, win 2056, options [nop,nop,TS val 1451219468 ecr 3784271195], length 0 ts IP host > client: Flags [R], seq 657848769, win 0, length 0 ts IP client > host: Flags [F.], seq 524, ack 151, win 2056, options [nop,nop,TS val 1451219468 ecr 3784271195], length 0 ts IP host > client: Flags [R], seq 657848919, win 0, length 0 ts IP host > client: Flags [R], seq 657848919, win 0, length 0 ts IP client > host: Flags [SEW], seq 1710339549, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 3288928666 ecr 0,sackOK,eol], length 0 ts IP host > client: Flags [R.], seq 0, ack 1710339550, win 0, length 0
Firefox
ts IP client > host: Flags [SEW], seq 626413754, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 3625754178 ecr 0,sackOK,eol], length 0 ts IP host > client: Flags [S.E], seq 1881453667, ack 626413755, win 65160, options [mss 1460,sackOK,TS val 3784031794 ecr 3625754178,nop,wscale 7], length 0 ts IP client > host: Flags [.], ack 1, win 2058, options [nop,nop,TS val 3625754209 ecr 3784031794], length 0 ts IP host > client: Flags [P.], seq 1:150, ack 1, win 510, options [nop,nop,TS val 3784031824 ecr 3625754209], length 149: HTTP: HTTP/1.1 200 OK ts IP host > client: Flags [F.], seq 150, ack 1, win 510, options [nop,nop,TS val 3784031824 ecr 3625754209], length 0 ts IP client > host: Flags [.], ack 150, win 2056, options [nop,nop,TS val 3625754239 ecr 3784031824], length 0 ts IP client > host: Flags [.], ack 151, win 2056, options [nop,nop,TS val 3625754239 ecr 3784031824], length 0 ts IP client > host: Flags [P.], seq 1:409, ack 151, win 2056, options [nop,nop,TS val 3625754895 ecr 3784031824], length 408: HTTP: GET / HTTP/1.1 ts IP client > host: Flags [F.], seq 409, ack 151, win 2056, options [nop,nop,TS val 3625754895 ecr 3784031824], length 0 ts IP host > client: Flags [R], seq 1881453818, win 0, length 0 ts IP host > client: Flags [R], seq 1881453818, win 0, length 0
Safari
ts IP client > host: Flags [SEW], seq 2577772978, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 1558328301 ecr 0,sackOK,eol], length 0 ts IP host > client: Flags [S.E], seq 4186102721, ack 2577772979, win 65160, options [mss 1460,sackOK,TS val 3784121701 ecr 1558328301,nop,wscale 7], length 0 ts IP client > host: Flags [.], ack 1, win 2058, options [nop,nop,TS val 1558328335 ecr 3784121701], length 0 ts IP host > client: Flags [P.], seq 1:150, ack 1, win 510, options [nop,nop,TS val 3784121729 ecr 1558328335], length 149: HTTP: HTTP/1.1 200 OK ts IP host > client: Flags [F.], seq 150, ack 1, win 510, options [nop,nop,TS val 3784121729 ecr 1558328335], length 0 ts IP client > host: Flags [.], ack 151, win 2056, options [nop,nop,TS val 1558328364 ecr 3784121729], length 0 ts IP client > host: Flags [F.], seq 1, ack 151, win 2056, options [nop,nop,TS val 1558328364 ecr 3784121729], length 0 ts IP host > client: Flags [.], ack 2, win 510, options [nop,nop,TS val 3784121758 ecr 1558328364], length 0 ts IP client > host: Flags [SEW], seq 3648579004, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 2532260604 ecr 0,sackOK,eol], length 0 ts IP host > client: Flags [R.], seq 0, ack 3648579005, win 0, length 0 ts IP client > host: Flags [SEW], seq 650543579, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 1158948454 ecr 0,sackOK,eol], length 0 ts IP host > client: Flags [R.], seq 0, ack 650543580, win 0, length 0 ts IP client > host: Flags [SEW], seq 698782494, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 772224008 ecr 0,sackOK,eol], length 0 ts IP host > client: Flags [R.], seq 0, ack 698782495, win 0, length 0
更新2
移除(usocket:socket-close socket)后,Safari可以正常渲染响应,无需手动刷新页面,但这会带来其他服务器问题,待解决后我会发布完整可行方案。
内容的提问来源于stack exchange,提问作者Tambarskjelve

