CGI (perl)
Use
When using CGI on its own, don't be satisfied with the normal use
. Prefer this:
use CGI 3.00; $CGI::DISABLE_UPLOADS = 1; $CGI::POST_MAX = 512 * 1024;
Version 3.00 introduced (as on 2005 April 12) the most recent XSS vulnerability fix.
$CGI::DISABLE_UPLOADS should be set high unless the script is intended to accept uploaded files.
$CGI::POST_MAX is the largest acceptable POST, in bytes.
Xana::CGI subclasses CGI::Safe, which sets the two variables already, and messes with %PATH for security. CGI::Safe itself is also pretty simple, if available (if it isn't, it's pure Perl so a compiler is not necessary to install).
use CGI::Safe 'taint';
Xana::CGI uses CGI::Safe with 'taint' already.
use Xana::CGI;
Instantiation
Using CGI:
my $cgi = new CGI;
Using CGI::Safe:
my $cgi = CGI::Safe->new( DISABLE_UPLOADS => 0, POST_MAX => 1024 * 1024 );
Those arguments are optional. Xana::CGI is-a CGI::Safe.
Typical Flow
print $cgi->header; # CGI.pm can generate its own HTML. Do we need it? No. print <<EOF ; <html> <head> <title>Some title</title> </head> <body> EOF print $cgi->start_form; # -method=>'POST', -action=>this script, -enctype=>'application/x-www-form-urlencoded' # -enctype may be multipart/form-data. # Set like -enctype => $cgi->URL_ENCODED (or $cgi->MULTIPART) # -name and -onSubmit can be used with scripts. # Abort submission by returning false from onSubmit. # Previous value in fields in maintained across requests. # Set -override=>1 to always use -value. print $cgi->textfield('field1','A default value',50,80); # -name, -value, -size, -maxlength print $cgi->textarea('field2','A long default value',80,25); # -name, -value, -rows, -columns print $cgi->password_field('pass1','a pass!',50,80); # Same as textfield # Dropdown lists: Tricky! my $labels = { red => 'The color red', green => 'The color green', blue => 'The color blue' }; my $attributes = { red => { class => 'redStyle' }, green => { class => 'greenStyle' }, blue => { class => 'blueStyle' } }; print $cgi->popup_menu('menu1',[qw/red green blue/],'red',$labels,$attributes); # -name, -values, -value, -labels, -attributes # -attributes sets plain HTML attributes, hence the outrageous syntax! # Nested dropdown lists: Trickier! my $labels2 = {}; my $attributes2 = {}; for(qw/red green blue silver lime/) { $labels2->{$_} = "The color $_"; $attributes2->{$_} = { class => $_ . 'Style' }; } print $cgi->popup_menu(-name => 'menu2', -values => [ 'red', 'green', 'blue', $cgi->optgroup(-name => 'Stranger colors', -values => ['silver','lime'], -labels => $labels2, -attributes => $attributes2) ], -labels => $labels2, -attributes => $attributes2); # The list ends up looking like this: # The color red # The color green # The color blue # *Stranger colors* # The color silver # The color lime # An option selected from the submenu is returned as the # value of 'menu2'. Note also that the submenu heading # may also be classed by setting -class in optgroup(). print $cgi->filefield('upload1',,50,80) # -name, -default, -size, -maxlength # -default is typically ignored. # DISABLE_UPLOADS must be false, form encoding must be $cgi->MULTIPART.
# ... to be continued ...
# Uploaded files are stuffed somewhere. upload() returns the filehandle # of the file uploaded with the given parameter name, or undef if there # wasn't one. my $upload1 = $cgi->upload('upload1'); if(defined $upload1) { # ... Use $upload1 as a filehandle ... open(OUTFILE,">>/dev/null") or die; my $buffer; while(my $read=read($upload1,$buffer,1024) { print OUTFILE $buffer; } } elsif($cgi->cgi_error) { # The HTTP error status 400 Bad Request is returned, # suitable for setting -status in header() }
Redirects
These statements generate entire headers. Don't print a $cgi->header
as well.
# Generic 302 print $cgi->redirect('http://example.com/');
# 301: Moved Permanently # 302: Found # 303: See Other print $cgi->redirect(-uri => 'http://example.com/', -status => 301);
Forms
See also Forms (CPAN).
print $cgi->start_form; print $cgi->end_form;