Why doesn't my Perl CGI program work on Windows? - perl

I have written following in index.pl which is the C:\xampp\htdocs\perl folder:
#!/usr/bin/perl
print "<html>";
print "<h2>PERL IT!</h2>";
print "this is some text that should get displyed in browser";
print "</html>";
When I browse to http://localhost:88/perl/ the above HTML doesn't get displayed (I have tried in IE FF and chrome).
What would be the reason?
I have xampp and apache2.2 installed on this Windows XP system.

See also How do I troubleshoot my Perl CGI Script?.
Your problem was due to the fact that your script did not send the appropriate headers.
A valid HTTP response consists of two sections: Headers and body.
You should make sure that you use a proper CGI processing module. CGI.pm is the de facto standard. However, it has a lot of historical baggage and CGI::Simple provides a cleaner alternative.
Using one of those modules, your script would have been:
#!/usr/bin/perl
use strict; use warnings;
use CGI::Simple;
my $cgi = CGI::Simple->new;
print $cgi->header, <<HTML;
<!DOCTYPE HTML>
<html>
<head><title>Test</title></head>
<body>
<h1>Perl CGI Script</h1>
<p>this is some text that should get displyed in browser</p>
</body>
</html>
HTML
Keep in mind that print has no problem with multiple arguments. There is no reason to learn to program like it's 1999.

Maybe it's because you didn't put your text between <body> tags. Also you have to specify the content type as text/html.
Try this:
print "Content-type: text/html\n\n";
print "<html>";
print "<h2>PERL IT!</h2>";
print "<body>";
print "this is some text that should get displyed in browser";
print "</body>";
print "</html>";
Also, from the link rics gave,
Perl:
Executable: \xampp\htdocs and \xampp\cgi-bin
Allowed endings: .pl
so you should be accessing your script like:
http://localhost/cgi-bin/index.pl

I am just guessing.
Have you started the apache server?
Is 88 the correct port for reaching your apache?
You may also try http://localhost:88/perl/index.pl (so adding the script name to the correct address).
Check this documentation for help.

Related

Perl UTF8 in CGI problems

I have a very simple Perl script which works right on the terminal but when run as a CGI script it produces garbage. The script basically take a HTML entities encoded data and converts it to print it. I have tried all the different setup like using "Encode" to change the output and set the STDOUT to utf8 mode and it does not help. I have also tried to change the environment of CGI to see if things will work like the terminal environment. Still no luck.
Here is the script
#!/usr/bin/perl
use HTML::Entities qw(encode_entities_numeric decode_entities);
use Encode qw/encode decode/;
binmode(STDOUT, ":utf8");
#$ENV{'PERL_UNICODE'} = 'D';
#$ENV{'LANG'} = 'en_US.UTF-8';
#$ENV{'TERM'} = 'vt100';
#$ENV{'SHELL'} = '/bin/bash';
#binmode(STDOUT, ":utf8");
print "Content-type: text/html\n\n";
my $y = decode_entities("Συστήματα_&#x
391;νίχνευσης_Εισ.pd
f");
#print encode("UTF8",$y);
print $y;
The output on terminal it is clean like
perl test.pl
Content-type: text/html
Συστήματα_Ανίχνευσης_Εισ.pdf
But on the CGI print it is garbled
ΣυστηÌματα_ΑνιÌχνευσης_Εισ.pdf
I am sort of stuck as I cannot find any simple way to solve this. Tried "encode_utf8" and utf8::upgrade of the variable but still no luck. Anyone's experience here will help a lot!
Thanks
Vijay
When interpreting a HTML document, the browser needs to know the encoding. The default encoding as per the HTML standard is not UTF-8. Since the browser is assuming the wrong encoding, it reads garbage.
Instead, you should specify the encoding explicitly, such as by printing a meta tag
<meta charset="utf-8">
or by including the encoding in the content type:
Content-type: text/html; charset=utf-8
Here, using the content type would seem most appropriate.

PERL CGI mailto does not work

I have a web report written in PERL CGI. It pulls some constantly changing data from a flat-file DB and displays the current status in a table on the web page. I want to be able to click a link that will push all of that data into an email that can be edited before sending.
This is what I have as my last chunk of HTML on the page. The "Go To Status" link works but the mailto:xxx#xx.com link causes server errors. Does "mailto" not work in a CGI script for some reason? It gets rendered as HTMl so I'm not sure why it wouldn't.
sub EndHtml {
print "<P align=right> <a href='http://www.xxx.com/~a0868183/cgi-bin/xxx.cgi'>Go to Status</a> </p>\n";
print "<p align=right> <a href='mailto:xxx#xx.com'></a>Send EOS</p>\n";
print "</BODY></HTML>\n";
}
(Once I figure this out I will then put the variables with the data into the email)
Thanks,
Jared
# has special meaning in a double quote delimited string.
Always start your script with:
use strict;
use warnings;
Then you will get alerted (if you read your log files):
Possible unintended interpolation of #xx in string
Then you can escape it:
mailto:xxx\#xx.com
Or use a single quoted string:
print q{<p align=right> <a href='mailto:xxx#xx.com'></a>Send EOS</p>\n};
Or don't embed your HTML in the middle of your Perl and use a Template language (like Template Toolkit).
You probably want to put some content in the anchor too.

perl cgi print header charset not work

I have a perl cgi program which output to a simple html form for user data input.
The form is in chinese big5 charset
When opened the cgi script, I have to manual switch web browser charset encoding to big5.
I searched on google and I found a method to set charset. Then
original code
$q = new CGI;
print $q->header;
to new code
$q = new CGI;
print $q->header(-charset=>'big5');
However, it just output a blank html.
This works for me:
use CGI;
my $q = CGI->new();
print $q->header(-charset => 'big5');
print '簡體字';
When i try it, it will be showed correctly. (Make sure, that your script is also saved in big5).
If those are the only two lines, then it's probably working.
Run the cgi from command line and you should see:
Content-Type: text/html; charset=big5
You're printing headers, but no content, so the page will be blank. Use Firebug or similar to verify the response from the server.

First cgi script in perl and don't know what it does

I am new to Perl and I am looking into CGI programs.
I tried the following from Perl Monks and it works. But I have no idea what it does.
1) What is the END_HERE? that is followed by HTML? :
print <<END_HERE;
<html>
<head>
<title>My First CGI Script</title>
</head>
<body bgcolor="#FFFFCC">
<h1>This is a pretty lame Web page</h1>
<p>Who is this Ovid guy, anyway?</p>
</body>
</html>
END_HERE
2) I modified the sample script by adding:
my $query = new CGI;
my $p= $query->param('myparam');
I.e. the new script is:
#!C:\perl\bin\perl.exe -wT
use strict;
use CGI;
my $query = new CGI;
print $query->header( "text/html" );
my $time = $query->param('fromDate');
print <<END_HERE;
<html>
<head>
<title>My First CGI Script $time</title>
</head>
<body bgcolor="#FFFFCC">
<h1>This is a pretty lame Web page</h1>
<p>Who is this Ovid guy, anyway?</p>
</body>
</html>
END_HERE
# must have a line after "END_HERE" or Perl won't recognize
# the token
It stopped working. I get the following error message:
Undefined subroutine &main::param called at C:/.../test2.cgi line 10.
How can I get the parameters send by the browser if not this way?
... <<END_HERE ...
foo
bar
END_HERE
means
... "foo
bar
" ...
The choice of terminator is up to you. You can use any bareword or any string if you add quotes. Both the following are equivalent to "foo\nbar\n":
<<MEOW
foo
bar
MEOW
<<"And they lived happily ever after."
foo
bar
And they lived happily ever after.
The script you posted has two problems, neither of them resulting in the error you specified.
Perl can't find the end of the here-doc since no line contains solely END_HERE. You have one that contains END_HERE with a whole bunch of leading spaces, but that's not the same thing. Remove the leading spaces.
It allows an arbitrary string to be placed in the HTML. Do escape (using, say, HTML::Entities's encode_entities)! Consider what happens if someone passes the following to the fromDate parameter:
<script>alert("owned")</script>

SSI not producing output, not giving error either

in the html file:
<!--#exec cgi="/cgi-bin/test.pl"-->
the perl script:
#!/usr/bin/perl
print "Content-Type: text/html\n\n";
print "<input type=\"hidden\" name=\"aname\" value=\"avalue\">\n";
print "<img src=\"/cgi-bin/script.pl\" />";
This does not give me an 'error processing directive' error, nor does it output my HTML inplace of the tag. I'll also add that the ssi tag gets replaced with nothing.
Are you sure the script is executing? If you print something to STDERR does it show up in th error log?
Beyond that I have a few comments:
I'm pretty sure printing the Content-Type is redundant, you (well, Apache anyway) have already done that by serving the HTML file that contains the SSI.
reference
exec is really meant for running commands like 'ls -l'. You should use include virtual instead. It also allows you to add arguments to the url. e.g.
<!--#include virtual="/cgi-bin/example.cgi?argument=value" --\>
do yourself a favor and use qq[] instead of the double-quotes. You won't have to escape everything then... e.g.
print qq[< input type="hidden" name="aname" value="avalue"\b];