http://qs321.pair.com?node_id=150612

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

Hi, I wrote a script to initiate one of three blocks of code based on the query string. When I try to run the program on the web, it returns a 500 internal server error (it is CHMODed 755). For an example of what I type in: http://www.publicutilityhome.com/ssrubin/ssrubin.cgi?progid=entry The code:
#!/usr/bin/perl -w use strict; use CGI qw(:standard); my $progid = param('progid'); if ($progid == "entry") { print "Content-Type: text/html\n\n"; open FH, "entry-pool.dump" or die $!; my $SEP = "--------"; local $/ = $SEP; my $line = <FH>; while (<FH>) { $line = $_ if rand($.) < 1; } close FH; $_ = $line; s!^\s*!!; s!$SEP\s*$!!; tr!\cM!!d; my($title, $link, $excerpt) = split /\n/, $_, 3; print <<HTML; <a href="$link">$title</a><br /> $excerpt HTML } elsif ($progid == "desc") { require "desc.conf"; open (FILE, my $random_file); my @LINES=<FILE>; close(FILE); srand; print "Content-type: text/html\n\n$LINES[int rand(@LINES)]\n"; } elsif ($progid == "bush") { require "bush.conf"; open (FILE, my $random_file); my @LINES=<FILE>; close(FILE); srand; print "Content-type: text/html\n\n$LINES[int rand(@LINES)]\n"; }

> munchie, the number munchin newb
Llama: The other other white meat!
(you had to be there :-P)

Replies are listed 'Best First'.
Re: Errors in my (simple?) CGI Script!
by shotgunefx (Parson) on Mar 09, 2002 at 21:09 UTC
    Two things right off the bat.
    1. Use "==" for comparing numbers and "eq" for strings.
    2. The end of HERETO docs need to be left justified.
    print <<HTML;
    HTML
    3. Try using CGI::Carp with fatals to browsers if you don't have access to the errorlog until you get it working.

    -Lee

    "To be civilized is to deny one's nature."
      The end of HERETO docs need to be left justified.

      This is correct, but if you want to give the appearance of indentation, you can quote the whitespace as well

      print <<' EOF'; <html> .... EOF

      Probably not good coding practice, but neat nonetheless. More information is available here (thanks to theguvnor for the original link :)

        Neat trick. The left alignment has always bugged me but I would think getting the spacing right a pain.

        -Lee

        "To be civilized is to deny one's nature."
      Thank you! I knew it had to be something simple (#1).

      > munchie, the number munchin newb
      Llama: The other other white meat!
      (you had to be there :-P)

Re: Errors in my (simple?) CGI Script!
by simon.proctor (Vicar) on Mar 09, 2002 at 21:23 UTC
    Just some thoughts:
    1. $progid == "bush" should be $progid eq "bush"
    2. You need to untaint your variable $progid, follow the link to Ovids tutorial below for more info on CGI security.
    3. When you open the '$random_file' file you do not test whether it suceeded (see example)
    4. You have no else clause in your conditional block
    5. Try using use CGI::Carp qw(fatalsToBrowser); for debugging. See the CGI::Carp manpage for details.
    6. Use CGI to print your header. Don't do it manually.
    7. You redifine $/ but don't do it locally. Yes I know you are doing this to slurp files but you might find you aren't opening your other files properly (not knowing their content I couldn't say either way).
    Your file opening code uses a variable to open the file 'random_file' but you declare it inside the open routine and never give it a value. Assuming its value is in 'bush.conf' then you need to remove the 'my'. An untested snippet would something like
    # Assuming is set in bush.conf unless(open(FILE,"<$random_file")) { # Handle it gracefully } my @lines = <FILE>; close(FILE);
    Or you could use $!:
    open(FILE,"<$random_file") || die "Could not open file",$!;
    Note that I have added a < to implicitly imply that I am opening the file. You might also want to consider the three argument form of open(). See the manpage for details.

    And finally: Ovids course
      I agree with most of your points but why would he untaint progid? It's not passed to any system calls and doesn't appear to be used anywhere but the if statements which is harmless.

      -Lee

      "To be civilized is to deny one's nature."
        Well for a start its coming from the outside world. In my opinion all CGI programs should be able to run under taint mode before they get put onto a live server. All incoming data must be taint checked before being used. In this case we expect a string so we can strip everything that isn't and so remove all the nasty shell characters and \00.

        In the context of the program above it might appear overkill but arguably its better to get into good habits early.
          A reply falls below the community's threshold of quality. You may see it by logging in.
      What is the advantage of using CGI.pm to print the header?

      Impossible Robot

        For one thing is less typing :) Also more recent versions of CGI.pm will print a header like :

        Content-Type: text/html; charset=ISO-8859-1
        which is recommended in a CERT Advisory ... this is one of the advantages of using a module, they often get quietly updated like this long before the information that gave rise to the update has been as widely propagated.

        /J\

Re: Errors in my (simple?) CGI Script!
by cayenne (Scribe) on Mar 10, 2002 at 08:07 UTC
    It's much easier to debug a cgi script if you know anything more than just the fact that it isn't working. There are several ways you can find out what in particular the error is:
    1. type perl -cT scriptname.cgi (or perl -c scriptname.cgi if you aren't using -T in your script) at the command line. This will tell you whatever errors occur during compilation.
    2. If you have access to/know where to find the log files for the webserver, you can look in there; the error will generally be recorded. If you don't know, figure it out.
    3. use CGI::Carp qw( fatalsToBrowser ). It's very useful when you're working on something that may or may not work each time you try it; if it doesn't work you don't have to go looking anywhere to see what went wrong, perl's error messages will be part of the error message you see in your browser. However it's generally not a good idea to leave it in when people are going to be using the site, as the possibility of people seeing error messages is bad security practice.