in reply to Re: LWP handlers examples?
in thread LWP handlers examples?

It's strange that the message is printed twice since it is being called once!!! Why?

I added some code lines to trace the handlers at any moment, but as $ua->handlers() require an HTTP::Response object, I had to split the $ua->get() calls, and an extra call must be added at the beginning, giving:

#!perl use strict; use warnings; use LWP::UserAgent qw( ); my $ua = LWP::UserAgent->new(); my $url = 'http://www.google.com/'; my $resp; $resp = $ua->get($url); print($resp->status_line(), "\n"); show(1); print("Added:\n"); $ua->add_handler(response_header => sub { print "HANDLER\n"; }); show(2); $resp = $ua->get($url); print($resp->status_line(), "\n"); show(3); print("Removed:\n"); $ua->remove_handler('response_header'); show(4); $resp = $ua->get($url); print($resp->status_line(), "\n"); show(5); sub show { print(join(" ", @_, $ua->handlers('response_header', $resp)), "\n"); }

Output:

200 OK 1 HASH(0x183657c) Added: 2 HASH(0x183657c) HASH(0x1b79944) HANDLER HANDLER 200 OK 3 HASH(0x183657c) HASH(0x1b79944) Removed: 4 200 OK 5

It seems that there is a default handler installed, and I would expect that trace lines 4 and 5 to show the same hash as line 1, not an empty list of handlers.

BTW, I changed your original test program to use a WWW::Mechanize object, and got the same output as you.

Replies are listed 'Best First'.
Re^3: LWP handlers examples?
by almut (Canon) on Aug 12, 2009 at 21:51 UTC

    After a bit of RTFM-ing, reading the source and experimenting, I think the %matchspec is supposed to be used something like this:

    use LWP::UserAgent qw( ); my $ua = LWP::UserAgent->new(); my $url = 'http://www.google.com/'; my $resp; $resp = $ua->get($url); print($resp->status_line(), "\n"); show(1); print("Added:\n"); $ua->add_handler( response_header => sub { print "HANDLER\n"; }, owner + => "myfunc"); show(2); $resp = $ua->get($url); print($resp->status_line(), "\n"); show(3); print("Removed:\n"); $ua->remove_handler('response_header', owner => "myfunc"); show(4); $resp = $ua->get($url); print($resp->status_line(), "\n"); show(5); sub show { print(join(" ", @_, $ua->handlers('response_header', $resp)), "\n"); } __END__ 200 OK 1 HASH(0x8c2440) Added: 2 HASH(0x8c2440) HASH(0x93b0e0) HANDLER HANDLER 200 OK 3 HASH(0x8c2440) HASH(0x93b0e0) Removed: 4 HASH(0x8c2440) 200 OK 5 HASH(0x8c2440)

    where "myfunc" is some self-chosen name that you use to identify the callback for removal.

    (When you dump the hashes, you can see that the one associated with the internal handler (HASH(0x8c2440)) has owner => 'LWP::UserAgent::parse_head')

    As you can see, the internal callback remains intact this way.

      This code works OK, even if I change it to use Mechanize instead of UserAgent, but does not work inside my original program... remove_handler() removes all available handlers, including the internal, ignoring %matchspec.

      print "Hdl1: ".join(" ",$mech->handlers('response_header', $mech->re +sponse()))."\n"; $mech->add_handler(response_header => \&response, owner => "vitoco") +; print "Hdl2: ".join(" ",$mech->handlers('response_header', $mech->re +sponse()))."\n"; $mech->add_header('If-Modified-Since', time2str($current)) if $curre +nt; my $resp = $mech->get($url, ':content_file' => "$file.tmp"); $mech->delete_header('If-Modified-Since') if $current; $mech->remove_handler('response_header', owner => "vitoco"); print "Hdl3: ".join(" ",$mech->handlers('response_header', $mech->re +sponse()))."\n"; print "Hdl4: ".join(" ",$mech->handlers('response_header', $resp))." +\n";
      Hdl1: HASH(0x1f87dbc) Hdl2: HASH(0x1f87dbc) HASH(0x1f9d174) Hdl3: Hdl4:

      I changed de example to use :content_file, and stil works, so it is not that. Note that Hdl3 and Hdl4 uses different response objects (or the same, obtained from different ways).

Re^3: LWP handlers examples?
by ikegami (Patriarch) on Aug 12, 2009 at 20:06 UTC

    It's strange that the message is printed twice since it is being called once!!! Why?

    I suspect two responses were received, the first being a redirect.

      You are right on this... change the unnamed sub to show that:

      $ua->add_handler(response_header => sub { print("HANDLER:", $_[0]->status_line(), "\n"); });

      That will be another thing I'll have to manage...