home | O'Reilly's CD bookshelfs | FreeBSD | Linux | Cisco | Cisco Exam  


20.2. Automating Form Submission

Problem

You want to submit form values to a CGI script from your program.

Solution

If you're submitting form values using the GET method, create a URL and encode the form using the query_form method:

use LWP::Simple;
use URI::URL;

my $url = url('http://www.perl.com/cgi-bin/cpan_mod');
$url->query_form(module => 'DB_File', readme => 1);
$content = get($url);

If you're using the POST method, create your own user agent and encode the content appropriately:

use HTTP::Request::Common qw(POST);
use LWP::UserAgent;

$ua = LWP::UserAgent->new();
my $req = POST 'http://www.perl.com/cgi-bin/cpan_mod',
               [ module => 'DB_File', readme => 1 ];
$content = $ua->request($req)->as_string;

Discussion

For simple operations, the procedural interface of the LWP::Simple module is sufficient. For fancier ones, the LWP::UserAgent module provides a virtual browser object, which you manipulate using method calls.

The format of a query string is:

field1=value1&field2=value2&field3=value3

In GET requests, this is encoded in the URL being requested:

http://www.site.com/path/to/
script.cgi?field1=value1&field2=value2&field3=value3

Fields must still be properly escaped, so setting the arg form parameter to "this isn't <EASY>&<FUN>" would yield:

http://www.site.com/path/to/
script.cgi?arg=%22this+isn%27t+%3CEASY%3E+%26+%3CFUN%3E%22

The query_form method called on a URL object correctly escapes the form values for you, or you could use the URI::Escape::uri_escape or CGI::escape_html functions on your own. In POST requests, the query string is the body of the HTTP document sent to the CGI script.

We can use the LWP::Simple module to submit data in a GET request, but there is no corresponding LWP::Simple interface for POST requests. Instead, the HTTP::Request::Common module's POST function conveniently creates a properly formatted request with everything properly escaped.

If you need to go through a proxy, construct your user agent and tell it to use a proxy this way:

$ua->proxy(['http', 'ftp'] => 'http://proxy.myorg.com:8081');

That says that both HTTP and FTP requests through this user agent should be routed through the proxy on port 8081 at proxy.myorg.com .

See Also

The documentation for the CPAN modules LWP::Simple, LWP::UserAgent, HTTP::Request::Common, URI::Escape, and URI::URL; Recipe 20.1