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

I have written a cgi script that is called by an html page. This page passes information to the cgi script via the GET method from a form on the page. I have run the .cgi script on my machine and have gotten it to work but when I try to run it from my Unix server's cgi-bin it won't work. The html page takes information by the user and uses it to update an xml configuration file specified by the .cgi file. When I hit the submit button I recieve a Server Error saying that there is a premature ending of script headers. All the appropriate permissions have been given.
Here is the script:
#!/usr/bin/perl -w use XML::Simple; use XML::Parser; if ($ENV{'REQUEST_METHOD'} eq 'POST') { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); } else { $buffer = $ENV{'QUERY_STRING'}; } @pairs = split(/&/, $buffer); foreach $pair (@pairs) { ($name, $value) = split(/=/, $pair); $name =~ tr/+/ /; $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $FORM{$name} = $value; } my $newHost = $FORM{'host'}; my $newMet = $FORM{'metric'}; my $newRedSign = $FORM{'redSign'}; my $newRedVal = $FORM{'redVal'}; my $newRed = $newRedSign . " " . $newRedVal; my $newGreenSign = $FORM{'greenSign'}; my $newGreenVal = $FORM{'greenVal'}; my $newGreen = $newGreenSign . " " . $newGreenVal; $newHost = lc($newHost); my %hostMets; my $confHost; my $confMet; my $confRed; my $confGreen; my $hostcount = 0; my $metscount = 0; my $foundHost = 0; my $foundMet = 0; my $added = 0; sub readConfig { my ($xpat, $elem, %attrs) = @_; if($elem =~ /HOST/){ $confHost = $attrs{'NAME'}; if($confHost eq $newHost){ $foundHost = 1; } $hostMets{HOST}[$hostcount]{NAME} = $confHost; } elsif($elem =~ /METRIC/){ $confMet = $attrs{'NAME'}; $confRed = $attrs{'RED'}; $confGreen = $attrs{'GREEN'}; if(($confMet eq $newMet) && $foundHost){ $hostMets{HOST}[$hostcount]{METRIC}[$metscount]{NAM +E} = $confMet; $hostMets{HOST}[$hostcount]{METRIC}[$metscount]{RED +} = $newRed; $hostMets{HOST}[$hostcount]{METRIC}[$metscount]{GRE +EN} = $newGreen; $foundMet = 1; $added = 1; } else { $hostMets{HOST}[$hostcount]{METRIC}[$metscount]{NAM +E} = $confMet; $hostMets{HOST}[$hostcount]{METRIC}[$metscount]{RED +} = $confRed; $hostMets{HOST}[$hostcount]{METRIC}[$metscount]{GRE +EN} = $confGreen; } } } sub HandleEnd { my($xpat, $elem) = @_; if ($elem =~ /HOST/){ if($foundHost && !($foundMet)){ $hostMets{HOST}[$hostcount]{METRIC}[$metscount]{NAM +E} = $newMet; $hostMets{HOST}[$hostcount]{METRIC}[$metscount]{RED +} = $newRed; $hostMets{HOST}[$hostcount]{METRIC}[$metscount]{GRE +EN} = $newGreen; $foundMet = 1; $added = 1; } $hostcount++; $foundHost = 0; $metscount = 0; } elsif ($elem =~ /METRIC/){ $metscount++; } elsif ($elem =~ /opt/){ if(!($added)){ $hostMets{HOST}[$hostcount]{NAME} = $newHost; $hostMets{HOST}[$hostcount]{METRIC}[$metscount]{NAME} = $ne +wMet; $hostMets{HOST}[$hostcount]{METRIC}[$metscount]{RED} = $new +Red; $hostMets{HOST}[$hostcount]{METRIC}[$metscount]{GREEN} = $n +ewGreen; } } } sub HandleChar { } my $configFile = "ScoreProdMetsTest.xml"; my $configReader = new XML::Parser; $configReader->setHandlers ( Start => \&readConfig, End => \&HandleEnd, Char => \&HandleChar ); $configReader->parsefile( $configFile ); my $xsimple = XML::Simple->new(); my $xmlFormat = $xsimple->XMLout(\%hostMets, NoSort => 1, xmldecl => '<?xml version="1.0"?>'); open(FILE, ">outfile.xml"); print FILE $xmlFormat; close(FILE); print "Content-type: text/html\n\n"; print "<html>\n"; print "<head><title>METRIC ADDED</title></head>\n"; print "<body>\n"; print "Metric added</br>\n"; print "</body>\n"; print "</html>\n";

and here is the html

<html> <head><title>Config File Manipulator</title> <script language="Javascript" type="text/javascript" src="validFor +m.js"> </script> </head> <body> <center><h4>Add to Score Config File</h4></center> </br> <form id="MainForm" action="../cgi-bin/ib/xmlWriter.cgi" method="GET"> Enter the host name (example: scrpropbal800):&nbsp; <input id="host" type="text" name="host" class="reqd">* </br> Enter the name of the metric (Note: it must appear as it is reported b +y Ganglia):&nbsp; <input id="metric" type="text" name="metric" class="reqd">* </br> </br> The value is Red when &nbsp; <select id="redSign" name="redSign"> <option value=">" > > </option> <option value="<" > < </option> <option value="."> never </option> </select> &nbsp; <input id="redVal" type="text" name="redVal" > </br> </br> The value is Green when &nbsp; <select id="greenSign" name="greenSign"> <option value=">" > > </option> <option value="<" > < </option> <option value="@"> = </option> </select> &nbsp; <input id="greenVal" type="text" name="greenVal" class="reqd">* </br> <center><input type="submit" value="Add Metric"></center> </br> </br> * required field </form> </body> </html>

Can anyone out there help me? Thanks.

Replies are listed 'Best First'.
Re: cgi help needed.
by Corion (Patriarch) on Apr 29, 2008 at 20:10 UTC

    You have not told us what error message appears in the web server error log.

    But then again, I guess that the error message will likely be something like File not found: ScoreProdMetsTest.xml, which happens because the "current directory" is not what you think it is. Use an absolute path instead.

    As an aside, you can cut away about half of your code by throwing out your hand-rolled CGI parameter parsing and just using CGI.pm instead.

      the error message is BEGIN failed--compilation aborted at scoredevbal800/www/cgi-bin/ib/xmlWriter.cgi line 3. referrer: http://scoredevbal800/addConfig.html.
      Premature end of script headers:....
      It says it is failing at the line use XML::Simple; Everytime i switch its location the error points to the line that it is on. The paths are correct and I did switch them to the absolute path before I posted this and it still didn't work. Thanks.
        Perhaps your web server is using a different perl than you think it is. Perhaps it doesn't have read permissions to your library directory. Perhaps @INC is different under your web server than under your personal shell. Perhaps your web server doesn't have the module installed.

        In any case, your issue appears to be that you're not getting XML::Simple from the context of your web server. Try some debugging or ask your server admin (or tech support) why you're having problems requiring XML::Simple since that's the problem.