perlanyevent

How to use AnyEvent::HTTP to get only part of the page?


It is necessary to read only part of the page (n bytes) and close the connection, how to do this on AnyEvent::HTTP ?


Solution

  • on_body is called repeatedly as chunks arrive. Returning false from on_body terminates the download.

    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);
          },
       );
    }
    

    Use my_http_request just like http_request, except it accepts an optional max_to_read parameter.

    For example,

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

    For example,

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