在 bash shell scipt 中,我使用多个命令行工具 ( wget
、curl
、httpie
) 来测试我的 http 服务器。
当使用例如curl 调用GET 请求时,我看到一个到我的服务器的tcp 连接打开,并在http 通信完成后立即关闭。
$ curl http://10.5.1.1/favicon.ico -o /dev/null
为了更好地测试服务器的保持活动行为,我希望在多个 http 请求/响应周期中保持 tcp 连接打开。
我能够直接从 bash 执行较差的 http 请求,如下所示:
exec 3<>/dev/tcp/10.5.1.1/80
printf "GET /\r\n\r\n" >&3
while IFS= read -r -u3 -t2 line || [[ -n "$line" ]]; do echo "$line"; done
exec 3>&-
exec 3<&-
但是因为我的测试通信要复杂得多(包括身份验证等),所以我不想用 bash 或其他脚本语言完全自己编写代码,而是想使用现有的工具。现在的想法是首先在 bash 中打开一个 tcp 套接字,然后强制某些命令行工具使用此连接而不是打开自己的套接字。也许像这样;
exec 3<>/dev/tcp/10.5.1.1/80
curl http://10.5.1.1/message.txt --use-existing-socket-fd=3
# ... do some other testing stuff ...
wget http://10.5.1.1/message.txt --use-existing-socket-fd=3
# ... do some other testing stuff ...
http http://10.5.1.1/message.txt --use-existing-socket-fd=3
exec 3>&-
exec 3<&-
使用上述工具或其他工具是否可以实现这一点?
答案1
您正在寻找的工具是socat
.由于您正在测试一台 Web 服务器,因此您可以要求它与该服务器建立永久连接(只要它不选择关闭它——相应地调整超时),一旦完成,您可以使用连接为隧道。以下是实现此目的的两种方法。
通过 Unix 套接字查询
curl
有一个--unix-socket
选项允许您通过 Unix 套接字发送 HTTP 请求并接收 HTTP 回复(谢谢 thrig,您的启发性评论)
你可以像这样使用它:
socat TCP:10.5.1.1:80 UNIX-LISTEN:/tmp/curl.sock,fork
然后,在另一个终端上:
curl --unix-socket /tmp/curl.sock http://10.5.1.1/message1.txt
curl --unix-socket /tmp/curl.sock http://10.5.1.1/message2.txt
...
通过伪 HTTP 代理进行查询
您还可以将您的隧道作为伪代理使用wget
, , curl
,... 将通过该代理进行连接。该解决方案的优点是不限于curl
。
这次,socat
监听本地 TCP 端口(例如 3128):
socat TCP:10.5.1.1:80 TCP-LISTEN:3128,fork,reuseaddr
然后,在另一个终端上:
export http_proxy='http://localhost:3128'
curl http://10.5.1.1/message.txt
wget http://10.5.1.1/message.txt
....
请注意,由于 HTTP 客户端使用代理,因此 HTTP 请求将略有改变,这可能是不可取的。
当然,这两种解决方案都不适用于多个 HTTP 服务器,因为这是接收所有请求的通道末端的 Web 服务器。
答案2
如果您在测试场景中仅使用 cURL 作为命令行工具,您可以使用其--next
选项来启用持久连接。例如,
curl -v http://google.com --next http://google.com |& grep -i connect
正在重用其输出所证明的打开连接
* Connected to google.com (142.250.179.206) port 80
* Connection #0 to host google.com left intact
* Re-using existing connection with host google.com
* Connection #0 to host google.com left intact