1N/A# See the bottom of this file for the POD documentation. Search for the 1N/A# You can run this file through either pod2man or pod2html to produce pretty 1N/A# documentation in manual or html file format (these utilities are part of the 1N/A# Perl 5 distribution). 1N/A# Copyright 1995-1998 Lincoln D. Stein. All rights reserved. 1N/A# It may be used and modified freely, but I do request that this copyright 1N/A# notice remain attached to the file. You may modify this module as you 1N/A# wish, but if you redistribute a modified version, please attach a note 1N/A# listing the modifications you have made. 1N/A# The most recent version and complete docs are available at: 1N/A# The revision is no longer being updated since moving to git. 1N/A# HARD-CODED LOCATION FOR FILE UPLOAD TEMPORARY FILES. 1N/A# UNCOMMENT THIS ONLY IF YOU KNOW WHAT YOU'RE DOING. 1N/A#use constant XHTML_DTD => ['-//W3C//DTD XHTML Basic 1.0//EN', 1N/A# >>>>> Here are some globals that you might want to adjust <<<<<< 1N/A # Set this to 1 to enable copious autoloader debugging messages 1N/A # Set this to 1 to generate XTML-compatible output 1N/A # Change this to the preferred DTD to print in start_html() 1N/A # or use default_dtd('text of DTD to use'); 1N/A # Set this to 1 to enable NOSTICKY scripts 1N/A # 1) use CGI '-nosticky'; 1N/A # 2) $CGI::NOSTICKY = 1; 1N/A # Set this to 1 to enable NPH scripts 1N/A # 1) use CGI qw(-nph) 1N/A # 3) print header(-nph=>1) 1N/A # Set this to 1 to enable debugging from @ARGV 1N/A # Set to 2 to enable debugging from STDIN 1N/A # Set this to 1 to make the temporary files created 1N/A # during file uploads safe from prying eyes 1N/A # 1) use CGI qw(:private_tempfiles) 1N/A # 2) CGI::private_tempfiles(1); 1N/A # Set this to 1 to generate automatic tab indexes 1N/A # Set this to 1 to cause files uploaded in multipart documents 1N/A # to be closed, instead of caching the file handle 1N/A # 1) use CGI qw(:close_upload_files) 1N/A # 2) $CGI::close_upload_files(1); 1N/A # Uploads with many files run out of file handles. 1N/A # Also, for performance, since the file is already on disk, 1N/A # it can just be renamed, instead of read and written. 1N/A # Automatically determined -- don't change 1N/A # Change this to 1 to suppress redundant HTTP headers 1N/A # separate the name=value pairs by semicolons rather than ampersands 1N/A # Do not include undefined params parsed from query string 1N/A # use CGI qw(-no_undef_params); 1N/A # return everything as utf-8 1N/A # Other globals that you shouldn't worry about. 1N/A # prevent complaints by mod_perl 1N/A# ------------------ START OF THE LIBRARY ------------ 1N/A# This method is DEPRECATED 1N/A# FIGURE OUT THE OS WE'RE RUNNING UNDER 1N/A# Some systems support the $^O variable. If not 1N/A# available then require() the Config library 1N/A# Some OS logic. Binary mode enabled on DOS, NT and VMS 1N/A# This is the default class for the CGI object to use when all else fails. 1N/A# This is where to look for autoloaded routines. 1N/A# The path separator is a slash, backslash or semicolon, depending 1N/A# This no longer seems to be necessary 1N/A# Turn on NPH scripts by default when running under IIS server! 1N/A# $NPH++ if defined($ENV{'SERVER_SOFTWARE'}) && $ENV{'SERVER_SOFTWARE'}=~/IIS/; 1N/A$
IIS++
if defined($
ENV{
'SERVER_SOFTWARE'}) && $
ENV{
'SERVER_SOFTWARE'}=~/
IIS/;
1N/A# Turn on special checking for ActiveState's PerlEx 1N/A# Turn on special checking for Doug MacEachern's modperl 1N/A# PerlEx::DBI tries to fool DBI by setting MOD_PERL 1N/A # mod_perl handlers may run system() on scripts using CGI.pm; 1N/A # Make sure so we don't get fooled by inherited $ENV{MOD_PERL} 1N/A# Define the CRLF sequence. I can't use a simple "\r\n" because the meaning 1N/A# of "\n" is different on different OS's (sometimes it generates CRLF, sometimes LF 1N/A# and sometimes CR). The most popular VMS web server 1N/A# doesn't accept CRLF -- instead it wants a LR. EBCDIC machines don't 1N/A# use ASCII, so \015\012 means something different. I find this all 1N/A# Custom 'can' method for both autoloaded and non-autoloaded subroutines. 1N/A# Author: Cees Hek <cees@sitesuite.com.au> 1N/A # See if UNIVERSAL::can finds it. 1N/A # Try to compile the function. 1N/A # _compile looks at $AUTOLOAD for the function name. 1N/A # Now that the function is loaded (if it exists) 1N/A # just use UNIVERSAL::can again to do the work. 1N/A# to import symbols into caller 1N/A # This causes modules to clash. 1N/A # To allow overriding, search through the packages 1N/A # Till we find one in which the correct subroutine is defined. 1N/A if (
defined(&{
"$pck\:\:$sym"})) {
1N/A *{
"${callpack}::$sym"} = \&{
"$def\:\:$sym"};
1N/A# The new routine. This will check the current environment 1N/A# for an existing query string, and initialize itself, if so. 1N/A # always use a tempfile 1N/A # XXX: once we have the new API 1N/A # will do a real PerlOptions -SetupEnv check 1N/A# We provide a DESTROY method so that we can ensure that 1N/A# temporary files are closed (via Fh->DESTROY) before they 1N/A# are unlinked (via CGITempFile->DESTROY) because it is not 1N/A# possible to unlink an open file on Win32. We explicitly 1N/A# call DESTROY on each, rather than just undefing them and 1N/A# letting Perl DESTROY them by garbage collection, in case the 1N/A# user is still holding any reference to them as well. 1N/A if (
ref $_[
0]
eq 'CODE') {
1N/A# Returns the value(s)of a named parameter. 1N/A# If invoked in a list context, returns the 1N/A# entire list. Otherwise returns the first 1N/A# member of the list. 1N/A# If name is not provided, return a list of all 1N/A# the known parameters names available. 1N/A# If more than one argument is provided, the 1N/A# second and subsequent arguments are used to 1N/A# set the value of the parameter. 1N/A # For compatibility between old calling style and use_named_parameters() style, 1N/A # we have to special case for a single parameter present. 1N/A if (
substr($p[
0],
0,
1)
eq '-') {
1N/A # If values is provided, then we set it. 1N/A eval "require Encode; 1;" unless Encode->
can(
'decode');
# bring in these functions 1N/A return @_
if defined($_[
0]) && (!
ref($_[
0])) &&($_[
0]
eq 'CGI');
1N/A unless (
defined($_[
0]) &&
1N/A (
ref($_[
0])
eq 'CGI' ||
UNIVERSAL::
isa($_[
0],
'CGI'))
# slightly optimized for common case 1N/A return wantarray ? @_ : $Q;
1N/A local $^W=
0;
# prevent a warning 1N/A if (
defined($_[
0]) &&
1N/A (
substr(
ref($_[
0]),
0,
3)
eq 'CGI' 1N/A######################################## 1N/A# THESE METHODS ARE MORE OR LESS PRIVATE 1N/A# GO TO THE __DATA__ SECTION TO SEE MORE 1N/A######################################## 1N/A# Initialize the query object from the environment. 1N/A# If a parameter list is found, this object will be set 1N/A# to a hash in which parameter names are keys 1N/A# and the values are stored as lists 1N/A# If a keyword list is found, this method creates a bogus 1N/A# parameter list with the single parameter 'keywords'. 1N/A # set autoescaping on by default 1N/A # if we get called more than once, we want to initialize 1N/A # ourselves from the original query (which may be gone 1N/A # if it was read from STDIN originally.) 1N/A for my $
fh (
grep {
defined(
fileno($_))} @$
val) {
1N/A seek($
fh,
0,
0);
# reset the filehandle. 1N/A # set charset to the safe ISO-8859-1 1N/A # avoid unreasonably large postings 1N/A #discard the post, unread 1N/A # Process multipart postings, but only if the initializer is 1N/A &&
defined($
ENV{
'CONTENT_TYPE'})
1N/A # Process XForms postings. We know that we have XForms in the 1N/A # method eq 'POST' && content-type =~ /multipart\/related.+start=/ 1N/A # There are more cases, actually, but for now, we don't support other 1N/A # methods for XForm posts. 1N/A # In a XForm POST, the QUERY_STRING is parsed normally. 1N/A # XForms:Model (referring to the xml syntax) param containing the 1N/A # unparsed XML data. 1N/A # the other parts are available as uploads with the Content-ID as the 1N/A # See the URL below for XForms specs on this issue. 1N/A if ($
meth eq 'POST' &&
defined($
ENV{
'CONTENT_TYPE'})) {
1N/A # If initializer is defined, then read parameters 1N/A # massage back into standard format 1N/A if (
"@lines" =~ /=/) {
1N/A # last chance -- treat it as a string 1N/A # If method is GET or HEAD, fetch the query from 1N/A # should this be PUTDATA in case of PUT ? 1N/A # Some people want to have their cake and eat it too! 1N/A # Uncomment this line to have the contents of the query string 1N/A # APPENDED to the POST data. 1N/A # $query_string .= (length($query_string) ? '&' : '') . $ENV{'QUERY_STRING'} if defined $ENV{'QUERY_STRING'}; 1N/A # If $meth is not of GET, POST, PUT or HEAD, assume we're 1N/A # being debugged offline. 1N/A # Check the command line and then the standard input for data. 1N/A # We use the shellwords package in order to behave the way that 1N/A # UN*X programmers expect. 1N/A# YL: Begin Change for XML handler 10/19/2001 1N/A &&
defined($
ENV{
'CONTENT_TYPE'})
1N/A# YL: End Change for XML handler 10/19/2001 1N/A # We now have the query string in hand. We do slightly 1N/A # different things for keyword lists and parameter lists. 1N/A # Special case. Erase everything if there is a field named 1N/A # hash containing our defined fieldnames 1N/A # Clear out our default submission button flag if present 1N/A# FUNCTIONS TO OVERRIDE: 1N/A# Turn a string into a filehandle 1N/A my($
tmp) = $
thingy=~/[\
':]/ ? $thingy : "$package\:\:$thingy"; 1N/A# send output to the browser 1N/A# print to standard output (for overriding in mod_perl) 1N/A # We're going to play with the package globals now so that if we get called 1N/A # again, we initialize ourselves in exactly the same way. This allows 1N/A # us to have several of these objects. 1N/A next unless defined $_;
1N/A return ()
unless defined($
self) && $
self->{
'.parameters'};
1N/A return ()
unless @{$
self->{
'.parameters'}};
1N/A# put a filehandle into binary mode (DOS) 1N/A return unless defined($_[
1]) &&
defined fileno($_[
1]);
1N/A if (
ref(\$a) &&
ref(\$a)
eq 'HASH') {
1N/A $
func .=
qq!
return "<\L$1\E\$attr>";} !;
1N/A $
func .=
qq!
return "<\L/$1\E>"; } !;
1N/A return \$
XHTML ?
"\L<$tagname\E\$attr />" :
"\L<$tagname\E\$attr>" unless \@
rest;
1N/A my(\$
tag,\$
untag) = (
"\L<$tagname\E\$attr>",
"\L</$tagname>\E");
1N/A (
ref(\$
rest[
0])
eq 'ARRAY') ? \@{\$
rest[
0]} :
"\@rest";
1N/A local($
1,$
2);
# this fixes an obscure variable suicide problem. 1N/A unless defined(${
"$pack\:\:AUTOLOADED_ROUTINES"});
1N/A my($
sub) = \%{
"$pack\:\:SUBS"};
1N/A my($
auto) = \${
"$pack\:\:AUTOLOADED_ROUTINES"};
1N/A eval "package $pack; $$auto";
1N/A croak(
"$AUTOLOAD: $@")
if $@;
1N/A $$
auto =
'';
# Free the unneeded storage (but don't undef it!!!) 1N/A croak(
"Undefined subroutine $AUTOLOAD\n")
unless $
code;
1N/A eval "package $pack; $code";
1N/A croak(
"$AUTOLOAD: $@");
1N/A return "$pack\:\:$func_name";
1N/A # to avoid reexporting unwanted variables 1N/A # This is probably extremely evil code -- to be deleted some day. 1N/A *{
"${pkg}::AUTOLOAD"} =
sub {
1N/A tr/a-
zA-
Z0-
9_//
cd;
# don't allow weird function names 1N/A sprintf(
'%010d',$
self->{
'.elid'}++);
1N/A############################################################################### 1N/A################# THESE FUNCTIONS ARE AUTOLOADED ON DEMAND #################### 1N/A############################################################################### 1N/A'URL_ENCODED'=> <<
'END_OF_FUNC',
1N/A'MULTIPART' => <<
'END_OF_FUNC',
1N/A'SERVER_PUSH' => <<
'END_OF_FUNC',
1N/A'new_MultipartBuffer' => <<
'END_OF_FUNC',
1N/A# Create a new multipart buffer 1N/A'read_from_client' => <<
'END_OF_FUNC',
1N/A# Read data from a file handle 1N/A local $^W=
0;
# prevent a warning 1N/A'read_from_stdin' => <<
'END_OF_FUNC',
1N/A# Read data from stdin until all is read 1N/A local $^W=
0;
# prevent a warning 1N/A # TODO: loop over STDIN until all is read 1N/A # TODO: how to do error reporting ? 1N/A'delete' => <<
'END_OF_FUNC',
1N/A# Deletes the named parameter entirely. 1N/A#### Method: import_names 1N/A# Import all parameters into the given namespace. 1N/A# Assumes namespace 'Q' if not specified 1N/A'import_names' => <<
'END_OF_FUNC',
1N/A die "Can't import names into \"main\"\n" if \%{
"${namespace}::"} == \%::;
1N/A # can anyone find an easier way to do this? 1N/A for (
keys %{
"${namespace}::"}) {
1N/A # protect against silly names 1N/A#### Method: keywords 1N/A# Keywords acts a bit differently. Calling it in a list context 1N/A# returns the list of keywords. 1N/A# Calling it in a scalar context gives you the size of the list. 1N/A'keywords' => <<
'END_OF_FUNC',
1N/A # If values is provided, then we set it. 1N/A# These are some tie() interfaces for compatibility 1N/A'Vars' => <<
'END_OF_FUNC',
1N/A# These are some tie() interfaces for compatibility 1N/A'ReadParse' => <<
'END_OF_FUNC',
1N/A'PrintHeader' => <<
'END_OF_FUNC',
1N/A'HtmlTop' => <<
'END_OF_FUNC',
1N/A'HtmlBot' => <<
'END_OF_FUNC',
1N/A'SplitParam' => <<
'END_OF_FUNC',
1N/A'MethGet' => <<
'END_OF_FUNC',
1N/A'MethPost' => <<
'END_OF_FUNC',
1N/A'MethPut' => <<
'END_OF_FUNC',
1N/A'TIEHASH' => <<
'END_OF_FUNC',
1N/A'STORE' => <<
'END_OF_FUNC',
1N/A'FETCH' => <<
'END_OF_FUNC',
1N/A return $_[
0]
if $_[
1]
eq 'CGI';
1N/A return undef unless defined $_[
0]->
param($_[
1]);
1N/A'FIRSTKEY' => <<
'END_OF_FUNC',
1N/A $_[
0]->{
'.iterator'}=
0;
1N/A $_[
0]->{
'.parameters'}->[$_[
0]->{
'.iterator'}++];
1N/A'NEXTKEY' => <<
'END_OF_FUNC',
1N/A $_[
0]->{
'.parameters'}->[$_[
0]->{
'.iterator'}++];
1N/A'EXISTS' => <<
'END_OF_FUNC',
1N/A'DELETE' => <<
'END_OF_FUNC',
1N/A $_[
0]->
delete($_[
1]);
1N/A'CLEAR' => <<
'END_OF_FUNC',
1N/A# Append a new value to an existing query 1N/A#### Method: delete_all 1N/A# Delete all parameters 1N/A'delete_all' => <<
'EOF',
1N/A'Delete_all' => <<
'EOF',
1N/A#### Method: autoescape 1N/A# If you want to turn off the autoescaping features, 1N/A# call this method with undef as the argument 1N/A'autoEscape' => <<
'END_OF_FUNC',
1N/A# Return the current version 1N/A'version' => <<
'END_OF_FUNC',
1N/A#### Method: url_param 1N/A# Return a parameter in the QUERY_STRING, regardless of 1N/A# whether this was a POST or a GET 1N/A'url_param' => <<
'END_OF_FUNC',
1N/A unless (
exists($
self->{
'.url_param'})) {
1N/A $
self->{
'.url_param'}={};
# empty hash 1N/A return keys %{$
self->{
'.url_param'}}
unless defined($
name);
1N/A# pairs are represented as nested lists, mainly for the purposes 1N/A'Dump' => <<
'END_OF_FUNC',
1N/A push(@
result,
"<li><strong>$name</strong></li>");
1N/A#### Method as_string 1N/A'as_string' => <<
'END_OF_FUNC',
1N/A# Write values out to a filehandle in such a way that they can 1N/A# be reinitialized by the filehandle form of the new() method 1N/A'save' => <<
'END_OF_FUNC',
1N/A local($,) =
'';
# set print field separator back to a sane value 1N/A local($\) =
'';
# set output line separator to a sane value 1N/A for (
keys %{$
self->{
'.fieldnames'}}) {
1N/A#### Method: save_parameters 1N/A# An alias for save() that is a better name for exportation. 1N/A# Only intended to be used with the function (non-OO) interface. 1N/A'save_parameters' => <<
'END_OF_FUNC',
1N/A#### Method: restore_parameters 1N/A# A way to restore CGI parameters from an initializer. 1N/A# Only intended to be used with the function (non-OO) interface. 1N/A'restore_parameters' => <<
'END_OF_FUNC',
1N/A#### Method: multipart_init 1N/A# Return a Content-Type: style header for server-push 1N/A# This has to be NPH on most web servers, and it is advisable to set $| = 1 1N/A# Many thanks to Ed Jordan <ed@fidalgo.net> for this 1N/A# contribution, updated by Andrew Benham (adsb@bigfoot.com) 1N/A'multipart_init' => <<
'END_OF_FUNC',
1N/A my @
chrs = (
'0'..
'9',
'A'..
'Z',
'a'..
'z');
1N/A $
self->{
'separator'} =
"$CRLF--$boundary$CRLF";
1N/A $
self->{
'final_separator'} =
"$CRLF--$boundary--$CRLF";
1N/A#### Method: multipart_start 1N/A# Return a Content-Type: style header for server-push, start of section 1N/A# Many thanks to Ed Jordan <ed@fidalgo.net> for this 1N/A# contribution, updated by Andrew Benham (adsb@bigfoot.com) 1N/A'multipart_start' => <<
'END_OF_FUNC',
1N/A # rearrange() was designed for the HTML portion, so we 1N/A # need to fix it up a little. 1N/A # Don't use \s because of perl bug 21951 1N/A#### Method: multipart_end 1N/A# Return a MIME boundary separator for server-push, end of section 1N/A# Many thanks to Ed Jordan <ed@fidalgo.net> for this 1N/A'multipart_end' => <<
'END_OF_FUNC',
1N/A#### Method: multipart_final 1N/A# Return a MIME boundary separator for server-push, end of all sections 1N/A# Contributed by Andrew Benham (adsb@bigfoot.com) 1N/A'multipart_final' => <<
'END_OF_FUNC',
1N/A return $
self->{
'final_separator'} .
"WARNING: YOUR BROWSER DOESN'T SUPPORT THIS SERVER-PUSH TECHNOLOGY." . $
CRLF;
1N/A# Return a Content-Type: style header 1N/A'header' => <<
'END_OF_FUNC',
1N/A 'STATUS',[
'COOKIE',
'COOKIES'],
'TARGET',
1N/A 'EXPIRES',
'NPH',
'CHARSET',
1N/A 'ATTACHMENT',
'P3P'],@p);
1N/A # CR escaping for values, per RFC 822 1N/A # Unfolding is accomplished by regarding CRLF immediately 1N/A # followed by a LWSP-char as equivalent to the LWSP-char. 1N/A # All other uses of newlines are invalid input. 1N/A # shorten very long values in the diagnostic 1N/A die "Invalid header value contains a newline not followed by whitespace: $header";
1N/A # sets if $charset is given, gets if not 1N/A # rearrange() was designed for the HTML portion, so we 1N/A # need to fix it up a little. 1N/A # Don't use \s because of perl bug 21951 1N/A # Maybe future compatibility. Maybe not. 1N/A # push all the cookies -- there may be several 1N/A # if the user indicates an expiration time, then we need 1N/A # both an Expires and a Date header (so that the browser is 1N/A# Control whether header() will produce the no-cache 1N/A'cache' => <<
'END_OF_FUNC',
1N/A#### Method: redirect 1N/A# Return a Location: style header 1N/A'redirect' => <<
'END_OF_FUNC',
1N/A for (@
other) {
tr/\
"//d; push(@o,split("=
",$_,2)); } 1N/A unshift(@o,
'-Type'=>
'');
1N/A#### Method: start_html 1N/A# $title -> (optional) The title for this HTML document (-title) 1N/A# $author -> (optional) e-mail address of the author (-author) 1N/A# $base -> (optional) if set to true, will enter the BASE address of this document 1N/A# for resolving relative references (-base) 1N/A# $xbase -> (optional) alternative base at some remote location (-xbase) 1N/A# $target -> (optional) target window to load all links into (-target) 1N/A# $script -> (option) Javascript code (-script) 1N/A# $no_script -> (option) Javascript <noscript> tag (-noscript) 1N/A# $meta -> (optional) Meta information tags 1N/A# $head -> (optional) any other elements you'd like to incorporate into the <head> tag 1N/A# (a scalar or array ref) 1N/A# $style -> (optional) reference to an external style sheet 1N/A# @other -> (optional) any other named parameters you'd like to incorporate into 1N/A'start_html' => <<
'END_OF_FUNC',
1N/A # Need to sort out the DTD before it's okay to call escapeHTML(). 1N/A if (
defined(
ref($
dtd))
and (
ref($
dtd)
eq 'ARRAY')) {
1N/A # Now that we know whether we're using the HTML 3.2 DTD or not, it's okay to 1N/A # call escapeHTML(). Strangely enough, the title needs to be escaped as 1N/A # HTML while the author needs to be escaped as a URL. 1N/A .
"<head><title>$title</title>");
1N/A :
"<link rev=\"made\" href=\"mailto:$author\">");
1N/A # handle the infrequently-used -style and -script parameters 1N/A # handle -noscript parameter 1N/A# internal method for generating a CSS style section 1N/A'_style' => <<
'END_OF_FUNC',
1N/A ref($s)
eq 'ARRAY' ? @$s : %$s));
1N/A if (
ref($
src)
eq "ARRAY")
# Check to see if the $src variable is an array reference 1N/A {
# If it is, push a LINK tag for each one 1N/A {
# Otherwise, push the single -src, if it exists. 1N/A'_script' => <<
'END_OF_FUNC',
1N/A '-foo'=>
'bar',
# a trick to allow the '-' to be omitted 1N/A#### Method: end_html 1N/A# End an HTML document. 1N/A# Trivial method for completeness. Just returns "</body>" 1N/A'end_html' => <<
'END_OF_FUNC',
1N/A return "\n</body>\n</html>";
1N/A################################ 1N/A# METHODS USED IN BUILDING FORMS 1N/A################################ 1N/A# Just prints out the isindex tag. 1N/A# $action -> optional URL of script to run 1N/A# A string containing a <isindex> tag 1N/A'isindex' => <<
'END_OF_FUNC',
1N/A return $
XHTML ?
"<isindex$action$other />" :
"<isindex$action$other>";
1N/A#### Method: startform 1N/A# This method is DEPRECATED 1N/A# $method -> optional submission method to use (GET or POST) 1N/A# $action -> optional URL of script to run 1N/A# $enctype ->encoding to use (URL_ENCODED or MULTIPART) 1N/A'startform' => <<
'END_OF_FUNC',
1N/A#### Method: start_form 1N/A# $method -> optional submission method to use (GET or POST) 1N/A# $action -> optional URL of script to run 1N/A# $enctype ->encoding to use (URL_ENCODED or MULTIPART) 1N/A'start_form' => <<
'END_OF_FUNC',
1N/A#### Method: start_multipart_form 1N/A'start_multipart_form' => <<
'END_OF_FUNC',
1N/A if (
defined($p[
0]) &&
substr($p[
0],
0,
1)
eq '-') {
1N/A#### Method: end_form 1N/A'end_form' => <<
'END_OF_FUNC',
1N/A return wantarray ? (
"</form>") :
"\n</form>";
1N/A return wantarray ? (
"<div>",@
fields,
"</div>",
"</form>")
1N/A :
"<div>".(
join '',@
fields).
"</div>\n</form>";
1N/A#### Method: end_multipart_form 1N/A# end a multipart form 1N/A'end_multipart_form' => <<
'END_OF_FUNC',
1N/A'_textfield' => <<
'END_OF_FUNC',
1N/A # this entered at cristy's request to fix problems with file upload fields 1N/A # and WebTV -- not sure it won't break stuff 1N/A#### Method: textfield 1N/A# $name -> Name of the text field 1N/A# $default -> Optional default value of the field if not 1N/A# $size -> Optional width of field in characaters. 1N/A# $maxlength -> Optional maximum number of characters. 1N/A# A string containing a <input type="text"> field 1N/A'textfield' => <<
'END_OF_FUNC',
1N/A#### Method: filefield 1N/A# $name -> Name of the file upload field 1N/A# $size -> Optional width of field in characaters. 1N/A# $maxlength -> Optional maximum number of characters. 1N/A# A string containing a <input type="file"> field 1N/A'filefield' => <<
'END_OF_FUNC',
1N/A#### Method: password 1N/A# Create a "secret password" entry field 1N/A# $name -> Name of the field 1N/A# $default -> Optional default value of the field if not 1N/A# $size -> Optional width of field in characters. 1N/A# $maxlength -> Optional maximum characters that can be entered. 1N/A# A string containing a <input type="password"> field 1N/A'password_field' => <<
'END_OF_FUNC',
1N/A#### Method: textarea 1N/A# $name -> Name of the text field 1N/A# $default -> Optional default value of the field if not 1N/A# $rows -> Optional number of rows in text area 1N/A# $columns -> Optional number of columns in text area 1N/A# A string containing a <textarea></textarea> tag 1N/A'textarea' => <<
'END_OF_FUNC',
1N/A# Create a javascript button. 1N/A# $name -> (optional) Name for the button. (-name) 1N/A# $value -> (optional) Value of the button when selected (and visible name) (-value) 1N/A# $onclick -> (optional) Text of the JavaScript to run when the button is 1N/A# A string containing a <input type="button"> tag 1N/A'button' => <<
'END_OF_FUNC',
1N/A# Create a "submit query" button. 1N/A# $name -> (optional) Name for the button. 1N/A# $value -> (optional) Value of the button when selected (also doubles as label). 1N/A# $label -> (optional) Label printed on the button(also doubles as the value). 1N/A# A string containing a <input type="submit"> tag 1N/A'submit' => <<
'END_OF_FUNC',
1N/A# Create a "reset" button. 1N/A# $name -> (optional) Name for the button. 1N/A# A string containing a <input type="reset"> tag 1N/A'reset' => <<
'END_OF_FUNC',
1N/A#### Method: defaults 1N/A# Create a "defaults" button. 1N/A# $name -> (optional) Name for the button. 1N/A# A string containing a <input type="submit" name=".defaults"> tag 1N/A# Note: this button has a special meaning to the initialization script, 1N/A# and tells it to ERASE the current query string so that your defaults 1N/A'defaults' => <<
'END_OF_FUNC',
1N/A# Create an HTML <!-- comment --> 1N/A# Parameters: a string 1N/A'comment' => <<
'END_OF_FUNC',
1N/A return "<!-- @p -->";
1N/A#### Method: checkbox 1N/A# Create a checkbox that is not logically linked to any others. 1N/A# The field value is "on" when the button is checked. 1N/A# $name -> Name of the checkbox 1N/A# $checked -> (optional) turned on by default if true 1N/A# $value -> (optional) value of the checkbox, 'on' by default 1N/A# $label -> (optional) a user-readable label printed next to the box. 1N/A# Otherwise the checkbox name is used. 1N/A# A string containing a <input type="checkbox"> field 1N/A'checkbox' => <<
'END_OF_FUNC',
1N/A'escapeHTML' => <<
'END_OF_FUNC',
1N/A # hack to work around earlier hacks 1N/A push @_,$_[
0]
if @_==
1 && $_[
0]
eq 'CGI';
1N/A # $quot; was accidentally omitted from the HTML 3.2 DTD -- see 1N/A # Handle bug in some browsers with Latin charsets 1N/A && (
uc($
self->{
'.charset'})
eq 'ISO-8859-1' 1N/A ||
uc($
self->{
'.charset'})
eq 'WINDOWS-1252')) {
1N/A# unescape HTML -- used internally 1N/A'unescapeHTML' => <<
'END_OF_FUNC',
1N/A # hack to work around earlier hacks 1N/A push @_,$_[
0]
if @_==
1 && $_[
0]
eq 'CGI';
1N/A # thanks to Randal Schwartz for the correct solution to this one 1N/A /^
#(\d+)$/ && $latin ? chr($1) : 1N/A /^
#x([0-9a-f]+)$/i && $latin ? chr(hex($1)) : 1N/A# Internal procedure - don't use 1N/A'_tableize' => <<
'END_OF_FUNC',
1N/A # rearrange into a pretty table 1N/A#### Method: radio_group 1N/A# Create a list of logically-linked radio buttons. 1N/A# $name -> Common name for all the buttons. 1N/A# $values -> A pointer to a regular array containing the 1N/A# values for each button in the group. 1N/A# $default -> (optional) Value of the button to turn on by default. Pass '-' 1N/A# to turn _nothing_ on. 1N/A# $linebreak -> (optional) Set to true to place linebreaks 1N/A# between the buttons. 1N/A# $labels -> (optional) 1N/A# A pointer to a hash of labels to print next to each checkbox 1N/A# in the form $label{'value'}="Long explanatory label". 1N/A# Otherwise the provided values are used as the labels. 1N/A# An ARRAY containing a series of <input type="radio"> fields 1N/A'radio_group' => <<
'END_OF_FUNC',
1N/A#### Method: checkbox_group 1N/A# Create a list of logically-linked checkboxes. 1N/A# $name -> Common name for all the check boxes 1N/A# $values -> A pointer to a regular array containing the 1N/A# values for each checkbox in the group. 1N/A# $defaults -> (optional) 1N/A# 1. If a pointer to a regular array of checkbox values, 1N/A# then this will be used to decide which 1N/A# checkboxes to turn on by default. 1N/A# 2. If a scalar, will be assumed to hold the 1N/A# value of a single checkbox in the group to turn on. 1N/A# $linebreak -> (optional) Set to true to place linebreaks 1N/A# between the buttons. 1N/A# $labels -> (optional) 1N/A# A pointer to a hash of labels to print next to each checkbox 1N/A# in the form $label{'value'}="Long explanatory label". 1N/A# Otherwise the provided values are used as the labels. 1N/A# An ARRAY containing a series of <input type="checkbox"> fields 1N/A'checkbox_group' => <<
'END_OF_FUNC',
1N/A'_box_group' => <<
'END_OF_FUNC',
1N/A # If no check array is specified, check the first by default 1N/A#### Method: popup_menu 1N/A# Create a popup menu. 1N/A# $name -> Name for all the menu 1N/A# $values -> A pointer to a regular array containing the 1N/A# text of each menu item. 1N/A# $default -> (optional) Default item to display 1N/A# $labels -> (optional) 1N/A# A pointer to a hash of labels to print next to each checkbox 1N/A# in the form $label{'value'}="Long explanatory label". 1N/A# Otherwise the provided values are used as the labels. 1N/A# A string containing the definition of a popup menu. 1N/A'popup_menu' => <<
'END_OF_FUNC',
1N/A for my $v (
split(/\n/)) {
1N/A $
result .=
"<option${attribs} ${selectit}value=\"$value\">$label</option>\n";
1N/A#### Method: optgroup 1N/A# $name -> Label for the group 1N/A# $values -> A pointer to a regular array containing the 1N/A# values for each option line in the group. 1N/A# $labels -> (optional) 1N/A# A pointer to a hash of labels to print next to each item 1N/A# in the form $label{'value'}="Long explanatory label". 1N/A# Otherwise the provided values are used as the labels. 1N/A# $labeled -> (optional) 1N/A# A true value indicates the value should be used as the label attribute 1N/A# in the option elements. 1N/A# The label attribute specifies the option label presented to the user. 1N/A# This defaults to the content of the <option> element, but the label 1N/A# attribute allows authors to more easily use optgroup without sacrificing 1N/A# compatibility with browsers that do not support option groups. 1N/A# $novals -> (optional) 1N/A# A true value indicates to suppress the val attribute in the option elements 1N/A# A string containing the definition of an option group. 1N/A'optgroup' => <<
'END_OF_FUNC',
1N/A :
"<option$attribs label=\"$value\" value=\"$value\">$label</option>\n" 1N/A : $
novals ?
"<option$attribs>$label</option>\n" 1N/A :
"<option$attribs value=\"$value\">$label</option>\n";
1N/A#### Method: scrolling_list 1N/A# Create a scrolling list. 1N/A# $name -> name for the list 1N/A# $values -> A pointer to a regular array containing the 1N/A# values for each option line in the list. 1N/A# $defaults -> (optional) 1N/A# 1. If a pointer to a regular array of options, 1N/A# then this will be used to decide which 1N/A# lines to turn on by default. 1N/A# 2. Otherwise holds the value of the single line to turn on. 1N/A# $size -> (optional) Size of the list. 1N/A# $multiple -> (optional) If set, allow multiple selections. 1N/A# $labels -> (optional) 1N/A# A pointer to a hash of labels to print next to each checkbox 1N/A# in the form $label{'value'}="Long explanatory label". 1N/A# Otherwise the provided values are used as the labels. 1N/A# A string containing the definition of a scrolling list. 1N/A'scrolling_list' => <<
'END_OF_FUNC',
1N/A for my $v (
split(/\n/)) {
1N/A $
result .=
"<option${attribs} ${selectit}value=\"$value\">$label</option>\n";
1N/A# $name -> Name of the hidden field 1N/A# @default -> (optional) Initial values of field (may be an array) 1N/A# $default->[initial values of field] 1N/A# A string containing a <input type="hidden" name="name" value="value"> 1N/A'hidden' => <<
'END_OF_FUNC',
1N/A # this is the one place where we departed from our standard 1N/A # calling scheme, so we have to special-case (darn) 1N/A if (
ref($p[
0]) ||
substr($p[
0],
0,
1)
eq '-') {
1N/A # use previous values if override is not set 1N/A#### Method: image_button 1N/A# $name -> Name of the button 1N/A# $src -> URL of the image source 1N/A# $align -> Alignment style (TOP, BOTTOM or MIDDLE) 1N/A# A string containing a <input type="image" name="name" src="url" align="alignment"> 1N/A'image_button' => <<
'END_OF_FUNC',
1N/A#### Method: self_url 1N/A# Returns a URL containing the current script and all its 1N/A# to create a link that, when selected, will reinvoke the 1N/A# script with all its state information preserved. 1N/A'self_url' => <<
'END_OF_FUNC',
1N/A return $
self->
url(
'-path_info'=>
1,
'-query'=>
1,
'-full'=>
1,@p);
1N/A# This is provided as a synonym to self_url() for people unfortunate 1N/A# enough to have incorporated it into their programs already! 1N/A'state' => <<
'END_OF_FUNC',
1N/A# Like self_url, but doesn't return the query string part of 1N/A'url' => <<
'END_OF_FUNC',
1N/A rearrange([
'RELATIVE',
'ABSOLUTE',
'FULL',[
'PATH',
'PATH_INFO'],[
'QUERY',
'QUERY_STRING'],
'BASE',
'REWRITE'],@p);
1N/A $
uri =~ s/\?.*$//s;
# remove query string 1N/A# $uri =~ s/\Q$path\E$// if defined $path; # remove path 1N/A $
vh =~ s/\:\d+$//;
# some clients add the port number (incorrectly). Get rid of it. 1N/A # add the port to the url unless it's the protocol's default port 1N/A $
url =~ s/([^a-
zA-
Z0-
9_.%;&?\/\\:+=~-])/
sprintf(
"%%%02X",
ord($
1))/
eg;
1N/A# Set or read a cookie from the specified name. 1N/A# Cookie can then be passed to header(). 1N/A# Usual rules apply to the stickiness of -value. 1N/A# -name -> name for this cookie (optional) 1N/A# -value -> value of this cookie (scalar, array or hash) 1N/A# -path -> paths for which this cookie is valid (optional) 1N/A# -domain -> internet domain in which this cookie is valid (optional) 1N/A# -secure -> if true, cookie only passed through secure channel (optional) 1N/A# -expires -> expiry date in format Wdy, DD-Mon-YYYY HH:MM:SS GMT (optional) 1N/A'cookie' => <<
'END_OF_FUNC',
1N/A # if no value is supplied, then we retrieve the 1N/A # value of the cookie, if any. For efficiency, we cache the parsed 1N/A # cookies in our state variables. 1N/A # If no name is supplied, then retrieve the names of all our cookies. 1N/A return ()
unless $
self->{
'.cookies'};
1N/A # If we get here, we're creating a new cookie 1N/A return undef unless defined($
name) && $
name ne '';
# this is an error 1N/A'parse_keywordlist' => <<
'END_OF_FUNC',
1N/A'param_fetch' => <<
'END_OF_FUNC',
1N/A############################################### 1N/A# OTHER INFORMATION PROVIDED BY THE ENVIRONMENT 1N/A############################################### 1N/A#### Method: path_info 1N/A# Return the extra virtual path information provided 1N/A# after the URL (if any) 1N/A'path_info' => <<
'END_OF_FUNC',
1N/A }
elsif (!
defined($
self->{
'.path_info'}) ) {
1N/A# This function returns a potentially modified version of SCRIPT_NAME 1N/A# and PATH_INFO. Some HTTP servers do sanitise the paths in those 1N/A# variables. It is the case of at least Apache 2. If for instance the 1N/A# This is all fine except that some bogus CGI scripts expect 1N/A# Old versions of this module used to accomodate with those scripts, so 1N/A# this is why we do this here to keep those scripts backward compatible. 1N/A# Basically, we accomodate with those scripts but within limits, that is 1N/A# we only try to preserve the number of / that were provided by the user 1N/A# if $REQUEST_URI and "$SCRIPT_NAME$PATH_INFO" only differ by the number 1N/A# possibly sanitised by the HTTP server, so in the case of Apache 2: 1N/A# Future versions of this module may no longer do that, so one should 1N/A# avoid relying on the browser, proxy, server, and CGI.pm preserving the 1N/A# number of consecutive slashes as no guarantee can be made there. 1N/A'_name_and_path_from_env' => <<
'END_OF_FUNC',
1N/A if ($
uri ne "$script_name$path_info") {
1N/A # REQUEST_URI and SCRIPT_NAME . PATH_INFO only differ by the 1N/A # numer of consecutive slashes, so we can extract the info from 1N/A#### Method: request_method 1N/A# Returns 'POST', 'GET', 'PUT' or 'HEAD' 1N/A'request_method' => <<
'END_OF_FUNC',
1N/A return (
defined $
ENV{
'REQUEST_METHOD'}) ? $
ENV{
'REQUEST_METHOD'} :
undef;
1N/A#### Method: content_type 1N/A# Returns the content_type string 1N/A'content_type' => <<
'END_OF_FUNC',
1N/A return (
defined $
ENV{
'CONTENT_TYPE'}) ? $
ENV{
'CONTENT_TYPE'} :
undef;
1N/A#### Method: path_translated 1N/A# Return the physical path information provided 1N/A# by the URL (if any) 1N/A'path_translated' => <<
'END_OF_FUNC',
1N/A return (
defined $
ENV{
'PATH_TRANSLATED'}) ? $
ENV{
'PATH_TRANSLATED'} :
undef;
1N/A#### Method: request_uri 1N/A# Return the literal request URI 1N/A'request_uri' => <<
'END_OF_FUNC',
1N/A return (
defined $
ENV{
'REQUEST_URI'}) ? $
ENV{
'REQUEST_URI'} :
undef;
1N/A#### Method: query_string 1N/A# Synthesize a query string from our current 1N/A'query_string' => <<
'END_OF_FUNC',
1N/A for (
keys %{$
self->{
'.fieldnames'}}) {
1N/A# Without parameters, returns an array of the 1N/A# MIME types the browser accepts. 1N/A# With a single parameter equal to a MIME 1N/A# type, will return undef if the browser won't 1N/A# accept it, 1 if the browser accepts it but 1N/A# doesn't give a preference, or a floating point 1N/A# value between 0.0 and 1.0 if the browser 1N/A# declares a quantitative score for it. 1N/A# This handles MIME type globs correctly. 1N/A'Accept' => <<
'END_OF_FUNC',
1N/A # if a search type is provided, we may need to 1N/A # perform a pattern matching operation. 1N/A # The MIME types use a glob mechanism, which 1N/A # is easily translated into a perl pattern match 1N/A # First return the preference for directly supported 1N/A # Didn't get it, so try pattern matching. 1N/A next unless /\*/;
# not a pattern match 1N/A ($
pat = $_) =~ s/([^\w*])/\\$
1/g;
# escape meta characters 1N/A $
pat =~ s/\*/.*/g;
# turn it into a pattern 1N/A#### Method: user_agent 1N/A# If called with no parameters, returns the user agent. 1N/A# If called with one parameter, does a pattern match (case 1N/A# insensitive) on the user agent. 1N/A'user_agent' => <<
'END_OF_FUNC',
1N/A#### Method: raw_cookie 1N/A# Returns the magic cookies for the session. 1N/A# The cookies are not parsed or altered in any way, i.e. 1N/A# cookies are returned exactly as given in the HTTP 1N/A# headers. If a cookie name is given, only that cookie's 1N/A# value is returned, otherwise the entire raw cookie 1N/A'raw_cookie' => <<
'END_OF_FUNC',
1N/A return ()
unless $
self->{
'.raw_cookies'};
1N/A#### Method: virtual_host 1N/A# Return the name of the virtual_host, which 1N/A# is not always the same as the server 1N/A'virtual_host' => <<
'END_OF_FUNC',
1N/A $
vh =~ s/:\d+$//;
# get rid of port number 1N/A#### Method: remote_host 1N/A# Return the name of the remote host, or its IP 1N/A# address if unavailable. If this variable isn't 1N/A# defined, it returns "localhost" for debugging 1N/A'remote_host' => <<
'END_OF_FUNC',
1N/A return $
ENV{
'REMOTE_HOST'} || $
ENV{
'REMOTE_ADDR'}
1N/A#### Method: remote_addr 1N/A# Return the IP addr of the remote host. 1N/A'remote_addr' => <<
'END_OF_FUNC',
1N/A return $
ENV{
'REMOTE_ADDR'} ||
'127.0.0.1';
1N/A#### Method: script_name 1N/A# Return the partial URL to this script for 1N/A# self-referencing scripts. Also see 1N/A# self_url(), which returns a URL with all state information 1N/A'script_name' => <<
'END_OF_FUNC',
1N/A $
self->{
'.script_name'} =
shift @p;
1N/A }
elsif (!
exists $
self->{
'.script_name'}) {
1N/A# Return the HTTP_REFERER: useful for generating 1N/A'referer' => <<
'END_OF_FUNC',
1N/A#### Method: server_name 1N/A# Return the name of the server 1N/A'server_name' => <<
'END_OF_FUNC',
1N/A return $
ENV{
'SERVER_NAME'} ||
'localhost';
1N/A#### Method: server_software 1N/A# Return the name of the server software 1N/A'server_software' => <<
'END_OF_FUNC',
1N/A return $
ENV{
'SERVER_SOFTWARE'} ||
'cmdline';
1N/A#### Method: virtual_port 1N/A# Return the server port, taking virtual hosts into account 1N/A'virtual_port' => <<
'END_OF_FUNC',
1N/A return ($
vh =~ /:(\d+)$/)[
0] || ($
protocol eq 'https' ?
443 :
80);
1N/A#### Method: server_port 1N/A# Return the tcp/ip port the server is running on 1N/A'server_port' => <<
'END_OF_FUNC',
1N/A return $
ENV{
'SERVER_PORT'} ||
80;
# for debugging 1N/A#### Method: server_protocol 1N/A# Return the protocol (usually HTTP/1.0) 1N/A'server_protocol' => <<
'END_OF_FUNC',
1N/A return $
ENV{
'SERVER_PROTOCOL'} ||
'HTTP/1.0';
# for debugging 1N/A# Return the value of an HTTP variable, or 1N/A# the list of variables if none provided 1N/A'http' => <<
'END_OF_FUNC',
1N/A return $
ENV{
"HTTP_$parameter"};
1N/A# Return the value of HTTPS, or 1N/A# the value of an HTTPS variable, or 1N/A# the list of variables 1N/A'https' => <<
'END_OF_FUNC',
1N/A return $
ENV{
"HTTPS_$parameter"};
1N/A#### Method: protocol 1N/A# Return the protocol (http or https currently) 1N/A'protocol' => <<
'END_OF_FUNC',
1N/A return "\L$protocol\E";
1N/A#### Method: remote_ident 1N/A# Return the identity of the remote user 1N/A# (but only if his host is running identd) 1N/A'remote_ident' => <<
'END_OF_FUNC',
1N/A return (
defined $
ENV{
'REMOTE_IDENT'}) ? $
ENV{
'REMOTE_IDENT'} :
undef;
1N/A#### Method: auth_type 1N/A'auth_type' => <<
'END_OF_FUNC',
1N/A return (
defined $
ENV{
'AUTH_TYPE'}) ? $
ENV{
'AUTH_TYPE'} :
undef;
1N/A#### Method: remote_user 1N/A# Return the authorization name used for user 1N/A'remote_user' => <<
'END_OF_FUNC',
1N/A return (
defined $
ENV{
'REMOTE_USER'}) ? $
ENV{
'REMOTE_USER'} :
undef;
1N/A#### Method: user_name 1N/A# Try to return the remote user's name by hook or by 1N/A'user_name' => <<
'END_OF_FUNC',
1N/A#### Method: nosticky 1N/A# Set or return the NOSTICKY global flag 1N/A'nosticky' => <<
'END_OF_FUNC',
1N/A# Set or return the NPH global flag 1N/A'nph' => <<
'END_OF_FUNC',
1N/A#### Method: private_tempfiles 1N/A# Set or return the private_tempfiles global flag 1N/A'private_tempfiles' => <<
'END_OF_FUNC',
1N/A#### Method: close_upload_files 1N/A# Set or return the close_upload_files global flag 1N/A'close_upload_files' => <<
'END_OF_FUNC',
1N/A#### Method: default_dtd 1N/A# Set or return the default_dtd global 1N/A'default_dtd' => <<
'END_OF_FUNC',
1N/A# -------------- really private subroutines ----------------- 1N/A'_maybe_escapeHTML' => <<
'END_OF_FUNC',
1N/A # hack to work around earlier hacks 1N/A push @_,$_[
0]
if @_==
1 && $_[
0]
eq 'CGI';
1N/A'previous_or_default' => <<
'END_OF_FUNC',
1N/A'register_parameter' => <<
'END_OF_FUNC',
1N/A'get_fields' => <<
'END_OF_FUNC',
1N/A '-values'=>[
keys %{$
self->{
'.parametersToAdd'}}],
1N/A'read_from_cmdline' => <<
'END_OF_FUNC',
1N/A print STDERR "(offline mode: enter name=value pairs on standard input; press ^D or ^Z when done)\n";
1N/A if (
"@words"=~/=/) {
1N/A# subroutine: read_multipart 1N/A# Read multipart data and store it into our parameters. 1N/A# An interesting feature is that if any of the parts is a file, we 1N/A# create a temporary file and open up a filehandle on it so that the 1N/A# caller can read from it if necessary. 1N/A'read_multipart' => <<
'END_OF_FUNC',
1N/A $
header{
'Content-Disposition'} ||=
'';
# quench uninit variable warning 1N/A # See RFC 1867, 2183, 2045 1N/A # NB: File content will be loaded into memory should 1N/A # content-disposition parsing fail. 1N/A =~/
filename=((
"[^"]*
")|([a-z\d!\#'\*\+,\.^_\`\{\}\|\~]*))/i; 1N/A # Test for Opera's multiple upload feature 1N/A # add this parameter to our list 1N/A # If no filename specified, then just read the data and assign it 1N/A # to our parameter list. 1N/A # If we get here, then we are dealing with a potentially large 1N/A # uploaded form. Save the data to a temporary file, then open 1N/A # the file for reading. 1N/A # skip the file if uploads disabled 1N/A # set the filename to some recognizable value 1N/A # choose a relatively unpredictable tmpfile sequence number 1N/A my $
seqno =
unpack(
"%16C*",
join(
'',
localtime,
grep {
defined $_}
values %
ENV));
1N/A # together with the body for later parsing with an external 1N/A # MIME parser module 1N/A if (
defined $
self->{
'.upload_hook'})
1N/A # back up to beginning of file 1N/A ## Close the filehandle if requested this allows a multipart MIME 1N/A ## upload to contain many files, and we won't die due to too many 1N/A ## open file handles. The user can access the files using the hash 1N/A # Save some information about the uploaded file where we can get 1N/A # Use the typeglob as the key, as this is guaranteed to be 1N/A # unique for each filehandle. Don't use the file descriptor as 1N/A # this will be re-used for each filehandle if the 1N/A # close_upload_files feature is used. 1N/A# subroutine: read_multipart_related 1N/A# first parameter sets the start of the data. The part identified by 1N/A# this Content-ID will not be stored as a file upload, but will be 1N/A# returned by this method. All other parts will be available as file 1N/A# uploads accessible by their Content-ID 1N/A'read_multipart_related' => <<
'END_OF_FUNC',
1N/A # If this is the start part, then just read the data and assign it 1N/A # to our return variable. 1N/A # add this parameter to our list 1N/A # If we get here, then we are dealing with a potentially large 1N/A # uploaded form. Save the data to a temporary file, then open 1N/A # the file for reading. 1N/A # skip the file if uploads disabled 1N/A # choose a relatively unpredictable tmpfile sequence number 1N/A my $
seqno =
unpack(
"%16C*",
join(
'',
localtime,
grep {
defined $_}
values %
ENV));
1N/A if (
defined $
self->{
'.upload_hook'})
1N/A # back up to beginning of file 1N/A ## Close the filehandle if requested this allows a multipart MIME 1N/A ## upload to contain many files, and we won't die due to too many 1N/A ## open file handles. The user can access the files using the hash 1N/A # Save some information about the uploaded file where we can get 1N/A # Use the typeglob as the key, as this is guaranteed to be 1N/A # unique for each filehandle. Don't use the file descriptor as 1N/A # this will be re-used for each filehandle if the 1N/A # close_upload_files feature is used. 1N/A'upload' =><<
'END_OF_FUNC',
1N/A'tmpFileName' => <<
'END_OF_FUNC',
1N/A'uploadInfo' => <<
'END_OF_FUNC',
1N/A# internal routine, don't use 1N/A'_set_values_and_labels' => <<
'END_OF_FUNC',
1N/A $$l = $v
if ref($v)
eq 'HASH' && !
ref($$l);
1N/A return $v
if !
ref($v);
1N/A return ref($v)
eq 'HASH' ?
keys %$v : @$v;
1N/A# internal routine, don't use 1N/A'_set_attributes' => <<
'END_OF_FUNC',
1N/A $
attribs .=
"@{[lc($clean_attrib)]}=\"$attributes->{$element}{$attrib}\" ";
1N/A'_compile_all' => <<
'END_OF_FUNC',
1N/A next if defined(&$_);
1N/A######################################################### 1N/A# Globals and stubs for other packages that we use. 1N/A######################################################### 1N/A################### Fh -- lightweight filehandle ############### 1N/A'asString' => <<
'END_OF_FUNC',
1N/A # get rid of package name 1N/A $i =~ s/%(..)/
chr(
hex($
1)) /
eg;
1N/A# This was an extremely clever patch that allowed "use strict refs". 1N/A# Unfortunately it relied on another bug that caused leaky file descriptors. 1N/A# The underlying bug has been fixed, so this no longer works. However 1N/A# "strict refs" still works for some reason. 1N/A# return ${*{$self}{SCALAR}}; 1N/A'compare' => <<
'END_OF_FUNC',
1N/A'new' => <<
'END_OF_FUNC',
1N/A # Note this same regex is also used elsewhere in the same file for CGITempFile::new 1N/A $
file =~ m!^([a-
zA-
Z0-
9_ \
'\":/.\$\\\+-]+)$! || return; 1N/A'handle' => <<
'END_OF_FUNC',
1N/A######################## MultipartBuffer #################### 1N/A# how many bytes to read at a time. We use 1N/A# a 4K buffer by default. 1N/A#reuse the autoload function 1N/A# avoid autoloader warnings 1N/A############################################################################### 1N/A################# THESE FUNCTIONS ARE AUTOLOADED ON DEMAND #################### 1N/A############################################################################### 1N/A'new' => <<
'END_OF_FUNC',
1N/A # If the user types garbage into the file upload field, 1N/A # then Netscape passes NOTHING to the server (not good). 1N/A # We may hang on this read in that case. So we implement 1N/A # a read timeout. If nothing is ready to read 1N/A # by then, we return. 1N/A # Netscape seems to be a little bit unreliable 1N/A # about providing boundary strings. 1N/A # Under the MIME spec, the boundary consists of the 1N/A # characters "--" PLUS the Boundary string 1N/A # BUG: IE 3.01 on the Macintosh uses just the boundary -- not 1N/A # the two extra hyphens. We do a special case here on the user-agent!!!! 1N/A }
else {
# otherwise we find it ourselves 1N/A ($
old,$/) = ($/,$
CRLF);
# read a CRLF-delimited line 1N/A $/ = $
old;
# restore old line separator 1N/A # Read the preamble and the topmost (boundary) line plus the CRLF. 1N/A die "Malformed multipart POST: data truncated\n" if $
self->
eof;
1N/A'readHeader' => <<
'END_OF_FUNC',
1N/A # this was a bad idea 1N/A # $FILLUNIT *= 2 if length($self->{BUFFER}) >= $FILLUNIT; 1N/A #EBCDIC NOTE: translate header into EBCDIC, but watch out for continuation lines! 1N/A warn "untranslated header=$header\n" if DEBUG;
1N/A warn "translated header=$header\n" if DEBUG;
1N/A # See RFC 2045 Appendix A and RFC 822 sections 3.4.8 1N/A # (Folding Long Header Fields), 3.4.3 (Comments) 1N/A # and 3.4.5 (Quoted-Strings). 1N/A# This reads and returns the body as a single scalar value. 1N/A'readBody' => <<
'END_OF_FUNC',
1N/A #EBCDIC NOTE: want to translate returnval into EBCDIC HERE 1N/A warn "untranslated body=$returnval\n" if DEBUG;
1N/A warn "translated body=$returnval\n" if DEBUG;
1N/A# This will read $bytes or until the boundary is hit, whichever happens 1N/A# first. After the boundary is hit, we return undef. The next read will 1N/A# skip over the boundary and begin reading again; 1N/A'read' => <<
'END_OF_FUNC',
1N/A # default number of bytes to read 1N/A # Fill up our internal buffer in such a way that the boundary 1N/A # is never split between reads. 1N/A # Find the boundary in the buffer (it may not be there). 1N/A warn "boundary=$self->{BOUNDARY} length=$self->{LENGTH} start=$start\n" if DEBUG;
1N/A # protect against malformed multipart POST operations 1N/A #EBCDIC NOTE: want to translate boundary search into ASCII here. 1N/A # If the boundary begins the data, then skip past it 1N/A # clear us out completely if we've hit the last boundary. 1N/A # just remove the boundary. 1N/A if ($
start >
0) {
# read up to the boundary 1N/A }
else {
# read the requested number of bytes 1N/A # leave enough bytes in the buffer to allow us to read 1N/A # the boundary. Thanks to Kevin Hendrick for finding 1N/A # If we hit the boundary, remove the CRLF from the end. 1N/A# This fills up our internal buffer in such a way that the 1N/A# boundary is never split between reads 1N/A'fillBuffer' => <<
'END_OF_FUNC',
1N/A # Try to read some data. We may hang here if the browser is screwed up. 1N/A warn "bytesToRead=$bytesToRead, bufferLength=$bufferLength, buffer=$self->{BUFFER}\n" if DEBUG;
1N/A # An apparent bug in the Apache server causes the read() 1N/A # to return zero bytes repeatedly without blocking if the 1N/A # remote user aborts during a file transfer. I don't know how 1N/A # they manage this, but the workaround is to abort if we get 1N/A # more than SPIN_LOOP_MAX consecutive zero reads. 1N/A die "CGI.pm: Server closed socket during multipart read (client aborted?).\n" 1N/A# Return true when we've finished reading 1N/A'eof' => <<
'END_OF_FUNC' 1N/A#################################################################################### 1N/A################################## TEMPORARY FILES ################################# 1N/A#################################################################################### 1N/A @
TEMP=(
"${SL}usr${SL}tmp",
"${SL}var${SL}tmp",
1N/A "C:${SL}temp",
"${SL}tmp",
"${SL}temp",
1N/A "${vol}${SL}Temporary Items",
1N/A "${SL}WWW_ROOT",
"${SL}SYS\$SCRATCH",
1N/A "C:${SL}system${SL}temp");
1N/A # PeterH: These evars may not exist if this is invoked within a service and untainting 1N/A # is in effect - with 'use warnings' the undefined array entries causes Perl to die 1N/A # this feature was supposed to provide per-user tmpfiles, but 1N/A # it is problematic. 1N/A # unshift(@TEMP,(getpwuid($<))[7].'/tmp') if $CGI::OS eq 'UNIX'; 1N/A # Rob: getpwuid() is unfortunately UNIX specific. On brain dead OS'es this 1N/A # : can generate a 'getpwuid() not implemented' exception, even though 1N/A # : it's never called. Found under DOS/Win with the DJGPP perl port. 1N/A # : Refer to getpwuid() only at run-time if we're fortunate and have UNIX. 1N/A # unshift(@TEMP,(eval {(getpwuid($>))[7]}).'/tmp') if $CGI::OS eq 'UNIX' and $> != 0; 1N/A# cute feature, but overload implementation broke it 1N/A# %OVERLOAD = ('""'=>'as_string'); 1N/A $$
self =~ m!^([a-
zA-
Z0-
9_ \
'\":/.\$\\~-]+)$! || return; 1N/A unlink $
safe;
# get rid of the file 1N/A############################################################################### 1N/A################# THESE FUNCTIONS ARE AUTOLOADED ON DEMAND #################### 1N/A############################################################################### 1N/A'new' => <<
'END_OF_FUNC',
1N/A # check that it is a more-or-less valid filename 1N/A # Note this same regex is also used elsewhere in the same file for Fh::new 1N/A # this used to untaint, now it doesn't 1N/A'as_string' => <<
'END_OF_FUNC' 1N/A# We get a whole bunch of warnings about "possibly uninitialized variables" 1N/A# when running with the -w switch. Touch them all once to get rid of the 1N/A# warnings. This is ugly and I hate it. 1N/ACGI - Handle Common Gateway Interface requests and responses 1N/A # Process an HTTP request 1N/A @values = $q->param('form_field'); 1N/A $fh = $q->upload('file_field'); 1N/A $riddle = $query->cookie('riddle_name'); 1N/A %answers = $query->cookie('answers'); 1N/A # Prepare various HTTP responses 1N/A $cookie1 = $q->cookie(-name=>'riddle_name', -value=>"The Sphynx's Question"); 1N/A $cookie2 = $q->cookie(-name=>'answers', -value=>\%answers); 1N/A -cookie => [$cookie1,$cookie2] 1N/ACGI.pm is a stable, complete and mature solution for processing and preparing 1N/AHTTP requests and responses. Major features including processing form 1N/Asubmissions, file uploads, reading and writing cookies, query string generation 1N/Aand manipulation, and processing and preparing HTTP headers. Some HTML 1N/Ageneration utilities are included as well. 1N/Awith built-in support for mod_perl and mod_perl2 as well as FastCGI. 1N/AIt has the benefit of having developed and refined over 10 years with input 1N/Afrom dozens of contributors and being deployed on thousands of websites. 1N/ACGI.pm has been included in the Perl distribution since Perl 5.4, and has 1N/Abecome a de-facto standard. 1N/A=head2 PROGRAMMING STYLE 1N/AThere are two styles of programming with CGI.pm, an object-oriented 1N/Astyle and a function-oriented style. In the object-oriented style you 1N/Acreate one or more CGI objects and then use object methods to create 1N/Athe various elements of the page. Each CGI object starts out with the 1N/Alist of named parameters that were passed to your CGI script by the 1N/Aserver. You can modify the objects, save them to a file or database 1N/Aand recreate them. Because each object corresponds to the "state" of 1N/Athe CGI script, and because each object's parameter list is 1N/Aindependent of the others, this allows you to save the state of the 1N/Ascript and restore it later. 1N/AFor example, using the object oriented style, here is how you create 1N/Aa simple "Hello World" HTML page: 1N/A use CGI; # load CGI routines 1N/A $q = CGI->new; # create new CGI object 1N/A print $q->header, # create the HTTP header 1N/A $q->start_html('hello world'), # start the HTML 1N/A $q->h1('hello world'), # level 1 header 1N/A $q->end_html; # end the HTML 1N/AIn the function-oriented style, there is one default CGI object that 1N/Ayou rarely deal with directly. Instead you just call functions to 1N/Aretrieve CGI parameters, create HTML tags, manage cookies, and so 1N/Aon. This provides you with a cleaner programming interface, but 1N/Alimits you to using one CGI object at a time. The following example 1N/Aprints the same page, but uses the function-oriented interface. 1N/AThe main differences are that we now need to import a set of functions 1N/Ainto our name space (usually the "standard" functions), and we don't 1N/Aneed to create the CGI object. 1N/A use CGI qw/:standard/; # load standard CGI routines 1N/A print header, # create the HTTP header 1N/A start_html('hello world'), # start the HTML 1N/A h1('hello world'), # level 1 header 1N/A end_html; # end the HTML 1N/AThe examples in this document mainly use the object-oriented style. 1N/ASee HOW TO IMPORT FUNCTIONS for important information on 1N/AMost CGI.pm routines accept several arguments, sometimes as many as 20 1N/Aoptional ones! To simplify this interface, all routines use a named 1N/Aargument calling style that looks like this: 1N/AEach argument name is preceded by a dash. Neither case nor order 1N/Amatters in the argument list. -type, -Type, and -TYPE are all 1N/Aacceptable. In fact, only the first argument needs to begin with a 1N/Adash. If a dash is present in the first argument, CGI.pm assumes 1N/Adashes for the subsequent ones. 1N/ASeveral routines are commonly called with just one argument. In the 1N/Acase of these routines you can provide the single argument without an 1N/Aargument name. header() happens to be one of these routines. In this 1N/Acase, the single argument is the document type. 1N/AOther such routines are documented below. 1N/ASometimes named arguments expect a scalar, sometimes a reference to an 1N/Aarray, and sometimes a reference to a hash. Often, you can pass any 1N/Atype of argument and the routine will do whatever is most appropriate. 1N/AFor example, the param() routine is used to set a CGI parameter to a 1N/Asingle or a multi-valued value. The two cases are shown below: 1N/A $q->param(-name=>'veggie',-value=>'tomato'); 1N/A $q->param(-name=>'veggie',-value=>['tomato','tomahto','potato','potahto']); 1N/AA large number of routines in CGI.pm actually aren't specifically 1N/Adefined in the module, but are generated automatically as needed. 1N/AThese are the "HTML shortcuts," routines that generate HTML tags for 1N/Ause in dynamically-generated pages. HTML tags have both attributes 1N/A(the attribute="value" pairs within the tag itself) and contents (the 1N/Apart between the opening and closing pairs.) To distinguish between 1N/Aattributes and contents, CGI.pm uses the convention of passing HTML 1N/Aattributes as a hash reference as the first argument, and the 1N/Acontents, if any, as any subsequent arguments. It works out like 1N/A h1('some','contents'); <h1>some contents</h1> 1N/A h1({-align=>left}); <h1 align="LEFT"> 1N/A h1({-align=>left},'contents'); <h1 align="LEFT">contents</h1> 1N/AHTML tags are described in more detail later. 1N/AMany newcomers to CGI.pm are puzzled by the difference between the 1N/Acalling conventions for the HTML shortcuts, which require curly braces 1N/Aaround the HTML tag attributes, and the calling conventions for other 1N/Aroutines, which manage to generate attributes without the curly 1N/Abrackets. Don't be confused. As a convenience the curly braces are 1N/Aoptional in all but the HTML shortcuts. If you like, you can use 1N/Acurly braces when calling any routine that takes named arguments. For 1N/A print $q->header( {-type=>'image/gif',-expires=>'+3d'} ); 1N/AIf you use the B<-w> switch, you will be warned that some CGI.pm argument 1N/Anames conflict with built-in Perl functions. The most frequent of 1N/Athese is the -values argument, used to create multi-valued menus, 1N/Aradio button clusters and the like. To get around this warning, you 1N/Ahave several choices: 1N/AUse another name for the argument, if one is available. 1N/AFor example, -value is an alias for -values. 1N/AChange the capitalization, e.g. -Values 1N/APut quotes around the argument name, e.g. '-values' 1N/AMany routines will do something useful with a named argument that it 1N/Adoesn't recognize. For example, you can produce non-standard HTTP 1N/Aheader fields by providing them as named arguments: 1N/A -cost => 'Three smackers', 1N/A -annoyance_level => 'high', 1N/A -complaints_to => 'bit bucket'); 1N/AThis will produce the following nonstandard HTTP header: 1N/A Cost: Three smackers 1N/A Annoyance-level: high 1N/A Complaints-to: bit bucket 1N/ANotice the way that underscores are translated automatically into 1N/Ahyphens. HTML-generating routines perform a different type of 1N/AThis feature allows you to keep up with the rapidly changing HTTP and 1N/A=head2 CREATING A NEW QUERY OBJECT (OBJECT-ORIENTED STYLE): 1N/AThis will parse the input (from both POST and GET methods) and store 1N/Ait into a perl5 object called $query. 1N/AAny filehandles from file uploads will have their position reset to 1N/Athe beginning of the file. 1N/A=head2 CREATING A NEW QUERY OBJECT FROM AN INPUT FILE 1N/A $query = CGI->new(INPUTFILE); 1N/AIf you provide a file handle to the new() method, it will read 1N/Aparameters from the file (or STDIN, or whatever). The file can be in 1N/Aany of the forms describing below under debugging (i.e. a series of 1N/Anewline delimited TAG=VALUE pairs will work). Conveniently, this type 1N/Aof file is created by the save() method (see below). Multiple records 1N/Acan be saved and restored. 1N/APerl purists will be pleased to know that this syntax accepts 1N/Areferences to file handles, or even references to filehandle globs, 1N/Awhich is the "official" way to pass a filehandle: 1N/A $query = CGI->new(\*STDIN); 1N/AYou can also initialize the CGI object with a FileHandle or IO::File 1N/AIf you are using the function-oriented interface and want to 1N/Ainitialize CGI state from a file handle, the way to do this is with 1N/AB<restore_parameters()>. This will (re)initialize the 1N/Adefault CGI object from the indicated file handle. 1N/A open (IN,"test.in") || die; 1N/A restore_parameters(IN); 1N/AYou can also initialize the query object from a hash 1N/A $query = CGI->new( {'dinosaur'=>'barney', 1N/A 'song'=>'I love you', 1N/Aor from a properly formatted, URL-escaped query string: 1N/A $query = CGI->new('dinosaur=barney&color=purple'); 1N/Aor from a previously existing CGI object (currently this clones the 1N/Aparameter list, but none of the other object-specific fields, such as 1N/A $old_query = CGI->new; 1N/A $new_query = CGI->new($old_query); 1N/ATo create an empty query, initialize it from an empty string or hash: 1N/A $empty_query = CGI->new(""); 1N/A $empty_query = CGI->new({}); 1N/A=head2 FETCHING A LIST OF KEYWORDS FROM THE QUERY: 1N/A @keywords = $query->keywords 1N/AIf the script was invoked as the result of an <ISINDEX> search, the 1N/Aparsed keywords can be obtained as an array using the keywords() method. 1N/A=head2 FETCHING THE NAMES OF ALL THE PARAMETERS PASSED TO YOUR SCRIPT: 1N/A @names = $query->param 1N/AIf the script was invoked with a parameter list 1N/A(e.g. "name1=value1&name2=value2&name3=value3"), the param() method 1N/Awill return the parameter names as a list. If the script was invoked 1N/Aas an <ISINDEX> script and contains a string without ampersands 1N/A(e.g. "value1+value2+value3") , there will be a single parameter named 1N/A"keywords" containing the "+"-delimited keywords. 1N/ANOTE: As of version 1.5, the array of parameter names returned will 1N/Abe in the same order as they were submitted by the browser. 1N/AUsually this order is the same as the order in which the 1N/Aparameters are defined in the form (however, this isn't part 1N/Aof the spec, and so isn't guaranteed). 1N/A=head2 FETCHING THE VALUE OR VALUES OF A SINGLE NAMED PARAMETER: 1N/A @values = $query->param('foo'); 1N/A $value = $query->param('foo'); 1N/APass the param() method a single argument to fetch the value of the 1N/Anamed parameter. If the parameter is multivalued (e.g. from multiple 1N/Aselections in a scrolling list), you can ask to receive an array. Otherwise 1N/Athe method will return a single value. 1N/AIf a value is not given in the query string, as in the queries 1N/A"name1=&name2=", it will be returned as an empty string. 1N/AIf the parameter does not exist at all, then param() will return undef 1N/Ain a scalar context, and the empty list in a list context. 1N/A=head2 SETTING THE VALUE(S) OF A NAMED PARAMETER: 1N/A $query->param('foo','an','array','of','values'); 1N/AThis sets the value for the named parameter 'foo' to an array of 1N/Avalues. This is one way to change the value of a field AFTER 1N/Athe script has been invoked once before. (Another way is with 1N/Athe -override parameter accepted by all methods that generate 1N/Aparam() also recognizes a named parameter style of calling described 1N/Ain more detail later: 1N/A $query->param(-name=>'foo',-values=>['an','array','of','values']); 1N/A $query->param(-name=>'foo',-value=>'the value'); 1N/A=head2 APPENDING ADDITIONAL VALUES TO A NAMED PARAMETER: 1N/A $query->append(-name=>'foo',-values=>['yet','more','values']); 1N/AThis adds a value or list of values to the named parameter. The 1N/Avalues are appended to the end of the parameter if it already exists. 1N/AOtherwise the parameter is created. Note that this method only 1N/Arecognizes the named argument calling syntax. 1N/A=head2 IMPORTING ALL PARAMETERS INTO A NAMESPACE: 1N/A $query->import_names('R'); 1N/AThis creates a series of variables in the 'R' namespace. For example, 1N/A$R::foo, @R:foo. For keyword lists, a variable @R::keywords will appear. 1N/AIf no namespace is given, this method will assume 'Q'. 1N/AWARNING: don't import anything into 'main'; this is a major security 1N/ANOTE 1: Variable names are transformed as necessary into legal Perl 1N/Avariable names. All non-legal characters are transformed into 1N/Aunderscores. If you need to keep the original names, you should use 1N/Athe param() method instead to access CGI variables by name. 1N/ANOTE 2: In older versions, this method was called B<import()>. As of version 2.20, 1N/Athis name has been removed completely to avoid conflict with the built-in 1N/APerl module B<import> operator. 1N/A=head2 DELETING A PARAMETER COMPLETELY: 1N/A $query->delete('foo','bar','baz'); 1N/AThis completely clears a list of parameters. It sometimes useful for 1N/Aresetting parameters that you don't want passed down between script 1N/AIf you are using the function call interface, use "Delete()" instead 1N/Ato avoid conflicts with Perl's built-in delete operator. 1N/A=head2 DELETING ALL PARAMETERS: 1N/A $query->delete_all(); 1N/AThis clears the CGI object completely. It might be useful to ensure 1N/Athat all the defaults are taken when you create a fill-out form. 1N/AUse Delete_all() instead if you are using the function call interface. 1N/A=head2 HANDLING NON-URLENCODED ARGUMENTS 1N/Ainstead be returned as-is in a parameter named POSTDATA. To retrieve 1N/Ait, use code like this: 1N/A my $data = $query->param('POSTDATA'); 1N/ALikewise if PUTed data can be retrieved with code like this: 1N/A my $data = $query->param('PUTDATA'); 1N/A(If you don't know what the preceding means, don't worry about it. It 1N/Aonly affects people trying to use CGI for XML processing and other 1N/A=head2 DIRECT ACCESS TO THE PARAMETER LIST: 1N/A $q->param_fetch('address')->[1] = '1313 Mockingbird Lane'; 1N/A unshift @{$q->param_fetch(-name=>'address')},'George Munster'; 1N/AIf you need access to the parameter list in a way that isn't covered 1N/Aby the methods given in the previous sections, you can obtain a direct 1N/Acalling the B<param_fetch()> method with the name of the parameter. This 1N/Awill return an array reference to the named parameter, which you then 1N/Acan manipulate in any way you like. 1N/AYou can also use a named argument style using the B<-name> argument. 1N/A=head2 FETCHING THE PARAMETER LIST AS A HASH: 1N/A print $params->{'address'}; 1N/A @foo = split("\0",$params->{'foo'}); 1N/AMany people want to fetch the entire parameter list as a hash in which 1N/Athe keys are the names of the CGI parameters, and the values are the 1N/Aparameters' values. The Vars() method does this. Called in a scalar 1N/Acontext, it returns the parameter list as a tied hash reference. 1N/AChanging a key changes the value of the parameter in the underlying 1N/ACGI parameter list. Called in a list context, it returns the 1N/Aparameter list as an ordinary hash. This allows you to read the 1N/Acontents of the parameter list, but not to change it. 1N/AWhen using this, the thing you must watch out for are multivalued CGI 1N/Aparameters. Because a hash cannot distinguish between scalar and 1N/Alist context, multivalued parameters will be returned as a packed 1N/Astring, separated by the "\0" (null) character. You must split this 1N/Apacked string in order to get at the individual values. This is the 1N/Amodule for Perl version 4. 1N/AIf you wish to use Vars() as a function, import the I<:cgi-lib> set of 1N/Afunction calls (also see the section on CGI-LIB compatibility). 1N/A=head2 SAVING THE STATE OF THE SCRIPT TO A FILE: 1N/A $query->save(\*FILEHANDLE) 1N/AThis will write the current state of the form to the provided 1N/Afilehandle. You can read it back in by providing a filehandle 1N/Ato the new() method. Note that the filehandle can be a file, a pipe, 1N/AThe format of the saved file is: 1N/ABoth name and value are URL escaped. Multi-valued CGI parameters are 1N/Arepresented as repeated names. A session record is delimited by a 1N/Asingle = symbol. You can write out multiple records and read them 1N/Aback in with several calls to B<new>. You can do this across several 1N/Asessions by opening the file in append mode, allowing you to create 1N/Aprimitive guest books, or to keep a history of users' queries. Here's 1N/Aa short example of creating multiple session records: 1N/A open (OUT,'>>','test.out') || die; 1N/A $q->param(-name=>'counter',-value=>$_); 1N/A # reopen for reading 1N/A open (IN,'<','test.out') || die; 1N/A my $q = CGI->new(\*IN); 1N/A print $q->param('counter'),"\n"; 1N/AWhitehead Genome Center's data exchange format "Boulderio", and can be 1N/Amanipulated and even databased using Boulderio utilities. See 1N/AIf you wish to use this method from the function-oriented (non-OO) 1N/Ainterface, the exported name for this method is B<save_parameters()>. 1N/A=head2 RETRIEVING CGI ERRORS 1N/AErrors can occur while processing user input, particularly when 1N/Aprocessing uploaded files. When these errors occur, CGI will stop 1N/Aprocessing and return an empty parameter list. You can test for 1N/Athe existence and nature of errors using the I<cgi_error()> function. 1N/AThe error messages are formatted as HTTP status codes. You can either 1N/Aincorporate the error text into an HTML page, or use it as the value 1N/A my $error = $q->cgi_error; 1N/A print $q->header(-status=>$error), 1N/A $q->start_html('Problems'), 1N/A $q->h2('Request not processed'), 1N/AWhen using the function-oriented interface (see the next section), 1N/Aerrors may only occur the first time you call I<param()>. Be ready 1N/A=head2 USING THE FUNCTION-ORIENTED INTERFACE 1N/ATo use the function-oriented interface, you must specify which CGI.pm 1N/Aroutines or sets of routines to import into your script's namespace. 1N/AThere is a small overhead associated with this importation, but it 1N/A use CGI <list of methods>; 1N/AThe listed methods will be imported into the current package; you can 1N/Acall them directly without creating a CGI object first. This example 1N/Ashows how to import the B<param()> and B<header()> 1N/Amethods, and then use them directly: 1N/A use CGI 'param','header'; 1N/A $zipcode = param('zipcode'); 1N/AMore frequently, you'll import common sets of functions by referring 1N/Ato the groups by name. All function sets are preceded with a ":" 1N/Acharacter as in ":html3" (for tags defined in the HTML 3 standard). 1N/AHere is a list of the function sets you can import: 1N/AImport all CGI-handling methods, such as B<param()>, B<path_info()> 1N/AImport all fill-out form generating methods, such as B<textfield()>. 1N/AImport all methods that generate HTML 2.0 standard elements. 1N/AImport all methods that generate HTML 3.0 elements (such as 1N/A<table>, <super> and <sub>). 1N/AImport all methods that generate HTML 4 elements (such as 1N/A<abbrev>, <acronym> and <thead>). 1N/AImport the <blink>, <fontsize> and <center> tags. 1N/AImport all HTML-generating shortcuts (i.e. 'html2', 'html3', 'html4' and 'netscape') 1N/AImport "standard" features, 'html2', 'html3', 'html4', 'form' and 'cgi'. 1N/AImport all the available methods. For the full list, see the CGI.pm 1N/Acode, where the variable %EXPORT_TAGS is defined. 1N/AIf you import a function name that is not part of CGI.pm, the module 1N/Awill treat it as a new HTML tag and generate the appropriate 1N/Asubroutine. You can then use it like any other HTML tag. This is to 1N/Aprovide for the rapidly-evolving HTML "standard." For example, say 1N/AMicrosoft comes out with a new tag called <gradient> (which causes the 1N/Auser's desktop to be flooded with a rotating gradient fill until his 1N/Amachine reboots). You don't need to wait for a new version of CGI.pm 1N/Ato start using it immediately: 1N/A use CGI qw/:standard :html3 gradient/; 1N/A print gradient({-start=>'red',-end=>'blue'}); 1N/ANote that in the interests of execution speed CGI.pm does B<not> use 1N/Athe standard L<Exporter> syntax for specifying load symbols. This may 1N/Achange in the future. 1N/AIf you import any of the state-maintaining CGI or form-generating 1N/Amethods, a default CGI object will be created and initialized 1N/Aautomatically the first time you use any of the methods that require 1N/Aone to be present. This includes B<param()>, B<textfield()>, 1N/AB<submit()> and the like. (If you need direct access to the CGI 1N/Aobject, you can find it in the global variable B<$CGI::Q>). By 1N/Aimporting CGI.pm methods, you can create visually elegant scripts: 1N/A use CGI qw/:standard/; 1N/A start_html('Simple Script'), 1N/A h1('Simple Script'), 1N/A "What's your name? ",textfield('name'),p, 1N/A "What's the combination?", 1N/A checkbox_group(-name=>'words', 1N/A -values=>['eenie','meenie','minie','moe'], 1N/A -defaults=>['eenie','moe']),p, 1N/A "What's your favorite color?", 1N/A popup_menu(-name=>'color', 1N/A -values=>['red','green','blue','chartreuse']),p, 1N/A "Your name is ",em(param('name')),p, 1N/A "The keywords are: ",em(join(", ",param('words'))),p, 1N/A "Your favorite color is ",em(param('color')),".\n"; 1N/AIn addition to the function sets, there are a number of pragmas that 1N/Ayou can import. Pragmas, which are always preceded by a hyphen, 1N/Achange the way that CGI.pm functions in various ways. Pragmas, 1N/Afunction sets, and individual functions can all be imported in the 1N/Asame use() line. For example, the following use statement imports the 1N/Astandard set of functions and enables debugging mode (pragma 1N/A use CGI qw/:standard -debug/; 1N/AThe current list of pragmas is as follows: 1N/AWhen you I<use CGI -any>, then any method that the query object 1N/Adoesn't recognize will be interpreted as a new HTML tag. This allows 1N/Ayou to support the next I<ad hoc> HTML 1N/Aextension. This lets you go wild with new and unsupported tags: 1N/A print $q->gradient({speed=>'fast',start=>'red',end=>'blue'}); 1N/ASince using <cite>any</cite> causes any mistyped method name 1N/Ato be interpreted as an HTML tag, use it with care or not at 1N/AThis causes the indicated autoloaded methods to be compiled up front, 1N/Arather than deferred to later. This is useful for scripts that run 1N/Afor an extended period of time under FastCGI or mod_perl, and for 1N/Athose destined to be crunched by Malcolm Beattie's Perl compiler. Use 1N/Ait in conjunction with the methods or method families you plan to use. 1N/A use CGI qw(-compile :standard :html3); 1N/A use CGI qw(-compile :all); 1N/ANote that using the -compile pragma in this way will always have 1N/Athe effect of importing the compiled functions into the current 1N/Anamespace. If you want to compile without importing use the 1N/Acompile() method instead: 1N/AThis is particularly useful in a mod_perl environment, in which you 1N/Amight want to precompile all CGI routines in a startup script, and 1N/Athen import the functions individually in each mod_perl script. 1N/ABy default the CGI module implements a state-preserving behavior 1N/Acalled "sticky" fields. The way this works is that if you are 1N/Aregenerating a form, the methods that generate the form field values 1N/Awill interrogate param() to see if similarly-named parameters are 1N/Apresent in the query string. If they find a like-named parameter, they 1N/Awill use it to set their default values. 1N/ASometimes this isn't what you want. The B<-nosticky> pragma prevents 1N/Athis behavior. You can also selectively change the sticky behavior in 1N/Aeach element that you generate. 1N/AAutomatically add tab index attributes to each form field. With this 1N/Aoption turned off, you can still add tab indexes manually by passing a 1N/A-tabindex option to each field-generating method. 1N/A=item -no_undef_params 1N/AThis keeps CGI.pm from including undef params in the parameter list. 1N/ABy default, CGI.pm versions 2.69 and higher emit XHTML 1N/Afeature. Thanks to Michalis Kabrianis <kabrianis@hellug.gr> for this 1N/AIf start_html()'s -dtd parameter specifies an HTML 2.0, 1N/A3.2, 4.0 or 4.01 DTD, 1N/AXHTML will automatically be disabled without needing to use this 1N/AThis makes CGI.pm treat all parameters as UTF-8 strings. Use this with 1N/Acare, as it will interfere with the processing of binary uploads. It 1N/Ais better to manually select which fields are expected to return utf-8 1N/Astrings and convert them using code like this: 1N/A my $arg = decode utf8=>param('foo'); 1N/AThis makes CGI.pm produce a header appropriate for an NPH (no 1N/Aparsed header) script. You may need to do other things as well 1N/Ato tell the server that the script is NPH. See the discussion 1N/Aof NPH scripts below. 1N/ASeparate the name=value pairs in CGI parameter query strings with 1N/Asemicolons rather than ampersands. For example: 1N/A ?name=fred;age=24;favorite_color=3 1N/ASemicolon-delimited query strings are always accepted, and will be emitted by 1N/Aself_url() and query_string(). newstyle_urls became the default in version 1N/ASeparate the name=value pairs in CGI parameter query strings with 1N/Aampersands rather than semicolons. This is no longer the default. 1N/AThis overrides the autoloader so that any function in your program 1N/Athat is not recognized is referred to CGI.pm for possible evaluation. 1N/AThis allows you to use all the CGI.pm functions without adding them to 1N/Ayour symbol table, which is of concern for mod_perl users who are 1N/Aworried about memory consumption. I<Warning:> when 1N/AI<-autoload> is in effect, you cannot use "poetry mode" 1N/A(functions without the parenthesis). Use I<hr()> rather 1N/Athan I<hr>, or add something like I<use subs qw/hr p header/> 1N/Ato the top of your script. 1N/AThis turns off the command-line processing features. If you want to 1N/Arun a CGI.pm script from the command line to produce HTML, and you 1N/Adon't want it to read CGI parameters from the command line or STDIN, 1N/Athen use this pragma: 1N/A use CGI qw(-no_debug :standard); 1N/AThis turns on full debugging. In addition to reading CGI arguments 1N/Afrom the command-line processing, CGI.pm will pause and try to read 1N/Aarguments from STDIN, producing the message "(offline mode: enter 1N/Aname=value pairs on standard input)" features. 1N/ASee the section on debugging for more details. 1N/A=item -private_tempfiles 1N/ACGI.pm can process uploaded file. Ordinarily it spools the uploaded 1N/Afile to a temporary directory, then deletes the file when done. 1N/AHowever, this opens the risk of eavesdropping as described in the file 1N/Aupload section. Another CGI script author could peek at this data 1N/Aduring the upload, even if it is confidential information. On Unix 1N/Asystems, the -private_tempfiles pragma will cause the temporary file 1N/Ato be unlinked as soon as it is opened and before any data is written 1N/Ainto it, reducing, but not eliminating the risk of eavesdropping 1N/A(there is still a potential race condition). To make life harder for 1N/Athe attacker, the program chooses tempfile names by calculating a 32 1N/Abit checksum of the incoming HTTP headers. 1N/ATo ensure that the temporary file cannot be read by other CGI scripts, 1N/Ause suEXEC or a CGI wrapper program to run your script. The temporary 1N/Afile is created with mode 0600 (neither world nor group readable). 1N/AThe temporary directory is selected using the following algorithm: 1N/A 1. if $CGITempFile::TMPDIRECTORY is already set, use that 1N/A 2. if the environment variable TMPDIR exists, use the location 1N/A /tmp, /temp, ::Temporary Items, and \WWW_ROOT. 1N/AEach of these locations is checked that it is a directory and is 1N/Awritable. If not, the algorithm tries the next choice. 1N/A=head2 SPECIAL FORMS FOR IMPORTING HTML-TAG FUNCTIONS 1N/AMany of the methods generate HTML tags. As described below, tag 1N/Afunctions automatically generate both the opening and closing tags. 1N/A print h1('Level 1 Header'); 1N/A <h1>Level 1 Header</h1> 1N/AThere will be some times when you want to produce the start and end 1N/Atags yourself. In this case, you can use the form start_I<tag_name> 1N/Aand end_I<tag_name>, as in: 1N/A print start_h1,'Level 1 Header',end_h1; 1N/AWith a few exceptions (described below), start_I<tag_name> and 1N/Aend_I<tag_name> functions are not generated automatically when you 1N/AI<use CGI>. However, you can specify the tags you want to generate 1N/AI<start/end> functions for by putting an asterisk in front of their 1N/Aname, or, alternatively, requesting either "start_I<tag_name>" or 1N/A"end_I<tag_name>" in the import list. 1N/A use CGI qw/:standard *table start_ul/; 1N/AIn this example, the following functions are generated in addition to 1N/A=item 1. start_table() (generates a <table> tag) 1N/A=item 2. end_table() (generates a </table> tag) 1N/A=item 3. start_ul() (generates a <ul> tag) 1N/A=item 4. end_ul() (generates a </ul> tag) 1N/A=head1 GENERATING DYNAMIC DOCUMENTS 1N/AMost of CGI.pm's functions deal with creating documents on the fly. 1N/AGenerally you will produce the HTTP header first, followed by the 1N/Adocument itself. CGI.pm provides functions for generating HTTP 1N/Aheaders of various types as well as for generating HTML. For creating 1N/AEach of these functions produces a fragment of HTML or HTTP which you 1N/Acan print out directly so that it displays in the browser window, 1N/Aappend to a string, or save to a file for later use. 1N/A=head2 CREATING A STANDARD HTTP HEADER: 1N/ANormally the first thing you will do in any CGI script is print out an 1N/AHTTP header. This tells the browser what type of document to expect, 1N/Aand gives other optional information, such as the language, expiration 1N/Adate, and whether to cache the document. The header can also be 1N/Amanipulated for special purposes, such as server push and pay per view 1N/A -status=>'402 Payment required', 1N/A -attachment=>'foo.gif', 1N/Aheader() returns the Content-type: header. You can provide your own 1N/AMIME type if you choose, otherwise it defaults to text/html. An 1N/Aoptional second parameter specifies the status code and a human-readable 1N/Amessage. For example, you can specify 204, "No response" to create a 1N/Ascript that tells the browser to do nothing at all. 1N/AThe last example shows the named argument style for passing arguments 1N/Ato the CGI methods using named parameters. Recognized parameters are 1N/AB<-type>, B<-status>, B<-expires>, and B<-cookie>. Any other named 1N/Aparameters will be stripped of their initial hyphens and turned into 1N/Aheader fields, allowing you to specify any HTTP header you desire. 1N/AInternal underscores will be turned into hyphens: 1N/A print header(-Content_length=>3002); 1N/AMost browsers will not cache the output from CGI scripts. Every time 1N/Athe browser reloads the page, the script is invoked anew. You can 1N/Achange this behavior with the B<-expires> parameter. When you specify 1N/Aan absolute or relative expiration interval with this parameter, some 1N/Abrowsers and proxy servers will cache the script's output until the 1N/Aindicated expiration date. The following forms are all valid for the 1N/A +30s 30 seconds from now 1N/A +10m ten minutes from now 1N/A +1h one hour from now 1N/A -1d yesterday (i.e. "ASAP!") 1N/A +10y in ten years time 1N/A Thursday, 25-Apr-1999 00:40:33 GMT at the indicated time & date 1N/AThe B<-cookie> parameter generates a header that tells the browser to provide 1N/Aa "magic cookie" during all subsequent transactions with your script. 1N/ASome cookies have a special format that includes interesting attributes 1N/Asuch as expiration time. Use the cookie() method to create and retrieve 1N/AThe B<-nph> parameter, if set to a true value, will issue the correct 1N/Aheaders to work with a NPH (no-parse-header) script. This is important 1N/Ato use with certain servers that expect all their scripts to be NPH. 1N/AThe B<-charset> parameter can be used to control the character set 1N/Asent to the browser. If not provided, defaults to ISO-8859-1. As a 1N/Aside effect, this sets the charset() method as well. 1N/AThe B<-attachment> parameter can be used to turn the page into an 1N/Aattachment. Instead of displaying the page, some browsers will prompt 1N/Athe user to save it to disk. The value of the argument is the 1N/Asuggested name for the saved file. In order for this to work, you may 1N/AThe B<-p3p> parameter will add a P3P tag to the outgoing header. The 1N/Aparameter can be an arrayref or a space-delimited string of P3P tags. 1N/A print header(-p3p=>[qw(CAO DSP LAW CURa)]); 1N/A print header(-p3p=>'CAO DSP LAW CURa'); 1N/AIn either case, the outgoing header will be formatted as: 1N/ACGI.pm will accept valid multi-line headers when each line is separated with a 1N/ACRLF value ("\r\n" on most platforms) followed by at least one space. For example: 1N/A print header( -ingredients => "ham\r\n\seggs\r\n\sbacon" ); 1N/AInvalid multi-line header input will trigger in an exception. When multi-line headers 1N/Aare received, CGI.pm will always output them back as a single line, according to the 1N/Afolding rules of RFC 2616: the newlines will be removed, while the white space remains. 1N/A=head2 GENERATING A REDIRECTION HEADER 1N/ASometimes you don't want to produce a document yourself, but simply 1N/Aredirect the browser elsewhere, perhaps choosing a URL based on the 1N/Atime of day or the identity of the user. 1N/AThe redirect() method redirects the browser to a different URL. If 1N/Ayou use redirection like this, you should B<not> print out a header as 1N/AYou should always use full URLs (including the http: or ftp: part) in 1N/Aredirection requests. Relative URLs will not work correctly. 1N/AYou can also use named arguments: 1N/AAll names arguments recognized by header() are also recognized by 1N/Aredirect(). However, most HTTP headers, including those generated by 1N/A-cookie and -target, are ignored by the browser. 1N/AThe B<-nph> parameter, if set to a true value, will issue the correct 1N/Aheaders to work with a NPH (no-parse-header) script. This is important 1N/Ato use with certain servers, such as Microsoft IIS, which 1N/Aexpect all their scripts to be NPH. 1N/AThe B<-status> parameter will set the status of the redirect. HTTP 1N/Adefines three different possible redirection status codes: 1N/A 301 Moved Permanently 1N/AThe default if not specified is 302, which means "moved temporarily." 1N/AYou may change the status to another status code if you wish. Be 1N/Aadvised that changing the status to anything other than 301, 302 or 1N/A303 will probably break redirection. 1N/A=head2 CREATING THE HTML DOCUMENT HEADER 1N/A print start_html(-title=>'Secrets of the Pyramids', 1N/A -author=>'fred@capricorn.org', 1N/A -meta=>{'keywords'=>'pharaoh secret mummy', 1N/A 'copyright'=>'copyright 1996 King Tut'}, 1N/AThe start_html() routine creates the top of the 1N/Apage, along with a lot of optional information that controls the 1N/Apage's appearance and behavior. 1N/AThis method returns a canned HTML header and the opening <body> tag. 1N/AAll parameters are optional. In the named parameter form, recognized 1N/Aparameters are -title, -author, -base, -xbase, -dtd, -lang and -target 1N/A(see below for the explanation). Any additional parameters you 1N/Aprovide, such as the unofficial BGCOLOR attribute, are added 1N/Ato the <body> tag. Additional parameters must be proceeded by a 1N/AThe argument B<-xbase> allows you to provide an HREF for the <base> tag 1N/Adifferent from the current location, as in 1N/AAll relative links will be interpreted relative to this tag. 1N/AThe argument B<-target> allows you to provide a default target frame 1N/Afor all the links and fill-out forms on the page. B<This is a 1N/Anon-standard HTTP feature which only works with some browsers!> 1N/A -target=>"answer_window" 1N/AAll relative links will be interpreted relative to this tag. 1N/AYou add arbitrary meta information to the header with the B<-meta> 1N/Aargument. This argument expects a reference to a hash 1N/Acontaining name/value pairs of meta information. These will be turned 1N/Ainto a series of header <meta> tags that look something like this: 1N/A <meta name="keywords" content="pharaoh secret mummy"> 1N/A <meta name="description" content="copyright 1996 King Tut"> 1N/ATo create an HTTP-EQUIV type of <meta> tag, use B<-head>, described 1N/AThe B<-style> argument is used to incorporate cascading stylesheets 1N/Ainto your code. See the section on CASCADING STYLESHEETS for more 1N/AThe B<-lang> argument is used to incorporate a language attribute into 1N/Athe <html> tag. For example: 1N/A print $q->start_html(-lang=>'fr-CA'); 1N/AThe default if not specified is "en-US" for US English, unless the 1N/A-dtd parameter specifies an HTML 2.0 or 3.2 DTD, in which case the 1N/Alang attribute is left off. You can force the lang attribute to left 1N/Aoff in other cases by passing an empty string (-lang=>''). 1N/AThe B<-encoding> argument can be used to specify the character set for 1N/AXHTML. It defaults to iso-8859-1 if not specified. 1N/AThe B<-dtd> argument can be used to specify a public DTD identifier string. For example: 1N/A -dtd => '-//W3C//DTD HTML 4.01 Transitional//EN') 1N/AAlternatively, it can take public and system DTD identifiers as an array: 1N/AFor the public DTD identifier to be considered, it must be valid. Otherwise it 1N/Awill be replaced by the default DTD. If the public DTD contains 'XHTML', CGI.pm 1N/AThe B<-declare_xml> argument, when used in conjunction with XHTML, 1N/Awill put a <?xml> declaration at the top of the HTML header. The sole 1N/Apurpose of this declaration is to declare the character set 1N/Aencoding. In the absence of -declare_xml, the output HTML will contain 1N/Aa <meta> tag that specifies the encoding, allowing the HTML to pass 1N/Amost validators. The default for -declare_xml is false. 1N/AYou can place other arbitrary HTML elements to the <head> section with the 1N/AB<-head> tag. For example, to place a <link> element in the 1N/Ahead section, use this: 1N/A print start_html(-head=>Link({-rel=>'shortcut icon', 1N/A -href=>'favicon.ico'})); 1N/ATo incorporate multiple HTML elements into the <head> section, just pass an 1N/A print start_html(-head=>[ 1N/A Link({-rel=>'previous', 1N/AAnd here's how to create an HTTP-EQUIV <meta> tag: 1N/A print start_html(-head=>meta({-http_equiv => 'Content-Type', 1N/AJAVASCRIPTING: The B<-script>, B<-noScript>, B<-onLoad>, 1N/AB<-onMouseOver>, B<-onMouseOut> and B<-onUnload> parameters are used 1N/Ato add JavaScript calls to your pages. B<-script> should 1N/Apoint to a block of text containing JavaScript function definitions. 1N/AThis block will be placed within a <script> block inside the HTML (not 1N/AHTTP) header. The block is placed in the header in order to give your 1N/Apage a fighting chance of having all its JavaScript functions in place 1N/Aeven if the user presses the stop button before the page has loaded 1N/Acompletely. CGI.pm attempts to format the script in such a way that 1N/AJavaScript-naive browsers will not choke on the code: unfortunately 1N/Athere are some browsers, such as Chimera for Unix, that get confused 1N/AThe B<-onLoad> and B<-onUnload> parameters point to fragments of JavaScript 1N/Acode to execute when the page is respectively opened and closed by the 1N/Abrowser. Usually these parameters are calls to functions defined in the 1N/A // Ask a silly question 1N/A function riddle_me_this() { 1N/A var r = prompt("What walks on four legs in the morning, " + 1N/A "two legs in the afternoon, " + 1N/A "and three legs in the evening?"); 1N/A // Get a silly answer 1N/A function response(answer) { 1N/A if (answer == "man") 1N/A alert("Right you are!"); 1N/A alert("Wrong! Guess again."); 1N/A print start_html(-title=>'The Riddle of the Sphinx', 1N/AUse the B<-noScript> parameter to pass some HTML text that will be displayed on 1N/Abrowsers that do not have JavaScript (or browsers where JavaScript is turned 1N/AThe <script> tag, has several attributes including "type", "charset" and "src". 1N/A"src" allows you to keep JavaScript code in an external file. To use these 1N/Aattributes pass a HASH reference in the B<-script> parameter containing one or 1N/Amore of -type, -src, or -code: 1N/A print $q->start_html(-title=>'The Riddle of the Sphinx', 1N/A -script=>{-type=>'JAVASCRIPT', 1N/A print $q->(-title=>'The Riddle of the Sphinx', 1N/A -script=>{-type=>'PERLSCRIPT', 1N/A -code=>'print "hello world!\n;"'} 1N/AA final feature allows you to incorporate multiple <script> sections into the 1N/Aheader. Just pass the list of script sections as an array reference. 1N/Athis allows you to specify different source files for different dialects 1N/Aof JavaScript. Example: 1N/A print $q->start_html(-title=>'The Riddle of the Sphinx', 1N/AThe option "-language" is a synonym for -type, and is supported for 1N/Abackwards compatibility. 1N/AThe old-style positional parameters are as follows: 1N/AThe author's e-mail address (will create a <link rev="MADE"> tag if present 1N/AA 'true' flag if you want to include a <base> tag in the header. This 1N/Ahelps resolve relative addresses to absolute ones when the document is moved, 1N/Abut makes the document hierarchy non-portable. Use with care! 1N/AAny other parameters you want to include in the <body> tag. This is a good 1N/Aplace to put HTML extensions, such as colors and wallpaper patterns. 1N/A=head2 ENDING THE HTML DOCUMENT: 1N/AThis ends an HTML document by printing the </body></html> tags. 1N/A=head2 CREATING A SELF-REFERENCING URL THAT PRESERVES STATE INFORMATION: 1N/A print q(<a href="$myself">I'm talking to myself.</a>); 1N/Aself_url() will return a URL, that, when selected, will reinvoke 1N/Athis script with all its state information intact. This is most 1N/Auseful when you want to jump around within the document using 1N/Ainternal anchors but you don't want to disrupt the current contents 1N/Aof the form(s). Something like this will do the trick. 1N/A print "<a href=\"$myself#table1\">See table 1</a>"; 1N/A print "<a href=\"$myself#table2\">See table 2</a>"; 1N/A print "<a href=\"$myself#yourself\">See for yourself</a>"; 1N/AIf you want more control over what's returned, using the B<url()> 1N/AYou can also retrieve the unprocessed query string with query_string(): 1N/A $the_string = query_string; 1N/A=head2 OBTAINING THE SCRIPT'S URL 1N/A $full_url = url(-full=>1); #alternative syntax 1N/A $relative_url = url(-relative=>1); 1N/A $absolute_url = url(-absolute=>1); 1N/A $url_with_path = url(-path_info=>1); 1N/A $url_with_path_and_query = url(-path_info=>1,-query=>1); 1N/A $netloc = url(-base => 1); 1N/AB<url()> returns the script's URL in a variety of formats. Called 1N/Awithout any arguments, it returns the full form of the URL, including 1N/Ahost name and port number 1N/AYou can modify this format with the following named arguments: 1N/AIf true, produce an absolute URL, e.g. 1N/AProduce a relative URL. This is useful if you want to reinvoke your 1N/Ascript with different parameters. For example: 1N/AProduce the full URL, exactly as if called without any arguments. 1N/AThis overrides the -relative and -absolute arguments. 1N/A=item B<-path> (B<-path_info>) 1N/AAppend the additional path information to the URL. This can be 1N/Acombined with B<-full>, B<-absolute> or B<-relative>. B<-path_info> 1N/Ais provided as a synonym. 1N/A=item B<-query> (B<-query_string>) 1N/AAppend the query string to the URL. This can be combined with 1N/AB<-full>, B<-absolute> or B<-relative>. B<-query_string> is provided 1N/AIf Apache's mod_rewrite is turned on, then the script name and path 1N/Ainfo probably won't match the request that the user sent. Set 1N/A-rewrite=>1 (default) to return URLs that match what the user sent 1N/A(the original request URI). Set -rewrite=>0 to return URLs that match 1N/Athe URL after mod_rewrite's rules have run. Because the additional 1N/Apath information only makes sense in the context of the rewritten URL, 1N/A-rewrite is set to false when you request path info in the URL. 1N/A=head2 MIXING POST AND URL PARAMETERS 1N/A $color = url_param('color'); 1N/AIt is possible for a script to receive CGI parameters in the URL as 1N/Awell as in the fill-out form by creating a form that POSTs to a URL 1N/Acontaining a query string (a "?" mark followed by arguments). The 1N/AB<param()> method will always return the contents of the POSTed 1N/Afill-out form, ignoring the URL's query string. To retrieve URL 1N/Aparameters, call the B<url_param()> method. Use it in the same way as 1N/AB<param()>. The main difference is that it allows you to read the 1N/Aparameters, but not set them. 1N/AUnder no circumstances will the contents of the URL query string 1N/Ainterfere with similarly-named CGI parameters in POSTed forms. If you 1N/Atry to mix a URL query string with a form submitted with the GET 1N/Amethod, the results will not be what you expect. 1N/A=head1 CREATING STANDARD HTML ELEMENTS: 1N/ACGI.pm defines general HTML shortcut methods for many HTML tags. HTML shortcuts are named after a single 1N/AHTML element and return a fragment of HTML text. Example: 1N/A print $q->blockquote( 1N/A "Many years ago on the island of", 1N/A "there lived a Minotaur named", 1N/A $q->strong("Fred."), 1N/AThis results in the following HTML code (extra newlines have been 1N/Aadded for readability): 1N/A Many years ago on the island of 1N/A a minotaur named <strong>Fred.</strong> 1N/AIf you find the syntax for calling the HTML shortcuts awkward, you can 1N/Aimport them into your namespace and dispense with the object syntax 1N/Acompletely (see the next section for more details): 1N/A use CGI ':standard'; 1N/A "Many years ago on the island of", 1N/A "there lived a minotaur named", 1N/A=head2 PROVIDING ARGUMENTS TO HTML SHORTCUTS 1N/AThe HTML methods will accept zero, one or multiple arguments. If you 1N/Aprovide no arguments, you get a single tag: 1N/AIf you provide one or more string arguments, they are concatenated 1N/Atogether with spaces and placed between opening and closing tags: 1N/A print h1("Chapter","1"); # <h1>Chapter 1</h1>" 1N/AIf the first argument is a hash reference, then the keys 1N/Aand values of the hash become the HTML tag's attributes: 1N/A "Open a new frame"); 1N/AYou may dispense with the dashes in front of the attribute names if 1N/A print img {src=>'fred.gif',align=>'LEFT'}; 1N/A <img align="LEFT" src="fred.gif"> 1N/ASometimes an HTML tag attribute has no argument. For example, ordered 1N/Alists can be marked as COMPACT. The syntax for this is an argument that 1N/Athat points to an undef string: 1N/A print ol({compact=>undef},li('one'),li('two'),li('three')); 1N/APrior to CGI.pm version 2.41, providing an empty ('') string as an 1N/Aattribute argument was the same as providing undef. However, this has 1N/Achanged in order to accommodate those who want to create tags of the form 1N/A<img alt="">. The difference is shown in these two pieces of code: 1N/A img({alt=>undef}) <img alt> 1N/A img({alt=>''}) <img alt=""> 1N/A=head2 THE DISTRIBUTIVE PROPERTY OF HTML SHORTCUTS 1N/AOne of the cool features of the HTML shortcuts is that they are 1N/Adistributive. If you give them an argument consisting of a 1N/AB<reference> to a list, the tag will be distributed across each 1N/Aelement of the list. For example, here's one way to make an ordered 1N/A li({-type=>'disc'},['Sneezy','Doc','Sleepy','Happy']) 1N/AThis example will result in HTML output that looks like this: 1N/A <li type="disc">Sneezy</li> 1N/A <li type="disc">Doc</li> 1N/A <li type="disc">Sleepy</li> 1N/A <li type="disc">Happy</li> 1N/AThis is extremely useful for creating tables. For example: 1N/A print table({-border=>undef}, 1N/A caption('When Should You Eat Your Vegetables?'), 1N/A Tr({-align=>'CENTER',-valign=>'TOP'}, 1N/A th(['Vegetable', 'Breakfast','Lunch','Dinner']), 1N/A td(['Tomatoes' , 'no', 'yes', 'yes']), 1N/A td(['Broccoli' , 'no', 'no', 'yes']), 1N/A td(['Onions' , 'yes','yes', 'yes']) 1N/A=head2 HTML SHORTCUTS AND LIST INTERPOLATION 1N/AConsider this bit of code: 1N/A print blockquote(em('Hi'),'mom!')); 1N/AIt will ordinarily return the string that you probably expect, namely: 1N/A <blockquote><em>Hi</em> mom!</blockquote> 1N/ANote the space between the element "Hi" and the element "mom!". 1N/ACGI.pm puts the extra space there using array interpolation, which is 1N/Acontrolled by the magic $" variable. Sometimes this extra space is 1N/Anot what you want, for example, when you are trying to align a series 1N/Aof images. In this case, you can simply change the value of $" to an 1N/A print blockquote(em('Hi'),'mom!')); 1N/AI suggest you put the code in a block as shown here. Otherwise the 1N/Achange to $" will affect all subsequent code until you explicitly 1N/A=head2 NON-STANDARD HTML SHORTCUTS 1N/AA few HTML tags don't follow the standard pattern for various 1N/AB<comment()> generates an HTML comment (<!-- comment -->). Call it 1N/A print comment('here is my comment'); 1N/ABecause of conflicts with built-in Perl functions, the following functions 1N/Abegin with initial caps: 1N/AIn addition, start_html(), end_html(), start_form(), end_form(), 1N/Astart_multipart_form() and all the fill-out form tags are special. 1N/ASee their respective sections. 1N/A=head2 AUTOESCAPING HTML 1N/ABy default, all HTML that is emitted by the form-generating functions 1N/Ais passed through a function called escapeHTML(): 1N/A=item $escaped_string = escapeHTML("unescaped string"); 1N/AEscape HTML formatting characters in a string. 1N/AProvided that you have specified a character set of ISO-8859-1 (the 1N/Adefault), the standard HTML escaping rules will be used. The "<" 1N/Acharacter becomes "<", ">" becomes ">", "&" becomes "&", and 1N/Athe quote character becomes """. In addition, the hexadecimal 1N/A0x8b and 0x9b characters, which some browsers incorrectly interpret 1N/Aas the left and right angle-bracket characters, are replaced by their 1N/Anumeric character entities ("‹" and "›"). If you manually change 1N/Athe charset, either by calling the charset() method explicitly or by 1N/Apassing a -charset argument to header(), then B<all> characters will 1N/Abe replaced by their numeric entities, since CGI.pm has no lookup 1N/Atable for all the possible encodings. 1N/AC<escapeHTML()> expects the supplied string to be a character string. This means you 1N/Ashould Encode::decode data received from "outside" and Encode::encode your 1N/Astrings before sending them back outside. If your source code UTF-8 encoded and 1N/Ayou want to upgrade string literals in your source to character strings, you 1N/Acan use "use utf8". See L<perlunitut>, L<perlunifaq> and L<perlunicode> for more 1N/Ainformation on how Perl handles the difference between bytes and characters. 1N/AThe automatic escaping does not apply to other shortcuts, such as 1N/Ah1(). You should call escapeHTML() yourself on untrusted data in 1N/Aorder to protect your pages against nasty tricks that people may enter 1N/Ainto guestbooks, etc.. To change the character set, use charset(). 1N/ATo turn autoescaping off completely, use autoEscape(0): 1N/A=item $charset = charset([$charset]); 1N/AGet or set the current character set. 1N/A=item $flag = autoEscape([$flag]); 1N/AGet or set the value of the autoescape flag. 1N/A=head2 PRETTY-PRINTING HTML 1N/ABy default, all the HTML produced by these functions comes out as one 1N/Along line without carriage returns or indentation. This is yuck, but 1N/Ait does reduce the size of the documents by 10-20%. To get 1N/Apretty-printed output, please use L<CGI::Pretty>, a subclass 1N/Acontributed by Brian Paulsen. 1N/A=head1 CREATING FILL-OUT FORMS: 1N/AI<General note> The various form-creating methods all return strings 1N/Ato the caller, containing the tag or tags that will create the requested 1N/Aform element. You are responsible for actually printing out these strings. 1N/AIt's set up this way so that you can place formatting tags 1N/Aaround the form elements. 1N/AI<Another note> The default values that you specify for the forms are only 1N/Aused the B<first> time the script is invoked (when there is no query 1N/Astring). On subsequent invocations of the script (when there is a query 1N/Astring), the former values are used even if they are blank. 1N/AIf you want to change the value of a field from its previous value, you have two 1N/A(1) call the param() method to set it. 1N/A(2) use the -override (alias -force) parameter (a new feature in version 2.15). 1N/AThis forces the default value to be used, regardless of the previous value: 1N/A print textfield(-name=>'field_name', 1N/A -default=>'starting value', 1N/AI<Yet another note> By default, the text and labels of form elements are 1N/Aescaped according to HTML rules. This means that you can safely use 1N/A"<CLICK ME>" as the label for a button. However, it also interferes with 1N/Ayour ability to incorporate special HTML character sequences, such as Á, 1N/Ainto your fields. If you wish to turn off automatic escaping, call the 1N/AautoEscape() method with a false value immediately after creating the CGI object: 1N/A $query->autoEscape(0); 1N/ANote that autoEscape() is exclusively used to effect the behavior of how some 1N/ACGI.pm HTML generation functions handle escaping. Calling escapeHTML() 1N/Aexplicitly will always escape the HTML. 1N/AI<A Lurking Trap!> Some of the form-element generating methods return 1N/Amultiple tags. In a scalar context, the tags will be concatenated 1N/Atogether with spaces, or whatever is the current value of the $" 1N/Aglobal. In a list context, the methods will return a list of 1N/Aelements, allowing you to modify them if you wish. Usually you will 1N/Anot notice this behavior, but beware of this: 1N/A printf("%s\n",end_form()) 1N/Aend_form() produces several tags, and only the first of them will be 1N/Aprinted because the format only expects one value. 1N/A=head2 CREATING AN ISINDEX TAG 1N/A print isindex(-action=>$action); 1N/A print isindex($action); 1N/APrints out an <isindex> tag. Not very exciting. The parameter 1N/A-action specifies the URL of the script to process the query. The 1N/Adefault is to process the query with the current script. 1N/A=head2 STARTING AND ENDING A FORM 1N/A print start_form(-method=>$method, 1N/A -enctype=>$encoding); 1N/A <... various form stuff ...> 1N/A print start_form($method,$action,$encoding); 1N/A <... various form stuff ...> 1N/Astart_form() will return a <form> tag with the optional method, 1N/Aaction and form encoding that you specify. The defaults are: 1N/Aend_form() returns the closing </form> tag. 1N/AStart_form()'s enctype argument tells the browser how to package the various 1N/Afields of the form before sending the form to the server. Two 1N/AB<Note:> These methods were previously named startform() and endform(). 1N/AThese methods are now DEPRECATED. 1N/APlease use start_form() and end_form() instead. 1N/AThis is the older type of encoding. It is compatible with many CGI scripts and is 1N/Asuitable for short fields containing text data. For your 1N/Aconvenience, CGI.pm stores the name of this encoding 1N/Atype in B<&CGI::URL_ENCODED>. 1N/AThis is the newer type of encoding. 1N/AIt is suitable for forms that contain very large fields or that 1N/Aare intended for transferring binary data. Most importantly, 1N/Ait enables the "file upload" feature. For 1N/Ayour convenience, CGI.pm stores the name of this encoding type 1N/Ain B<&CGI::MULTIPART> 1N/AForms that use this type of encoding are not easily interpreted 1N/Aby CGI scripts unless they use CGI.pm or another library designed 1N/AIf XHTML is activated (the default), then forms will be automatically 1N/Acreated using this type of encoding. 1N/AThe start_form() method uses the older form of encoding by 1N/Adefault unless XHTML is requested. If you want to use the 1N/Anewer form of encoding by default, you can call 1N/AB<start_multipart_form()> instead of B<start_form()>. The 1N/Amethod B<end_multipart_form()> is an alias to B<end_form()>. 1N/AJAVASCRIPTING: The B<-name> and B<-onSubmit> parameters are provided 1N/Afor use with JavaScript. The -name parameter gives the 1N/Aform a name so that it can be identified and manipulated by 1N/AJavaScript functions. -onSubmit should point to a JavaScript 1N/Afunction that will be executed just before the form is submitted to your 1N/Aserver. You can use this opportunity to check the contents of the form 1N/Afor consistency and completeness. If you find something wrong, you 1N/Acan put up an alert box or maybe fix things up yourself. You can 1N/Aabort the submission by returning false from this function. 1N/AUsually the bulk of JavaScript functions are defined in a <script> 1N/Ablock in the HTML header and -onSubmit points to one of these function 1N/Acall. See start_html() for details. 1N/AAfter starting a form, you will typically create one or more 1N/Atextfields, popup menus, radio groups and other form elements. Each 1N/Aof these elements takes a standard set of named arguments. Some 1N/Aelements also have optional arguments. The standard arguments are as 1N/AThe name of the field. After submission this name can be used to 1N/Aretrieve the field's value using the param() method. 1N/A=item B<-value>, B<-values> 1N/AThe initial value of the field which will be returned to the script 1N/Aafter form submission. Some form elements, such as text fields, take 1N/Aa single scalar -value argument. Others, such as popup menus, take a 1N/Areference to an array of values. The two arguments are synonyms. 1N/AA numeric value that sets the order in which the form element receives 1N/Afocus when the user presses the tab key. Elements with lower values 1N/AA string identifier that can be used to identify this element to 1N/AJavaScript and DHTML. 1N/AA boolean, which, if true, forces the element to take on the value 1N/Aspecified by B<-value>, overriding the sticky behavior described 1N/Aearlier for the B<-nosticky> pragma. 1N/A=item B<-onChange>, B<-onFocus>, B<-onBlur>, B<-onMouseOver>, B<-onMouseOut>, B<-onSelect> 1N/AThese are used to assign JavaScript event handlers. See the 1N/AJavaScripting section for more details. 1N/AOther common arguments are described in the next section. In addition 1N/Ato these, all attributes described in the HTML specifications are 1N/A=head2 CREATING A TEXT FIELD 1N/A print textfield(-name=>'field_name', 1N/A -value=>'starting value', 1N/A print textfield('field_name','starting value',50,80); 1N/Atextfield() will return a text input field. 1N/AThe first parameter is the required name for the field (-name). 1N/AThe optional second parameter is the default starting value for the field 1N/Acontents (-value, formerly known as -default). 1N/AThe optional third parameter is the size of the field in 1N/AThe optional fourth parameter is the maximum number of characters the 1N/A field will accept (-maxlength). 1N/AAs with all these methods, the field will be initialized with its 1N/Aprevious contents from earlier invocations of the script. 1N/AWhen the form is processed, the value of the text field can be 1N/A $value = param('foo'); 1N/AIf you want to reset it from its initial value after the script has been 1N/Acalled once, you can do so like this: 1N/A param('foo',"I'm taking over this value!"); 1N/A=head2 CREATING A BIG TEXT FIELD 1N/A print textarea(-name=>'foo', 1N/A -default=>'starting value', 1N/A print textarea('foo','starting value',10,50); 1N/Atextarea() is just like textfield, but it allows you to specify 1N/Arows and columns for a multiline text entry box. You can provide 1N/Aa starting value for the field, which can be long and contain 1N/A=head2 CREATING A PASSWORD FIELD 1N/A print password_field(-name=>'secret', 1N/A -value=>'starting value', 1N/A print password_field('secret','starting value',50,80); 1N/Apassword_field() is identical to textfield(), except that its contents 1N/Awill be starred out on the web page. 1N/A=head2 CREATING A FILE UPLOAD FIELD 1N/A print filefield(-name=>'uploaded_file', 1N/A -default=>'starting value', 1N/A print filefield('uploaded_file','starting value',50,80); 1N/Afilefield() will return a file upload field. 1N/AIn order to take full advantage of this I<you must use the new 1N/Amultipart encoding scheme> for the form. You can do this either 1N/Aby calling B<start_form()> with an encoding type of B<&CGI::MULTIPART>, 1N/Aor by calling the new method B<start_multipart_form()> instead of 1N/Avanilla B<start_form()>. 1N/AThe first parameter is the required name for the field (-name). 1N/AThe optional second parameter is the starting value for the field contents 1N/Ato be used as the default file name (-default). 1N/AFor security reasons, browsers don't pay any attention to this field, 1N/Aand so the starting value will always be blank. Worse, the field 1N/Aloses its "sticky" behavior and forgets its previous contents. The 1N/Astarting value field is called for in the HTML specification, however, 1N/Aand possibly some browser will eventually provide support for it. 1N/AThe optional third parameter is the size of the field in 1N/AThe optional fourth parameter is the maximum number of characters the 1N/Afield will accept (-maxlength). 1N/AJAVASCRIPTING: The B<-onChange>, B<-onFocus>, B<-onBlur>, 1N/AB<-onMouseOver>, B<-onMouseOut> and B<-onSelect> parameters are 1N/Arecognized. See textfield() for details. 1N/A=head2 PROCESSING A FILE UPLOAD FIELD 1N/AWhen the form is processed, you can retrieve an L<IO::Handle> compatible 1N/Ahandle for a file upload field like this: 1N/A $lightweight_fh = $q->upload('field_name'); 1N/A # undef may be returned if it's not a valid file handle 1N/A if (defined $lightweight_fh) { 1N/A # Upgrade the handle to one compatible with IO::Handle: 1N/A my $io_handle = $lightweight_fh->handle; 1N/A while ($bytesread = $io_handle->read($buffer,1024)) { 1N/A print OUTFILE $buffer; 1N/AIn a list context, upload() will return an array of filehandles. 1N/AThis makes it possible to process forms that use the same name for 1N/Amultiple upload fields. 1N/AIf you want the entered file name for the file, you can just call param(): 1N/A $filename = $q->param('field_name'); 1N/ADifferent browsers will return slightly different things for the 1N/Aname. Some browsers return the filename only. Others return the full 1N/Apath to the file, using the path conventions of the user's machine. 1N/ARegardless, the name returned is always the name of the file on the 1N/AI<user's> machine, and is unrelated to the name of the temporary file 1N/Athat CGI.pm creates during upload spooling (see below). 1N/AWhen a file is uploaded the browser usually sends along some 1N/Ainformation along with it in the format of headers. The information 1N/Ausually includes the MIME content type. To 1N/Aretrieve this information, call uploadInfo(). It returns a reference to 1N/Aa hash containing all the document headers. 1N/A $filename = $q->param('uploaded_file'); 1N/A $type = $q->uploadInfo($filename)->{'Content-Type'}; 1N/A die "HTML FILES ONLY!"; 1N/AIf you are using a machine that recognizes "text" and "binary" data 1N/Amodes, be sure to understand when and how to use them (see the Camel book). 1N/AOtherwise you may find that binary files are corrupted during file 1N/A=head3 Accessing the temp files directly 1N/AWhen processing an uploaded file, CGI.pm creates a temporary file on your hard 1N/Adisk and passes you a file handle to that file. After you are finished with the 1N/Afile handle, CGI.pm unlinks (deletes) the temporary file. If you need to you 1N/Acan access the temporary file directly. You can access the temp file for a file 1N/Aupload by passing the file name to the tmpFileName() method: 1N/A $filename = $query->param('uploaded_file'); 1N/A $tmpfilename = $query->tmpFileName($filename); 1N/AThe temporary file will be deleted automatically when your program exits unless 1N/Ayou manually rename it. On some operating systems (such as Windows NT), you 1N/Awill need to close the temporary file's filehandle before your program exits. 1N/AOtherwise the attempt to delete the temporary file will fail. 1N/A=head3 Handling interrupted file uploads 1N/AThere are occasionally problems involving parsing the uploaded file. 1N/AThis usually happens when the user presses "Stop" before the upload is 1N/Afinished. In this case, CGI.pm will return undef for the name of the 1N/Auploaded file and set I<cgi_error()> to the string "400 Bad request 1N/A(malformed multipart POST)". This error message is designed so that 1N/Ayou can incorporate it into a status code to be sent to the browser. 1N/A $file = $q->upload('uploaded_file'); 1N/A if (!$file && $q->cgi_error) { 1N/A print $q->header(-status=>$q->cgi_error); 1N/AYou are free to create a custom HTML page to complain about the error, 1N/A=head3 Progress bars for file uploads and avoiding temp files 1N/ACGI.pm gives you low-level access to file upload management through 1N/Aa file upload hook. You can use this feature to completely turn off 1N/Athe temp file storage of file uploads, or potentially write your own 1N/Afile upload progress meter. 1N/AThis is much like the UPLOAD_HOOK facility available in L<Apache::Request>, with 1N/Athe exception that the first argument to the callback is an L<Apache::Upload> 1N/Aobject, here it's the remote filename. 1N/A $q = CGI->new(\&hook [,$data [,$use_tempfile]]); 1N/A my ($filename, $buffer, $bytes_read, $data) = @_; 1N/A print "Read $bytes_read bytes of $filename\n"; 1N/AThe C<< $data >> field is optional; it lets you pass configuration 1N/Ainformation (e.g. a database handle) to your hook callback. 1N/AThe C<< $use_tempfile >> field is a flag that lets you turn on and off 1N/ACGI.pm's use of a temporary disk-based file during file upload. If you 1N/Aset this to a FALSE value (default true) then $q->param('uploaded_file') 1N/Awill no longer work, and the only way to get at the uploaded data is 1N/Avia the hook you provide. 1N/AIf using the function-oriented interface, call the CGI::upload_hook() 1N/Amethod before calling param() or any other CGI functions: 1N/A CGI::upload_hook(\&hook [,$data [,$use_tempfile]]); 1N/AThis method is not exported by default. You will have to import it 1N/Aexplicitly if you wish to use it without the CGI:: prefix. 1N/A=head3 Troubleshooting file uploads on Windows 1N/AIf you are using CGI.pm on a Windows platform and find that binary 1N/Afiles get slightly larger when uploaded but that text files remain the 1N/Asame, then you have forgotten to activate binary mode on the output 1N/Afilehandle. Be sure to call binmode() on any handle that you create 1N/Ato write the uploaded file to disk. 1N/A=head3 Older ways to process file uploads 1N/A( This section is here for completeness. if you are building a new application with CGI.pm, you can skip it. ) 1N/AThe original way to process file uploads with CGI.pm was to use param(). The 1N/Avalue it returns has a dual nature as both a file name and a lightweight 1N/Afilehandle. This dual nature is problematic if you following the recommended 1N/Apractice of having C<use strict> in your code. Perl will complain when you try 1N/Ato use a string as a filehandle. More seriously, it is possible for the remote 1N/Auser to type garbage into the upload field, in which case what you get from 1N/Aparam() is not a filehandle at all, but a string. 1N/ATo solve this problem the upload() method was added, which always returns a 1N/Alightweight filehandle. This generally works well, but will have trouble 1N/Ainteroperating with some other modules because the file handle is not derived 1N/Afrom L<IO::Handle>. So that brings us to current recommendation given above, 1N/Awhich is to call the handle() method on the file handle returned by upload(). 1N/AThat upgrades the handle to an IO::Handle. It's a big win for compatibility for 1N/Aa small penalty of loading IO::Handle the first time you call it. 1N/A=head2 CREATING A POPUP MENU 1N/A print popup_menu('menu_name', 1N/A ['eenie','meenie','minie'], 1N/A %labels = ('eenie'=>'your first choice', 1N/A 'meenie'=>'your second choice', 1N/A 'minie'=>'your third choice'); 1N/A %attributes = ('eenie'=>{'class'=>'class of first choice'}); 1N/A print popup_menu('menu_name', 1N/A ['eenie','meenie','minie'], 1N/A 'meenie',\%labels,\%attributes); 1N/A -or (named parameter style)- 1N/A print popup_menu(-name=>'menu_name', 1N/A -values=>['eenie','meenie','minie'], 1N/A -default=>['meenie','minie'], 1N/A -attributes=>\%attributes); 1N/Apopup_menu() creates a menu. 1N/AThe required first argument is the menu's name (-name). 1N/AThe required second argument (-values) is an array B<reference> 1N/Acontaining the list of menu items in the menu. You can pass the 1N/Amethod an anonymous array, as shown in the example, or a reference to 1N/Aa named array, such as "\@foo". 1N/AThe optional third parameter (-default) is the name of the default 1N/Amenu choice. If not specified, the first item will be the default. 1N/AThe values of the previous choice will be maintained across 1N/Aqueries. Pass an array reference to select multiple defaults. 1N/AThe optional fourth parameter (-labels) is provided for people who 1N/Awant to use different values for the user-visible label inside the 1N/Apopup menu and the value returned to your script. It's a pointer to an 1N/Ahash relating menu values to user-visible labels. If you 1N/Aleave this parameter blank, the menu values will be displayed by 1N/Adefault. (You can also leave a label undefined if you want to). 1N/AThe optional fifth parameter (-attributes) is provided to assign 1N/Aany of the common HTML attributes to an individual menu item. It's 1N/Aa pointer to a hash relating menu values to another 1N/Ahash with the attribute's name as the key and the 1N/Aattribute's value as the value. 1N/AWhen the form is processed, the selected value of the popup menu can 1N/A $popup_menu_value = param('menu_name'); 1N/A=head2 CREATING AN OPTION GROUP 1N/ANamed parameter style 1N/A print popup_menu(-name=>'menu_name', 1N/A optgroup(-name=>'optgroup_name', 1N/A -values => ['moe','catch'], 1N/A -attributes=>{'catch'=>{'class'=>'red'}})], 1N/A -labels=>{'eenie'=>'one', 1N/A -default=>'meenie'); 1N/A print popup_menu('menu_name', 1N/A ['eenie','meenie','minie', 1N/A optgroup('optgroup_name', ['moe', 'catch'], 1N/A {'catch'=>{'class'=>'red'}})],'meenie', 1N/A {'eenie'=>'one','meenie'=>'two','minie'=>'three'}); 1N/Aoptgroup() creates an option group within a popup menu. 1N/AThe required first argument (B<-name>) is the label attribute of the 1N/Aoptgroup and is B<not> inserted in the parameter list of the query. 1N/AThe required second argument (B<-values>) is an array reference 1N/Acontaining the list of menu items in the menu. You can pass the 1N/Amethod an anonymous array, as shown in the example, or a reference 1N/Ato a named array, such as \@foo. If you pass a HASH reference, 1N/Athe keys will be used for the menu values, and the values will be 1N/Aused for the menu labels (see -labels below). 1N/AThe optional third parameter (B<-labels>) allows you to pass a reference 1N/Ato a hash containing user-visible labels for one or more 1N/Aof the menu items. You can use this when you want the user to see one 1N/Amenu string, but have the browser return your program a different one. 1N/AIf you don't specify this, the value string will be used instead 1N/A("eenie", "meenie" and "minie" in this example). This is equivalent 1N/Ato using a hash reference for the -values parameter. 1N/AAn optional fourth parameter (B<-labeled>) can be set to a true value 1N/Aand indicates that the values should be used as the label attribute 1N/Afor each option element within the optgroup. 1N/AAn optional fifth parameter (-novals) can be set to a true value and 1N/Aindicates to suppress the val attribute in each option element within 1N/ASee the discussion on optgroup at W3C 1N/AAn optional sixth parameter (-attributes) is provided to assign 1N/Aany of the common HTML attributes to an individual menu item. It's 1N/Aa pointer to a hash relating menu values to another 1N/Ahash with the attribute's name as the key and the 1N/Aattribute's value as the value. 1N/A=head2 CREATING A SCROLLING LIST 1N/A print scrolling_list('list_name', 1N/A ['eenie','meenie','minie','moe'], 1N/A ['eenie','moe'],5,'true',{'moe'=>{'class'=>'red'}}); 1N/A print scrolling_list('list_name', 1N/A ['eenie','meenie','minie','moe'], 1N/A ['eenie','moe'],5,'true', 1N/A \%labels,%attributes); 1N/A print scrolling_list(-name=>'list_name', 1N/A -values=>['eenie','meenie','minie','moe'], 1N/A -default=>['eenie','moe'], 1N/A -attributes=>\%attributes); 1N/Ascrolling_list() creates a scrolling list. 1N/AThe first and second arguments are the list name (-name) and values 1N/A(-values). As in the popup menu, the second argument should be an 1N/AThe optional third argument (-default) can be either a reference to a 1N/Alist containing the values to be selected by default, or can be a 1N/Asingle value to select. If this argument is missing or undefined, 1N/Athen nothing is selected when the list first appears. In the named 1N/Aparameter version, you can use the synonym "-defaults" for this 1N/AThe optional fourth argument is the size of the list (-size). 1N/AThe optional fifth argument can be set to true to allow multiple 1N/Asimultaneous selections (-multiple). Otherwise only one selection 1N/Awill be allowed at a time. 1N/AThe optional sixth argument is a pointer to a hash 1N/Acontaining long user-visible labels for the list items (-labels). 1N/AIf not provided, the values will be displayed. 1N/AThe optional sixth parameter (-attributes) is provided to assign 1N/Aany of the common HTML attributes to an individual menu item. It's 1N/Aa pointer to a hash relating menu values to another 1N/Ahash with the attribute's name as the key and the 1N/Aattribute's value as the value. 1N/AWhen this form is processed, all selected list items will be returned as 1N/Aa list under the parameter name 'list_name'. The values of the 1N/Aselected items can be retrieved with: 1N/A @selected = param('list_name'); 1N/A=head2 CREATING A GROUP OF RELATED CHECKBOXES 1N/A print checkbox_group(-name=>'group_name', 1N/A -values=>['eenie','meenie','minie','moe'], 1N/A -default=>['eenie','moe'], 1N/A -disabled => ['moe'], 1N/A -attributes=>\%attributes); 1N/A print checkbox_group('group_name', 1N/A ['eenie','meenie','minie','moe'], 1N/A ['eenie','moe'],'true',\%labels, 1N/A {'moe'=>{'class'=>'red'}}); 1N/A HTML3-COMPATIBLE BROWSERS ONLY: 1N/A print checkbox_group(-name=>'group_name', 1N/A -values=>['eenie','meenie','minie','moe'], 1N/A -rows=2,-columns=>2); 1N/Acheckbox_group() creates a list of checkboxes that are related 1N/AThe first and second arguments are the checkbox name and values, 1N/Arespectively (-name and -values). As in the popup menu, the second 1N/Aargument should be an array reference. These values are used for the 1N/Auser-readable labels printed next to the checkboxes as well as for the 1N/Avalues passed to your script in the query string. 1N/AThe optional third argument (-default) can be either a reference to a 1N/Alist containing the values to be checked by default, or can be a 1N/Asingle value to checked. If this argument is missing or undefined, 1N/Athen nothing is selected when the list first appears. 1N/AThe optional fourth argument (-linebreak) can be set to true to place 1N/Aline breaks between the checkboxes so that they appear as a vertical 1N/Alist. Otherwise, they will be strung together on a horizontal line. 1N/AThe optional B<-labels> argument is a pointer to a hash 1N/Arelating the checkbox values to the user-visible labels that will be 1N/Aprinted next to them. If not provided, the values will be used as the 1N/AThe optional parameters B<-rows>, and B<-columns> cause 1N/Acheckbox_group() to return an HTML3 compatible table containing the 1N/Acheckbox group formatted with the specified number of rows and 1N/Acolumns. You can provide just the -columns parameter if you wish; 1N/Acheckbox_group will calculate the correct number of rows for you. 1N/AThe option B<-disabled> takes an array of checkbox values and disables 1N/Athem by greying them out (this may not be supported by all browsers). 1N/AThe optional B<-attributes> argument is provided to assign any of the 1N/Acommon HTML attributes to an individual menu item. It's a pointer to 1N/Aa hash relating menu values to another hash 1N/Awith the attribute's name as the key and the attribute's value as the 1N/AThe optional B<-tabindex> argument can be used to control the order in which 1N/Aradio buttons receive focus when the user presses the tab button. If 1N/Apassed a scalar numeric value, the first element in the group will 1N/Areceive this tab index and subsequent elements will be incremented by 1N/Aone. If given a reference to an array of radio button values, then 1N/Athe indexes will be jiggered so that the order specified in the array 1N/Awill correspond to the tab order. You can also pass a reference to a 1N/Ahash in which the hash keys are the radio button values and the values 1N/Aare the tab indexes of each button. Examples: 1N/A -tabindex => 100 # this group starts at index 100 and counts up 1N/A -tabindex => ['moe','minie','eenie','meenie'] # tab in this order 1N/A -tabindex => {meenie=>100,moe=>101,minie=>102,eenie=>200} # tab in this order 1N/AThe optional B<-labelattributes> argument will contain attributes 1N/Aattached to the <label> element that surrounds each button. 1N/AWhen the form is processed, all checked boxes will be returned as 1N/Aa list under the parameter name 'group_name'. The values of the 1N/A"on" checkboxes can be retrieved with: 1N/A @turned_on = param('group_name'); 1N/AThe value returned by checkbox_group() is actually an array of button 1N/Aelements. You can capture them and use them within tables, lists, 1N/Aor in other creative ways: 1N/A @h = checkbox_group(-name=>'group_name',-values=>\@values); 1N/A &use_in_creative_way(@h); 1N/A=head2 CREATING A STANDALONE CHECKBOX 1N/A print checkbox(-name=>'checkbox_name', 1N/A -label=>'CLICK ME'); 1N/A print checkbox('checkbox_name','checked','ON','CLICK ME'); 1N/Acheckbox() is used to create an isolated checkbox that isn't logically 1N/Arelated to any others. 1N/AThe first parameter is the required name for the checkbox (-name). It 1N/Awill also be used for the user-readable label printed next to the 1N/AThe optional second parameter (-checked) specifies that the checkbox 1N/Ais turned on by default. Synonyms are -selected and -on. 1N/AThe optional third parameter (-value) specifies the value of the 1N/Acheckbox when it is checked. If not provided, the word "on" is 1N/AThe optional fourth parameter (-label) is the user-readable label to 1N/Abe attached to the checkbox. If not provided, the checkbox name is 1N/AThe value of the checkbox can be retrieved using: 1N/A $turned_on = param('checkbox_name'); 1N/A=head2 CREATING A RADIO BUTTON GROUP 1N/A print radio_group(-name=>'group_name', 1N/A -values=>['eenie','meenie','minie'], 1N/A -attributes=>\%attributes); 1N/A print radio_group('group_name',['eenie','meenie','minie'], 1N/A 'meenie','true',\%labels,\%attributes); 1N/A HTML3-COMPATIBLE BROWSERS ONLY: 1N/A print radio_group(-name=>'group_name', 1N/A -values=>['eenie','meenie','minie','moe'], 1N/A -rows=2,-columns=>2); 1N/Aradio_group() creates a set of logically-related radio buttons 1N/A(turning one member of the group on turns the others off) 1N/AThe first argument is the name of the group and is required (-name). 1N/AThe second argument (-values) is the list of values for the radio 1N/Abuttons. The values and the labels that appear on the page are 1N/Aidentical. Pass an array I<reference> in the second argument, either 1N/Ausing an anonymous array, as shown, or by referencing a named array as 1N/AThe optional third parameter (-default) is the name of the default 1N/Abutton to turn on. If not specified, the first item will be the 1N/Adefault. You can provide a nonexistent button name, such as "-" to 1N/Astart up with no buttons selected. 1N/AThe optional fourth parameter (-linebreak) can be set to 'true' to put 1N/Aline breaks between the buttons, creating a vertical list. 1N/AThe optional fifth parameter (-labels) is a pointer to an associative 1N/Aarray relating the radio button values to user-visible labels to be 1N/Aused in the display. If not provided, the values themselves are 1N/AAll modern browsers can take advantage of the optional parameters 1N/AB<-rows>, and B<-columns>. These parameters cause radio_group() to 1N/Areturn an HTML3 compatible table containing the radio group formatted 1N/Awith the specified number of rows and columns. You can provide just 1N/Athe -columns parameter if you wish; radio_group will calculate the 1N/Acorrect number of rows for you. 1N/ATo include row and column headings in the returned table, you 1N/Acan use the B<-rowheaders> and B<-colheaders> parameters. Both 1N/Aof these accept a pointer to an array of headings to use. 1N/AThe headings are just decorative. They don't reorganize the 1N/Ainterpretation of the radio buttons -- they're still a single named 1N/AThe optional B<-tabindex> argument can be used to control the order in which 1N/Aradio buttons receive focus when the user presses the tab button. If 1N/Apassed a scalar numeric value, the first element in the group will 1N/Areceive this tab index and subsequent elements will be incremented by 1N/Aone. If given a reference to an array of radio button values, then 1N/Athe indexes will be jiggered so that the order specified in the array 1N/Awill correspond to the tab order. You can also pass a reference to a 1N/Ahash in which the hash keys are the radio button values and the values 1N/Aare the tab indexes of each button. Examples: 1N/A -tabindex => 100 # this group starts at index 100 and counts up 1N/A -tabindex => ['moe','minie','eenie','meenie'] # tab in this order 1N/A -tabindex => {meenie=>100,moe=>101,minie=>102,eenie=>200} # tab in this order 1N/AThe optional B<-attributes> argument is provided to assign any of the 1N/Acommon HTML attributes to an individual menu item. It's a pointer to 1N/Aa hash relating menu values to another hash 1N/Awith the attribute's name as the key and the attribute's value as the 1N/AThe optional B<-labelattributes> argument will contain attributes 1N/Aattached to the <label> element that surrounds each button. 1N/AWhen the form is processed, the selected radio button can 1N/A $which_radio_button = param('group_name'); 1N/AThe value returned by radio_group() is actually an array of button 1N/Aelements. You can capture them and use them within tables, lists, 1N/Aor in other creative ways: 1N/A @h = radio_group(-name=>'group_name',-values=>\@values); 1N/A &use_in_creative_way(@h); 1N/A=head2 CREATING A SUBMIT BUTTON 1N/A print submit(-name=>'button_name', 1N/A print submit('button_name','value'); 1N/Asubmit() will create the query submission button. Every form 1N/Ashould have one of these. 1N/AThe first argument (-name) is optional. You can give the button a 1N/Aname if you have several submission buttons in your form and you want 1N/Ato distinguish between them. 1N/AThe second argument (-value) is also optional. This gives the button 1N/Aa value that will be passed to your script in the query string. The 1N/Aname will also be used as the user-visible label. 1N/AYou can use -label as an alias for -value. I always get confused 1N/Aabout which of -name and -value changes the user-visible label on the 1N/AYou can figure out which button was pressed by using different 1N/A $which_one = param('button_name'); 1N/A=head2 CREATING A RESET BUTTON 1N/Areset() creates the "reset" button. Note that it restores the 1N/Aform to its value from the last time the script was called, 1N/ANOT necessarily to the defaults. 1N/ANote that this conflicts with the Perl reset() built-in. Use 1N/ACORE::reset() to get the original reset function. 1N/A=head2 CREATING A DEFAULT BUTTON 1N/A print defaults('button_label') 1N/Adefaults() creates a button that, when invoked, will cause the 1N/Aform to be completely reset to its defaults, wiping out all the 1N/Achanges the user ever made. 1N/A=head2 CREATING A HIDDEN FIELD 1N/A print hidden(-name=>'hidden_name', 1N/A -default=>['value1','value2'...]); 1N/A print hidden('hidden_name','value1','value2'...); 1N/Ahidden() produces a text field that can't be seen by the user. It 1N/Ais useful for passing state variable information from one invocation 1N/Aof the script to the next. 1N/AThe first argument is required and specifies the name of this 1N/AThe second argument is also required and specifies its value 1N/A(-default). In the named parameter style of calling, you can provide 1N/Aa single value here or a reference to a whole list 1N/AFetch the value of a hidden field this way: 1N/A $hidden_value = param('hidden_name'); 1N/ANote, that just like all the other form elements, the value of a 1N/Ahidden field is "sticky". If you want to replace a hidden field with 1N/Asome other values after the script has been called once you'll have to 1N/A param('hidden_name','new','values','here'); 1N/A=head2 CREATING A CLICKABLE IMAGE BUTTON 1N/A print image_button(-name=>'button_name', 1N/Aimage_button() produces a clickable image. When it's clicked on the 1N/Aposition of the click is returned to your script as "button_name.x" 1N/Aand "button_name.y", where "button_name" is the name you've assigned 1N/AThe first argument (-name) is required and specifies the name of this 1N/AThe second argument (-src) is also required and specifies the URL 1N/AThe third option (-align, optional) is an alignment type, and may be 1N/ATOP, BOTTOM or MIDDLE 1N/AFetch the value of the button this way: 1N/A $x = param('button_name.x'); 1N/A $y = param('button_name.y'); 1N/A=head2 CREATING A JAVASCRIPT ACTION BUTTON 1N/A print button(-name=>'button_name', 1N/A -value=>'user visible label', 1N/A -onClick=>"do_something()"); 1N/A print button('button_name',"user visible value","do_something()"); 1N/Abutton() produces an C<< <input> >> tag with C<type="button">. When it's 1N/Apressed the fragment of JavaScript code pointed to by the B<-onClick> parameter 1N/ABrowsers support a so-called "cookie" designed to help maintain state 1N/Awithin a browser session. CGI.pm has several methods that support 1N/AA cookie is a name=value pair much like the named parameters in a CGI 1N/Aquery string. CGI scripts create one or more cookies and send 1N/Athem to the browser in the HTTP header. The browser maintains a list 1N/Aof cookies that belong to a particular Web server, and returns them 1N/Ato the CGI script during subsequent interactions. 1N/AIn addition to the required name=value pair, each cookie has several 1N/A=item 1. an expiration time 1N/AThis is a time/date string (in a special GMT format) that indicates 1N/Awhen a cookie expires. The cookie will be saved and returned to your 1N/Ascript until this expiration date is reached if the user exits 1N/Athe browser and restarts it. If an expiration date isn't specified, the cookie 1N/Awill remain active until the user quits the browser. 1N/AThis is a partial or complete domain name for which the cookie is 1N/Avalid. The browser will return the cookie to any host that matches 1N/Athe partial domain name. For example, if you specify a domain name 1N/Aof ".capricorn.com", then the browser will return the cookie to 1N/AWeb servers running on any of the machines "www.capricorn.com", 1N/A"www2.capricorn.com", "feckless.capricorn.com", etc. Domain names 1N/Amust contain at least two periods to prevent attempts to match 1N/Aon top level domains like ".edu". If no domain is specified, then 1N/Athe browser will only return the cookie to servers on the host the 1N/Acookie originated from. 1N/AIf you provide a cookie path attribute, the browser will check it 1N/Aagainst your script's URL before returning the cookie. For example, 1N/Aif you specify the path "/cgi-bin", then the cookie will be returned 1N/Acauses the cookie to be sent to any CGI script on your site. 1N/A=item 4. a "secure" flag 1N/AIf the "secure" attribute is set, the cookie will only be sent to your 1N/Ascript if the CGI request is occurring on a secure channel, such as SSL. 1N/AThe interface to HTTP cookies is the B<cookie()> method: 1N/A $cookie = cookie(-name=>'sessionID', 1N/A -domain=>'.capricorn.org', 1N/A print header(-cookie=>$cookie); 1N/AB<cookie()> creates a new cookie. Its parameters include: 1N/AThe name of the cookie (required). This can be any string at all. 1N/AAlthough browsers limit their cookie names to non-whitespace 1N/Aalphanumeric characters, CGI.pm removes this restriction by escaping 1N/Aand unescaping cookies behind the scenes. 1N/AThe value of the cookie. This can be any scalar value, 1N/Aarray reference, or even hash reference. For example, 1N/Ayou can store an entire hash into a cookie this way: 1N/A $cookie=cookie(-name=>'family information', 1N/A -value=>\%childrens_ages); 1N/AThe optional partial path for which this cookie will be valid, as described 1N/AThe optional partial domain for which this cookie will be valid, as described 1N/AThe optional expiration date for this cookie. The format is as described 1N/Ain the section on the B<header()> method: 1N/A "+1h" one hour from now 1N/AIf set to true, this cookie will only be used within a secure 1N/AThe cookie created by cookie() must be incorporated into the HTTP 1N/Aheader within the string returned by the header() method: 1N/A use CGI ':standard'; 1N/A print header(-cookie=>$my_cookie); 1N/ATo create multiple cookies, give header() an array reference: 1N/A $cookie1 = cookie(-name=>'riddle_name', 1N/A -value=>"The Sphynx's Question"); 1N/A $cookie2 = cookie(-name=>'answers', 1N/A print header(-cookie=>[$cookie1,$cookie2]); 1N/ATo retrieve a cookie, request it by name by calling cookie() method 1N/Awithout the B<-value> parameter. This example uses the object-oriented 1N/A $riddle = $query->cookie('riddle_name'); 1N/A %answers = $query->cookie('answers'); 1N/ACookies created with a single scalar value, such as the "riddle_name" 1N/Acookie, will be returned in that form. Cookies with array and hash 1N/Avalues can also be retrieved. 1N/AThe cookie and CGI namespaces are separate. If you have a parameter 1N/Anamed 'answers' and a cookie named 'answers', the values retrieved by 1N/Aparam() and cookie() are independent of each other. However, it's 1N/Asimple to turn a CGI parameter into a cookie, and vice-versa: 1N/A # turn a CGI parameter into a cookie 1N/A $c=cookie(-name=>'answers',-value=>[param('answers')]); 1N/A param(-name=>'answers',-value=>[cookie('answers')]); 1N/AIf you call cookie() without any parameters, it will return a list of 1N/Athe names of all cookies passed to your script: 1N/A @cookies = cookie(); 1N/ASee the B<cookie.cgi> example script for some ideas on how to use 1N/A=head1 WORKING WITH FRAMES 1N/AIt's possible for CGI.pm scripts to write into several browser panels 1N/Aand windows using the HTML 4 frame mechanism. There are three 1N/Atechniques for defining new frames programmatically: 1N/A=item 1. Create a <Frameset> document 1N/AAfter writing out the HTTP header, instead of creating a standard 1N/AHTML document using the start_html() call, create a <frameset> 1N/Adocument that defines the frames on the page. Specify your script(s) 1N/A(with appropriate parameters) as the SRC for each of the frames. 1N/AThere is no specific support for creating <frameset> sections 1N/Ain CGI.pm, but the HTML is very simple to write. 1N/A=item 2. Specify the destination for the document in the HTTP header 1N/AYou may provide a B<-target> parameter to the header() method: 1N/A print header(-target=>'ResultsWindow'); 1N/AThis will tell the browser to load the output of your script into the 1N/Aframe named "ResultsWindow". If a frame of that name doesn't already 1N/Aexist, the browser will pop up a new window and load your script's 1N/Adocument into that. There are a number of magic names that you can 1N/Ause for targets. See the HTML C<< <frame> >> documentation for details. 1N/A=item 3. Specify the destination for the document in the <form> tag 1N/AYou can specify the frame to load in the FORM tag itself. With 1N/A print start_form(-target=>'ResultsWindow'); 1N/AWhen your script is reinvoked by the form, its output will be loaded 1N/Ainto the frame named "ResultsWindow". If one doesn't already exist 1N/Aa new window will be created. 1N/AThe script "frameset.cgi" in the examples directory shows one way to 1N/Acreate pages in which the fill-out form and the response live in 1N/A=head1 SUPPORT FOR JAVASCRIPT 1N/AThe usual way to use JavaScript is to define a set of functions in a 1N/A<SCRIPT> block inside the HTML header and then to register event 1N/Ahandlers in the various elements of the page. Events include such 1N/Athings as the mouse passing over a form element, a button being 1N/Aclicked, the contents of a text field changing, or a form being 1N/Asubmitted. When an event occurs that involves an element that has 1N/Aregistered an event handler, its associated JavaScript code gets 1N/AThe elements that can register event handlers include the <BODY> of an 1N/AHTML document, hypertext links, all the various elements of a fill-out 1N/Aform, and the form itself. There are a large number of events, and 1N/Aeach applies only to the elements for which it is relevant. Here is a 1N/AThe browser is loading the current document. Valid in: 1N/A + The HTML <BODY> section only. 1N/AThe browser is closing the current page or frame. Valid for: 1N/A + The HTML <BODY> section only. 1N/AThe user has pressed the submit button of a form. This event happens 1N/Ajust before the form is submitted, and your function can return a 1N/Avalue of false in order to abort the submission. Valid for: 1N/AThe mouse has clicked on an item in a fill-out form. Valid for: 1N/A + Buttons (including submit, reset, and image buttons) 1N/AThe user has changed the contents of a field. Valid for: 1N/AThe user has selected a field to work with. Valid for: 1N/AThe user has deselected a field (gone to work somewhere else). Valid 1N/AThe user has changed the part of a text field that is selected. Valid 1N/AThe mouse has moved over an element. 1N/AThe mouse has moved off an element. 1N/AIn order to register a JavaScript event handler with an HTML element, 1N/Ajust use the event name as a parameter when you call the corresponding 1N/ACGI method. For example, to have your validateAge() JavaScript code 1N/Aexecuted every time the textfield named "age" changes, generate the 1N/A print textfield(-name=>'age',-onChange=>"validateAge(this)"); 1N/AThis example assumes that you've already declared the validateAge() 1N/Afunction by incorporating it into a <SCRIPT> block. The CGI.pm 1N/Astart_html() method provides a convenient way to create this section. 1N/ASimilarly, you can create a form that checks itself over for 1N/Aconsistency and alerts the user if some essential value is missing by 1N/Acreating it this way: 1N/A print start_form(-onSubmit=>"validateMe(this)"); 1N/ASee the javascript.cgi script for a demonstration of how this all 1N/A=head1 LIMITED SUPPORT FOR CASCADING STYLE SHEETS 1N/ACGI.pm has limited support for HTML3's cascading style sheets (css). 1N/ATo incorporate a stylesheet into your document, pass the 1N/Astart_html() method a B<-style> parameter. The value of this 1N/Aparameter may be a scalar, in which case it is treated as the source 1N/AURL for the stylesheet, or it may be a hash reference. In the latter 1N/Acase you should provide the hash with one or more of B<-src> or 1N/AB<-code>. B<-src> points to a URL where an externally-defined 1N/Astylesheet can be found. B<-code> points to a scalar value to be 1N/Aincorporated into a <style> section. Style definitions in B<-code> 1N/Aoverride similarly-named ones in B<-src>, hence the name "cascading." 1N/AYou may also specify the type of the stylesheet by adding the optional 1N/AB<-type> parameter to the hash pointed to by B<-style>. If not 1N/ATo refer to a style within the body of your document, add the 1N/AB<-class> parameter to any HTML element: 1N/A print h1({-class=>'Fancy'},'Welcome to the Party'); 1N/AOr define styles on the fly with the B<-style> parameter: 1N/A print h1({-style=>'Color: red;'},'Welcome to Hell'); 1N/AYou may also use the new B<span()> element to apply a style to a 1N/A print span({-style=>'Color: red;'}, 1N/A h1('Welcome to Hell'), 1N/A "Where did that handbasket get to?" 1N/ANote that you must import the ":html3" definitions to have the 1N/AB<span()> method available. Here's a quick and dirty example of using 1N/ACSS's. See the CSS specification at 1N/A use CGI qw/:standard :html3/; 1N/A #here's a stylesheet incorporated directly into the page 1N/A font-family: sans-serif; 1N/A print start_html( -title=>'CGI with Style', 1N/A print h1('CGI with Style'), 1N/A "Better read the cascading style sheet spec before playing with this!"), 1N/A span({-style=>'color: magenta'}, 1N/A "Look Mom, no hands!", 1N/APass an array reference to B<-code> or B<-src> in order to incorporate 1N/Amultiple stylesheets into your document. 1N/AShould you wish to incorporate a verbatim stylesheet that includes 1N/Aarbitrary formatting in the header, you may pass a -verbatim tag to 1N/Athe -style hash, as follows: 1N/AThis will generate an HTML header that contains this: 1N/AAny additional arguments passed in the -style value will be 1N/Aincorporated into the <link> tag. For example: 1N/ATo make more complicated <link> tags, use the Link() function 1N/Aand pass it to start_html() in the -head argument, as in: 1N/A print start_html({-head=>\@h}) 1N/ATo create primary and "alternate" stylesheet, use the B<-alternate> option: 1N/A start_html(-style=>{-src=>[ 1N/AIf you are running the script from the command line or in the perl 1N/Adebugger, you can pass the script a list of keywords or 1N/Aparameter=value pairs on the command line or from standard input (you 1N/Adon't have to worry about tricking your script into reading from 1N/Aenvironment variables). You can pass keywords like this: 1N/ATo turn off this feature, use the -no_debug pragma. 1N/ATo test the POST method, you may enable full debugging with the -debug 1N/Apragma. This will allow you to feed newline-delimited name=value 1N/Apairs to the script on standard input. 1N/AWhen debugging, you can use quotes and backslashes to escape 1N/Acharacters in the familiar shell manner, letting you place 1N/Aspaces and other funny characters in your parameter=value 1N/AFinally, you can set the path info for the script by prefixing the first 1N/Aname/value parameter with the path followed by a question mark (?): 1N/AThe Dump() method produces a string consisting of all the query's 1N/Aname/value pairs formatted nicely as a nested list. This is useful 1N/Afor debugging purposes: 1N/AProduces something that looks like: 1N/AAs a shortcut, you can interpolate the entire CGI object into a string 1N/Aand it will be replaced with the a nice HTML dump shown above: 1N/A print "<h2>Current Values</h2> $query\n"; 1N/A=head1 FETCHING ENVIRONMENT VARIABLES 1N/ASome of the more useful environment variables can be fetched 1N/Athrough this interface. The methods are as follows: 1N/AReturn a list of MIME types that the remote browser accepts. If you 1N/Agive this method a single argument corresponding to a MIME type, as in 1N/AAccept('text/html'), it will return a floating point value 1N/Acorresponding to the browser's preference for this type from 0.0 1N/A(don't want) to 1.0. Glob types (e.g. text/*) in the browser's accept 1N/Alist are handled correctly. 1N/ANote that the capitalization changed between version 2.43 and 2.44 in 1N/Aorder to avoid conflict with Perl's accept() function. 1N/A=item B<raw_cookie()> 1N/AReturns the HTTP_COOKIE variable. Cookies have a special format, and 1N/Athis method call just returns the raw form (?cookie dough). See 1N/Acookie() for ways of setting and retrieving cooked cookies. 1N/ACalled with no parameters, raw_cookie() returns the packed cookie 1N/Astructure. You can separate it into individual cookies by splitting 1N/Aon the character sequence "; ". Called with the name of a cookie, 1N/Aretrieves the B<unescaped> form of the cookie. You can use the 1N/Aregular cookie() method to get the names, or use the raw_fetch() 1N/Amethod from the CGI::Cookie module. 1N/A=item B<user_agent()> 1N/AReturns the HTTP_USER_AGENT variable. If you give 1N/Athis method a single argument, it will attempt to 1N/Apattern match on it, allowing you to do something 1N/Alike user_agent(Mozilla); 1N/AReturns additional path information from the script URL. 1N/ANOTE: The Microsoft Internet Information Server 1N/Ais broken with respect to additional path information. If 1N/Ayou use the Perl DLL library, the IIS server will attempt to 1N/Aexecute the additional path information as a Perl script. 1N/AIf you use the ordinary file associations mapping, the 1N/Apath information will be present in the environment, 1N/Abut incorrect. The best thing to do is to avoid using additional 1N/Apath information in CGI scripts destined for use with IIS. 1N/A=item B<path_translated()> 1N/AAs per path_info() but returns the additional 1N/Apath information translated into a physical path, e.g. 1N/AThe Microsoft IIS is broken with respect to the translated 1N/A=item B<remote_host()> 1N/AReturns either the remote host name or IP address. 1N/Aif the former is unavailable. 1N/A=item B<remote_addr()> 1N/AReturns the remote host IP address, or 1N/A127.0.0.1 if the address is unavailable. 1N/A=item B<script_name()> 1N/AReturn the script name as a partial URL, for self-referring 1N/AReturn the URL of the page the browser was viewing 1N/Aprior to fetching your script. Not available for all 1N/A=item B<auth_type ()> 1N/A=item B<server_name ()> 1N/AReturns the name of the server, usually the machine's host 1N/A=item B<virtual_host ()> 1N/AWhen using virtual hosts, returns the name of the host that 1N/Athe browser attempted to contact 1N/A=item B<server_port ()> 1N/AReturn the port that the server is listening on. 1N/A=item B<virtual_port ()> 1N/ALike server_port() except that it takes virtual hosts into account. 1N/AUse this when running with virtual hosts. 1N/A=item B<server_software ()> 1N/AReturns the server software and version number. 1N/A=item B<remote_user ()> 1N/Averification, if this script is protected. 1N/A=item B<user_name ()> 1N/AAttempt to obtain the remote user's name, using a variety of different 1N/Atechniques. This only works with older browsers such as Mosaic. 1N/ANewer browsers do not report the user name for privacy reasons! 1N/A=item B<request_method()> 1N/AReturns the method used to access your script, usually 1N/Aone of 'POST', 'GET' or 'HEAD'. 1N/A=item B<content_type()> 1N/AReturns the content_type of data submitted in a POST, generally 1N/ACalled with no arguments returns the list of HTTP environment 1N/Avariables, including such things as HTTP_USER_AGENT, 1N/AHTTP_ACCEPT_LANGUAGE, and HTTP_ACCEPT_CHARSET, corresponding to the 1N/Alike-named HTTP header fields in the request. Called with the name of 1N/Aan HTTP header field, returns its value. Capitalization and the use 1N/Aof hyphens versus underscores are not significant. 1N/AFor example, all three of these examples are equivalent: 1N/A $requested_language = http('Accept-language'); 1N/A $requested_language = http('Accept_language'); 1N/A $requested_language = http('HTTP_ACCEPT_LANGUAGE'); 1N/AThe same as I<http()>, but operates on the HTTPS environment variables 1N/Apresent when the SSL protocol is in effect. Can be used to determine 1N/Awhether SSL is turned on. 1N/A=head1 USING NPH SCRIPTS 1N/ANPH, or "no-parsed-header", scripts bypass the server completely by 1N/Asending the complete HTTP header directly to the browser. This has 1N/Aslight performance benefits, but is of most use for taking advantage 1N/Aof HTTP extensions that are not directly supported by your server, 1N/Asuch as server push and PICS headers. 1N/AServers use a variety of conventions for designating CGI scripts as 1N/ANPH. Many Unix servers look at the beginning of the script's name for 1N/Athe prefix "nph-". The Macintosh WebSTAR server and Microsoft's 1N/AInternet Information Server, in contrast, try to decide whether a 1N/Aprogram is an NPH script by examining the first line of script output. 1N/ACGI.pm supports NPH scripts with a special NPH mode. When in this 1N/Amode, CGI.pm will output the necessary extra header information when 1N/Athe header() and redirect() methods are 1N/AThe Microsoft Internet Information Server requires NPH mode. As of 1N/Aversion 2.30, CGI.pm will automatically detect when the script is 1N/Arunning under IIS and put itself into this mode. You do not need to 1N/Ado this manually, although it won't hurt anything if you do. However, 1N/Anote that if you have applied Service Pack 6, much of the 1N/Afunctionality of NPH scripts, including the ability to redirect while 1N/Asetting a cookie, B<do not work at all> on IIS without a special patch 1N/ANon-Parsed Headers Stripped From CGI Applications That Have nph- 1N/A=item In the B<use> statement 1N/ASimply add the "-nph" pragma to the list of symbols to be imported into 1N/A use CGI qw(:standard -nph) 1N/A=item By calling the B<nph()> method: 1N/ACall B<nph()> with a non-zero parameter at any point after using CGI.pm in your program. 1N/A=item By using B<-nph> parameters 1N/Ain the B<header()> and B<redirect()> statements: 1N/A print header(-nph=>1); 1N/ACGI.pm provides four simple functions for producing multipart 1N/Adocuments of the type needed to implement server push. These 1N/Afunctions were graciously provided by Ed Jordan <ed@fidalgo.net>. To 1N/Aimport these into your namespace, you must import the ":push" set. 1N/AYou are also advised to put the script into NPH mode and to set $| to 1N/A1 to avoid buffering problems. 1N/AHere is a simple script that demonstrates server push: 1N/A use CGI qw/:push -nph/; 1N/A print multipart_init(-boundary=>'----here we go!'); 1N/A "The current time is ",scalar(localtime),"\n"; 1N/A print multipart_end; 1N/A print multipart_final; 1N/AThis script initializes server push by calling B<multipart_init()>. 1N/AIt then enters a loop in which it begins a new multipart section by 1N/Acalling B<multipart_start()>, prints the current local time, 1N/Aand ends a multipart section with B<multipart_end()>. It then sleeps 1N/Aa second, and begins again. On the final iteration, it ends the 1N/Amultipart section with B<multipart_final()> rather than with 1N/A=item multipart_init() 1N/A multipart_init(-boundary=>$boundary); 1N/AInitialize the multipart system. The -boundary argument specifies 1N/Awhat MIME boundary string to use to separate parts of the document. 1N/AIf not provided, CGI.pm chooses a reasonable boundary for you. 1N/A=item multipart_start() 1N/A multipart_start(-type=>$type) 1N/AStart a new part of the multipart document using the specified MIME 1N/A=item multipart_end() 1N/AEnd a part. You must remember to call multipart_end() once for each 1N/Amultipart_start(), except at the end of the last part of the multipart 1N/Adocument when multipart_final() should be called instead of multipart_end(). 1N/A=item multipart_final() 1N/AEnd all parts. You should call multipart_final() rather than 1N/Amultipart_end() at the end of the last part of the multipart document. 1N/AUsers interested in server push applications should also have a look 1N/Aat the CGI::Push module. 1N/A=head1 Avoiding Denial of Service Attacks 1N/AA potential problem with CGI.pm is that, by default, it attempts to 1N/Aprocess form POSTings no matter how large they are. A wily hacker 1N/Acould attack your site by sending a CGI script a huge POST of many 1N/Amegabytes. CGI.pm will attempt to read the entire POST into a 1N/Avariable, growing hugely in size until it runs out of memory. While 1N/Athe script attempts to allocate the memory the system may slow down 1N/Adramatically. This is a form of denial of service attack. 1N/AAnother possible attack is for the remote user to force CGI.pm to 1N/Aaccept a huge file upload. CGI.pm will accept the upload and store it 1N/Ain a temporary directory even if your script doesn't expect to receive 1N/Aan uploaded file. CGI.pm will delete the file automatically when it 1N/Aterminates, but in the meantime the remote user may have filled up the 1N/Aserver's disk space, causing problems for other programs. 1N/AThe best way to avoid denial of service attacks is to limit the amount 1N/Aof memory, CPU time and disk space that CGI scripts can use. Some Web 1N/Aservers come with built-in facilities to accomplish this. In other 1N/Acases, you can use the shell I<limit> or I<ulimit> 1N/Acommands to put ceilings on CGI resource usage. 1N/ACGI.pm also has some simple built-in protections against denial of 1N/Aservice attacks, but you must activate them before you can use them. 1N/AThese take the form of two global variables in the CGI name space: 1N/A=item B<$CGI::POST_MAX> 1N/AIf set to a non-negative integer, this variable puts a ceiling 1N/Aon the size of POSTings, in bytes. If CGI.pm detects a POST 1N/Athat is greater than the ceiling, it will immediately exit with an error 1N/Amessage. This value will affect both ordinary POSTs and 1N/Amultipart POSTs, meaning that it limits the maximum size of file 1N/Auploads as well. You should set this to a reasonably high 1N/Avalue, such as 1 megabyte. 1N/A=item B<$CGI::DISABLE_UPLOADS> 1N/AIf set to a non-zero value, this will disable file uploads 1N/Acompletely. Other fill-out form values will work as usual. 1N/AYou can use these variables in either of two ways. 1N/A=item B<1. On a script-by-script basis> 1N/ASet the variable at the top of the script, right after the "use" statement: 1N/A use CGI qw/:standard/; 1N/A use CGI::Carp 'fatalsToBrowser'; 1N/A $CGI::POST_MAX=1024 * 100; # max 100K posts 1N/A $CGI::DISABLE_UPLOADS = 1; # no uploads 1N/A=item B<2. Globally for all scripts> 1N/AOpen up CGI.pm, find the definitions for $POST_MAX and 1N/A$DISABLE_UPLOADS, and set them to the desired values. You'll 1N/Afind them towards the top of the file in a subroutine named 1N/Ainitialize_globals(). 1N/AAn attempt to send a POST larger than $POST_MAX bytes will cause 1N/AI<param()> to return an empty CGI parameter list. You can test for 1N/Athis event by checking I<cgi_error()>, either after you create the CGI 1N/Aobject or, if you are using the function-oriented interface, call 1N/A<param()> for the first time. If the POST was intercepted, then 1N/Acgi_error() will return the message "413 POST too large". 1N/AThis error message is actually defined by the HTTP protocol, and is 1N/Adesigned to be returned to the browser as the CGI script's status 1N/A $uploaded_file = param('upload'); 1N/A if (!$uploaded_file && cgi_error()) { 1N/A print header(-status=>cgi_error()); 1N/AHowever it isn't clear that any browser currently knows what to do 1N/Awith this status code. It might be better just to create an 1N/AHTML page that warns the user of the problem. 1N/ATo make it easier to port existing programs that use cgi-lib.pl the 1N/Acompatibility routine "ReadParse" is provided. Porting is simple: 1N/A print "The value of the antique is $in{antique}.\n"; 1N/A print "The value of the antique is $in{antique}.\n"; 1N/ACGI.pm's ReadParse() routine creates a tied variable named %in, 1N/Awhich can be accessed to obtain the query variables. Like 1N/AReadParse, you can also provide your own variable. Infrequently 1N/Aused features of ReadParse, such as the creation of @in and $in 1N/Avariables, are not supported. 1N/AOnce you use ReadParse, you can retrieve the query object itself 1N/A print $q->textfield(-name=>'wow', 1N/A -value=>'does this really work?'); 1N/AThis allows you to start using the more interesting features 1N/Aof CGI.pm without rewriting your old scripts from scratch. 1N/AAn even simpler way to mix cgi-lib calls with CGI.pm calls is to import both the 1N/AC<:cgi-lib> and C<:standard> method: 1N/A use CGI qw(:cgi-lib :standard); 1N/A print "The price of your purchase is $in{price}.\n"; 1N/A print textfield(-name=>'price', -default=>'$1.99'); 1N/A=head2 Cgi-lib functions that are available in CGI.pm 1N/Aavailable for your use: 1N/A=head2 Cgi-lib functions that are not available in CGI.pm 1N/A * Extended form of ReadParse() 1N/A The extended form of ReadParse() that provides for file upload 1N/A spooling, is not available. 1N/A This function is not available. Use CGI.pm's url() method instead. 1N/A This function is not available. Use CGI.pm's self_url() method 1N/A * CgiError(), CgiDie() 1N/A These functions are not supported. Look at CGI::Carp for the way I 1N/A prefer to handle error messages. 1N/A This function is not available. To achieve the same effect, 1N/A just print out the CGI object: 1N/A use CGI qw(:standard); 1N/A print h1("The Variables Are"),$q; 1N/A This function is not available. You'll have to roll your own if you really need it. 1N/A=head1 AUTHOR INFORMATION 1N/AThe CGI.pm distribution is copyright 1995-2007, Lincoln D. Stein. It is 1N/Adistributed under GPL and the Artistic License 2.0. 1N/AAddress bug reports and comments to: lstein@cshl.org. When sending 1N/Abug reports, please provide the version of CGI.pm, the version of 1N/APerl, the name and version of your Web server, and the name and 1N/Aversion of the operating system you are using. If the problem is even 1N/Aremotely browser dependent, please provide information about the 1N/Aaffected browsers as well. 1N/A=item Matt Heffron (heffron@falstaff.css.beckman.com) 1N/A=item James Taylor (james.taylor@srs.gov) 1N/A=item Scott Anguish <sanguish@digifix.com> 1N/A=item Mike Jewell (mlj3u@virginia.edu) 1N/A=item Timothy Shimmin (tes@kbs.citri.edu.au) 1N/A=item Joergen Haegg (jh@axis.se) 1N/A=item Laurent Delfosse (delfosse@delfosse.com) 1N/A=item Richard Resnick (applepi1@aol.com) 1N/A=item Craig Bishop (csb@barwonwater.vic.gov.au) 1N/A=item Tony Curtis (tc@vcpc.univie.ac.at) 1N/A=item Tim Bunce (Tim.Bunce@ig.co.uk) 1N/A=item Tom Christiansen (tchrist@convex.com) 1N/A=item Andreas Koenig (k@franz.ww.TU-Berlin.DE) 1N/A=item Tim MacKenzie (Tim.MacKenzie@fulcrum.com.au) 1N/A=item Kevin B. Hendricks (kbhend@dogwood.tyler.wm.edu) 1N/A=item Stephen Dahmen (joyfire@inxpress.net) 1N/A=item Ed Jordan (ed@fidalgo.net) 1N/A=item David Alan Pisoni (david@cnation.com) 1N/A=item Doug MacEachern (dougm@opengroup.org) 1N/A=item Robin Houston (robin@oneworld.org) 1N/A=item ...and many many more... 1N/Afor suggestions and bug fixes. 1N/A=head1 A COMPLETE EXAMPLE OF A SIMPLE FORM-BASED SCRIPT 1N/A use CGI ':standard'; 1N/A print "<em>What's your name?</em><br>"; 1N/A print textfield('name'); 1N/A print checkbox('Not my real name'); 1N/A print "<p><em>Where can you find English Sparrows?</em><br>"; 1N/A print checkbox_group( 1N/A -name=>'Sparrow locations', 1N/A -values=>[England,France,Spain,Asia,Hoboken], 1N/A -defaults=>[England,Asia]); 1N/A print "<p><em>How far can they fly?</em><br>", 1N/A -values=>['10 ft','1 mile','10 miles','real far'], 1N/A -default=>'1 mile'); 1N/A print "<p><em>What's your favorite color?</em> "; 1N/A print popup_menu(-name=>'Color', 1N/A -values=>['black','brown','red','yellow'], 1N/A print hidden('Reference','Monty Python and the Holy Grail'); 1N/A print "<p><em>What have you got there?</em><br>"; 1N/A print scrolling_list( 1N/A -name=>'possessions', 1N/A -values=>['A Coconut','A Grail','An Icon', 1N/A 'A Sword','A Ticket'], 1N/A print "<p><em>Any parting comments?</em><br>"; 1N/A print textarea(-name=>'Comments', 1N/A print submit('Action','Shout'); 1N/A print submit('Action','Scream'); 1N/A print "<h2>Here are the current settings in this form</h2>"; 1N/A for my $key (param) { 1N/A print "<strong>$key</strong> -> "; 1N/A my @values = param($key); 1N/A print join(", ",@values),"<br>\n"; 1N/A <address>Lincoln D. Stein</address><br> 1N/A <a href="/">Home Page</a> 1N/AL<CGI::Carp> - provides a L<Carp> implementation tailored to the CGI environment. 1N/AL<CGI::Fast> - supports running CGI applications under FastCGI 1N/AL<CGI::Pretty> - pretty prints HTML generated by CGI.pm (with a performance penalty)