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

Now this is probably just some little simple thing that I'm overlooking, but alas, I am human...Anyway, the script in question is a polling script and i've stripped it down to the minimum needed to show the problem...What happens is, the script checks for the existence of a configuration file and do()es it if it exists. if it doesn't, it goes into setup mode with the subroutine firstSetup. When the form in setup mode is filled out & submitted, the configuration file is created and everything in the sub secondSetup, and it's supposed to redirect it to the login page (where it executes the sub login), but instead it gives me a 404...however when I close the browser window and go to the login url again in a different window, it works fine. Any ideas? (and yes, I'm using CGI.pm, I just put all the param()s in %INPUT for backward compatability with my previous versions of the script.)
BEGIN {use CGI::Carp qw/fatalsToBrowser/} $cwd = $0; $cwd =~ s/\\/\//g; $cwd =~ s/\/poll\.cgi$//ig; if(-e "$cwd/poll_config.cgi") {do("$cwd/poll_config.cgi")} elsif($INPUT{'action'} eq "firstSetup") {secondSetup()} else {firstSetup()} sub firstSetup { $urldir = $this = "http://"."$ENV{'SERVER_NAME'}"."$ENV{'SCRIP +T_NAME'}"; $urldir =~ s/\/poll.cgi$//g; $outmail = "$ENV{'SERVER_NAME'}"; $outmail =~ s/^www.//; $outmail = "poll\@$outmail"; if(-e "$cwd/template.html") {$template = "$cwd/template.html"} elsif(-e "$cwd/template.shtml") {$template = "$cwd/template.sh +tml"} else {$template = ''} print <<"EOC"; Content-type: text/html <html> <head> <title>Poll Administration >> First Time Setup</title> </head> <body> <h1><font face="Arial">First Time Setup</font></h1> <font face="Arial" size=2>It has been determined that this is the firs +t time you have run this script. You must set the basic options for +the Poll before you can use it. Please fill in the following setting +s. The script has tried to fill them in for you, but please verify t +hat they are correct. <p><hr><p> <form method=post action="$this"> <input type=hidden name="action" value="firstSetup"> <table border=0 bordercolor=#000000 bgcolor=#000000 cellpadding=5 cell +spacing=2 width=100\%> <tr> <td valign=top bgcolor=#e0e0e0><font face="Arial">Poll passwor +d:<br><font size=1> Needed to login to administration panel and cha +nge settings</font></td> <td valign=top bgcolor=#e0e0e0><input type=password name="pw" +size=35></td> </tr> <tr> <td valign=top bgcolor=#e0e0e0><font face="Arial">Re-type pass +word to confirm:<br></td> <td valign=top bgcolor=#e0e0e0><input type=password name="pw_c +" size=35></td> </tr> <tr> <td valign=top bgcolor=#e0e0e0><font face="Arial">System path +to current directory:</td> <td valign=top bgcolor=#e0e0e0><input type=text name="path" va +lue="$cwd" size=35></td> </tr> <tr> <td valign=top bgcolor=#e0e0e0><font face="Arial">URL to curre +nt directory:</td> <td valign=top bgcolor=#e0e0e0><input type=text name="url" val +ue="$urldir" size=35></td> </tr> <tr> <td valign=top bgcolor=#e0e0e0><font face="Arial">Title of you +r poll:<br><font size=1> This will appear when visitors to your sit +e take the poll.</font></td> <td valign=top bgcolor=#e0e0e0><input type=text name="s_title" + value="My Poll" size=35></td> </tr> <tr> <td valign=top bgcolor=#e0e0e0><font face="Arial">Number of an +swer choices per poll:</td> <td valign=top bgcolor=#e0e0e0><input type=text name="n_a" val +ue="4" size=35></td> </tr> <tr> <td valign=top bgcolor=#e0e0e0><font face="Arial">System path +to the template file:<br><font size=1> If not set, a default will b +e created</font></td> <td valign=top bgcolor=#e0e0e0><input type=text name="template +" value="$template" size=35></td> </tr> <tr> <td valign=top bgcolor=#e0e0e0><font face="Arial">Opening & cl +osing title tags:<br><font size=1> Customizing this will change the + way the page titles and section titles render</font></td> <td valign=top bgcolor=#e0e0e0><font face="Arial"> Opening tag:<br><input type=text name="topen" value='<font face="Arial +" size=3><b>' size=35><br><br> Closing tag:<br><input type=text name="tclose" value="</b></font>" siz +e=35> </td> </tr> <tr> <td valign=top bgcolor=#e0e0e0><font face="Arial">Opening & cl +osing main font tags:<br><font size=1> Customizing this will change + the way the main text in the script renders</font></td> <td valign=top bgcolor=#e0e0e0><font face="Arial"> Opening tag:<br><input type=text name="fopen" value='<font face="Arial +" size=2>' size=35><br><br> Closing tag:<br><input type=text name="fclose" value="</font>" size=35 +> </td> </tr> <tr> <td valign=top bgcolor=#e0e0e0><font face="Arial">Opening & cl +osing footnote tags:<br><font size=1> Customizing this will change +the way the footnotes render</font></td> <td valign=top bgcolor=#e0e0e0><font face="Arial"> Opening tag:<br><input type=text name="sopen" value='<font face="Arial +" size=1>' size=35><br><br> Closing tag:<br><input type=text name="sclose" value="</font>" size=35 +> </td> </tr> <tr> <td valign=top bgcolor=#e0e0e0><font face="Arial">Custom table + tags:<br><font size=1> Here, you can change the way tables render. + If you'd like to leave an attribute unset, leave it blank</font></t +d> <td valign=top bgcolor=#e0e0e0><font face="Arial"> Border:<br><input type=text name="border" value="0" size=35><br><br> Border color: <br><input type=text name="bordercolor" value="#000000" +size=35><br><br> Background color: <br><input type=text name="bgcolor" value="#000000" +size=35><br><br> Cellpadding: <br><input type=text name="cpadding" value="5" size=35><b +r><br> Cellspacing: <br><input type=text name="cspacing" value="2" size=35><b +r><br> Cell background color: <br><input type=text name="tdbg" value="#e0e0e0 +" size=35><br><br> Small table width: <br><input type=text name="width" value="" size=35> +<br><br> Small table alignment: <br><input type=text name="align" value="center +" size=35> </td> </tr> </table> <br> <center><input type=submit value="Save Settings"> <input type=reset va +lue="Reset"></center> </form> </body> </html> EOC exit; } sub secondSetup { unless($INPUT{'pw'} eq $INPUT{'pw_c'}) {die("Password ($INPUT{ +'pw'}) & confirmation password ($INPUT{'pw_c'}) did not match.")} unless($INPUT{'n_a'} =~ /^(\d+)$/) {die("Number of answers per + poll ($INPUT{'n_a'}) must be a number.")} my $z = chr(0); # I did this instead of \0 just to be safe if($INPUT{'pw'} eq '' || $INPUT{'pw'} =~ /$z|\n|\r|\t|\f|\\/) +{die("Password was an empty string or contained invalid characters. +(It cannot include null characters, newlines, backslashes, form feeds +, or tabs)")} $INPUT{'path'} =~ s/\\/\//g; $INPUT{'template'} =~ s/\\/\//g; if($INPUT{'path'} =~ /\/$/) {$INPUT{'path'} =~ s/\/$//} if($INPUT{'url'} =~ /\/$/) {$INPUT{'url'} =~ s/\/$//} @fields = ('pw','path','url','s_title','template','border','bo +rdercolor','bgcolor','cpadding','cspacing','tdbg','width','align'); foreach $i (@fields) {$INPUT{$i} =~ s/'/\\'/g} undef @fields; %fields = ( 'topen' => 'Opening title text formatting', 'tclose' => 'Closing title text formatting', 'fopen' => 'Opening text formatting', 'fclose' => 'Closing text formatting', 'sopen' => 'Opening footnote formatting', 'sclose' => 'Closing footnote formatting' ); foreach $i (keys(%fields)) { if($INPUT{$i} =~ /'/) { die("'$fields{$i}' field cannot contain single + quotations"); } } undef %fields; unless(defined($INPUT{'border'}) || $INPUT{'border'} ne '') { $INPUT{'border'} = '_DEFAULT_'; } unless(defined($INPUT{'bordercolor'}) || $INPUT{'bordercolor'} + ne '') { $INPUT{'bordercolor'} = '_DEFAULT_'; } unless(defined($INPUT{'bgcolor'}) || $INPUT{'bgcolor'} ne '') +{ $INPUT{'bgcolor'} = '_DEFAULT_'; } unless(defined($INPUT{'cpadding'}) || $INPUT{'cpadding'} ne '' +) { $INPUT{'cpadding'} = '_DEFAULT_'; } unless(defined($INPUT{'cspacing'}) || $INPUT{'cspacing'} ne '' +) { $INPUT{'cspacing'} = '_DEFAULT_'; } unless(defined($INPUT{'tdbg'}) || $INPUT{'tdbg'} ne '') { $INPUT{'tdbg'} = '_DEFAULT_'; } unless(defined($INPUT{'width'}) || $INPUT{'width'} ne '') { $INPUT{'width'} = '_DEFAULT_'; } unless(defined($INPUT{'align'}) || $INPUT{'align'} ne '') { $INPUT{'align'} = '_DEFAULT_'; } if(! defined($INPUT{'template'}) || $INPUT{'template'} eq '') +{ $INPUT{'template'} = "$INPUT{'path'}/template.shtml"; } if(! (-e "$INPUT{'template'}")) { open(NEWTEMPLATE,">$INPUT{'template'}"); print NEWTEMPLATE <<"EOC"; <HTML> <HEAD> <TITLE><_Title_></TITLE> </HEAD> <BODY> <H1><_Name_></H1> <P><HR><P> <_Content_> <P><HR><P> <_Menu_> </BODY> </HTML> EOC close(NEWTEMPLATE); } open(CONFIGWRITE,">$cwd/poll_config.cgi"); print CONFIGWRITE <<"EOC"; ###################################################################### +############ ## Poll Configuration File # Note: Generated file...Manual editing not recommended! # Poll password \$pw = '$INPUT{'pw'}'; # Full system path to current directory \$path = '$INPUT{'pw'}'; # Absolute URL of current directory \$url = '$INPUT{'url'}'; # Title of your site's poll \$s_title = '$INPUT{'s_title'}'; # Number of answer choices per poll \$n_a = $INPUT{'n_a'}; # Full system path to the HTML template file \$template = '$INPUT{'template'}'; # Custom title opening tag \$topen = '$INPUT{'topen'}'; # Custom title closing tag \$tclose = '$INPUT{'tclose'}'; # Custom text opening tag \$fopen = '$INPUT{'fopen'}'; # Custom text closing tag \$fclose = '$INPUT{'fclose'}'; # Custom footnote opening tag \$sopen = '$INPUT{'sopen'}'; # Custom footnote closing tag \$sclose = '$INPUT{'sclose'}'; # Table border width \$border = '$INPUT{'border'}'; # Table border color \$bordercolor = '$INPUT{'bordercolor'}'; # Table background color \$bgcolor = '$INPUT{'bgcolor'}'; # Table cellpadding \$cpadding = '$INPUT{'cpadding'}'; # Table cellspacing \$cspacing = '$INPUT{'cspacing'}'; # Table cell background \$tdbg = '$INPUT{'tdbg'}'; if(\$tdbg ne "_DEFAULT_") {\$td = " bgcolor=\$tdbg"} else {\$td = ''} # Miniature poll width \$width = '$INPUT{'width'}'; # Miniature poll alignment \$align = '$INPUT{'align'}'; # All this is just for formatting purposes \$table = ''; if(\$border ne "_DEFAULT_") {\$table .= " border=\$border"} if(\$bordercolor ne "_DEFAULT_") {\$table .= " bordercolor=\$bordercol +or"} if(\$bgcolor ne "_DEFAULT_") {\$table .= " bgcolor=\$bgcolor"} if(\$cpadding ne "_DEFAULT_") {\$table .= " cellpadding=\$cpadding"} if(\$cspacing ne "_DEFAULT_") {\$table .= " cellspacing=\$cspacing"} \$table .= ' width=100%'; \$wtable = ''; if(\$border ne "_DEFAULT_") {\$wtable .= " border=\$border"} if(\$bordercolor ne "_DEFAULT_") {\$wtable .= " bordercolor=\$borderco +lor"} if(\$bgcolor ne "_DEFAULT_") {\$wtable .= " bgcolor=\$bgcolor"} if(\$cpadding ne "_DEFAULT_") {\$wtable .= " cellpadding=\$cpadding"} if(\$cspacing ne "_DEFAULT_") {\$wtable .= " cellspacing=\$cspacing"} if(\$width ne "_DEFAULT_") {\$wtable .= "width=\$width"} 1; EOC close(CONFIGWRITE); unless(-e "$INPUT{'path'}/archives" && -d "$INPUT{'path'}/arch +ives") { `mkdir $INPUT{'path'}/archives`; if(! (-e "$INPUT{'path'}/archives")) {die("Archives di +rectory could not be made in $INPUT{'path'}")} } my $key = crypt("Copyright © 2001, Evan Kaufman","EK"); $content = <<"EOC"; <br>$INPUT{'sopen'}<a href="$url/archives/index2.shtml">Sort by Questi +on</a>$INPUT{'sclose'} <ul> <!--POLL-$key-BEGIN--> <li>$INPUT{'fopen'} [Archive Empty]$INPUT{'fclose'}</li> <!--POLL-$key-END--> </ul> EOC open(ARCHLIST,">$INPUT{'path'}/archives/index.shtml"); print ARCHLIST displayAs("$s_title Archived Polls >> Sorted by + Date",$content,0,1); close(ARCHLIST); $content = <<"EOC"; <br>$INPUT{'sopen'}<a href="$url/archives/index.shtml">Sort by Date</a +>$INPUT{'sclose'} <ul> <!--POLL-$key-BEGIN--> <li>$INPUT{'fopen'} [Archive Empty]$INPUT{'fclose'}</li> <!--POLL-$key-END--> </ul> EOC open(ARCHLISTB,">$INPUT{'path'}/archives/index2.shtml"); print ARCHLIST displayAs("$s_title Archived Polls >> Sorted by + Question",$content,0,1); close(ARCHLISTB); print "Location: $url/poll.cgi?action=login\n\n"; } sub login { displayAs("Poll Administration >> Login","$_[0]\n<form method= +post action='$url/poll.cgi'>\n<input type=hidden name=\"action\" valu +e=\"showData\">\nPassword: <input type=text name='pw'> <input type=s +ubmit value='Login'>\n</form>",0,0); } sub displayAs { my($title,$content,$admin,$tostring) = @_; unless($title ne '' && defined($title)) {$title = $s_title} if($admin != 1) {$admin = 0} my($html,$i,$menu); if($admin) { $menu = <<"EOC"; <p> <table$table> <tr> <td align=center$td width=25\%>$fopen<a href="$url/poll.cgi">V +iew Poll</a>$fclose</td> <td align=center$td width=25\%>$fopen<a href="$url/poll.cgi?ac +tion=admin&pw=$INPUT{'pw'}">Administration Panel</a>$fclose</td> <td align=center$td width=25\%>$fopen<a href="$url/poll.cgi?ac +tion=results">View Results</a>$fclose</td> <td align=center$td width=25\%>$fopen<a href="$url/poll.cgi?ac +tion=code">View Code</a>$fclose</td> </tr> </table> EOC } open(TEMPLATE, $template); @template = <TEMPLATE>; close(TEMPLATE); for $i (@template) { chomp($i); $html .= "$i\n"; } $html =~ s/<_Title_>/$title/ig; $title =~ s/(.+) >> (.+)/\2/; $html =~ s/<_Name_>/$topen$title$tclose/ig; $html =~ s/<_Content_>/$content/ig; if($admin) { $html =~ s/<_Menu_>/$menu/ig; } else { $html =~ s/<_Menu_>//ig; } if($tostring == 1) { return $html; } else { print "Content-type: text/html\n\n$html"; exit; } }

______________________________________________
When I get a little money, I buy books. If I have any left over, I buy food and clothes.
-Erasmus

Replies are listed 'Best First'.
Re: I'm sure I'm missing some little thing...
by dws (Chancellor) on Feb 03, 2001 at 00:55 UTC
    1. (mentioned above)

    2. Your problem (or at least a problem) might well pop right out at you if you use strict;

    3. Your code would be more understandable if you were to keep the HTML in separate files, and use one of the many fine templating mechanisms that are available.

    4. Have you checked your web server logs?

    2001-03-03 Edit by Corion : Fixed closing OL tag.

Re: I'm sure I'm missing some little thing...
by eg (Friar) on Feb 03, 2001 at 00:51 UTC

    If you're not doing it already, you should definately use strict. A 404 error (file not found) means that your redirect is wrong. Throw either

    print "Content-type: text/html\n\n"; # or print $cgi->header();

    in front of

    print "Location: $url/poll.cgi?action=login\n\n";

    and see what's wrong with it (probably $url is somehow off.)

    Since you're already using CGI, why not let it make the the redirect?

    print $cgi->redirect( -uri => 'whatever' );