Doe-Eyed Innocent has asked for the wisdom of the Perl Monks concerning the following question:

Newbie writing a simple CGI to take data from a form and append it to a text file containing data from previous submissions. I checked the error log, and I seem to have two problems: I cannot open the text file because permission denied (even though I did chmod 775 on the text file), and "premature end of script headers". Here's the code:
#!/usr/bin/perl -w read (STDIN, $x, $ENV{'CONTENT_LENGTH'}); @data = split(/&/, $x); @data = (@data, '======================'); open(PRES, ">>poll_results.txt") or die "could not open $!"; print PRES @data; close PRES;
After that it's just a series of prints to let the user know the form was submitted. (And yes, I remembered to print "Content-type: text/html\n\n", so that's not the source of the script headers error.) What in the world is going on? What's broken about this code?

Replies are listed 'Best First'.
Re: Cannot open file for appending
by chromatic (Archbishop) on Feb 25, 2003 at 23:15 UTC

    The web server is probably running as a different user than you expect, so the CGI probably lacks user or group permissions to write.

    Besides that, your argument parsing has several flaws:

    • It doesn't account for the semicolon, which is the recommended separator for name/value pairs
    • It doesn't check the content length, so you leave yourself open for a denial of service attack
    • It only takes arguments from POSTs, not GETs, which may or may not be an issue

    The two error messages you're seeing are really from the same issue. The die happens before anything is printed to the browser, so the web server sends back content saying "Sorry, the script died before it could send anything."

Re: Cannot open file for appending
by Ovid (Cardinal) on Feb 25, 2003 at 23:21 UTC

    First, you may wish to read my CGI course to get an idea of better methods of handling CGI data. For your program, you can alsor read How to get your CGI scripts working (written by our own tachyon).

    Have you tried running the script from the command line? If so, what does it say? Have you checked your error log?

    You may wish to try the following:

    #!/usr/bin/perl -wT use strict; use CGI; my $poll_results = 'poll_results.txt'; my $cgi = CGI->new; open POLL_RESULTS, ">> $poll_results" or die "Cannot open ($poll_results) for appending: $!"; $cgi->save(POLL_RESULTS); close POLL_RESULTS or die "Cannot close ($poll_results): $!";

    Cheers,
    Ovid

    Update: D'oh!!! As chromatic just pointed out to me, you state that you have read the error log. I wasn't paying attention. I wonder if people upvoted me for that suggestion (and also weren't paying attention) or for my code snippet :)

    New address of my CGI Course.
    Silence is Evil (feel free to copy and distribute widely - note copyright text)

Re: Cannot open file for appending
by jasonk (Parson) on Feb 25, 2003 at 23:16 UTC

    It is very likely that your web server is configured to run your script as a user who doesn't have permission to write to files. Check your web server logs for the error message you are printing, or use use CGI::Carp 'fatalsToBrowser'; to redirect the error messages to your browser.

Re: Cannot open file for appending
by Thelonius (Priest) on Feb 26, 2003 at 00:30 UTC
    open(PRES, ">>poll_results.txt")
    You should probably use an absolute path here or chdir() to where you want to write the file. Although it depends on your web server and configuration, a CGI process generally does not start off with its current directory equal to the directory where the script is found.
Re: Cannot open file for appending
by JayBonci (Curate) on Feb 26, 2003 at 07:48 UTC
    Anothing point that bears mentioning (and someone correct me if I'm wrong), is that CONTENT-LENGTH I think is a field that is provided raw by the browser, and isn't trustworthy per-se. You might want to try to read STDIN a different way.

        --jaybonci
Re: Cannot open file for appending
by Doe-Eyed Innocent (Initiate) on Feb 27, 2003 at 19:27 UTC
    Thanks for your help. It turned out to be a permissions problem after all. When I changed the permissions from 775 to 776 everything worked just fine.