I'm utilizing WWW::Mechanize to get a page and return the content of that page, and then in a different instance of the script, submit a form on that same page with the original session. The way I intended to do this was to store the mech object via Storable or YAML in the first instance, then retrieve the mech object in the second instance.

Note: for the purpose of these tests, I'm requesting to "http://localhost/mech-form.php" which is just a page with a form that submits to itself and prints out its current session id.

use strict; use WWW::Mechanize; use Storable qw(store retrieve freeze thaw); # init a mech instance my $mech = WWW::Mechanize->new(); # on first instance... if(! -f 'stored_mech.dat') { # create, get, freeze, and store $mech->get('http://localhost/mech-form.php'); store([freeze($mech)], 'stored_mech.dat'); exit; } # on subsequent instance... else { # retrieve, thaw, and submit form my $stored = retrieve('stored_mech.dat'); $mech = thaw($stored->[0]); $mech->submit_form(form_number=>1); }
Storable dies complaining that it can't store CODE items, so I'm using YAML's freeze/thaw and DumpFile/LoadFile instead:
use strict; use WWW::Mechanize; use YAML qw(DumpFile LoadFile freeze thaw); # init a mech instance my $mech = WWW::Mechanize->new(); # on first instance... if(! -f 'stored_mech.dat') { # get, freeze, and store $mech->get('http://localhost/mech-form.php'); DumpFile('stored_mech.dat', [freeze($mech)]); exit; } # on subsequent instance... else { # retrieve, thaw, and submit form my $stored = LoadFile('stored_mech.dat'); $mech = thaw($stored->[0]); $mech->submit_form(form_number=>1); }
But after I load the mech object and try to submit the form, I get the following error:
Can't locate object method "scheme" via package "URI::http" at /usr/sh +are/perl5/URI.pm line 52.
I decided to try and save/load the cookies as well. That way, after I load the mech object, I can re-get the page, then just reload the saved cookie jar which should continue the same session
use strict; use WWW::Mechanize; use YAML qw(DumpFile LoadFile freeze thaw); # init a mech instance my $mech = WWW::Mechanize->new(cookie_jar => {ignore_discard => 0}); # + save even browser-lifetime cookies # on first instance... if(! -f 'stored_mech.dat') { # get, freeze, save cookie jar, and store $mech->get('http://localhost/mech-form.php'); $mech->cookie_jar->save('cookies.dat'); DumpFile('stored_mech.dat', [freeze($mech)]); exit; } # on subsequent instance... else { # retrieve, thaw my $stored = LoadFile('stored_mech.dat'); $mech = thaw($stored->[0]); # re-get page and reload cookies $mech->get('http://localhost/mech-form.php'); $mech->cookie_jar->clear(); $mech->cookie_jar->load('cookies.dat'); # submit form with (presumably) original session $mech->submit_form(form_number=>1); }
However, it seems like it's still using a new session after i reload the cookie jar, which I confirmed by dumping the response headers and page content (which contains the server-side session id):
use strict; use WWW::Mechanize; use YAML qw(DumpFile LoadFile freeze thaw); # init a mech instance my $mech = WWW::Mechanize->new(cookie_jar => {ignore_discard => 0}); # + save even browser-lifetime cookies # on first instance... if(! -f 'stored_mech.dat') { # get, freeze, save cookie jar, and store $mech->get('http://localhost/mech-form.php'); $mech->cookie_jar->save('cookies.dat'); printf "Before freeze & save: \%s\n\n", $mech->response()->headers +()->as_string(); printf "Page session id: \%s\n\n", $mech->content(); DumpFile('stored_mech.dat', [freeze($mech)]); exit; } # on subsequent instance... else { # retrieve, thaw my $stored = LoadFile('stored_mech.dat'); $mech = thaw($stored->[0]); # re-get page and reload cookies $mech->get('http://localhost/mech-form.php'); $mech->cookie_jar->clear(); $mech->cookie_jar->load('cookies.dat'); # submit form with (presumably) original session $mech->submit_form(form_number=>1); printf "After thaw & submit: \%s\n", $mech->response()->headers()- +>as_string(); printf "Page session id: \%s\n\n", $mech->content(); }
This results in the output below (after I've stripped the page's markup and the non-related headers):
~$ perl ./mech-test.pl Before freeze & save: Set-Cookie: PHPSESSID=p9ogedv2qf1r5h664la79is1j2 +; path=/ Page session id: p9ogedv2qf1r5h664la79is1j2 ~$ perl ./mech-test.pl After thaw & submit: Set-Cookie: PHPSESSID=tq3devkvch2t5fsq6qbp707de4; + path=/ Page session id: tq3devkvch2t5fsq6qbp707de4
So even after clearing and reloading the cookie jar, it's not keeping the same session across multiple instances of this script...and I have no clue where to go from here. Is there something I'm missing? Am I going to have to go mucking about in the Mechanize internals?

In reply to Maintaining sessions with WWW::Mechanize across script instances? by EvanK

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.