Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the WWW-Mechanize CPAN distribution.

Report information
The Basics
Id: 8109
Status: resolved
Priority: 0/
Queue: WWW-Mechanize

People
Owner: MARKSTOS [...] cpan.org
Requestors: perlbug20041024.z.jp [...] xoxy.net
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: (no value)
Fixed in: (no value)



Subject: WWW::Mechanize back() broken after reload()
According to the WWW::Mechanize documentation, $mech->back() is ``the equivalent of hitting the "back" button in a browser.'' Now, in a browser, hitting Reload doesn't affect the history. But calling $mech->reload() *does* affect the history: it pushes the current page on to the history stack again. So if you press Reload followed by Back in a browser, it takes you to the previous page. But if you call $mech->reload() followed by $mech->back(), you stay at the same page. The test program below demonstrates this. Either 1) the documentation for $mech->back() should be updated to reflect this anomaly, or 2) the code should be changed so that WWW::Mechanize behaves more like a browser. I prefer option 2). #!/usr/bin/perl use WWW::Mechanize; my $mech = WWW::Mechanize->new(); $mech->get("http://www.yahoo.com"); $mech->get("http://www.google.com"); $mech->reload(); $mech->back(); print $mech->title, "\n"; # should print Yahoo!, but prints Google instead
RT-Send-CC: www-mechanize-development [...] lists.sourceforge.net
[guest - Sun Oct 24 19:34:05 2004]: Show quoted text
> According to the WWW::Mechanize documentation, $mech->back() is ``the > equivalent of hitting the "back" button in a browser.'' Now, in a > browser, hitting Reload doesn't affect the history. But calling > $mech->reload() *does* affect the history: it pushes the current page > on > to the history stack again. So if you press Reload followed by Back > in > a browser, it takes you to the previous page. But if you call > $mech->reload() followed by $mech->back(), you stay at the same page. > The test program below demonstrates this. > > Either 1) the documentation for $mech->back() should be updated to > reflect this anomaly, or 2) the code should be changed so that > WWW::Mechanize behaves more like a browser. I prefer option 2). > > #!/usr/bin/perl > use WWW::Mechanize; > my $mech = WWW::Mechanize->new(); > $mech->get("http://www.yahoo.com"); > $mech->get("http://www.google.com"); > $mech->reload(); > $mech->back(); > print $mech->title, "\n"; # should print Yahoo!, but prints Google > instead
I agree the this sounds like a bug, and I'm in favor of the code rather than the docs being update. You can submit a patch yourself (preferably updating the test suite as well), or another Mech user/developer will get to it eventually. Mark
Here's another serious problem with $mech->back(): after using it even once, Mech no longer uses cookies. In fact, its cookie_jar object has been undefined, as shown by this test script: #!/usr/bin/perl -w use strict; use WWW::Mechanize; my $mech = WWW::Mechanize->new(cookie_jar => {}); $mech->get("http://www.yahoo.com"); $mech->get("http://www.google.com"); print "before=$mech->{'cookie_jar'}\n"; $mech->back(); print "after=$mech->{'cookie_jar'}\n"; # One would expect that the cookie jar would be the same before and after # $mech->back() is called. But instead, it prints: # before=HTTP::Cookies=HASH(0x8166d88) # Use of uninitialized value in concatenation (.) or string at mtest line 9. # after=
Date: Tue, 02 Nov 2004 13:37:16 +0100
From: Dominique Quatravaux <dom [...] idealx.com>
To: bug-www-mechanize [...] rt.cpan.org
Subject: [cpan #8109] back() reload()ed!
RT-Send-Cc:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Dear Mechanists, Here's the patch that closes #8109: the back() button in Mech now behaves according to expectation, documentation and testation. Best of everything, - -- Dominique QUATRAVAUX Ingénieur senior 01 44 42 00 08 IDEALX -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.4 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org iD8DBQFBh398MJAKAU3mjcsRAncnAJ4yQerI7vJpgt9vODEw36s9v5xsDgCePuhd qfRYmz7UFWGecx1bLWta6jI= =LyVJ -----END PGP SIGNATURE-----
diff -Nr -U3 --exclude=CVS www-mechanize.WALK-TREE-CONTEXT/lib/WWW/Mechanize.pm www-mechanize/lib/WWW/Mechanize.pm --- www-mechanize.WALK-TREE-CONTEXT/lib/WWW/Mechanize.pm Tue Nov 2 13:24:48 2004 +++ www-mechanize/lib/WWW/Mechanize.pm Tue Nov 2 13:29:44 2004 @@ -325,7 +325,7 @@ =head2 $mech->reload() Acts like the reload button in a browser: Reperforms the current -request. +request. The history (as per the L</back> method) is not altered. Returns the L<HTTP::Response> object from the reload, or C<undef> if there's no current request. @@ -337,7 +337,8 @@ return unless $self->{req}; - return $self->request( $self->{req} ); + local $self->{inhibit_page_stack} = 1; + return $self->request( $self->{req}); } =head2 $mech->back() @@ -2024,12 +2222,19 @@ sub _push_page_stack { my $self = shift; + # Hook for reload() and maybe future code (e.g. 302 chasing, + # frames) that may want to fetch stuff without altering the history. + return 1 if $self->{inhibit_page_stack}; # Don't push anything if it's a virgin object if ( $self->{res} ) { my $save_stack = $self->{page_stack}; $self->{page_stack} = []; - push( @$save_stack, $self->clone ); + my $clone = $self->clone; + # Huh, LWP::UserAgent->clone() ditches cookie_jar? Copy it over now. + $clone->{cookie_jar} = $self->cookie_jar; + push( @$save_stack, $clone ); + if ( $self->stack_depth > 0 ) { while ( @$save_stack > $self->stack_depth ) { shift @$save_stack; @@ -2043,6 +2248,10 @@ sub _pop_page_stack { my $self = shift; + + # Hook for reload() and maybe future code (e.g. 302 chasing, + # frames) that may want to fetch stuff without altering the history. + return 1 if $self->{inhibit_page_stack}; if (@{$self->{page_stack}}) { my $popped = pop @{$self->{page_stack}}; diff -Nr -U3 --exclude=CVS www-mechanize.WALK-TREE-CONTEXT/t/local/back.t www-mechanize/t/local/back.t --- www-mechanize.WALK-TREE-CONTEXT/t/local/back.t Thu Jan 1 01:00:00 1970 +++ www-mechanize/t/local/back.t Tue Nov 2 12:38:39 2004 @@ -0,0 +1,168 @@ +#!perl + +use strict; +use Test::More tests => 38; +use lib 't/local'; +use LocalServer; +use HTTP::Daemon; +use HTTP::Response; + +=head1 NAME + +=head1 SYNOPSIS + +This tests Mech's Back "button". Tests were converted from t/live/back.t, +and subsequently enriched to deal with RT ticket #8109. + +=cut + +BEGIN { + use_ok( 'WWW::Mechanize' ); + delete @ENV{ qw( http_proxy HTTP_PROXY PATH IFS + CDPATH ENV BASH_ENV) }; + +} + +my $mech = WWW::Mechanize->new(cookie_jar => {}); +isa_ok( $mech, "WWW::Mechanize" ); +ok(defined($mech->cookie_jar()), + 'this $mech starts with a cookie jar'); + +isa_ok((my $server = LocalServer->spawn(html => <<'HTML')), "LocalServer"); +<html> +<head><title>%s</title></head> +<body>Whatever. +<a href="images/">Images</a> +<a href="/scripts">Scripts</a> +<a href="/ports/">Ports</a> +<a href="modules/">Modules</a> +<form action="/search.cgi"> +<input type="text" name="q"> +<input type="submit"> +</form> +</body> +</html> +HTML + +$mech->get($server->url); +ok( $mech->success, 'Fetched OK' ); + +my $first_base = $mech->base; +my $title = $mech->title; + +$mech->follow_link( n=>2 ); +ok( $mech->success, 'Followed OK' ); + +$mech->back(); +is( $mech->base, $first_base, "Did the base get set back?" ); +is( $mech->title, $title, "Title set back?" ); + +$mech->follow( "Images" ); +ok( $mech->success, 'Followed OK' ); + +$mech->back(); +is( $mech->base, $first_base, "Did the base get set back?" ); +is( $mech->title, $title, "Title set back?" ); + +is( scalar @{$mech->{page_stack}}, 0, "Pre-search check" ); +$mech->submit_form( + fields => { 'q' => "perl" }, +); +ok( $mech->success, "Searched for Perl" ); +like( $mech->title, qr/search.cgi/, "Right page title" ); +is( scalar @{$mech->{page_stack}}, 1, "POST is in the stack" ); + +$mech->head( $server->url ); +ok( $mech->success, "HEAD succeeded" ); +is( scalar @{$mech->{page_stack}}, 1, "HEAD is not in the stack" ); + +$mech->back(); +ok( $mech->success, "Back" ); +is( $mech->base, $first_base, "Did the base get set back?" ); +is( $mech->title, $title, "Title set back?" ); +is( scalar @{$mech->{page_stack}}, 0, "Post-search check" ); + +=head2 Back and misc. internal fields + +RT ticket #8109 reported that back() is broken after reload(), and +that the cookie_jar was also damaged by back(). We test for that: +reload() should not alter the back() stack, and the cookie jar should +not be versioned (once a cookie is set, hitting the back button in a +browser does not cause it to go away). + +=cut + +$mech->follow( "Images" ); +$mech->reload(); +$mech->back(); +is($mech->title, $title, "reload() does not push page to stack" ); + +ok(defined($mech->cookie_jar()), + '$mech still has a cookie jar after a number of back()'); + +# Now some other weird stuff. Start with a fresh history by recreating +# $mech. +SKIP: { + eval "use Test::Memory::Cycle"; + skip "Test::Memory::Cycle not installed", 1 if $@; + + memory_cycle_ok( $mech, "No memory cycles found" ); +} + +$mech = WWW::Mechanize->new(); +isa_ok( $mech, "WWW::Mechanize" ); +$mech->get( $server->url ); +ok( $mech->success, 'Got root URL' ); + +my @links = qw( + /scripts + /ports/ + modules/ +); + +is( scalar @{$mech->{page_stack}}, 0, "Pre-404 check" ); + +my $server404 = HTTP::Daemon->new or die; + +die "Cannot fork" if (! defined (my $pid404 = fork())); +END { + local $?; + kill KILL => $pid404; # Extreme prejudice intended, because we do not + # want the global cleanup to be done twice. +} + +if (! $pid404) { # Fake HTTP server code: a true 404-compliant server! + while(my $c = $server404->accept()) { + while($c->get_request()) { + $c->send_response(new HTTP::Response(404)); + $c->close(); + } + } +} + +$mech->get($server404->url); +is( $mech->status, 404 , "404 check"); + +is( scalar @{$mech->{page_stack}}, 1, "Even 404s get on the stack" ); + +$mech->back(); +is( $mech->uri, $server->url, "Back from the 404" ); +is( scalar @{$mech->{page_stack}}, 0, "Post-404 check" ); + +for my $link ( @links ) { + $mech->get( $link ); + warn $mech->status() if (! $mech->success()); + is( $mech->status, 200, "Get $link" ); + + $mech->back(); + is( $mech->uri, $server->url, "Back from $link" ); +} + +SKIP: { + eval "use Test::Memory::Cycle"; + skip "Test::Memory::Cycle not installed", 1 if $@; + + memory_cycle_ok( $mech, "No memory cycles found" ); +} + +
Date: Tue, 02 Nov 2004 17:30:16 +0100
From: Dominique Quatravaux <dom [...] idealx.com>
To: bug-www-mechanize [...] rt.cpan.org
Subject: [cpan #8109] back() reload()ed, sans inhibition
RT-Send-Cc:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hello, Here is my renewed patch on the same issue, please ignore the previous one. I've taken Andy's comment into account, by removing the - ->{inhibit_page_stack} flag and refactoring ->request() into - ->_push_page_stack() followed by ->_update_page() (new method). Best regards, - -- Dominique QUATRAVAUX Ingénieur senior 01 44 42 00 08 IDEALX -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.4 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org iD8DBQFBh7YYMJAKAU3mjcsRAmXjAJ9BDj/OkdEVKLn9wC9n7EcOf/MVuwCfS37n Rh/UQcvkIZW8aHrh7B4wpIU= =gvXY -----END PGP SIGNATURE-----
diff -Nr -U3 --exclude=CVS www-mechanize.WALK-TREE-CONTEXT/lib/WWW/Mechanize.pm www-mechanize/lib/WWW/Mechanize.pm --- www-mechanize.WALK-TREE-CONTEXT/lib/WWW/Mechanize.pm Tue Nov 2 13:24:48 2004 +++ www-mechanize/lib/WWW/Mechanize.pm Tue Nov 2 17:09:24 2004 @@ -324,8 +320,8 @@ =head2 $mech->reload() -Acts like the reload button in a browser: Reperforms the current -request. +Acts like the reload button in a browser: reperforms the current +request. The history (as per the L</back> method) is not altered. Returns the L<HTTP::Response> object from the reload, or C<undef> if there's no current request. @@ -335,9 +331,9 @@ sub reload { my $self = shift; - return unless $self->{req}; + return unless defined(my $request = $self->{req}); - return $self->request( $self->{req} ); + $self->_update_page($request, $self->_make_request( $request, @_ )); } =head2 $mech->back() @@ -1686,35 +1866,8 @@ $self->_push_page_stack(); } - $self->{req} = $request; - $self->{redirected_uri} = $request->uri->as_string; - - my $res = $self->{res} = $self->_make_request( $request, @_ ); - - # These internal hash elements should be dropped in favor of - # the accessors soon. -- 1/19/03 - $self->{status} = $res->code; - $self->{base} = $res->base; - $self->{ct} = $res->content_type || ""; - - if ( $res->is_success ) { - $self->{uri} = $self->{redirected_uri}; - $self->{last_uri} = $self->{uri}; - } else { - if ( $self->{autocheck} ) { - $self->die( "Error ", $request->method, "ing ", $request->uri, ": ", $res->message ); - } - } - - $self->_reset_page; - if ($self->is_html) { - $self->update_html($res->content); - } else { - $self->{content} = $res->content; - } - - return $res; -} # request + $self->_update_page($request, $self->_make_request( $request, @_ )); +} =head2 $mech->update_html( $html ) @@ -1926,6 +2103,48 @@ return; } +=head2 $mech->_update_page($request, $response) + +Updates all internal variables in $mech as if $request was just +performed, and returned $response. The page stack is B<not> altered by +this method, it is up to caller (e.g. L</request>) to do that. + +=cut + +sub _update_page { + my ($self, $request, $res) = @_; + + $self->{req} = $request; + $self->{redirected_uri} = $request->uri->as_string; + + $self->{res} = $res; + + # These internal hash elements should be dropped in favor of + # the accessors soon. -- 1/19/03 + $self->{status} = $res->code; + $self->{base} = $res->base; + $self->{ct} = $res->content_type || ""; + + if ( $res->is_success ) { + $self->{uri} = $self->{redirected_uri}; + $self->{last_uri} = $self->{uri}; + } else { + if ( $self->{autocheck} ) { + $self->die( "Error ", $request->method, "ing ", $request->uri, ": ", $res->message ); + } + } + + $self->_reset_page; + if ($self->is_html) { + $self->update_html($res->content); + } else { + $self->{content} = $res->content; + } + + return $res; +} # _update_state + + =head2 $mech->_extract_links() Extracts links from the content of a webpage, and populates the C<{links}> @@ -2029,7 +2248,11 @@ my $save_stack = $self->{page_stack}; $self->{page_stack} = []; - push( @$save_stack, $self->clone ); + my $clone = $self->clone; + # Huh, LWP::UserAgent->clone() ditches cookie_jar? Copy it over now. + $clone->{cookie_jar} = $self->cookie_jar; + push( @$save_stack, $clone ); + if ( $self->stack_depth > 0 ) { while ( @$save_stack > $self->stack_depth ) { shift @$save_stack; diff -Nr -U3 --exclude=CVS www-mechanize.WALK-TREE-CONTEXT/t/local/back.t www-mechanize/t/local/back.t --- www-mechanize.WALK-TREE-CONTEXT/t/local/back.t Thu Jan 1 01:00:00 1970 +++ www-mechanize/t/local/back.t Tue Nov 2 12:38:39 2004 @@ -0,0 +1,168 @@ +#!perl + +use strict; +use Test::More tests => 38; +use lib 't/local'; +use LocalServer; +use HTTP::Daemon; +use HTTP::Response; + +=head1 NAME + +=head1 SYNOPSIS + +This tests Mech's Back "button". Tests were converted from t/live/back.t, +and subsequently enriched to deal with RT ticket #8109. + +=cut + +BEGIN { + use_ok( 'WWW::Mechanize' ); + delete @ENV{ qw( http_proxy HTTP_PROXY PATH IFS + CDPATH ENV BASH_ENV) }; + +} + +my $mech = WWW::Mechanize->new(cookie_jar => {}); +isa_ok( $mech, "WWW::Mechanize" ); +ok(defined($mech->cookie_jar()), + 'this $mech starts with a cookie jar'); + +isa_ok((my $server = LocalServer->spawn(html => <<'HTML')), "LocalServer"); +<html> +<head><title>%s</title></head> +<body>Whatever. +<a href="images/">Images</a> +<a href="/scripts">Scripts</a> +<a href="/ports/">Ports</a> +<a href="modules/">Modules</a> +<form action="/search.cgi"> +<input type="text" name="q"> +<input type="submit"> +</form> +</body> +</html> +HTML + +$mech->get($server->url); +ok( $mech->success, 'Fetched OK' ); + +my $first_base = $mech->base; +my $title = $mech->title; + +$mech->follow_link( n=>2 ); +ok( $mech->success, 'Followed OK' ); + +$mech->back(); +is( $mech->base, $first_base, "Did the base get set back?" ); +is( $mech->title, $title, "Title set back?" ); + +$mech->follow( "Images" ); +ok( $mech->success, 'Followed OK' ); + +$mech->back(); +is( $mech->base, $first_base, "Did the base get set back?" ); +is( $mech->title, $title, "Title set back?" ); + +is( scalar @{$mech->{page_stack}}, 0, "Pre-search check" ); +$mech->submit_form( + fields => { 'q' => "perl" }, +); +ok( $mech->success, "Searched for Perl" ); +like( $mech->title, qr/search.cgi/, "Right page title" ); +is( scalar @{$mech->{page_stack}}, 1, "POST is in the stack" ); + +$mech->head( $server->url ); +ok( $mech->success, "HEAD succeeded" ); +is( scalar @{$mech->{page_stack}}, 1, "HEAD is not in the stack" ); + +$mech->back(); +ok( $mech->success, "Back" ); +is( $mech->base, $first_base, "Did the base get set back?" ); +is( $mech->title, $title, "Title set back?" ); +is( scalar @{$mech->{page_stack}}, 0, "Post-search check" ); + +=head2 Back and misc. internal fields + +RT ticket #8109 reported that back() is broken after reload(), and +that the cookie_jar was also damaged by back(). We test for that: +reload() should not alter the back() stack, and the cookie jar should +not be versioned (once a cookie is set, hitting the back button in a +browser does not cause it to go away). + +=cut + +$mech->follow( "Images" ); +$mech->reload(); +$mech->back(); +is($mech->title, $title, "reload() does not push page to stack" ); + +ok(defined($mech->cookie_jar()), + '$mech still has a cookie jar after a number of back()'); + +# Now some other weird stuff. Start with a fresh history by recreating +# $mech. +SKIP: { + eval "use Test::Memory::Cycle"; + skip "Test::Memory::Cycle not installed", 1 if $@; + + memory_cycle_ok( $mech, "No memory cycles found" ); +} + +$mech = WWW::Mechanize->new(); +isa_ok( $mech, "WWW::Mechanize" ); +$mech->get( $server->url ); +ok( $mech->success, 'Got root URL' ); + +my @links = qw( + /scripts + /ports/ + modules/ +); + +is( scalar @{$mech->{page_stack}}, 0, "Pre-404 check" ); + +my $server404 = HTTP::Daemon->new or die; + +die "Cannot fork" if (! defined (my $pid404 = fork())); +END { + local $?; + kill KILL => $pid404; # Extreme prejudice intended, because we do not + # want the global cleanup to be done twice. +} + +if (! $pid404) { # Fake HTTP server code: a true 404-compliant server! + while(my $c = $server404->accept()) { + while($c->get_request()) { + $c->send_response(new HTTP::Response(404)); + $c->close(); + } + } +} + +$mech->get($server404->url); +is( $mech->status, 404 , "404 check"); + +is( scalar @{$mech->{page_stack}}, 1, "Even 404s get on the stack" ); + +$mech->back(); +is( $mech->uri, $server->url, "Back from the 404" ); +is( scalar @{$mech->{page_stack}}, 0, "Post-404 check" ); + +for my $link ( @links ) { + $mech->get( $link ); + warn $mech->status() if (! $mech->success()); + is( $mech->status, 200, "Get $link" ); + + $mech->back(); + is( $mech->uri, $server->url, "Back from $link" ); +} + +SKIP: { + eval "use Test::Memory::Cycle"; + skip "Test::Memory::Cycle not installed", 1 if $@; + + memory_cycle_ok( $mech, "No memory cycles found" ); +} + +
Date: Tue, 09 Nov 2004 19:31:35 +0100
From: Dominique Quatravaux <dom [...] idealx.com>
To: bug-www-mechanize [...] rt.cpan.org
Subject: [cpan #8109] back() reload()ed, sans inhibition
RT-Send-Cc:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Dear Mechanists, Here is the new-and-improved patch that takes Andy's comment into account: $mech->{inhibit_page_stack} is gone, and a new refactored function appears. Please apply to CVS HEAD. (Off-topic note: I just spent some time installing svk and this is just another insanely cool Perl package! It made my keeping track of pending patches much easier. Well worth a try for all folks working concurrently on lots of FOSS projects IMHO) Regards, - -- Dominique QUATRAVAUX Ingénieur senior 01 44 42 00 08 IDEALX -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.4 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org iD8DBQFBkQ0HMJAKAU3mjcsRAvIHAJ92+ZLT9Sfgwmar1uDcwlS2MZCkRwCffxP4 aGFogppkEDkHw2XS3e2Ra1Q= =j70l -----END PGP SIGNATURE-----
Date: Tue, 09 Nov 2004 19:34:30 +0100
From: Dominique Quatravaux <dom [...] idealx.com>
To: bug-www-mechanize [...] rt.cpan.org
Subject: [cpan #8109] back() reload()ed, sans inhibition
RT-Send-Cc:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Yeah, I know, the attachment :-/... - -- Dominique QUATRAVAUX Ingénieur senior 01 44 42 00 08 IDEALX -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.4 (GNU/Linux) Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org iD8DBQFBkQ21MJAKAU3mjcsRAq3vAJ9hn0tdip1U8ssHnPEyYiF/yJPktwCfUb9J oLfqDiyi8/oEZ+Doj+gTRaw= =/wVV -----END PGP SIGNATURE-----
=== lib/WWW/Mechanize.pm ================================================================== --- lib/WWW/Mechanize.pm (revision 389) +++ lib/WWW/Mechanize.pm (revision 390) @@ -324,7 +324,7 @@ =head2 $mech->reload() -Acts like the reload button in a browser: Reperforms the current +Acts like the reload button in a browser: reperforms the current request. The history (as per the L<back> method) is not altered. Returns the L<HTTP::Response> object from the reload, or C<undef> @@ -337,8 +337,8 @@ return unless $self->{req}; - local $self->{inhibit_page_stack} = 1; - return $self->request( $self->{req}); + return unless defined(my $request = $self->{req}); + $self->_update_page($request, $self->_make_request( $request, @_ )); } =head2 $mech->back() @@ -1568,36 +1568,9 @@ $self->_push_page_stack(); } - $self->{req} = $request; - $self->{redirected_uri} = $request->uri->as_string; + $self->_update_page($request, $self->_make_request( $request, @_ )); +} - my $res = $self->{res} = $self->_make_request( $request, @_ ); - - # These internal hash elements should be dropped in favor of - # the accessors soon. -- 1/19/03 - $self->{status} = $res->code; - $self->{base} = $res->base; - $self->{ct} = $res->content_type || ""; - - if ( $res->is_success ) { - $self->{uri} = $self->{redirected_uri}; - $self->{last_uri} = $self->{uri}; - } else { - if ( $self->{autocheck} ) { - $self->die( "Error ", $request->method, "ing ", $request->uri, ": ", $res->message ); - } - } - - $self->_reset_page; - if ( $self->is_html ) { - $self->update_html( $res->content ); - } else { - $self->{content} = $res->content; - } - - return $res; -} # request - =head2 $mech->update_html( $html ) Allows you to replace the HTML that the mech has found. Updates the @@ -1661,6 +1634,48 @@ return; } +=head2 $mech->_update_page($request, $response) + +Updates all internal variables in $mech as if $request was just +performed, and returned $response. The page stack is B<not> altered by +this method, it is up to caller (e.g. L</request>) to do that. + +=cut + +sub _update_page { + my ($self, $request, $res) = @_; + + $self->{req} = $request; + $self->{redirected_uri} = $request->uri->as_string; + + $self->{res} = $res; + + # These internal hash elements should be dropped in favor of + # the accessors soon. -- 1/19/03 + $self->{status} = $res->code; + $self->{base} = $res->base; + $self->{ct} = $res->content_type || ""; + + if ( $res->is_success ) { + $self->{uri} = $self->{redirected_uri}; + $self->{last_uri} = $self->{uri}; + } else { + if ( $self->{autocheck} ) { + $self->die( "Error ", $request->method, "ing ", $request->uri, ": ", $res->message ); + } + } + + $self->_reset_page; + if ($self->is_html) { + $self->update_html($res->content); + } else { + $self->{content} = $res->content; + } + + return $res; +} # _update_page + + =head2 $mech->_modify_request( $req ) Modifies the request according to all the internal header mangling. @@ -1943,10 +1958,6 @@ sub _push_page_stack { my $self = shift; - # Hook for reload() and maybe future code (e.g. 302 chasing, - # frames) that may want to fetch stuff without altering the history. - return 1 if $self->{inhibit_page_stack}; - # Don't push anything if it's a virgin object if ( $self->{res} ) { my $save_stack = $self->{page_stack}; @@ -1971,10 +1982,6 @@ sub _pop_page_stack { my $self = shift; - # Hook for reload() and maybe future code (e.g. 302 chasing, - # frames) that may want to fetch stuff without altering the history. - return 1 if $self->{inhibit_page_stack}; - if (@{$self->{page_stack}}) { my $popped = pop @{$self->{page_stack}};
Date: Tue, 9 Nov 2004 14:21:14 -0500
From: Mark Stosberg <mark [...] summersault.com>
To: "dom [...] idealx.com via RT" <bug-WWW-Mechanize [...] rt.cpan.org>
Subject: Re: [cpan #8109] back() reload()ed, sans inhibition
RT-Send-Cc:
On Tue, Nov 09, 2004 at 01:29:01PM -0500, dom@idealx.com via RT wrote: Show quoted text
> > This message about WWW-Mechanize was sent to you by dom@idealx.com <dom@idealx.com> via rt.cpan.org > > Full context and any attached attachments can be found at: > <URL: https://rt.cpan.org/Ticket/Display.html?id=8109 > > > Dear Mechanists, > > Here is the new-and-improved patch that takes Andy's comment into > account: $mech->{inhibit_page_stack} is gone, and a new refactored > function appears.
Thanks. I"ll take a look. Show quoted text
> Please apply to CVS HEAD. (Off-topic note: I just spent some time > installing svk and this is just another insanely cool Perl package! It > made my keeping track of pending patches much easier. Well worth a try > for all folks working concurrently on lots of FOSS projects IMHO)
Good to here. I know Andy is a Subversion fan, and I prefer darcs. I was actually going to recommend 'darcs' to you, once I figured out how to setup a CVS <-> darcs gateway for Mech. It sounds like you have a solution you like, though. From what I've seen, svk is partially inspired by the command set of darcs. I would like to play with svk more myself sometime. ( BTW, darcs just turned 1.0 yesterday: http://www.darcs.net/ ). Mark