######################################################################
#
# File:    ReadParse.pl
#
# Read and parse URL-encoded data.  If METHOD=GET, obtain the input 
# data from the environment variable QUERY_STRING; if METHOD=POST, 
# the data is read from STDIN a character at a time; otherwise, the
# data is taken from standard input.  Return an associative array 
# of key-value pairs.
#
######################################################################

sub ReadParse {
  my ($in, @lines, @pairs, $key, $val, %in);

  # Note the added else-block for command-line debugging:
  if ( defined($ENV{'REQUEST_METHOD'}) ) {
    if ( $ENV{'REQUEST_METHOD'} eq "GET" ) {
      $in = $ENV{'QUERY_STRING'};
    } elsif ( $ENV{'REQUEST_METHOD'} eq "POST" ) {
      for ( $i = 0; $i < $ENV{'CONTENT_LENGTH'}; $i++ ) {
        $in .= getc;
      }
    } 
  } else {
    print STDERR "(enter name=value pairs on standard input)\n";
    print STDERR "(enter control-D when finished)\n";
    chomp(@lines = <STDIN>);  # remove newlines
    $in = join('&', @lines);
  }

  # Split input string into an array of key-value pairs:
  @pairs = split(/&/, $in);

  # Process each key-value pair individually:
  foreach $pair (@pairs) {
    # Convert plus signs to spaces:
    $pair =~ s/\+/ /g;
    # Convert %nn from hex to alphanumeric:
    $pair =~ s/%(..)/pack("C", hex($1))/ge;
    # Split the key-value pair:
    ($key, $val) = split(/=/, $pair);
    # Multiple values are separated by a null character:
    $in{$key} .= '\0' if ( defined($in{$key}) );
    $in{$key} = $val;
  }

  return %in;
}

1;  # Perl's 'require' will fail without this line!
