Re: Quitting a fetch early

Eric Bennett (bennett@hpel.cees.edu)
Wed, 24 Apr 1996 02:47:09 -0400 (EDT)


On Tue, 23 Apr 1996, Nelson Minar wrote:
> 
> working out. I'm not sure if it's because I don't get the way Perl
> does exceptions, or if this is just hard.

The interface clearly wasn't designed with this in mind...  Perhaps 
something should be done with the callback's return value.  If the 
callback is expected to return the next preferred hunk size then zero would 
indicate close the socket.

> I can think of various ways to hack around this - use a global
> variable, or pass the Response back magically through the argument to
> die(). Is there a better way?

It's the only way I see without modifying the library.  Access to the
socket/other retreival mechanism has been carefully divorced from
Protocol::collect and from the response object;  die is the only way to
close the socket.  Given that, the response object must be returned
out-of-band.  If global variables strike you as a hack you can use a
lexical within your callback to pass back the response.

Here's sorta what I mean (totally off the top of my head, so beware): 

> #!/usr/local/bin/perl
> use LWP::UserAgent;
> use HTTP::Response;
> 
  my $savedResponse;
> # callback for useragent requests - only read the first block, then quit.
> sub readUntilTitle {
>     my($data, $response, $protocol) = @_;
>     $response->add_content($data);
      $savedResponse = $response;
>     die('abort');
> }
> 
> $ua = new LWP::UserAgent;
> $ua->use_eval(0);
> 
> my $req = new HTTP::Request 'GET', $ARGV[0];
> 
> $res = eval { $ua->request($req, \&readUntilTitle, 4096); };
> # If we had a die, catch it
> if ($@) {
>     if ($@ =~ /^timeout/i) {
> 	print "Timeout error.\n";
      elsif ($@ =~ /^abort/) {
        print "Usual abort ", $@, "\n";
        $res = $savedResponse;
>     } else {
> 	print "Received error ", $@, "\n";
>     }
> }
> 
> if ($res) {
>     print $res->as_string;
> } else {
>     print "No response object.\n";
> }
>