Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

CGI script makes Internal Server-error

by reaction (Acolyte)
on Aug 29, 2004 at 17:14 UTC ( [id://386776]=perlquestion: print w/replies, xml ) Need Help??

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

Hi, I am fairly new to perl (but not C) and am trying out some code. In a nutshell, it spits out the old 'Internal Server' error page. To make matters worse, I cannot check my server logs for more information. The code is supposed to be a simple counter, and I am trying some interesting type switching (no 'atoi()' or 'itoa()' functions that I am aware of). If someone could find the error I would be very grateful :) ...
#!/usr/bin/perl ######################################## ## INITIALIZE CGI ###################### ######################################## use lib qw(.); use CGI; use CGI::Carp qw(fatalsToBrowser); $cgi = new CGI; ######################################## ## MAIN ################################ ######################################## $DATAFILE = "hitcount-sendtoevery.txt"; $WEBPAGE_INITIALIZE = "<html><body bgcolor=\"#000000\" text=\"#ffffff\ +" link=\"#ffffff\" vlink=\"#ffffff\" alink=\"#ffffff\"><font face=\"A +rial\" color=\"#000000\"><center><table border=\"0\" width=\"400\" ce +llspacing=\"20\" cellpadding=\"20\"><tr><td><center><h5>"; $WEBPAGE_SHUTDOWN = "</h5></center></td></tr></table></center></font>< +/body></html>"; $val = 0; open(RECORD, "$DATAFILE") or error_page_exit("Could not open datafile" +); $val = $_; close(RECORD); $val++; open(RECORD, ">$DATAFILE") or error_page_exit("Could not open datafile +"); print(RECORD, $val); close(RECORD); print $cgi->header(); print $WEBPAGE_INITIALIZE; print "Your download will begin automatically...(not working yet!)"; print $WEBPAGE_SHUTDOWN; ######################################## ## EXIT ################################ ######################################## exit; ######################################## ## ERROR ############################### ######################################## sub error_page_exit { print $cgi->header(); print $WEBPAGE_INITIALIZE; print "ERROR - Reason: "; print shift; print $WEBPAGE_SHUTDOWN; exit; } ######################################## ## END OF FILE ######################### ########################################
... thanks again, reaction

Edited by Chady -- retitled from 'noob question'

Replies are listed 'Best First'.
Re: CGI script makes Internal Server-error
by davido (Cardinal) on Aug 29, 2004 at 17:23 UTC

    The error is on approximately line 31 of your script (give or take a few):

    print(RECORD, $val);

    That should be...

    print(RECORD $val);

    Filehandles don't have commas after them.

    How I found the problem:

    It's safe to assume that if you're getting an server error despite using the CGI::Carp module, you must be getting that error prior to the printing of your headers. So that usually means there's either a permissions error or a syntax error. I cut-n-pasted your code into "mytest.pl" and typed: perl -c mytest.pl. The result was a nicely formatted (ala CGI::Carp) error message reminding me that you shouldn't put commas after filehandles in print statements.


    Dave

      Brilliant! Thank you Dave.

        You may also want to try the fatalsToBrowser option of CGI::Carp to read CGI errors in the browser when you are debugging code; if you do so you must (yes, I said MUST) eliminate it when putting your cgi in production --unless you want to show your web site internals all over the world, of course ;-)

        Update: ooooopppss!!! Here it is!? Did you add me under my nose or I have to change my glasses? :-% Anyway, the advice of removing it in production code still stands.

        Ciao!
        --bronto


        The very nature of Perl to be like natural language--inconsistant and full of dwim and special cases--makes it impossible to know it all without simply memorizing the documentation (which is not complete or totally correct anyway).
        --John M. Dlugosz
Re: CGI script makes Internal Server-error
by jdporter (Paladin) on Aug 29, 2004 at 17:43 UTC
    The short answer to your specific question (Update: in addition to what davido said!) is that open() only opens the file, it doesn't read anything in from the file; and $_ doesn't implicitly read anything; it simply contains data. The line missing from your program is
    $_ = <RECORD>;
    I.e.
    open(RECORD, "$DATAFILE") or error_page_exit("Could not open datafile" +); $_ = <RECORD>; $val = $_; close(RECORD);
    However, I would be irresponsible if I did not alert you to some other areas of potential difficulty with your code.
    1. All veteran perl hackers agree that you should use strict in your code. It closes the door on a wide range of potential bugs.
    2. You have a potential race condition, in that the update of the file content is done separately from getting the current content. You'd like any given instance of your script to get and set that value atomically, i.e. in one swoop, with no possibility of any other instance getting in there in the mean time. The way to do this requires two things:
      1. opening the file only once, for both read and write;
      2. getting an exclusive lock on the file while it's open.
      Of course, there's more to each of these, and they kind of work together anyway.
    To open the file for reading and updating, do this:
    open RECORD, "+< $DATAFILE"
    Now attempt to get an exclusive lock. If some other process has the lock, this simply waits until the lock is available:
    flock RECORD, 2; # exclusive lock
    Now you can read the current value and modify it:
    my $val = <RECORD>; chomp $val; $val++;
    Now here's another tricky part: you need to reset the read/write pointer back to the beginning of the file before you write:
    seek RECORD, 0, 0;
    Now you can write the new value, and wrap up:
    print RECORD "$val\n"; close RECORD; # automatically releases the lock
    More detail is available in the documentation of the open() and flock() functions. And be sure to read the open() tutorial. Also, FAQ 9 has a little info on debugging CGI scripts. In addition, you might find some useful info in the Perl Debugging Tutorial. Lastly, don't forget to check the QandASection: CGI programming section of Categorized Questions and Answers to see if similar questions have been answered before.
Re: CGI script makes Internal Server-error
by DamnDirtyApe (Curate) on Aug 29, 2004 at 22:48 UTC

    Since you've stated that you're fairly new to Perl, allow me to make some additional suggestions:

    • Always use strict, unless you know precisely why not to. This will require you to declare all of your variables with my, eg. my $cgi = new CGI;
    • Only use lib qw(.); if you actually need to load some modules from the current directory (which you're not doing in this script.)
    • Rather than the lengthy strings your using to set your page header and footer, consider using a heredoc, like so:
      my $WEBPAGE_INITIALIZE = <<'END_OF_HTML'; <html> <body bgcolor="#000000" text="#ffffff" link="#ffffff" vlink="#ffffff +" alink="#ffffff"> <font face="Arial" color="#000000"> <center> <table border="0" width="400" cellspacing="20" cellpadding="20 +"> <tr> <td> <center> <h5> END_OF_HTML my $WEBPAGE_SHUTDOWN = <<'END_OF_HTML'; </h5> </center> </td> </tr> </table> </center> </font> </body> </html> END_OF_HTML
      I find this style much more comfortable for blocks of text.
    • Do away with the error_page_exit() function, and just use die() instead; that's what use CGI::Carp qw(fatalsToBrowser) is for.

    Hope you find that helpful.


    _______________
    DamnDirtyApe
    Those who know that they are profound strive for clarity. Those who
    would like to seem profound to the crowd strive for obscurity.
                --Friedrich Nietzsche

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://386776]
Approved by Corion
Front-paged by Paulster2
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (7)
As of 2024-04-19 11:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found