in reply to perl script without cgi

Here is a function that reads POST CGI data and puts it into a hash, where the CGI name is the key and the value is the value. The function returns a reference to that hash. I used to have one that would do both GET and POST methods, but I cannot seem to find it. However, this will work just as good.
sub ReadCGI {
     my($cgi, @junk, $val, $field, %in, $i);
     read(STDIN, $cgi, $ENV{'CONTENT_LENGTH'});
     @junk = split(/&/,$cgi);
     foreach $i (0 .. $#junk) {
          $junk[$i] =~ s/\+/ /g;
          ($field, $val) = split (/=/,$junk[$i]);
          $field=~ s/%(..)/pack("c",hex($1))/ge;
          $val=~ s/%(..)/pack("c",hex($1))/ge;
          $in{$field} .= $val;
     }
     return(\%in);
}

The code that can be written
is not the eternal Code.
The typeglob that can be named
is not the eternal Typeglob.
- The Tao of Perl

Replies are listed 'Best First'.
(Ovid) Re: Re: perl script without cgi
by Ovid (Cardinal) on Nov 07, 2001 at 06:07 UTC

    This is broken.

    • This doesn't allow for multiple values in a query string (color=red&color=blue is perfectly legal).
    • What happens if your $ENV{CONTENT_LENGTH} doesn't match the length of data read from STDIN: you get corrupted data, but you'll never know it.
    • Newer clients are supposed to separate name/value pairs with semi-colons instead of ampersands. This will break your code.

    As for the first bullet point, you might think that your code allows for multiple values, but it doesn't. If you have multiple values for one param name, you simply concatenate them. Consider the following:

    color=red&color=blue

    In your code, that results in:

    $in{ 'color' } == 'redblue'

    That's probably going to cause someone problems.

    Hope you don't take this personally, and welcome to the Monastery! :)

    Cheers,
    Ovid

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

      And that is why all my CGI scripts now start as such:
      #!/usr/bin/perl
      
      use CGI;
      
      That subroutine was something I worked with about 5 years ago, but then I moved to CGI.pm when I had trouble with all the points you brought up. That and cutting and pasting was a pain in the rumpus.

      The code that can be written
      is not the eternal Code.
      The typeglob that can be named
      is not the eternal Typeglob.
      - The Tao of Perl