1  ######################################################################
  2  #
  3  # File:    ReadParse.pl
  4  #
  5  # Read and parse URL-encoded data.  If METHOD=GET, obtain the input 
  6  # data from the environment variable QUERY_STRING; if METHOD=POST, 
  7  # the data is read from STDIN a character at a time; otherwise, the
  8  # data is taken from standard input.  Return an associative array 
  9  # of key-value pairs.
 10  #
 11  ######################################################################
 12  
 13  sub ReadParse {
 14    my ($in, @lines, @pairs, $key, $val, %in);
 15  
 16    # Note the added else-block for command-line debugging:
 17    if ( defined($ENV{'REQUEST_METHOD'}) ) {
 18      if ( $ENV{'REQUEST_METHOD'} eq "GET" ) {
 19        $in = $ENV{'QUERY_STRING'};
 20      } elsif ( $ENV{'REQUEST_METHOD'} eq "POST" ) {
 21        for ( $i = 0; $i < $ENV{'CONTENT_LENGTH'}; $i++ ) {
 22          $in .= getc;
 23        }
 24      } 
 25    } else {
 26      print STDERR "(enter name=value pairs on standard input)\n";
 27      print STDERR "(enter control-D when finished)\n";
 28      chomp(@lines = <STDIN>);  # remove newlines
 29      $in = join('&', @lines);
 30    }
 31  
 32    # Split input string into an array of key-value pairs:
 33    @pairs = split(/&/, $in);
 34  
 35    # Process each key-value pair individually:
 36    foreach $pair (@pairs) {
 37      # Convert plus signs to spaces:
 38      $pair =~ s/\+/ /g;
 39      # Convert %nn from hex to alphanumeric:
 40      $pair =~ s/%(..)/pack("C", hex($1))/ge;
 41      # Split the key-value pair:
 42      ($key, $val) = split(/=/, $pair);
 43      # Multiple values are separated by a null character:
 44      $in{$key} .= '\0' if ( defined($in{$key}) );
 45      $in{$key} = $val;
 46    }
 47  
 48    return %in;
 49  }
 50  
 51  1;  # Perl's 'require' will fail without this line!