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

Hi all,

I've got the following snippet that doesn't seem to work. When I run it, it fails and spits out fail 2 and fail 3. I'm afraid I can't see the problem, help?

$contentpost = "id=20010131". "&username=$username". "&password=$password". "&subject=$subject". "&comments=$post". "&submit=Submit"; $contentpost =~ s/ /+/g; $ua = new LWP::UserAgent; my $req = new HTTP::Request 'POST',$formurl || print "fail 1"; $req->content_type('application/x-www-form-urlencoded') || print "fail + 2"; $req->content("$contentpost") || print "fail 3"; my $res = $ua->request($req) || print "fail 4";

Kickstart

Replies are listed 'Best First'.
Re: LWP posting a form
by MeowChow (Vicar) on Feb 06, 2001 at 13:24 UTC
    There are many problems with this code, but here are your biggies:

    • Don't construct your query string by hand. The POST method of HTTP::Request::Common does this for you. You simply supply it with an anonymous array in the form of [username=>$username, password=>$password, ...].
    • If you do the above, you will not need your substitution statement.
    • The || operator is a high-precedence operator. See perlop for the details, but in short, the || in the "fail 1" line evaluates before the comma operator does. In fact, the only reason your code does not print "fail 1" is because || short-circuits on the "true" evaluation of $formurl.
    • In general, what you're trying to do is actually much easier than you are making it out to be. Here is one way it can be done:
      use LWP::UserAgent; use HTTP::Request::Common; my $formurl = "http://www.amihotornot.com/board.pl"; my $id = 20010131; my $username = "MeowChow"; my $password = "catfood"; my $subject = "Fancy Feast is neither fancy nor a feast."; my $post = "Discuss amongst yourselves..."; # construct an anonymous array for the Http::Request::Common::POST met +hod my $formvars = [ id => $id, username => $username, password => $password. subject => $subject, comments => $post, submit => "Submit", ]; $ua = new LWP::UserAgent; $ua->request(POST $formurl, $formvars);
    • Read the HTTP::Request::Common documentation, specifically the part about POST.
       MeowChow                                               
                    print $/='"',(`$^X\144oc $^X\146aq1`)[-2]
Re: LWP posting a form
by dkubb (Deacon) on Feb 06, 2001 at 14:03 UTC

    If I may add a suggestion, you should look at using HTTP::Request::Common to simplify this code.

    HTTP::Request::Common has a routine called POST, which does almost the same thing as what you are doing with HTTP::Request, only in less steps.

    Using these two modules your code changes to something like this:

    #!/usr/bin/perl -w use strict; use URI; use HTTP::Request::Common qw(POST); use LWP::UserAgent; my $username = 'username'; my $password = 'password'; my $subject = 'subject'; my $comments = 'comment'; my $post = 'post'; my $url = 'http://www.somesite.com'; my $ua = LWP::UserAgent->new; my $result = $ua->request(POST $url, [ id => '20010131', username => $username, password => $password, subject => $subject, comments => $post, submit => 'Submit', ]); print $result->as_string; __END__
Re: LWP posting a form
by doran (Deacon) on Feb 06, 2001 at 12:58 UTC
    Well, the first thing I notice is that $contentpost doesn't have any whitespace. So I'm wondering about that s///. Did you want to put a '+' sign in-between the params? If so, it's not happening here. If that's what you want to do, it's probably better to just do it manually, rather than using a regex.

    my $contentpost = "id=20010131".'+'. "&username=$username".'+'. "&password=$password".'+'. "&subject=$subject".'+'. "&comments=$post".'+'. "&submit=Submit";
    I'm sure it can be prettier, but you get the idea.

    Good luck,
    db
      Some of the variables (specifically $post and $subject) contain spaces, and that part seems to work fine. I'm thinking that the text in those might need to be url-encoded further (exclamation points prolly cause a problem). That part seems to be ok.

      Kickstart

        Oh, okay, that makes sense. That's what I get for offering advice before running the code. ;)