Perl:HTTP::Tiny 连接停止,get() 从不 returns

Perl: HTTP::Tiny Connection Stalls, get() never returns

我在 fedora35 上使用 perl-HTTP-Tiny-0.080 并尝试检查 URL 的状态以确定 return 代码。我的脚本运行良好,直到它遇到这个特定的 URL 和 sophos.com 的 PDF。脚本只是停止,并且 get() 或 head() 调用 new() 永远不会 returns。我也试过设置超时,但它似乎被忽略了。

use HTTP::Tiny;  
use Net::FTP::Tiny qw(ftp_get);
my $url = "https://news.sophos.com/wp-content/uploads/2020/02/CloudSnooper_report.pdf";
my $response = HTTP::Tiny->new(timeout => 2)->get($url);
print "status: $response->{status} $url\n";

印刷品从未达到。手动使用 wget 成功,而尝试将代理设置为“HTTP/Tiny”以外的内容失败。

my $response = HTTP::Tiny->new(agent => "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36")->get($url);

此代码是我用来检查缓冲区中的一系列 URL 以确定它们是否为 404 并应删除或仍在工作的链接的较大脚本的一部分。

我不确定我可以提供哪些进一步的信息。

您为 news.sophos.com 设置的 URL 重定向到 www.sophos.com 的其他 URL。后一个服务器受 Akamai CDN 保护:

$ dig www.sophos.com
...
www.sophos.com.         169     IN      CNAME   www.sophos.com.edgekey.net.
www.sophos.com.edgekey.net. 469 IN      CNAME   e6203.b.akamaiedge.net.
e6203.b.akamaiedge.net. 300     IN      A       23.60.192.131

如果请求不是浏览器发送的典型请求,Akamai 的机器人保护可能会出现一些奇怪的行为。这可能会失败,状态代码为 403,但也会像您遇到的那样挂起,即 tarpitting 客户端。另请参阅请求 SSL 连接超时奇怪的 CURL 特定网站 SSL 证书问题。另请参阅 为什么 Akamai 边缘服务有时不发送任何响应,使连接超时,这顺便描述了您在 www.sophos.com.

中遇到的类似问题

在这种特定情况下,只需将 Accept header 添加到对我有用的请求中:

my $response = HTTP::Tiny->new(default_headers => { Accept => '*/*' })->get($url);

请注意,当 Akamai 调整其爬虫程序检测后,此解决方法将来可能不再有效。

I've also tried to set a timeout and it appears to be ignored.

这是一个已知问题,在使用 TLS 1.3 时尤为明显 - 此处就是这种情况。参见 Sometimes, timeout can fail to fire #146