2017-04-11 82 views
4

有必要只读取部分页面(n字节)并关闭连接,如何在AnyEvent :: HTTP上执行此操作?如何使用AnyEvent :: HTTP获取页面的一部分?

+2

它看起来像池上的答案几乎肯定你在找什么,但值得指出的是,“范围”功能内置于HTTP协议中以准确处理这种类型的请求。如果你正在通话的服务器支持它,你可以像这样为你的请求添加一个头部:'Range:bytes = 0-4096'来获得第一个4KB。 –

+0

@GrantMcLean,谢谢,有用的信息! – Dmitry

回答

5

on_body随着块到达而被重复调用。从on_body返回错误将终止下载。

sub my_http_request { 
    my $cb = pop; 
    my ($method, $url, %args) = @_; 

    croak("Unsupported: on_body")   if $args{on_body}; 
    croak("Unsupported: want_body_handle") if $args{want_body_handle}; 

    my $max_to_read = delete($args{max_to_read}); 

    my $data; 
    return http_request(
     $method => $url, 
     %args, 
     on_body => sub { 
     #my ($chunk, $headers) = @_; 
     $data .= $_[0]; 
     return !defined($max_to_read) || length($data) < $max_to_read; 
     }, 
     sub { 
     my (undef, $headers) = @_; 
     $cb->($data, $headers); 
     }, 
    ); 
} 

使用my_http_request就像http_request,除了它接受一个可选的参数max_to_read

例如,

my $cb = AnyEvent->condvar(); 
my_http_request(
    GET => 'http://...', 
    ... 
    max_to_read => ..., 
    $cb, 
); 

my ($data, $headers) = $cb->recv(); 

例如,

my $done = AnyEvent->condvar(); 
my_http_request(
    GET => 'http://...', 
    ... 
    max_to_read => ..., 
    sub { 
     my ($data, $headers) = @_; 
     ... 
     $done->send(); 
    }, 
); 

$done->recv(); 
+0

我打算让'max_to_read'可选。固定。还删除了已删除代码的注释,并使参数顺序与原始函数保持一致。 – ikegami