Perl https代理问题
我似乎无法通过代理获取https 例如:Perl https代理问题,perl,lwp,lwp-useragent,Perl,Lwp,Lwp Useragent,我似乎无法通过代理获取https 例如: require LWP::UserAgent; my $ua = LWP::UserAgent->new; $ua->timeout(10); $ua->proxy('https', 'https://proxy:8080'); # $ua->proxy(['https'], 'https://proxy:8080'); # Fails # $ua->env_proxy; # This also fails. my $r
require LWP::UserAgent;
my $ua = LWP::UserAgent->new;
$ua->timeout(10);
$ua->proxy('https', 'https://proxy:8080');
# $ua->proxy(['https'], 'https://proxy:8080'); # Fails
# $ua->env_proxy; # This also fails.
my $response = $ua->get('https://aws.amazon.com/cloudwatch/');
if ($response->is_success) {
print $response->decoded_content; # or whatever
}
else {
die $response->status_line;
}
结果:
500无法连接到test.pl第17行的aws.amazon.com:443(超时)
但是如果我用curl(也是wget)尝试相同的代理,效果就很好
$ curl --head --proxy https://proxy:8080 https://aws.amazon.com/cloudwatch/
HTTP/1.1 200 Connection established
HTTP/1.1 200 OK
Server: Server
Date: Thu, 08 Dec 2016 16:42:01 GMT
Content-Type: text/html;charset=UTF-8
Content-Length: 214187
Perl版本
$ perl -MLWP -le "print(LWP->VERSION)"
6.15
$ perl --version
This is perl, v5.10.1 (*) built for x86_64-linux-thread-multi
我也尝试过使用和不使用这些:
export HTTPS_VERSION=3
export PERL_NET_HTTPS_SSL_SOCKET_CLASS="Net::SSL"
export PERL_LWP_ENV_PROXY=1
export PERL_LWP_SSL_VERIFY_HOSTNAME=0
我在这里的实际目标是在代理后面的机器上工作,但它也使用LWP::UserAgent
,因此,如果我让它工作,那么它可能也会工作
添加信息
事实证明,如果我通过
$ua->proxy('http','http://proxy:8080');
并访问http url,然后它就可以正常工作了。问题是我需要它来处理https
mon put instance data.pl的错误是:
./mon-put-instance-data.pl --mem-util --disk-space-util --disk-path=/
ERROR: Failed to call CloudWatch: HTTP 500. Message: Can't connect to monitoring.eu-west-1.amazonaws.com:443 (timeout)
LWP::Protocol::https::Socket: connect: timeout at /usr/local/share/perl5/LWP/Protocol/http.pm line 47.
在中找到
LWP不支持使用使用HTTPS访问的HTTP代理。但我的猜测是,您的代理根本无法使用HTTPS访问,也就是说,即使代理HTTPS请求(*),它也可以使用HTTP访问。因此,代码应该使用http://
URL来访问代理,而不是https://
URL:
$ua->proxy('https', 'http://proxy:8080/');
请注意,这仅适用于通常的设置,即在系统上安装IO::Socket::SSL并由LWP使用的情况下。特别是将PERL_NET_HTTPS_SSL_SOCKET_CLASS设置为NET::SSL
或显式地将NET::SSL
导入程序时,在代理处理完全不同的情况下,将使用过时的
(*)即使代理将通过HTTP而不是HTTPS访问,连接仍然是加密的。这是由客户端使用该方法请求代理创建到原始目标的隧道,然后在此隧道内执行端到端SSL来完成的。虽然也有一些代理和一些客户端支持通过HTTPS访问,但这基本上意味着在客户端和代理之间建立SSL连接,在该SSL连接内,在客户端和最终目标之间建立另一个SSL连接,即双重加密。对不起。查看错误报告,似乎有一个通过代理打开的关于https的错误:不过,在这个答案()中,似乎有人找到了解决方法。这篇文章的日期是2013年,但可能值得一试。
成功地向CloudWatch报告了指标。
如果解决方法奏效,在bug报告中添加一条注释可能对其他好的建议非常有帮助。我做到了:为什么你用require
而不是use
?为什么程序顶部没有使用strict
和使用警告'all'
?这些对于任何Perl程序都是必不可少的。我明白你的意思,但我只是简单地从CPAN做了一个快速复制和粘贴,这就是使用LWP:Useragent的示例的样子。OP使用的是LWP 6.15,上面说的是$ua->proxy('https'),'http://proxyhost:proxyport/');
不起作用。@ThisSuitesBlack不:事实上,OP说使用https://
访问代理不起作用,正是这一点(使用https://
而不是http://
访问代理)才是真正的问题。感谢您指出OP使用的版本,因为我错过了这个细节。您的猜测似乎是错误的。我尝试了$ua->proxy('https','https://proxy:8080');代码>但仍有500无法连接到aws.amazon.com:443(超时)在test.pl第16行。
您的建议似乎也无法解释为什么curl--head--proxyhttps://proxy:8080 https://aws.amazon.com/cloudwatch/
有效。@JonasElfström:根据您的评论,您再次尝试了代理的https://
,而不是http://
。此外,如果将http://
或https://
放在那里,curl将忽略,因为(从--proxy
的文档中):没有指定协议,http://和所有其他协议将被视为http代理。。这意味着https://proxy
,http://proxy
,whatever://proxy
或代理将被一视同仁。@JonasElfström:这很奇怪,因为这与另一个答案中的connect方法相同。
$ua->proxy('https', 'https://proxy:8080');
$ua->proxy('https', 'http://proxy:8080/');