我有一个文件托管在 https 服务器上,我希望能够使用openssl s_client
以下方式将其传输到我的客户端:openssl s_client -connect <my_ip:my_port>/my_file
。
目前,我可以通过运行该命令然后输入 来获取文件的内容GET my_file
,但我想自动执行此操作,以便它不是交互式的。使用-quiet
开关也没有帮助。
注意:我尝试使用它的设备没有任何其他文件传输程序,所以我坚持使用openssl
答案1
如果你真的可以使用 HTTP/0.9 那么这对你有用
printf '%s\r\n\r\n' 'GET my_file' | openssl s_client -connect <my_ip:my_port>
答案2
openssl s_client
这并不是一个特别好的工具,但它是可以做到的。让我们将其分为两部分。首先,发出 HTTP 请求,然后从响应中提取内容。
发出 HTTP 请求
这里最难的部分是s_client
当标准输入关闭时关闭连接。因此,您需要保持标准输入打开,直到连接关闭。基于这个服务器故障答案,你可以这样做:
(printf "GET $PATH HTTP/1.0\r\nHost: $HOST\r\n\r\n"; sleep 10) | \
openssl s_client -connect $HOST:443 -quiet) > /tmp/output.tmp
这里有一些很大的限制。首先,您需要设置sleep
足够长的时间以便传输可以完成。但时间不会太长,让你永远等待。其次,没有重定向处理,因此您需要一个能够直接在您请求的 URL 上提供数据的 URL,而不是302
将您带到其他地方。
提取数据
现在您已经有了一个/tmp/output.tmp
包含 HTTP 响应的文件,其中包含您的数据和一些标题。剥离标头比听起来更难,因为您可能混合使用\r\n
和\n
换行符,并且可能正在传输二进制数据。
如果您的文件是 Unix 样式文本(例如 shell 脚本),那么您可以删除所有\r
字符并删除所有内容,包括第一个空行:
tr -d '\r' < /tmp/output.tmp | sed '1,/^$/d' > /tmp/output
如果您的文件是二进制文件(例如可执行文件),那么您不能只删除字符\r
。假设你的文件的前几个字节是相当独特的(假设\xF7ELF
在这个例子中),并且假设你有 GNU grep 可用,你可以这样做:
SKIP=$(grep -aboF "$(printf "\xf7ELF")" output | head -1 | awk -F: '{print $1}')
dd ibs=1 if=/tmp/output.tmp of=/tmp/output skip=$SKIP