如何使用 openssl 获取 HTTP GET 请求的结果?

如何使用 openssl 获取 HTTP GET 请求的结果?

我需要使用 openssl 在 shell 脚本中执行一些 HTTP GET 请求。我现在用来执行此操作的行如下所示。这是解析以下格式的 XML 响应的内容。

<Result>success</Result>

<Result>failure</Result>

echo -e "GET /test HTTP/1.1\r\nHost:$(hostname)\r\n\r\n" | openssl 2>&1 s_client -quiet -connect server-url:443 | grep -o -P --color '(?<=Result\>).*(?=\</Result)'

这有效并相应地返回字符串“成功”或“失败”。我面临的问题是,命令openssl在执行 GET 请求后不会终止,而是停留在那里等待更多输入。我相信这是由于隐式-ign_eof阻止了由选项引起的自动终止-quiet。我尝试使用该-no_ign_eof选项,但这会导致openssl命令在 GET 请求收到响应之前终止,因此如果我使用该选项,我无法获取响应的内容。

我如何修改此命令,以便我可以通过 stdin 传递 GET 请求(因为我想将其放入循环中,所以需要这样做)但让命令openssl在每次请求后终止?

答案1

真的应该做的是使用专为获取 Web 资源而设计的工具,例如curlwget或 libwww-perl 的GET命令。如果没有可用的工具,您应该让系统管理员安装适当的工具。

解决了这个问题...

openssl由于 Web 服务器未关闭连接,因此命令不会终止。

请记住,默认情况下,HTTP 会在每次请求后保持连接打开,以优化性能。一个请求完成后,可以通过同一连接发送另一个请求,而不必关闭并重新打开新连接。

如果您想指示服务器关闭连接,您可以发送Connection: closeHTTP 标头。

答案2

IBM 使用 Perl 进行引导下载,我建议使用 Perl,直到您获得正确安装 curl 的批准,因为它与操作系统捆绑在一起。具体来说,他们的dnf_aixtoolbox.sh脚本使用如下行lwp-download来下载包:rpm.rte

    LDR_CNTRL=MAXDATA=0x80000000@DSA /usr/opt/perl5/bin/lwp-download https://public.dhe.ibm.com/aix/freeSoftware/aixtoolbox/ezinstall/ppc/dnf_bundle_aix_73.tar

当您没有尝试下载文件时,LWP 库为不同用途提供了许多不同的示例。

答案3

另一个简单(但可能更糟糕)的解决方案是使用 HTTP/1.0 而不是 HTTP/1.1。

答案4

有一个新的场景,它提出了之前在本主题中讨论的几个要点。
一个与 curl 相关,另一个与 tlsv1.3 相关

首先,我使用 curl 时发现 curl 会将“#”解释为新 URL 的开头。我发现其他人在使用其他特殊字符时也发现了同样的问题。在这种情况下,URL 被截断,curl 失败。

标题

确切的问题是使用不合规范的字符来扩展 URL 名称。Web 开发人员在“.html”后添加数据。我遇到的是 ---------.html#<date>
输入后,curl 会在 # 处截断 URL。如果我对其进行编码-------.html%23<date>,然后通过浏览器将编码后的 URL 粘贴到网站中,它会再次对编码后的字符进行编码,结果为“未找到页面”。

Web 开发人员正在将数据附加到 URL,这样每次用户请求更改表格(通常是一个表格)时,不必发送新的网页,只需通过 JSON 发送表格数据而不是整个网页即可更新网页。

我认为 curl 近期不会发生改变。因此,如果要测试此类功能,则必须使用 OpenSSL 来调出 URL。我找到了一个不安全的网站,该网站恰好在服务器路径中使用了 #。我使用 OpenSSL 对此进行了测试,并成功完成。

echo -e "GET /#/Methods HTTP/1.1\r\nHost: eu.httpbin.org\r\nConnection: Close\r\n\r\n" | openssl s_client -quiet -state -connect eu.httpbin.org:443

因此,可以得出结论,OpenSSL 不会将'#'URL 视为特殊字符。Curl 将输入解析为 HTML,其中'#'是与 HTML 锚点相关的特殊字符。

第二个问题与最初的主题有些相关,即在 tlsv1.3 中使用相同的 OpenSSL 技术。OpenSSL 没有报告任何错误,但它在第二次“读取 R 块”后停止。

echo -e "GET / HTTP/1.1\r\nHost: cmegroup.com\r\nConnection: Close\r\n\r\n" | openssl 2>&1 s_client -CAfile firefoxCertBundle.pem -cert privClientCrt.pem -key privClient.key -tls1_3 -ciphersuites TLS_AES_256_GCM_SHA384 -quiet -state -connect cmegroup.com:443
    SSL_connect:before SSL initialization
    SSL_connect:SSLv3/TLS write client hello
    SSL_connect:SSLv3/TLS write client hello
    SSL_connect:SSLv3/TLS read server hello
    SSL_connect:TLSv1.3 read encrypted extensions
    depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global 
    Root CA
    verify return:1
    depth=1 C = US, O = DigiCert Inc, CN = DigiCert SHA2 Secure Server CA
    verify return:1
    depth=0 C = US, ST = Illinois, L = Chicago, O = Chicago Mercantile Exchange Inc, 
    CN = www.cmegroup.com
    verify return:1
    SSL_connect:SSLv3/TLS read server certificate
    SSL_connect:TLSv1.3 read server certificate verify
    SSL_connect:SSLv3/TLS read finished
    SSL_connect:SSLv3/TLS write change cipher spec
    SSL_connect:SSLv3/TLS write finished
    SSL_connect:SSL negotiation finished successfully
    SSL_connect:SSL negotiation finished successfully
    SSL_connect:SSLv3/TLS read server session ticket
    SSL_connect:SSL negotiation finished successfully
    SSL_connect:SSL negotiation finished successfully
    SSL_connect:SSLv3/TLS read server session ticket

相关内容