perlquestion
Kozz
Most esteemed monks:
<p>I have been wrestling with a problem in a CGI script which is included in a .html file as <code>#exec cgi="retrieve_password.pl"</code>. (".html" has been set to server-parsed html).</p>
<p>A form (method=GET) calls another html page, resulting in a GET query of <code>"/retrieve_password.html?email=user@domain.com"</code>. Then the QUERY_STRING is passed along to retrieve_password.pl through the Apache sub-request.</p>
<p>However, upon output, the <code>Content-type: text/html</code> is visible on the webpage! I triple-checked, and I do not see my script outputting headers more than once. But if I edit the script and comment-out the line which prints the header, it produces an error.</p>
<p>It seems that if I comment-out my call to <code>send_account()</code> that the header no longer becomes visible. But why is this?</p>
<p>Any help you can provide would be most welcome.</p>
<readmore>
<code>
#!/usr/bin/perl
# database names, emails, subjects have been changed
# to protect the innocent
use strict;
use CGI;
use CGI::Carp qw(fatalsToBrowser);
use Postgres; # old module, I know
use Mail::Send;
my $sql = db_connect("mydbname");
if (!$sql){
die "Unable to open database: $!\n";
}
my $table = 'users';
my $q = new CGI;
print $q->header;
if($q->param('email') eq ''){
print $q->p(qq{<p>Please <a href="javascript:history.go(-1)">go back</a> and provide your account email address.</p>\n});
exit;
}
my $query = sprintf(q{SELECT email, namefirst, namelast, username, userpass from %s WHERE email ~ %s},
$table, qstr($q->param('email')) );
my $result = $sql->execute($query);
my @data = $result->fetchrow();
my $email = $data[0];
if($email ne ''){
send_account(\@data);
print $q->p( "Thank you! Your account information has been sent to " . $email );
print $q->p( qq{<a href="/login.php">Log In</a>} );
}else{
print $q->p(qq{<p>Sorry! No account found with that email address. Please } .
qq{<a href="javascript:history.go(-1)">go back</a> and try again.</p>\n});
}
sub qstr{
# this old Postgres module does not have its own quote() method.
# this is a weak implementation, but better than nothing. (I think)
my ($str) = @_;
$str =~ s#(\\)#/#sg; # replace backslashes with slashes
$str =~ s/(['])/\\$1/; # escape single-quotes
return qq{'$str'};
}
sub send_account{
my ($matching_row) = @_;
# Set Mail Headers
my $mailout = new Mail::Send;
$mailout->to( shift @{$matching_row} );
$mailout->subject("Online Registration");
$mailout->add('From', 'user@domain.com');
$mailout->add('Reply-To', 'user@domain.com');
# open up a mail filehandle
my $mailfh = $mailout->open;
# print mail body
my $mailbody=<<END_OF_MAIL;
Dear %s %s:
Thank you for registering. Here is your
account information:
USERNAME: %s
PASSWORD: %s
Please keep this information safe.
Your account is active, and you may log in any time to place your first
order.
Sincerely,
Administrator
END_OF_MAIL
printf $mailfh $mailbody, @{$matching_row};
# close and send
$mailfh->close;
}
</code>
</readmore>
<p>I realize that some of the code is not the most elegant, and you are welcome to provide corrections, but my most pressing need is this spurious display of the content-type header.</p>
<p>Oh, it may also be worth noting that there are other perl scripts included in the page in a similar fashion, and these do NOT show a visible content-type header, though they DO have a "print $q->header;" line.</p>