2017-04-11 89 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