lib
Current Perl documentation can be found at
perldoc.perl.org.
Here is our local, out-dated (pre-5.6) version:
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.
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.
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.
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.
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.
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);
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.
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.
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.
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');
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');
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 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.
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 your
script(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.
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;
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"
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";
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 regular
cookie() method to get the names, or use the
raw_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'.
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);
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 each
multipart_start().
Users interested in server push applications should also have a look at the
CGI::Push module.
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 named
initialize_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.
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.
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
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.
#!/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
}
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.
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>
|