【问题标题】:500 error with LWP:UserAgentLWP:UserAgent 出现 500 错误
【发布时间】:2014-11-04 10:13:09
【问题描述】:

解决了! 感谢我的每一个帮助:)

找到http://stackoverflow.com/questions/8026524/how-do-i-force-lwp-to-use-cryptssleay-for-https-requests 并解决了我的问题

use Net::SSL (); # From Crypt-SSLeay
BEGIN {
  $Net::HTTPS::SSL_SOCKET_CLASS = "Net::SSL"; # Force use of Net::SSL
  $ENV{HTTPS_PROXY} = 'http://10.0.3.1:3128';

}

我尝试了上千种不同的方式来连接到 URL

https://sis-t.redsys.es:25443/sis/entradaXMLEntidad/

我似乎无法得到 500 错误以外的其他信息。

我尝试的最新代码是

require LWP::UserAgent;

## Code added according to Sinan Ünür s comment
use Net::SSLeay;
$Net::SSLeay::trace = 2;
## End of code added

my $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 0});
$ua->agent("Mozilla/8.0");
$ua->timeout(10);
my $url = 'https://sis-t.redsys.es:25443/sis/entradaXMLEntidad/'

my $req = HTTP::Request->new( GET => $url);
$req->header( 'Accept' => 'text/html' );

# send request
my $res = $ua->request($req);

# check the outcome
if ( $res->is_success ) {
    print $res->decoded_content;
} else {
    print "Error: " . $res->status_line . "\n";
}

我尝试了有没有尝试

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

我尝试了 POST 和 GET(因为最后,我将不得不使用 POST 访问那个 URL)。

当然,我确保我能够从常规浏览器获取此页面。我确保我的代码始终能够以

的形式连接到其他页面
https + example.com:example-port + /path/to/another/page.

如果有人能帮我找出我做错了什么,我将不胜感激。

编辑 为 Sinan Ünür 的评论添加的代码产生了以下错误

DEBUG: .../IO/Socket/SSL.pm:449: socket not yet connected
DEBUG: .../IO/Socket/SSL.pm:451: socket connected
DEBUG: .../IO/Socket/SSL.pm:469: ssl handshake not started
DEBUG: .../IO/Socket/SSL.pm:504: using SNI with hostname sis-t.redsys.es
DEBUG: .../IO/Socket/SSL.pm:527: set socket to non-blocking to enforce timeout=10
DEBUG: .../IO/Socket/SSL.pm:550: ssl handshake in progress
DEBUG: .../IO/Socket/SSL.pm:560: waiting for fd to become ready: SSL wants a read first
DEBUG: .../IO/Socket/SSL.pm:570: handshake failed because socket did not became ready
Error: 500 Can't connect to sis-t.redsys.es:25443

输出是相同的,结合了我为创建 ua 想到的不同组合(带有/out 验证/SSL_version/...

my $ua = LWP::UserAgent->new; #(ssl_opts => { verify_hostname => 1, SSL_version => 'TLSv1' });

因为这里也发现了这个:http://www.perlmonks.org/?node_id=1106004


编辑2: 代码

#!/usr/bin/perl -w
use strict;

use Net::SSLeay;
$Net::SSLeay::trace = 2;

require LWP::UserAgent;

my $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 0, SSL_version => 'TLSv1:!TLSv11:!TLSv12:!SSLv2:!SSLv3'});
$ua->agent("Mozilla/8.0");
$ua->timeout(10);

my $req = HTTP::Request->new( GET => "https://sis-t.redsys.es:25443/sis/entradaXMLEntidad/");
$req->header( 'Accept' => 'text/html' );

# send request
my $res = $ua->request($req);

# check the outcome
if ( $res->is_success ) {
    print $res->decoded_content;
} else {
    print "Error: " . $res->status_line . "\n";
}

在一台机器上工作正常 perl 5.14.2 LWP:用户::代理 6.04 IO::Socket::SSL 1.76 Net::SSLeay 1.48

但不是我的 perl 5.14.2 LWP:用户::代理 6.06 IO::Socket::SSL 1.955 净::SSLeay 1.55 而且我似乎无法找到更多差异......

【问题讨论】:

  • 再次检查网址? https://sis-t.redsys.es:25443/si\n+s/entradaXMLEntidad/
  • URL 是sis-t.redsys.es:25443/sis/entradaXMLEntidad,如图所示。由于线路太长,我发布时看起来有点修改。我会尝试在主消息中修复它
  • 他们可以通过用户代理阻止你

标签: perl lwp-useragent


【解决方案1】:

(基于我在http://www.perlmonks.org/?node_id=1106240 的回答)

... sis-t.redsys.es:25443

此服务器存在一些严重问题。您使用的 IO::Socket::SSL 版本 (1.76) 的默认密码集是“ALL:!LOW”。如果此密码集与 TLS1.0 或更高版本一起使用,则连接只会挂起。您可以使用 s_client 验证这一点:

$ openssl s_client -cipher 'ALL:!LOW' -connect  sis-t.redsys.es:25443 -servername sis-t.redsys.es
CONNECTED(00000004)
... and there it hangs ...

这种问题经常出现在服务器前面的旧 F5 负载平衡器中,它只是丢弃大于 255 字节的 ClientHello 数据包。如果您不在s_client 调用中添加servername 选项,请求将神奇地成功,因为数据包现在小于255 字节。从 1.962 版(大约一年前)开始,IO::Socket::SSL 将使用更小(且更安全)的密码集来解决此类问题。

Crypt::SSLeay 使用默认的 OpenSSL 密码集,这使得在这种情况下的数据包只有 248 个字节,因此足够小。这就是它与 Crypt::SSLeay 一起使用的原因。但请注意,Crypt::SSLeay 不会根据服务器证书对主机名进行任何验证,因此容易受到中间人攻击。

使用当前版本的 IO::Socket::SSL 问题应该得到解决,也就是说,您不需要任何特殊设置,并且可以启用验证等。因此,您的最新代码在我的 IO 机器上可以正常工作: :Socket::SSL 2.002.

但是,由于您使用的是代理,因此您也应该使用最新版本的 LWP::UserAgent 和 LWP::Protocol::https,因为仅在版本中添加了对 IO::Socket::SSL 后端的适当代理支持6.06(如果您使用 Debian 或 Ubuntu 之类的衍生产品,它可能已经在 6.04 中)。虽然看起来您使用的是 LWP::UserAgent 6.06,但您没有显示 LWP::Protocol::https 的版本。这个单独的模块也必须是 6.06 版才能获得有效的代理支持。

【讨论】:

    【解决方案2】:

    首先,鉴于网站的证书不是自签名的,没有充分的理由:

    LWP::UserAgent->new(ssl_opts => { verify_hostname => 0});
    

    这让我怀疑你的问题可能与Crypt::SSLeay 有关,但我没有设置代理来测试这个。

    无论如何,除非您发现问题是由于您的爬虫被阻止,或者与您的代理设置有关,否则我会要求您运行以下代码:

    #!/usr/bin/env perl
    
    use strict;
    use warnings;
    
    use LWP::UserAgent;
    use Net::HTTPS;
    my $sc = $Net::HTTPS::SSL_SOCKET_CLASS;
    my $v = eval "require $sc; \${${sc}::VERSION}";
    print "$_\n" for $sc, $v;
    

    并在此处报告信息以及您的 perlLWP 版本。

    根据您的评论,您正在使用:

    • IO::Socket::SSL1.955
    • perl5.14.2
    • LWP::UserAgent6.06

    请补充

    use Net::SSLeay;
    $Net::SSLeay::trace = 2;
    

    到原始脚本的顶部,并使用调试输出更新您的问题。

    【讨论】:

    • 我不认为这 2 点会误导某人,对此感到抱歉。执行你的代码给出 IO::Socket::SSL 1.955 Perl 版本是 5.14.2 LWP::UserAgent 版本是 6.06
    • @squale 我只是想确保你没有使用所有东西的古老版本。鉴于情况似乎并非如此,请打开调试,并使用输出编辑您的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-07
    • 2013-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多