Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

one of the perl scripts we use has this library reference:

require "/usr/local/etc/httpd/htbin-post/cgi_handlers.pl";

I've read that cgi_handlers.pl has been supplanted by CGI.pm and perl5 package...

I'm new to PERL and feel comfortable changing PERL code, but don't know enough about porting considerations so that this script will work with the CGI.pm or CGI::* modules (whichever is installed) on our unix web server (perl5).

Any considerations or comments please (assuming a relatively simple form handling script)?

Replies are listed 'Best First'.
(Ovid) Re: cgi_handlers.pl
by Ovid (Cardinal) on Nov 06, 2001 at 00:06 UTC

    Assuming that we're referring to the same code, you do not want to to use cgi_handlers.pl. Here's the relevant code section (comments removed):

    sub get_request { if ($ENV{'REQUEST_METHOD'} eq "POST") { read(STDIN, $request, $ENV{'CONTENT_LENGTH'}); } elsif ($ENV{'REQUEST_METHOD'} eq "GET" ) { $request = $ENV{'QUERY_STRING'}; } %rqpairs = &url_decode(split(/[&=]/, $request)); } sub url_decode { foreach (@_) { tr/+/ /; s/%(..)/pack("c",hex($1))/ge; } @_; }

    This code has virtually all of the bugs one is likely to find in most hand-rolled code, plus some extras.

    • Since it doesn't use strict or have a package declaration, it's going to overwrite any global %rqpairs or $request variables you have in the namespace of the package that requires this code (unlikely, but it's possible).
    • 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 cgi_handlers.pl.

    There are a variety of other issues with this code, but this is a good start. See use CGI or die; for more information.

    Cheers,
    Ovid

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

      One more bug: It is perfectly valid (although I think it should be avoided) to pass information in the query string of a POST request.

        Nice catch. Yes, I think that qualifies as a bug but I didn't list it as there is a workaround: set $ENV{'REQUEST_METHOD'} to 'GET' and call get_request() again (after previously saving the contents of %rqpairs). This is a typical workaround for most faulty implementations, but it bugs me that most cgi handlers miss this.

        Cheers,
        Ovid

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

Re: cgi_handlers.pl
by Purdy (Hermit) on Nov 06, 2001 at 00:02 UTC
    I'm not sure how cgi_handlers.pl worked, but I would see how variables are created from the HTML form. Most old CGI scripts I've run into set up some type of hash with the field name as the key and the user-supplied value as the value.

    With CGI.pm, you can port your old CGI script and create a hash with the HTML form variables with a simple loop:

    use CGI; $query = new CGI; foreach ($query->param()) { $fields{$_} = $query->param($_); } # now you can access the HTML form field 'name' like so: print "Hello, " . $fields{'name'} . "!\n"; # or you can use the CGI.pm methodology (which would mean # you'd have to port all of the instances of your HTML form # variables: print "Hello, " . $query->param('name') . "!\n";

    HTH,

    Jason

      As a side note: to get the params in a hash with CGI you can also do the handy thing:
      use CGI ':cgi-lib'; my %params = Vars;
      Neat.

      --
      my one true love