Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Passing POST parameters

by Anonymous Monk
on Apr 04, 2000 at 02:26 UTC ( #6769=perlquestion: print w/ replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Ok.. here goes:
Is there a way to pass parameters with a form that uses the POST method?
For instance, you can go point a URL at: http://www.server.com/cgi-bin/form.pl?id=103. (passing the parameter 'id=3'). Can I have something that points the browser to that same form, and pass that same parameter (id=103) in a POST form, and then read the parameter using the STDIN? HELP!!

Comment on Passing POST parameters
Re: Passing POST parameters
by btrott (Parson) on Apr 04, 2000 at 03:09 UTC
    Sure. You should take a look at the source of lwp-request, an app that uses LWP::UserAgent to make requests. It does exactly what you're looking for, so you could either use it directly or incorporate its relevant bits into your code.

    Essentially, you just do:

    # create a new LWP::UserAgent my $ua = new LWP::UserAgent; # create a new HTTP::Request, specifying # the POST method my $request = new HTTP::Request; # read in the content from STDIN; print "Enter in your content:\n"; my $content = join '', <STDIN>; # attach the content to the request # (change content-type to the appropriate type) $request->header('Content-Type' => 'text/plain'); $request->header('Content-Length' => length $content); $request->content($content); # send request and get a response my $response = $ua->request($request);
    And that's that.
RE: Passing POST parameters
by Anonymous Monk on Apr 04, 2000 at 03:17 UTC
    What about using actual code? Don't even ask why (cause I don't know), because modules never work for me!
Re: Passing POST parameters
by btrott (Parson) on Apr 04, 2000 at 03:25 UTC
    That *is* actual code. Do you mean code that doesn't use modules? Modules use actual code, too. Do you not have LWP? It comes with Perl.

    I'm not going to write out an entire POST application w/o using modules... sorry. The basic idea is that you want to open up a socket (using socket) to the remote host, send the request headers, then send the content of the request. Then you read back the response. perlipc has some examples of using sockets to read from and write to tcp/ip servers. You'll also want to read the HTTP specification.

    Personally, I think you'd be better off figuring out why LWP doesn't work for you than completely rewriting it. It's not that I'm against learning for learning's sake-- I agree with japhy's comment that you should know how a module works, and understand it, before you actually use it--but I don't think that you should actually *rewrite* a standard module.

    If you can post specific problems about why "modules never work for you", I'd be happy to try and offer some suggestions.

      I don't think LWP is in the 5.005 core... I certainly had to download it on at least two of my Linux boxen. Maybe I should have compiled my own?
        Ah. Perhaps not. Perhaps I did have to install it specially. Although not for MacPerl, but then, that's special. :)

        All the same, though, it's relatively standard.

        Ah. Perhaps not. Perhaps I did have to install it specially. Although not for MacPerl, but then, that's special. :)

        All the same, though, it's relatively standard.

      All right then... so I suppose I will write you up a short example of POST-ing to a web server, w/o using modules (except for Socket, but you *really* should have that one)--(and not that you really asked :).

      WARNING: this may not be great code. But I think it's got the essentials of what you need to do to write a client that POSTs to a web server and receives a response.

      use Socket; # remote hostname and port (80, most likely) my $remote = "www.server.com"; my $port = 80; # the URL you want to POST to my $url = "/cgi-bin/form.pl"; # the content you want to POST # (key value pairs, most likely) my $content = "id=103"; # network stuff--lookup host name and convert # it into a packed IP address suitable for # passing to connect. then get the protocol # data needed by socket (for the "tcp" protocol). my $paddr = sockaddr_in $port, inet_aton $remote; my $proto = getprotobyname('tcp'); # open up a socket on your local machine socket S, &AF_INET, &SOCK_STREAM, $proto or die "Can't open socket: $!"; # connect your local socket to the remote host and port connect S, $paddr or die "Can't connect: $!"; # make your socket unbuffered select((select(S), $|=1)[0]); # print POST line to web server, followed by # Content-Length header--this header is essential # so that the web server knows that content will # be sent along in the body of the request print S "POST $url HTTP/1.0\n"; print S "Content-Length: ", length $content, "\n"; print S "\n"; print S $content, "\n\n"; # you've sent the request, now just read back the # response, headers and all, and print it print while <S>; # close up the socket close S;
        Wow! Thanks for this script. It happens to be exactly what I was looking for because I needed to write a cron job that passes certain parameters to an ASP script. This of course had to be done without user interaction of pressing a 'submit' button.
        This, or the LWP program, works great! However, how would you do that to a program on a Secure Socket layer (https://foo.com/bar.pl)?
Re: Passing POST parameters
by turnstep (Parson) on Apr 04, 2000 at 08:30 UTC

    Hrmmm...I interpret this question differently.

    <FORM METHOD="Post" ACTION="http://www.server.com/cgi-bin/form.pl"> <INPUT TYPE="Hidden" NAME="id" VALUE="103"> <INPUT TYPE="Submit" VALUE="Send this as a POST!"> </FORM>

    As long as form.pl is a fairly standard script, it should have no problem reading the data as either a GET or a POST request.

    Still, the question is confusing..are you trying to write a server? A client? Both? Neither?

Re: Passing POST parameters
by Anonymous Monk on Apr 04, 2000 at 17:46 UTC
    Sorry, turnstep, I already use that code, but I don't want to have a form, I need to be able to just redirect the browser attaching some post content

    Also, the server I'm on does not allow using sockets. I'd like to able to just use the
    print "Location: http://www.server.com/cgi-bin/post_form.pl\n\n";

      I think turnstep's FORM method is the way to go. The browser will probably dump any POST data if you do a redirect (I'm sure of it). The only possible solution I can come up with is writing some sort of proxying server in the first script, in which case you're back to using LWP as btrott suggested.

      There may be a JavaScript way to avoid displaying the form and the Action button for the user, but that's beyond the realm of this lowly Perl Monk.

      Well, you can't do it with a Location redirect, I'm afraid. The only thing you can pass through that is a URL, which might happen to have some GET data embedded inside it. It's still not exactly clear what you are trying to do. The only way to send the information as a POST request is to connect to the web server, send the header information, including the length of your data, then send the data itself, and close the connection. That's basically what a web browser does, and what some of the above-mentioned modules can help with.

      I'm going to make a wild stab here: you would like people to be able to click on a normal link (with GET information encoded) and have the server somehow redirect them to another script in which the information is sent only via POST and not in the new URL? If so, you can simulate that connection by having your script connect to the new website, deliver the data as POST, and dump the results back to the person browsing. The only other way would be to have your script output a page in which they could hit a submit button and do it themselves. But there is no way to force/trick a browser to send post information without user interaction (e.g. clicking on the submit button)

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://6769]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (6)
As of 2014-07-10 04:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    When choosing user names for websites, I prefer to use:








    Results (198 votes), past polls