cgi-dev

Repository that serves as my CGI "scratchpad" to try things out.
git clone git://git.samirparikh.com/cgi-dev
Log | Files | Refs | README

Parse_Form_Data.pm (2178B) - raw


      1 package Parse_Form_Data;
      2 use strict;
      3 use warnings;
      4 use Exporter qw( import );
      5 our @EXPORT_OK = qw( parse_form_data );
      6 
      7 sub parse_form_data {
      8     my %form_data;
      9 
     10     # split query string into name-value pairs and store each pair
     11     # in @parameters array, splitting on the ampersand as the delimiter
     12     my @parameters = split /&/, $ENV{ QUERY_STRING };
     13 
     14     # if the request happens to be a POST, also read the content of the
     15     # request from STDIN.  If number of bytes read does not equal number of
     16     # bytes we expect in CONTENT_LENGTH, throw error.
     17     if ( $ENV{ REQUEST_METHOD } eq 'POST' ) {
     18         my $query;
     19         read( STDIN, $query, $ENV{ CONTENT_LENGTH } ) == $ENV{ CONTENT_LENGTH }
     20             or die "Could not read POST request payload.";
     21         push @parameters => split /&/, $query;
     22     }
     23 
     24     # loop through parameters to split them into $name and $value
     25     foreach my $name_value ( @parameters ) {
     26         my ( $name, $value ) = split /=/, $name_value;
     27 
     28         # decode URL-encoded characters
     29         # replace each plus sign with a space
     30         $name =~ tr/+/ /; # could also be $name =~ s/\+/ / g;
     31 
     32         # scan for a percentage sign followed by two hexadecimal digits and
     33         # use Perl's chr function to convert the hexadecimal value into a
     34         # character
     35         $name =~ s/%([\da-f][\da-f])/chr( hex($1) )/egi;
     36 
     37         # possible that a parameter can be passed without an equal sign or a
     38         # value.  Set to empty string to avoid warnings
     39         $value = "" unless defined $value;
     40 
     41         # see comments above for $name
     42         $value =~ tr/+/ /;
     43         $value =~ s/%([\da-f][\da-f])/chr( hex($1) )/egi;
     44 
     45         # if the form has elements that share the same name, or if there is
     46         # a scrolling box that supports multiple values, then it is possible
     47         # for us to receive multiple values for the same name.
     48         # to address this, store the multiple values as a single text string
     49         # that is delimited by a colon
     50         if ( exists $form_data{$name} ) {
     51             $form_data{$name} .= ":$value";
     52         } else {
     53             $form_data{$name} = $value;
     54         }
     55     }
     56 
     57     return %form_data;
     58 }