Perl https代理问题

时间:2016-12-08 16:52:18

标签: 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 $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 

我这里的实际目标是让aws-scripts-mon在代理后面的机器上运行,但它也使用LWP::UserAgent,所以如果我得到了这个,那么也可能。

添加了信息

事实证明,如果我改为http by $ua->proxy('http', 'http://proxy:8080');并访问一个http网址,然后就可以了。问题是我需要这个才能使用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.

2 个答案:

答案 0 :(得分:3)

尝试LWP::Protocol::connect

中的https://stackoverflow.com/a/17787133/44620
  use LWP::UserAgent;

  $ua = LWP::UserAgent->new(); 
  $ua->proxy('https', 'connect://proxyhost.domain:3128/');

  $ua->get('https://www.somesslsite.com');

答案 1 :(得分:1)

  $ua->proxy('https', 'https://proxy:8080');

LWP不支持使用HTTPS访问的HTTP代理。但我的猜测是你的代理根本无法使用HTTPS访问,即使它代理HTTPS请求(*),它也可以通过HTTP访问。因此,代码应该使用http://网址来访问代理,而不是https://网址:

   $ua->proxy('https', 'http://proxy:8080/');

请注意,这仅适用于常规设置,即系统上安装了IO :: Socket :: SSL并由LWP使用。特别是将PERL_NET_HTTPS_SSL_SOCKET_CLASS设置为Net::SSL或将Net::SSL显式导入程序时,将使用过时的Crypt::SSLeay,代理处理完全不同。

(*)即使代理将通过HTTP而不是HTTPS访问,连接仍然是加密的。这是由客户端请求代理使用CONNECT方法创建到原始目标的隧道,然后在此隧道内执行端到端SSL来完成的。虽然有一些代理和一些客户端支持通过HTTPS访问,但这实际上意味着在客户端和代理之间以及在此SSL连接内部建立客户端和最终目标之间的另一个SSL连接,即双重加密。