Daniel, Here is the routine I use. As inidicated in the comment, it is code I found on the Web (from the UK). It is nice in that it handles the details of BOTH POST and GET methods, freeing the script from worrying about which is being used. Note: it would be more efficient to rewrite the routine so that it takes a reference to a hash and then stuffs the elements into the hash; instead, this routine makes a hash, returns it as a list, then your subsequent assignment turns it *back* into a hash. -c ### ReadQueryStrings ### ### Reads the CGI query strings, whether they originated from a POST ### method, a GET method, or a combination of the two. ### ### The following subroutine is lifted directly out of the Leeds CGI tutorial. ### http://agora.leeds.ac.uk/nik/Cgi/start.html ### It is very similar to the code in the cgi-lib.pl stuff sub ReadQueryStrings { local ($buffer, @pairs, $pair, $name, $value, %FORM); # Read in text $ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/; if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); } else { # this is a "GET method $buffer = $ENV{'QUERY_STRING'}; } # else @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $value =~ tr/+/ /; $value =~ s/%(..)/pack("C", hex($1))/eg; $FORM{$name} = $value; } # foreach return(%FORM); }