cobra has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to write a program that sends random variables to an online form and then retrieving the results after the Web server has done the computations. The problem I am having is that I cannot seem to send the details to the form. I tried teh following code:
#!/user/local/bin/perl use strict; use CGI; use HTTP::Request; use LWP::UserAgent; use HTTP::Header; my $start_town = "Guildford"; my $destination_town = "Portsmouth"; my $ua = LWP::UserAgent->new(); my $method = "POST"; my $url = "http://212.87.65.227/bin/query.exe/en"; my $header = HTTP::Header->new(); my $content = "to=".$start_town."&from=".$destination_town; my $request = HTTP::Request->new($method, $url, $header, $content); use HTTP::Response; my $response = $ua->request($request, "page.html"); if($response->is_success) { open PLEASE, "<page.html"; while (<PLEASE>) { print; } close PLEASE; } else { print $response->error_as_HTML; }
But get the following error on running the script:
Can't locate HTTP/Header.pm in @INC (@INC contains: /opt/PDperl/5005_0 +3/lib/5.00 503/sun4-solaris-thread /opt/PDperl/5005_03/lib/5.00503 /opt/PDperl/50 +05_03/lib/ site_perl/5.005/sun4-solaris-thread /opt/PDperl/5005_03/lib/site_perl/ +5.005 .) a t tester3.cgi line 7. BEGIN failed--compilation aborted at tester3.cgi line 7.
From this I assumed that the Web server I am using does not have the Header.pm module. So I tried removing the header line and using the following code:
#!/user/local/bin/perl use strict; use CGI; use HTTP::Request; use LWP::UserAgent; #use HTTP::Header; my $start_town = "Guildford"; my $destination_town = "Portsmouth"; my $ua = LWP::UserAgent->new(); my $method = "POST"; my $url = "http://212.87.65.227/bin/query.exe/en"; #my $header = HTTP::Header->new(); my $content = "to=".$start_town."&from=".$destination_town; my $request = HTTP::Request->new($method, $url, [$content]); use HTTP::Response; my $response = $ua->request($request, "page.html"); if($response->is_success) { open PLEASE, "<page.html"; while (<PLEASE>) { print; } close PLEASE; } else { print $response->error_as_HTML;
But got the following error:
Can't call method "clone" on unblessed reference at /opt/PDperl/5005_0 +3/lib/site _perl/5.005/HTTP/Message.pm line 53.
What is blessing and what variable do I need to bless? Or am I on the wrong track? Any help would be gratefully appreciated. Cobra

Replies are listed 'Best First'.
Re: Submitting information to an online form
by merlyn (Sage) on Apr 25, 2001 at 17:37 UTC
    I'm gonna sound like a broken record on this one, but as I've said many times before here, when you've gotta submit a form, first check lwpcook, which tells you to use HTTP::Request::Common.

    In your case, the code will look like:

    use LWP; use HTTP::Request::Common; my $start_town = "Guildford"; my $destination_town = "Portsmouth"; my $ua = LWP::UserAgent->new; # alter ua here if needed my $response = $ua->simple_request(POST "http://212.87.65.227/bin/query.exe/en", [ to => $start_town, from => $destination_town ] ); if ($response->is_success) { print $response->content; } else { print "ERROR: ", $response->status_line; }
    One advantage is that your form values will be properly URI escaped, something you hadn't coded yet. {grin}

    -- Randal L. Schwartz, Perl hacker

Re: Submitting information to an online form
by arturo (Vicar) on Apr 25, 2001 at 17:13 UTC

    UPDATE prepare to dopeslap yourself -- I bet the root problem is that you've misspelled the name of the module HTTP::Headers -- note the 's' on the end! So make that change and go back to your old code. BTW this also makes sense of the error message; the Request object expects the third argument to be an anonymous array of an HTTP::Headers object and an anonymous array of the content, i.e. [$header, [$content]] ... the way it is now, it sees first the reference to the array whose sole member is $content, and that's not a blessed reference.

    bless is a perl function that's used in Object oriented programming -- you use it to 'bless' an object into a class, to mark it as an object (rather than a plain ol' reference). The basic idea is that a reference must be *blessed* before you can call *methods* on it, and somwhere inside HTTP:Message, something that's not an object (because it hasn't been blessed) is being treated as if it were.

    What's going on is that one of the modules you are using uses HTTP::Message internally -- and there are a couple of candidates here (HTTP:::Request is a subclass of HTTP::Message) -- and you've subtly messed up a call to a constructor. I'm not feeling generous enough with my time to track down *which* one for you, but go over the documentation for the objects you're instantiating and make sure those calls pass in the right kinds of arguments.

    I'm not sure you need to explicitly use all those modules, either. Try it with just use LWP::UserAgent left in there and see if that works. It may even solve your problem.

    Side note: when you get errors you don't understand, you can often get a lot more info by calling perldoc perldiag and searching for (the generic part of) your error message. Similar results can be obtained by putting use diagnostics at the top of your script.

      response to myself ... you don't need HTTP::Headers at all. Here's working code, culled from perldoc lwpcook and modified to fit your example (note, the only module you explicitly have to use is LWP::UserAgent) :

      #!/usr/bin/perl -w use strict; use LWP::UserAgent; my $ua = LWP::UserAgent->new(); my $req = HTTP::Request->new(POST=>'http://212.87.65.227/bin/query.exe +/en'); $req->content_type('application/x-www-form-urlencoded'); $req->content('to=Guildford&from=Portsmouth'); my $res = $ua->request($req); if ($res->is_success) { print $res->content; } else { print "Error: ", $res->status_line, "\n"; }
Re: Submitting information to an online form
by diarmuid (Beadle) on Apr 25, 2001 at 20:09 UTC
    Looks like your your webserver does not have the PERL5LIB environmental variable set correctly.
    You could create a c-shell wrapper correctly setting the PERL5LIB variable and then calling your perl script. Not nice, but it might be all you need