lib
Current Perl documentation can be found at perldoc.perl.org.
Here is our local, out-dated (pre-5.6) version:
CREATING A FILE UPLOAD FIELD
print $query->filefield(-name=>'uploaded_file', -default=>'starting value', -size=>50, -maxlength=>80); -or-
print $query->filefield('uploaded_file','starting value',50,80);
filefield()
will return a
file upload field for Netscape 2.0 browsers. In order to take full
advantage of this you must use the new
multipart encoding scheme for the form. You can do this either by calling startform() with an encoding type of $CGI::MULTIPART, or by calling the new method start_multipart_form() instead of vanilla startform().
- Parameters
-
- .
The first parameter is the required name for the field (-name).
- . The optional second parameter is the starting value for the field contents to be used as the default file name (-default).
The beta2 version of Netscape 2.0 currently doesn't pay any attention to this field, and so the starting value will always be blank. Worse, the field loses its ``sticky'' behavior and forgets its previous contents. The starting value field is called for in the HTML specification, however, and possibly later versions of Netscape will honor it.
- . The optional third parameter is the size of the field in characters (-size).
- . The optional fourth parameter is the maximum number of characters the field will accept (-maxlength).
- .
When the form is processed, you can retrieve the entered filename by calling
param().
$filename = $query->param('uploaded_file');
In Netscape Navigator 2.0, the filename that gets returned is the full local filename on the remote user's machine. If the remote user is on a Unix machine, the filename will follow Unix conventions:
/path/to/the/file
On an MS-DOS/Windows and OS/2 machines, the filename will follow DOS conventions:
C:\PATH\TO\THE\FILE.MSW
On a Macintosh machine, the filename will follow Mac conventions:
HD 40:Desktop Folder:Sort Through:Reminders
The filename returned is also a file handle. You can read the contents of the file using standard Perl file reading calls:
# Read a text file and print it out while (<$filename>) { print; }
# Copy a binary file to somewhere safe open (OUTFILE,">>/usr/local/web/users/feedback"); while ($bytesread=read($filename,$buffer,1024)) { print OUTFILE $buffer; }
When a file is uploaded the browser usually sends along some information along with it in the format of headers. The information usually includes the
MIME content type. Future browsers may send other information as well (such as modification date and size). To retrieve this information, call
uploadInfo().
It returns a reference to an associative array containing all the document headers.
$filename = $query->param('uploaded_file'); $type = $query->uploadInfo($filename)->{'Content-Type'}; unless ($type eq 'text/html') { die "HTML FILES ONLY!"; }
If you are using a machine that recognizes ``text'' and ``binary'' data modes, be sure to understand when and how to use them (see the Camel book). Otherwise you may find that binary files are corrupted during file uploads.
JAVASCRIPTING: The -onChange, -onFocus, -onBlur,
-onMouseOver, -onMouseOut and -onSelect parameters are recognized. See
textfield()
for details.
CREATING A POPUP MENU
print $query->popup_menu('menu_name', ['eenie','meenie','minie'], 'meenie');
-or-
%labels = ('eenie'=>'your first choice', 'meenie'=>'your second choice', 'minie'=>'your third choice'); print $query->popup_menu('menu_name', ['eenie','meenie','minie'], 'meenie',\%labels);
-or (named parameter style)-
print $query->popup_menu(-name=>'menu_name', -values=>['eenie','meenie','minie'], -default=>'meenie', -labels=>\%labels);
popup_menu()
creates a
menu.
- .
The required first argument is the menu's name (-name).
- . The required second argument (-values) is an array reference containing the list of menu items in the menu. You can pass the method an anonymous array, as shown in the example, or a reference to a named array, such as ``\@foo''.
- . The optional third parameter (-default) is the name of the default menu choice. If not specified, the first item will be the default. The values of the previous choice will be maintained across queries.
- . The optional fourth parameter (-labels) is provided for people who want to use different values for the user-visible label inside the popup menu nd the value returned to your script. It's a pointer to an associative array relating menu values to user-visible labels. If you leave this parameter blank, the menu values will be displayed by default. (You can also leave a label undefined if you want to).
When the form is processed, the selected value of the popup menu can be retrieved using:
$popup_menu_value = $query->param('menu_name');
JAVASCRIPTING:
popup_menu()
recognizes the following event handlers:
-onChange, -onFocus, -onMouseOver, -onMouseOut, and
-onBlur. See the
textfield()
section for
details on when these handlers are called.
CREATING A SCROLLING LIST
print $query->scrolling_list('list_name', ['eenie','meenie','minie','moe'], ['eenie','moe'],5,'true'); -or-
print $query->scrolling_list('list_name', ['eenie','meenie','minie','moe'], ['eenie','moe'],5,'true', \%labels);
-or-
print $query->scrolling_list(-name=>'list_name', -values=>['eenie','meenie','minie','moe'], -default=>['eenie','moe'], -size=>5, -multiple=>'true', -labels=>\%labels);
scrolling_list()
creates a scrolling list.
- Parameters:
-
- .
The first and second arguments are the list name (-name) and values (-values). As in the popup menu, the second argument should be an array reference.
- . The optional third argument (-default) can be either a reference to a list containing the values to be selected by default, or can be a single value to select. If this argument is missing or undefined, then nothing is selected when the list first appears. In the named parameter version, you can use the synonym ``-defaults'' for this parameter.
- . The optional fourth argument is the size of the list (-size).
- . The optional fifth argument can be set to true to allow multiple simultaneous selections (-multiple). Otherwise only one selection will be allowed at a time.
- . The optional sixth argument is a pointer to an associative array containing long user-visible labels for the list items (-labels). If not provided, the values will be displayed.
When this form is processed, all selected list items will be returned as a list under the parameter name 'list_name'. The values of the selected items can be retrieved with:
@selected = $query->param('list_name');
- .
JAVASCRIPTING:
scrolling_list()
recognizes the following event handlers:
-onChange, -onFocus, -onMouseOver, -onMouseOut
and -onBlur. See
textfield()
for the
description of when these handlers are called.
CREATING A GROUP OF RELATED CHECKBOXES
print $query->checkbox_group(-name=>'group_name', -values=>['eenie','meenie','minie','moe'], -default=>['eenie','moe'], -linebreak=>'true', -labels=>\%labels);
print $query->checkbox_group('group_name', ['eenie','meenie','minie','moe'], ['eenie','moe'],'true',\%labels);
HTML3-COMPATIBLE BROWSERS ONLY:
print $query->checkbox_group(-name=>'group_name', -values=>['eenie','meenie','minie','moe'], -rows=2,-columns=>2);
checkbox_group()
creates a list of checkboxes that are related by the same name.
- Parameters:
-
- .
The first and second arguments are the checkbox name and values, respectively (-name and -values). As in the popup menu, the second argument should be an array reference. These values are used for the user-readable labels printed next to the checkboxes as well as for the values passed to your script in the query string.
- . The optional third argument (-default) can be either a reference to a list containing the values to be checked by default, or can be a single value to checked. If this argument is missing or undefined, then nothing is selected when the list first appears.
- . The optional fourth argument (-linebreak) can be set to true to place line breaks between the checkboxes so that they appear as a vertical list. Otherwise, they will be strung together on a horizontal line.
- . The optional fifth argument is a pointer to an associative array relating the checkbox values to the user-visible labels that will be printed next to them (-labels). If not provided, the values will be used as the default.
- . HTML3-compatible browsers (such as Netscape) can take advantage of the optional parameters -rows, and -columns. These parameters cause
checkbox_group()
to return an HTML3 compatible table containing the checkbox group formatted with the specified number of rows and columns. You can provide just the -columns parameter if you wish; checkbox_group will calculate the correct number of rows for you.To include row and column headings in the returned table, you can use the -rowheaders and -colheaders parameters. Both of these accept a pointer to an array of headings to use. The headings are just decorative. They don't reorganize the interpretation of the checkboxes -- they're still a single named unit.
- .
When the form is processed, all checked boxes will be returned as a list under the parameter name 'group_name'. The values of the ``on'' checkboxes can be retrieved with:
@turned_on = $query->param('group_name');
The value returned by
checkbox_group()
is
actually an array of button elements. You can capture them and use them
within tables, lists, or in other creative ways:
@h = $query->checkbox_group(-name=>'group_name',-values=>\@values); &use_in_creative_way(@h);
JAVASCRIPTING:
checkbox_group()
recognizes the
-onClick
parameter. This specifies a JavaScript code fragment or function call to be
executed every time the user clicks on any of the buttons in the group. You
can retrieve the identity of the particular button clicked on using the
``this'' variable.
CREATING A STANDALONE CHECKBOX
print $query->checkbox(-name=>'checkbox_name', -checked=>'checked', -value=>'ON', -label=>'CLICK ME');
-or-
print $query->checkbox('checkbox_name','checked','ON','CLICK ME');
checkbox()
is used to
create an isolated checkbox that isn't logically related to any others.
- Parameters:
-
- .
The first parameter is the required name for the checkbox (-name). It will also be used for the user-readable label printed next to the checkbox.
- . The optional second parameter (-checked) specifies that the checkbox is turned on by default. Synonyms are -selected and -on.
- . The optional third parameter (-value) specifies the value of the checkbox when it is checked. If not provided, the word ``on'' is assumed.
- . The optional fourth parameter (-label) is the user-readable label to be attached to the checkbox. If not provided, the checkbox name is used.
- .
The value of the checkbox can be retrieved using:
$turned_on = $query->param('checkbox_name');
JAVASCRIPTING:
checkbox()
recognizes the
-onClick
parameter. See
checkbox_group()
for
further details.
CREATING A RADIO BUTTON GROUP
print $query->radio_group(-name=>'group_name', -values=>['eenie','meenie','minie'], -default=>'meenie', -linebreak=>'true', -labels=>\%labels);
-or-
print $query->radio_group('group_name',['eenie','meenie','minie'], 'meenie','true',\%labels);
HTML3-COMPATIBLE BROWSERS ONLY:
print $query->radio_group(-name=>'group_name', -values=>['eenie','meenie','minie','moe'], -rows=2,-columns=>2);
radio_group()
creates a
set of logically-related radio buttons (turning one member of the group on
turns the others off)
- Parameters:
-
- .
The first argument is the name of the group and is required (-name).
- . The second argument (-values) is the list of values for the radio buttons. The values and the labels that appear on the page are identical. Pass an array reference in the second argument, either using an anonymous array, as shown, or by referencing a named array as in ``\@foo''.
- . The optional third parameter (-default) is the name of the default button to turn on. If not specified, the first item will be the default. You can provide a nonexistent button name, such as ``-'' to start up with no buttons selected.
- . The optional fourth parameter (-linebreak) can be set to 'true' to put line breaks between the buttons, creating a vertical list.
- . The optional fifth parameter (-labels) is a pointer to an associative array relating the radio button values to user-visible labels to be used in the display. If not provided, the values themselves are displayed.
- . HTML3-compatible browsers (such as Netscape) can take advantage of the optional parameters -rows, and -columns. These parameters cause
radio_group()
to return an HTML3 compatible table containing the radio group formatted with the specified number of rows and columns. You can provide just the -columns parameter if you wish; radio_group will calculate the correct number of rows for you.To include row and column headings in the returned table, you can use the -rowheader and -colheader parameters. Both of these accept a pointer to an array of headings to use. The headings are just decorative. They don't reorganize the interpetation of the radio buttons -- they're still a single named unit.
- .
When the form is processed, the selected radio button can be retrieved using:
$which_radio_button = $query->param('group_name');
The value returned by
radio_group()
is
actually an array of button elements. You can capture them and use them
within tables, lists, or in other creative ways:
@h = $query->radio_group(-name=>'group_name',-values=>\@values); &use_in_creative_way(@h);
CREATING A SUBMIT BUTTON
print $query->submit(-name=>'button_name', -value=>'value');
-or-
print $query->submit('button_name','value');
submit()
will create the
query submission button. Every form should have one of these.
- Parameters:
-
- .
The first argument (-name) is optional. You can give the button a name if you have several submission buttons in your form and you want to distinguish between them. The name will also be used as the user-visible label. Be aware that a few older browsers don't deal with this correctly and never send back a value from a button.
- . The second argument (-value) is also optional. This gives the button a value that will be passed to your script in the query string.
- .
You can figure out which button was pressed by using different values for each one:
$which_one = $query->param('button_name');
JAVASCRIPTING:
radio_group()
recognizes the
-onClick
parameter. See
checkbox_group()
for
further details.
CREATING A RESET BUTTON
print $query->reset
reset()
creates the ``reset'' button. Note that it restores the form to its value from the last time the script was called,
NOT necessarily to the defaults.
CREATING A DEFAULT BUTTON
print $query->defaults('button_label')
defaults()
creates a button
that, when invoked, will cause the form to be completely reset to its
defaults, wiping out all the changes the user ever made.
CREATING A HIDDEN FIELD
print $query->hidden(-name=>'hidden_name', -default=>['value1','value2'...]);
-or-
print $query->hidden('hidden_name','value1','value2'...);
hidden()
produces a text
field that can't be seen by the user. It is useful for passing state
variable information from one invocation of the script to the next.
- Parameters:
-
- .
The first argument is required and specifies the name of this field (-name).
- . The second argument is also required and specifies its value (-default). In the named parameter style of calling, you can provide a single value here or a reference to a whole list
- .
Fetch the value of a hidden field this way:
$hidden_value = $query->param('hidden_name');
Note, that just like all the other form elements, the value of a hidden field is ``sticky''. If you want to replace a hidden field with some other values after the script has been called once you'll have to do it manually:
$query->param('hidden_name','new','values','here');
CREATING A CLICKABLE IMAGE BUTTON
print $query->image_button(-name=>'button_name', -src=>'/source/URL', -align=>'MIDDLE');
-or-
print $query->image_button('button_name','/source/URL','MIDDLE');
image_button()
produces
a clickable image. When it's clicked on the position of the click is
returned to your script as ``button_name.x'' and ``button_name.y'', where
``button_name'' is the name you've assigned to it.
JAVASCRIPTING:
image_button()
recognizes the
-onClick
parameter. See
checkbox_group()
for
further details.
- Parameters:
-
- .
The first argument (-name) is required and specifies the name of this field.
- . The second argument (-src) is also required and specifies the URL
- The third option (-align, optional) is an alignment type, and may be TOP, BOTTOM or MIDDLE
- .
Fetch the value of the button this way: $x
=
$query->param('button_name.x'); $y =
$query->param('button_name.y');
CREATING A JAVASCRIPT ACTION BUTTON
print $query->button(-name=>'button_name', -value=>'user visible label', -onClick=>"do_something()");
-or-
print $query->button('button_name',"do_something()");
button()
produces a button
that is compatible with Netscape 2.0's JavaScript. When it's pressed the
fragment of JavaScript code pointed to by the -onClick parameter will be executed. On non-Netscape browsers this form element will
probably not even display.
NETSCAPE COOKIES
Netscape browsers versions 1.1 and higher support a so-called ``cookie'' designed to help maintain state within a browser session. CGI.pm has several methods that support cookies.
A cookie is a name=value pair much like the named parameters in a CGI query string. CGI scripts create one or more cookies and send them to the browser in the HTTP header. The browser maintains a list of cookies that belong to a particular Web server, and returns them to the CGI script during subsequent interactions.
In addition to the required name=value pair, each cookie has several optional attributes:
- an expiration time
This is a time/date string (in a special GMT format) that indicates when a cookie expires. The cookie will be saved and returned to your script until this expiration date is reached if the user exits Netscape and restarts it. If an expiration date isn't specified, the cookie will remain active until the user quits Netscape.
- a domain This is a partial or complete domain name for which the cookie is valid. The browser will return the cookie to any host that matches the partial domain name. For example, if you specify a domain name of ``.capricorn.com'', then Netscape will return the cookie to Web servers running on any of the machines ``www.capricorn.com'', ``www2.capricorn.com'', ``feckless.capricorn.com'', etc. Domain names must contain at least two periods to prevent attempts to match on top level domains like ``.edu''. If no domain is specified, then the browser will only return the cookie to servers on the host the cookie originated from.
- a path If you provide a cookie path attribute, the browser will check it against your script's URL before returning the cookie. For example, if you specify the path ``/cgi-bin'', then the cookie will be returned to each of the scripts ``/cgi-bin/tally.pl'', ``/cgi-bin/order.pl'', and ``/cgi-bin/customer_service/complain.pl'', but not to the script ``/cgi-private/site_admin.pl''. By default, path is set to ``/'', which causes the cookie to be sent to any CGI script on your site.
- a "secure" flag If the ``secure'' attribute is set, the cookie will only be sent to your script if the CGI request is occurring on a secure channel, such as SSL.
The interface to Netscape cookies is the cookie() method:
$cookie = $query->cookie(-name=>'sessionID', -value=>'xyzzy', -expires=>'+1h', -path=>'/cgi-bin/database', -domain=>'.capricorn.org', -secure=>1); print $query->header(-cookie=>$cookie);
cookie() creates a new cookie. Its parameters include:
- -name
- The name of the cookie (required). This can be any string at all. Although Netscape limits its cookie names to non-whitespace alphanumeric characters, CGI.pm removes this restriction by escaping and unescaping cookies behind the scenes.
- -value
-
The value of the cookie. This can be any scalar value, array reference, or
even associative array reference. For example, you can store an entire
associative array into a cookie this way:
$cookie=$query->cookie(-name=>'family information', -value=>\%childrens_ages);
- -path
- The optional partial path for which this cookie will be valid, as described above.
- -domain
- The optional partial domain for which this cookie will be valid, as described above.
- -expires
-
The optional expiration date for this cookie. The format is as described in
the section on the header() method:
"+1h" one hour from now
- -secure
- If set to true, this cookie will only be used within a secure SSL session.
The cookie created by
cookie()
must be incorporated into the
HTTP header within the string returned by the
header()
method:
print $query->header(-cookie=>$my_cookie);
To create multiple cookies, give
header()
an array reference:
$cookie1 = $query->cookie(-name=>'riddle_name', -value=>"The Sphynx's Question"); $cookie2 = $query->cookie(-name=>'answers', -value=>\%answers); print $query->header(-cookie=>[$cookie1,$cookie2]);
To retrieve a cookie, request it by name by calling
cookie()
method without the -value parameter:
use CGI; $query = new CGI; %answers = $query->cookie(-name=>'answers'); # $query->cookie('answers') will work too!
The cookie and
CGI namespaces are separate. If you have a parameter named 'answers' and a cookie named 'answers', the values retrieved by
param()
and
cookie()
are independent of each other. However, it's simple to turn a
CGI parameter into a cookie, and vice-versa:
# turn a CGI parameter into a cookie $c=$q->cookie(-name=>'answers',-value=>[$q->param('answers')]); # vice-versa $q->param(-name=>'answers',-value=>[$q->cookie('answers')]);
See the cookie.cgi example script for some ideas on how to use cookies effectively.
NOTE: There appear to be some (undocumented) restrictions on Netscape cookies. In Netscape 2.01, at least, I haven't been able to set more than three cookies at a time. There may also be limits on the length of cookies. If you need to store a lot of information, it's probably better to create a unique session ID, store it in a cookie, and use the session ID to locate an external file/database saved on the server's side of the connection.
WORKING WITH NETSCAPE FRAMES
It's possible for CGI.pm scripts to write into several browser panels and windows using Netscape's frame mechanism. There are three techniques for defining new frames programmatically:
- Create a <Frameset> document
After writing out the HTTP header, instead of creating a standard HTML document using the
start_html()
call, create a <FRAMESET> document that defines the frames on the page. Specify yourscript(s)
(with appropriate parameters) as the SRC for each of the frames.There is no specific support for creating <FRAMESET> sections in CGI.pm, but the HTML is very simple to write. See the frame documentation in Netscape's home pages for details
frames
- Specify the destination for the document in the HTTP header
You may provide a -target parameter to the
header()
method: print $q->header(-target=>'ResultsWindow');This will tell Netscape to load the output of your script into the frame named ``ResultsWindow''. If a frame of that name doesn't already exist, Netscape will pop up a new window and load your script's document into that. There are a number of magic names that you can use for targets. See the frame documents on Netscape's home pages for details.
- Specify the destination for the document in the <FORM> tag
You can specify the frame to load in the
FORM tag itself. With CGI.pm it looks like this:
print $q->startform(-target=>'ResultsWindow');
When your script is reinvoked by the form, its output will be loaded into the frame named ``ResultsWindow''. If one doesn't already exist a new window will be created.
The script ``frameset.cgi'' in the examples directory shows one way to create pages in which the fill-out form and the response live in side-by-side frames.
LIMITED SUPPORT FOR CASCADING STYLE SHEETS
CGI.pm has limited support for HTML3's cascading style sheets (css). To incorporate a stylesheet into your document, pass the
start_html()
method a
-style parameter. The value of this parameter may be a scalar, in which case it is
incorporated directly into a <
STYLE> section, or it may be a hash reference. In
the latter case you should provide the hash with one or more of -src or
-code. -src points to a
URL where an externally-defined stylesheet can be
found. -code points to a scalar value to be incorporated into a <
STYLE> section. Style definitions in -code
override similarly-named ones in -src, hence the name ``cascading.''
You may also specify the type of the stylesheet by adding the optional -type parameter to the hash pointed to by -style. If not specified, the style defaults to 'text/css'.
To refer to a style within the body of your document, add the -class parameter to any HTML element:
print h1({-class=>'Fancy'},'Welcome to the Party');
Or define styles on the fly with the -style parameter:
print h1({-style=>'Color: red;'},'Welcome to Hell');
You may also use the new span() element to apply a style to a section of text:
print span({-style=>'Color: red;'}, h1('Welcome to Hell'), "Where did that handbasket get to?" );
Note that you must import the ``:html3'' definitions to have the span() method available. Here's a quick and dirty example of using CSS's. See the CSS specification at http://www.w3.org/pub/WWW/TR/Wd-css-1.html for more information.
use CGI qw/:standard :html3/;
#here's a stylesheet incorporated directly into the page $newStyle=<<END; <!-- P.Tip { margin-right: 50pt; margin-left: 50pt; color: red; } P.Alert { font-size: 30pt; font-family: sans-serif; color: red; } --> END print header(); print start_html( -title=>'CGI with Style', -style=>{-src=>'http://www.capricorn.com/style/st1.css', -code=>$newStyle} ); print h1('CGI with Style'), p({-class=>'Tip'}, "Better read the cascading style sheet spec before playing with this!"), span({-style=>'color: magenta'}, "Look Mom, no hands!", p(), "Whooo wee!" ); print end_html;
DEBUGGING
If you are running the script from the command line or in the perl debugger, you can pass the script a list of keywords or parameter=value pairs on the command line or from standard input (you don't have to worry about tricking your script into reading from environment variables). You can pass keywords like this:
your_script.pl keyword1 keyword2 keyword3
or this:
your_script.pl keyword1+keyword2+keyword3
or this:
your_script.pl name1=value1 name2=value2
or this:
your_script.pl name1=value1&name2=value2
or even as newline-delimited parameters on standard input.
When debugging, you can use quotes and backslashes to escape characters in the familiar shell manner, letting you place spaces and other funny characters in your parameter=value pairs:
your_script.pl "name1='I am a long value'" "name2=two\ words"
DUMPING OUT ALL THE NAME/VALUE PAIRS
The
dump()
method produces a string
consisting of all the query's name/value pairs formatted nicely as a nested
list. This is useful for debugging purposes:
print $query->dump
Produces something that looks like:
<UL> <LI>name1 <UL> <LI>value1 <LI>value2 </UL> <LI>name2 <UL> <LI>value1 </UL> </UL>
You can pass a value of 'true' to
dump()
in order to get it to print the results out as plain text, suitable for incorporating into a
<PRE> section.
As a shortcut, as of version 1.56 you can interpolate the entire CGI object into a string and it will be replaced with the a nice HTML dump shown above:
$query=new CGI; print "<H2>Current Values</H2> $query\n";
FETCHING ENVIRONMENT VARIABLES
Some of the more useful environment variables can be fetched through this interface. The methods are as follows:
- accept()
- Return a list of MIME types that the remote browser accepts. If you give this method a single argument corresponding to a MIME type, as in $query->accept('text/html'), it will return a floating point value corresponding to the browser's preference for this type from 0.0 (don't want) to 1.0. Glob types (e.g. text/*) in the browser's accept list are handled correctly.
- raw_cookie()
-
Returns the
HTTP_COOKIE variable, an
HTTP extension implemented by Netscape browsers version 1.1 and higher. Cookies have a special format, and this method call just returns the raw form (?cookie dough). See
cookie()
for ways of setting and retrieving cooked cookies.Called with no parameters,
raw_cookie()
returns the packed cookie structure. You can separate it into individual cookies by splitting on the character sequence ``; ''. Called with the name of a cookie, retrieves the unescaped form of the cookie. You can use the regularcookie()
method to get the names, or use theraw_fetch()
method from the CGI::Cookie module. - user_agent()
- Returns the HTTP_USER_AGENT variable. If you give this method a single argument, it will attempt to pattern match on it, allowing you to do something like $query->user_agent(netscape);
- path_info()
-
Returns additional path information from the script
URL.
E.G. fetching /cgi-bin/your_script/additional/stuff will result in $query->path_info() returning ``additional/stuff''.
NOTE: The Microsoft Internet Information Server is broken with respect to additional path information. If you use the Perl DLL library, the IIS server will attempt to execute the additional path information as a Perl script. If you use the ordinary file associations mapping, the path information will be present in the environment, but incorrect. The best thing to do is to avoid using additional path information in CGI scripts destined for use with IIS.
- path_translated()
-
As per
path_info()
but returns the additional path information translated into a physical path, e.g. ``/usr/local/etc/httpd/htdocs/additional/stuff''.The Microsoft IIS is broken with respect to the translated path as well.
- remote_host()
- Returns either the remote host name or IP address. if the former is unavailable.
- script_name() Return the script name as a partial URL, for self-refering scripts.
- referer()
- Return the URL of the page the browser was viewing prior to fetching your script. Not available for all browsers.
- auth_type ()
- Return the authorization/verification method in use for this script, if any.
- server_name ()
- Returns the name of the server, usually the machine's host name.
- virtual_host ()
- When using virtual hosts, returns the name of the host that the browser attempted to contact
- server_software ()
- Returns the server software and version number.
- remote_user ()
- Return the authorization/verification name used for user verification, if this script is protected.
- user_name ()
- Attempt to obtain the remote user's name, using a variety of different techniques. This only works with older browsers such as Mosaic. Netscape does not reliably report the user name!
- request_method()
- Returns the method used to access your script, usually one of 'POST', 'GET' or 'HEAD'.
USING NPH SCRIPTS
NPH, or ``no-parsed-header'', scripts bypass the server completely by sending the complete HTTP header directly to the browser. This has slight performance benefits, but is of most use for taking advantage of HTTP extensions that are not directly supported by your server, such as server push and PICS headers.
Servers use a variety of conventions for designating CGI scripts as NPH. Many Unix servers look at the beginning of the script's name for the prefix ``nph-''. The Macintosh WebSTAR server and Microsoft's Internet Information Server, in contrast, try to decide whether a program is an NPH script by examining the first line of script output.
CGI.pm supports
NPH scripts with a special
NPH mode. When in this mode, CGI.pm will output the necessary extra header information when the
header()
and
redirect()
methods are called.
The Microsoft Internet Information Server requires NPH mode. As of version 2.30, CGI.pm will automatically detect when the script is running under IIS and put itself into this mode. You do not need to do this manually, although it won't hurt anything if you do.
There are a number of ways to put CGI.pm into NPH mode:
- In the use statement
-
Simply add the ``-nph'' pragmato the list of symbols to be imported into
your script:
use CGI qw(:standard -nph)
- By calling the nph() method:
-
Call nph() with a non-zero parameter at any point after using CGI.pm in your program.
CGI->nph(1)
- By using -nph parameters in the header() and redirect() statements:
-
print $q->header(-nph=>1);
Server Push
CGI.pm provides three simple functions for producing multipart documents of the type needed to implement server push. These functions were graciously provided by Ed Jordan <ed@fidalgo.net> To import these into your namespace, you must import the ``:push'' set. You are also advised to put the script into NPH mode and to set $| to 1 to avoid buffering problems.
Here is a simple script that demonstrates server push:
#!/usr/local/bin/perl use CGI qw/:push -nph/; $| = 1; print multipart_init(-boundary=>'----------------here we go!'); while (1) { print multipart_start(-type=>'text/plain'), "The current time is ",scalar(localtime),"\n", multipart_end; sleep 1; }
This script initializes server push by calling multipart_init(). It then enters an infinite loop in which it begins a new multipart section by calling multipart_start(), prints the current local time, and ends a multipart section with multipart_end(). It then sleeps a second, and begins again.
- multipart_init()
multipart_init(-boundary=>$boundary);
- Initialize the multipart system. The -boundary argument specifies what MIME boundary string to use to separate parts of the document. If not provided, CGI.pm chooses a reasonable boundary for you.
- multipart_start()
-
multipart_start(-type=>$type)
Start a new part of the multipart document using the specified MIME type. If not specified, text/html is assumed.
- multipart_end()
-
multipart_end()
End a part. You must remember to call
multipart_end()
once for eachmultipart_start().
Users interested in server push applications should also have a look at the CGI::Push module.
Avoiding Denial of Service Attacks
A potential problem with CGI.pm is that, by default, it attempts to process form POSTings no matter how large they are. A wily hacker could attack your site by sending a CGI script a huge POST of many megabytes. CGI.pm will attempt to read the entire POST into a variable, growing hugely in size until it runs out of memory. While the script attempts to allocate the memory the system may slow down dramatically. This is a form of denial of service attack.
Another possible attack is for the remote user to force CGI.pm to accept a huge file upload. CGI.pm will accept the upload and store it in a temporary directory even if your script doesn't expect to receive an uploaded file. CGI.pm will delete the file automatically when it terminates, but in the meantime the remote user may have filled up the server's disk space, causing problems for other programs.
The best way to avoid denial of service attacks is to limit the amount of memory, CPU time and disk space that CGI scripts can use. Some Web servers come with built-in facilities to accomplish this. In other cases, you can use the shell limit or ulimit commands to put ceilings on CGI resource usage.
CGI.pm also has some simple built-in protections against denial of service attacks, but you must activate them before you can use them. These take the form of two global variables in the CGI name space:
- $CGI::POST_MAX
- If set to a non-negative integer, this variable puts a ceiling on the size of POSTings, in bytes. If CGI.pm detects a POST that is greater than the ceiling, it will immediately exit with an error message. This value will affect both ordinary POSTs and multipart POSTs, meaning that it limits the maximum size of file uploads as well. You should set this to a reasonably high value, such as 1 megabyte.
- $CGI::DISABLE_UPLOADS
- If set to a non-zero value, this will disable file uploads completely. Other fill-out form values will work as usual.
You can use these variables in either of two ways.
- On a script-by-script basis
Set the variable at the top of the script, right after the ``use'' statement:
use CGI qw/:standard/; use CGI::Carp 'fatalsToBrowser'; $CGI::POST_MAX=1024 * 100; # max 100K posts $CGI::DISABLE_UPLOADS = 1; # no uploads
- Globally for all scripts
Open up CGI.pm, find the definitions for
$POST_MAX
and $DISABLE_UPLOADS, and set them to the desired values. You'll find them towards the top of the file in a subroutine namedinitialize_globals().
Since an attempt to send a
POST larger than $POST_MAX
bytes will
cause a fatal error, you might want to use CGI::Carp to echo the fatal
error message to the browser window as shown in the example above.
Otherwise the remote user will see only a generic ``Internal Server'' error
message. See the CGI::Carp manual page for more details.
COMPATIBILITY WITH CGI-LIB.PL
To make it easier to port existing programs that use cgi-lib.pl the compatibility routine ``ReadParse'' is provided. Porting is simple:
OLD VERSION require ``cgi-lib.pl''; &ReadParse; print ``The value of the antique is $in{antique}.\n'';
NEW VERSION use CGI; CGI::ReadParse print ``The value of the antique is $in{antique}.\n'';
CGI.pm's
ReadParse()
routine
creates a tied variable named %in, which can be accessed to obtain the
query variables. Like ReadParse, you can also provide your own variable.
Infrequently used features of ReadParse, such as the creation of
@in
and $in
variables, are not supported.
Once you use ReadParse, you can retrieve the query object itself this way:
$q = $in{CGI}; print $q->textfield(-name=>'wow', -value=>'does this really work?');
This allows you to start using the more interesting features of CGI.pm without rewriting your old scripts from scratch.
AUTHOR INFORMATION
Copyright 1995-1997, Lincoln D. Stein. All rights reserved. It may be used and modified freely, but I do request that this copyright notice remain attached to the file. You may modify this module as you wish, but if you redistribute a modified version, please attach a note listing the modifications you have made.
Address bug reports and comments to: lstein@genome.wi.mit.edu
CREDITS
Thanks very much to:
- Matt Heffron (heffron@falstaff.css.beckman.com)
- James Taylor (james.taylor@srs.gov)
- Scott Anguish <sanguish@digifix.com>
- Mike Jewell (mlj3u@virginia.edu)
- Timothy Shimmin (tes@kbs.citri.edu.au)
- Joergen Haegg (jh@axis.se)
- Laurent Delfosse (delfosse@csgrad1.cs.wvu.edu)
- Richard Resnick (applepi1@aol.com)
- Craig Bishop (csb@barwonwater.vic.gov.au)
- Tony Curtis (tc@vcpc.univie.ac.at)
- Tim Bunce (Tim.Bunce@ig.co.uk)
- Tom Christiansen (tchrist@convex.com)
- Andreas Koenig (k@franz.ww.TU-Berlin.DE)
- Tim MacKenzie (Tim.MacKenzie@fulcrum.com.au)
- Kevin B. Hendricks (kbhend@dogwood.tyler.wm.edu)
- Stephen Dahmen (joyfire@inxpress.net)
- Ed Jordan (ed@fidalgo.net)
- David Alan Pisoni (david@cnation.com)
- Doug MacEachern (dougm@opengroup.org)
- Robin Houston (robin@oneworld.org)
- ...and many many more...
- for suggestions and bug fixes.
A COMPLETE EXAMPLE OF A SIMPLE FORM-BASED SCRIPT
#!/usr/local/bin/perl use CGI; $query = new CGI;
print $query->header; print $query->start_html("Example CGI.pm Form"); print "<H1> Example CGI.pm Form</H1>\n"; &print_prompt($query); &do_work($query); &print_tail; print $query->end_html; sub print_prompt { my($query) = @_; print $query->startform; print "<EM>What's your name?</EM><BR>"; print $query->textfield('name'); print $query->checkbox('Not my real name'); print "<P><EM>Where can you find English Sparrows?</EM><BR>"; print $query->checkbox_group( -name=>'Sparrow locations', -values=>[England,France,Spain,Asia,Hoboken], -linebreak=>'yes', -defaults=>[England,Asia]); print "<P><EM>How far can they fly?</EM><BR>", $query->radio_group( -name=>'how far', -values=>['10 ft','1 mile','10 miles','real far'], -default=>'1 mile'); print "<P><EM>What's your favorite color?</EM> "; print $query->popup_menu(-name=>'Color', -values=>['black','brown','red','yellow'], -default=>'red'); print $query->hidden('Reference','Monty Python and the Holy Grail'); print "<P><EM>What have you got there?</EM><BR>"; print $query->scrolling_list( -name=>'possessions', -values=>['A Coconut','A Grail','An Icon', 'A Sword','A Ticket'], -size=>5, -multiple=>'true'); print "<P><EM>Any parting comments?</EM><BR>"; print $query->textarea(-name=>'Comments', -rows=>10, -columns=>50); print "<P>",$query->reset; print $query->submit('Action','Shout'); print $query->submit('Action','Scream'); print $query->endform; print "<HR>\n"; } sub do_work { my($query) = @_; my(@values,$key);
print "<H2>Here are the current settings in this form</H2>";
foreach $key ($query->param) { print "<STRONG>$key</STRONG> -> "; @values = $query->param($key); print join(", ",@values),"<BR>\n"; } } sub print_tail { print <<END; <HR> <ADDRESS>Lincoln D. Stein</ADDRESS><BR> <A HREF="/">Home Page</A> END }
BUGS
This module has grown large and monolithic. Furthermore it's doing many things, such as handling URLs, parsing CGI input, writing HTML, etc., that are also done in the LWP modules. It should be discarded in favor of the CGI::* modules, but somehow I continue to work on it.
Note that the code is truly contorted in order to avoid spurious warnings when programs are run with the -w switch.
SEE ALSO
CGI::Carp, URI, CGI::Request, CGI::MiniSvr, CGI::Base, CGI::Form, CGI::Apache, CGI::Switch, CGI::Push, CGI::Fast
DISCLAIMER
We are painfully aware that these documents may contain incorrect links and misformatted HTML. Such bugs lie in the automatic translation process that automatically created the hundreds and hundreds of separate documents that you find here. Please do not report link or formatting bugs, because we cannot fix per-document problems. The only bug reports that will help us are those that supply working patches to the installhtml or pod2html programs, or to the Pod::HTML module itself, for which I and the entire Perl community will shower you with thanks and praises.If rather than formatting bugs, you encounter substantive content errors in these documents, such as mistakes in the explanations or code, please use the perlbug utility included with the Perl distribution.
- --Tom Christiansen, Perl Documentation Compiler and Editor
Return to the index.
Return to the Perl Home Page. </BODY> </HTML>