使用 openssl s_client 从命令行从 https 服务器获取文件

使用 openssl s_client 从命令行从 https 服务器获取文件

我有一个文件托管在 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

相关内容