Perl LWP::UserAgent 针对给定服务器随机挂起 120 秒

标签 perl www-mechanize lwp lwp-useragent

我注意到在 WWW::Mechanize 中处理 response_dataresponse_done 事件之间存在大约 120 秒的延迟。使用给定的 https 网站。我使用普通的网络浏览器进行了检查,没有遇到这种缓慢的情况,所以我怀疑我必须做错什么。

这是我为追踪事件所做的(出于某种原因 use LWP::Debug qw(+) 没有做任何事情):

use WWW::Mechanize;
use Time::HiRes qw(gettimeofday);
use IO::Handle;

my $mech = WWW::Mechanize->new(
  timeout     => 3,
  autocheck   => 1,       # check success of each query
  stack_depth => 0,       # no keeping history
  keep_alive  => 50,      # connection pool
);

$mech->agent_alias( 'Windows IE 6' );
open my $debugfile, '>traffic.txt';
$debugfile->autoflush(1);

$mech->add_handler( request_send => sub {
    my $cur_time = gettimeofday();
    my $req = shift;
    print $debugfile "\n$cur_time === BEGIN HTTP REQUEST ===\n";
    print $debugfile $req->dump();
    print $debugfile "\n$cur_time ===   END HTTP REQUEST ===\n";
    return
  }
);
$mech->add_handler( response_header => sub {
    my $cur_time = gettimeofday();
    my $res = shift;
    print $debugfile "\n$cur_time === GOT RESPONSE HDRS ===\n";
    print $debugfile $res->dump();
    return
  }
);
$mech->add_handler( response_data => sub {
    my $cur_time = gettimeofday();
    my $res = shift;
    my $content_length = length($res->content);
    print $debugfile "$cur_time === Got response data chunk resp size = $content_length ===\n";
    return
  }
);
$mech->add_handler( response_done => sub {
    my $cur_time = gettimeofday();
    my $res = shift;
    print $debugfile "\n$cur_time === BEGIN HTTP RESPONSE ===\n";
    print $debugfile $res->dump();
    print $debugfile "\n===   END HTTP RESPONSE ===\n";
    return
  }
);

这里是跟踪的摘录(URL 和 cookie 被混淆了):

1347463214.24724 === BEGIN HTTP REQUEST ===
GET https://...
Accept-Encoding: gzip
Referer: https://...
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
Cookie: ...
Cookie2: $Version="1"

(no content)

1347463214.24724 ===   END HTTP REQUEST ===

1347463216.13134 === GOT RESPONSE HDRS ===
HTTP/1.1 200 OK
Date: Wed, 12 Sep 2012 15:20:08 GMT
Accept-Ranges: bytes
...
Server: Lotus-Domino
Content-Length: 377806
Content-Type: application/octet-stream
Last-Modified: Fri, 07 Sep 2012 06:25:33 GMT
Client-Peer: ...
Client-Response-Num: 1
Client-SSL-Cert-Issuer: ...
Client-SSL-Cert-Subject: ...
Client-SSL-Cipher: DES-CBC3-SHA
Client-SSL-Socket-Class: IO::Socket::SSL

(no content)
1347463216.48305 === Got response data chunk resp size = 4096 ===

1347463337.98131 === BEGIN HTTP RESPONSE ===
HTTP/1.1 200 OK
Date: Wed, 12 Sep 2012 15:20:08 GMT
Accept-Ranges: bytes
...
Server: Lotus-Domino
Content-Length: 377806
Content-Type: application/octet-stream
Last-Modified: Fri, 07 Sep 2012 06:25:33 GMT
Client-Date: Wed, 12 Sep 2012 15:22:17 GMT
Client-Peer: ...
Client-Response-Num: 1
Client-SSL-Cert-Issuer: ...
Client-SSL-Cert-Subject: ...
Client-SSL-Cipher: DES-CBC3-SHA
Client-SSL-Socket-Class: IO::Socket::SSL

PK\3\4\24\0\6\0\10\0\0\0!\0\x88\xBC\21Xi\2\0\0\x84\22\0\0\23\0\10\2[Content_Types].xml \xA2...
(+ 377294 more bytes not shown)

===   END HTTP RESPONSE ===

在“Got response data chunk”和“BEGIN HTTP RESPONSE”消息期间,您可以看到 121.5 秒的间隔。我感觉有时 LWP::UserAgent 在收到全部数据后会挂起两分钟。

你有什么线索可以从哪里来吗?

编辑这是 Wireshark 中的屏幕截图:我在 120 秒后收到 FIN/ACK 消息……

Wireshark Excerpt

谢谢

最佳答案

我认为您的交易实际上可能需要这么长时间。 LWP::UserAgent 的文档这么说

[The response_data handler] needs to return a TRUE value to be called again for subsequent chunks for the same request

所以,因为您的处理程序不返回任何内容,所以您只跟踪第一个返回的数据包

根据您的输出,前 4KB 的数据在 2.2 秒内到达,或大约每秒 2KB。整个数据的长度为 369KB,因此您预计会再收到 92 个数据包,而以每秒 2KB 的速度传输需要三分钟。你会在两分钟内得到回复,所以我认为你的时间是合理的

关于Perl LWP::UserAgent 针对给定服务器随机挂起 120 秒,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12391671/

相关文章:

javascript - WWW::Scripter 作为父类导致奇怪的错误消息

javascript - Perl/LWP 无法提交 javascript 表单

Perl透明代理

perl - 使用 apt-get 而不是 cpan 安装 perl 模块的目的

perl 只打印数组的最后一行

perl - 用解析收集数据::recdescent

javascript - 在 Perl 中使用 WWW::Scripter 模块时,如何获取尽可能多的调试流量信息?

perl - 如何获取符号链接(symbolic link)文件的绝对路径?

perl - 提交表单后,如何使用 WWW::Mechanize 下载文件?

perl - WWW::Scripter 的身份验证问题