I am new to CGI. I wrote a very complex module around perl, cgi, html and javascript. And it runs perfectly on command line. But I am not able to run it via browser. I went on debugging line by line from bottom of my script, only to find that the issue was around the HTML::TableExtract module itself. So to make it simple -
# perl -c test.cgi
test.cgi syntax OK
test.cgi
#!/usr/bin/perl
use strict;
use warnings;
use HTML::TableExtract;
print "Content-type: text/html\n\n";
print <<htmlcode;
<html>
<head>
<title>CGI Perl Example</title>
</head>
<body>
<h1>CGI Perl Example</h1>
<p>CGI Perl Example</p>
</body>
</html>
htmlcode
This works perfectly on command line. But if I run it via Browser it just doesn't work. However, if I remove "use HTML::TableExtract" it works perfectly fine again - even in browser. The permissions are correctly set to 755.
Can someone please help me understand, what I am missing? And how can I fire it up from browser. How can I go about debugging this - My browser redirects me to page not found if I mention use HTML::TableExtract.
Note: Would like to point out one thing, this may be related to setting up some environment variable around HTML::TableExtract. When I first installed the module, there was an error which my hosting administrator helped resolve.
# ./test.cgi
Content-type: text/html
<html>
<head>
<title>CGI Perl Example</title>
</head>
<body>
<h1>CGI Perl Example</h1>
<p>CGI Perl Example</p>
</body>
</html>
Debugging perl CGI scripts
Add use CGI::Carp; to you script to make it report bugs to browser
[It produces http reply over STDOUT instead of default text over STDERR]
Most likely scripts executed from command line and from web server search for modules in different places e.g. due to different settings of PERL5LIB or PERLLIB environment variables.
WARNING
CGI::Carp may be a security threat in "production" version of cgi scripts.
It may provide crucial information to (potential) hackers.
Related
Hi since other posts about this topic didn't do me much justice ( none of them seem to apply for Ubuntu 13.10, the version of Ubuntu I run), I decided to make another one. After running these lines ( a fellow stackoverflow member suggested running these)..
cd /etc/apache2/mods-enabled
sudo ln -s ../mods-available/cgi.load .
sudo ln -s ../mods-available/cgid.load .
sudo service apache2 restart
I placed the cgi files ( they are perl ones ) into my Apache2's cgi-bin # /usr/lib/cgi-bin. When typing localhost/cgi-bin/test.cgi, I got a 500 Internal server error. This is what the Server error log says..
[Fri Nov 22 21:23:29.045785 2013] [cgi:error] [pid 9559] [client 127.0.0.1:47663] AH01215: (8)Exec format error: exec of '/usr/lib/cgi-bin/test.cgi' failed
[Fri Nov 22 21:23:29.046720 2013] [cgi:error] [pid 9559] [client 127.0.0.1:47663] End of script output before headers: test.cgi
test.cgi looks like this...
#!/usr/bin/perl
print "Content-type: text/html\n\n";
print <<HTML;
<html>
<head>
<title>A Simple Perl CGI</title>
</head>
<body>
<h1>A Simple Perl CGI</h1>
<p>Hello World</p>
</body>
HTML
exit;
Does anyone know what to do when then happens or have any suggestions? Thanks
EDIT:: Oddly enough, I got this cgi file i call test2.cgi to run.
#!/usr/bin/perl
use strict;
use warnings;
sub main {
print "Content-type: text/html\n\n";
print "Hello world\n\n";
print "What's your favorite food brah?\n";
}
main();
But the larger, more advanced cgi files that I need to work on wont run. These ones include stuff being printed out in html tags.
EDIT: Ignore any weird spacing in code. Its just how i copied it into the post.
Edit: Its not quite clear if there are extra spaces in the original code at the start of each line causing this issue, if not, ignore the rest of this! Thanks Amon
If you try running them from the console, it will help see immediately any errors. In this case...
Can't find string terminator "HTML" anywhere before EOF
#!/usr/bin/perl # make sure no space before # and this comment is not here
print "Content-type: text/html\n\n";
print <<HTML;
<html>
....
</body>
HTML
exit; # Make sure the HTML line before this has nothing either side of it
Basically, remove the single space before the #!/usr/bin/perl line as Amon points out if it exists, and also the closing HTML line should fix it (There shouldn't be anything surrounding the heredoc terminator, its not obvious there are spaces at the start of each line, but there are).
Sometimes when putting example code on a site, spaces etc may be introduced to help visually. I'm guessing some were introduced here that were copied into the code. Hard to spot!
I'm having problems with apache2 on Ubuntu ( 11.04 and 12.04 ) buffering all cgi output until the script terminates. If I run the same script on Centos/rhel 6.2 apache2, it runs normally.
#!/usr/bin/perl
$|=1;
print "Content-type: text/html\r\n\r\n";
print "hi..";
sleep 1;
print "hi..";
sleep 1;
print "hi..";
sleep 1;
I have verified that mod_deflate is disabled.
Also, it's NOT just a perl thing, the same cgi script written in bash behaves the same on Ubuntu VS centos/rhel.
I encountered a similar problem on Solaris 10, but found out, that is was actually not a problem of apache but instead of the web browser (firefox 15.0.1).
(I could verify this with telnet webserver 80 and speaking plain HTML, the response showed that the output was indeed not buffered)
I could solve this for firefox by also printing a header with a Content-Type meta tag:
print<<'_EOF_';
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head>
<body>
_EOF_
Explorer however still seems to wait for all data before rendering the page, other browsers I do not have available.
The debian/ubuntu ( and solaris too obviously ) apache package stock configs doesn't specify the character set like on Redhat. The real solution is to define simply it.
on ubuntu, add the following to /etc/apache2/httpd.conf
AddDefaultCharset UTF-8
Wihtout it, the browser caches the output of the cgi script.
For me it helps to disable the deflate module:
sudo a2dismod deflate
Can someone please explain to me the very basics of getting perl to work on a server. Do I need a module on the server? If so where does it go? What do I name my files and where do they go?
From my understanding you need a module and it goes in the cgi-bin. I can't get a clear answer whether I name the file .pl or .cgi and when I put it in the cgi-bin I am getting a server error. I also have my permissions set to 777, so that shouldn't be the problem.
Please help! I just want to understand the how to get the very basic program working such as the one below. Thanks in advance!
#!/usr/bin/perl
require("cgi-lib.pl");
print &PrintHeader;
print "<html>";
print "<head><title>Hello world!</title></head>";
print "<body>";
print "<p>Hello world!</p>";
print "</body>";
print "</html>";
The latest version of cgi-lib.pl is dated 1999 and is very out of date. I suggest you use the CGI library instead, which is almost bound to be installed already on your server and is kept up to date (most recently on August 16 2012)
Your program should look like this:
#!/usr/bin/perl --
use strict;
use warnings;
use CGI ':standard';
print header;
print <<END;
<html>
<head><title>Hello world!</title></head>
<body>
<p>Hello world!</p>
</body>
</html>
END
Also note that you can run the program from the command line to see if it compiles and what output it generates. Once you have it working there you can move it to the server
The problem you are facing is you probably edited the source file on a Windows machine, which inserts a CR character before each linefeed. Make sure your code does not include any CRs or change the first line to:
#!/usr/bin/perl --
(that's two dashes and a space at the end of the line)
I concur with Dave Cross' comment, you need to tell your school that they are teaching you incorrectly. We in the Perl land are trying to get people to stop using the CGI module, and you are using its predecessor!
Here is a hello world app in a modern Perl framework, Mojolicious:
#!/usr/bin/env perl
use Mojolicious::Lite;
get '/' => 'hello';
app->start;
__DATA__
## hello.html.ep
<html>
<head><title>Hello world!</title></head>
<body>
<p>Hello world!</p>
</body>
</html>
which you place into a file, (lets say test.pl). Install Mojolicious by running:
curl get.mojolicio.us | sh
and then start your app by running
perl test.pl daemon
Now you can visit http://localhost:3000 in your browser to see the result, no Apache, no cgi-bin needed!
A more fun example takes an "argument" with a default:
#!/usr/bin/env perl
use Mojolicious::Lite;
get '/:name' => { name => 'world' } => 'hello';
app->start;
__DATA__
## hello.html.ep
<html>
<head><title>Hello <%= $name %>!</title></head>
<body>
<p>Hello <%= $name %>!</p>
</body>
</html>
Run this and try visiting http://localhost:3000/SilverNightaFall and see what it does!
This process of interpolating dynamic values into your HTML is known as templating, and it is much preferred these days (vs generating your entire HTML on each request).
I am new to both perl and apache servers. I'm trying to get a basic Hello World going for a CGI script. Here is the code for my hello world CGI file:
#!/usr/bin/perl
print "Content-type: text/html\n\n";
print "<H1>Hello World</H1>\n";
When I execute the CGI script on the command line, ./hello.cgi, it works, but when I open hello.cgi in my browser, it just displays the text of the cgi file.
When I look at my error_log in /var/log/apache2/error_log I can see that mod_perl is running:
Apache/2.2.21 (Unix) DAV/2 mod_perl/2.0.5 Perl/v5.12.3 configured -- resuming normal operations
but when I run the following perl program, it appears that I don't have the "MOD_PERL" env variable:
if (exists $ENV{"MOD_PERL"}) {
print "YAY!\n";
}
else{
print"mod_perl is not working\n";
}
By the way, my hello.cgi file and the perl script above are located in /Users/myusername/Sites/
Could someone help me configure mod_perl properly so that I can properly view hello.cgi in my browser? I've been reading the mod_perl documentation and searching forums for many, many hours with no avail. Thanks in advance
#SebastianStumpf I got your first example to work, but I still can't seem to get a mod_perl script going. I've been reading through the documentation, but I haven't been able to figure it out. Thanks for your help, by the way. I'm very grateful
UPDATE: i believe I got it working! Thanks for the help!
If you are using the stock Apache/Perl of Mac OS X Lion and don't need mod_perl then you don't have to configure anything. Just create your file with the .cgi extension in /Library/WebServer/CGI-Executables and adjust the permissions via sudo chmod 755 file.cgi. The script will be executed via CGI (not mod_perl). I tried this and it worked just fine:
$ sudo -s
# cat - > /Library/WebServer/CGI-Executables/test.cgi
#!/usr/bin/perl
use strict;
use warnings;
use CGI qw/:standard/;
use Data::Dumper;
print header, start_html, h1('works'), end_html;
^D
# sudo chmod 755 /Library/WebServer/CGI-Executables/test.cgi
# exit
Testing it:
$ curl -i http://localhost/cgi-bin/test.cgi
HTTP/1.1 200 OK
Date: Mon, 11 Jun 2012 22:29:24 GMT
Server: Apache/2.2.21 (Unix) DAV/2
Transfer-Encoding: chunked
Content-Type: text/html; charset=ISO-8859-1
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head>
<body>
<h1>works</h1>
</body>
</html>
If you need mod_perl, then have a look at the documentation. The configuration part of the introduction should be all you need to get mod_perl running.
EDIT:
I've added the following lines to /etc/apache2/httpd.conf, restarted the web server and mod_perl works:
LoadModule perl_module libexec/apache2/mod_perl.so
Alias /perl /Library/WebServer/perl
<Location /perl>
SetHandler perl-script
PerlResponseHandler ModPerl::Registry
Options ExecCGI
PerlSendHeader On
Order allow,deny
Allow from all
</Location>
If the script is saved in /Library/WebServer/perl/ you can see that all mod_perl headers are available now, but I'd rather setup a private installation of Apache/mod_perl. MacPorts makes this a lot easier...
I have run this Perl code:
#!/usr/bin/perl
print "content-type: text/html \n\n";
print "Hello World.\n";
I have tried it in two ways, first one is Testing your Perl installation, but when I run by this way, it has some troubles, it asks me to choose a program with which I can run it, but no running yet.
Second way is first script with Padre, the Perl IDE, but when I write Perl code and try to save it, it does not show me Perl file's extension, so I can't save it as Perl file, so what could I do?
Your code looks like you want a CGI program. CGI means that you call your program through a web browser and get a website back. While vstm's comment was of course right for non-cgi programs, your example requires a little more stuff in order to work like that.
You will need to install a web server. Take a look at xampp. It is simple to install and maintain and comes with a mysql as well as an apache installation. I recommend the lite version since that does not have all the overhead.
Once you've installed it, you need to make some configuration so it can run your perl scripts. I take it you have already installed Active Perl. You then need to tweak the apache config.
in c:\xampp\apache\conf\httpd.conf you need to find the line that says
<Directory "C:/xampp/htdocs">
and read the comments (marked with #). You have to add ExecCGI inside the <Directory> section. Do that for every directory you want perl scripts to be run. Then look for a line that says
AddHandler cgi-script .cgi .pl .asp
and make sure it is not commented out.
Once you're done, place your program in the c:\xampp\htdocs folder (cgi-bin should also work) and change the shebang-line (the first line with #!) to where you've installed Active Perl, e.g. C:\perl\bin\perl.exe. It tells apache what program it should use to execute the perl script.
Also, add some more lines to your code:
#!C:\perl\bin\perl.exe
use strict;
use warnings;
use CGI;
use CGI::Carp('fatalsToBrowser');
print "Content-type: text/html \n\n";
print "Hello World.\n";
Now you need to run the apache web server. In the xampp installation dir there are several batch files that control apache and mysql. There's also a xampp-control.exe. Run it. In the new window, click on the Start button next to Apache.
In your browser, go to http://localhost/<yourscript.pl>. It should now say "Hello World!".
If it does not, make sure you're not running Skype. It blocks your port 80 which the apache tries to run on. You need to change apache's port to something else. Refer to this video.
A few words on the changes in the code I made and what they do:
use strict; should always be in your code. It forces you to honor certain guidelines and to write better code. This might seem strange in a Hello World program, but please do it anyway.
use warnings; tells you about things that might go wrong. Warnings are not errors but rather perl being helpful about stuff you might not know yourself. Use it.
use CGI makes the program's output go to the web server. You need that when you work with CGI programs.
print "Content-type: text/html \n\n"; is needed so the browser knows what to expect. In this case, an HTML website. It is called the HTTP-Header and contains a mime-type.
use CGI::Carp('fatalsToBrowser'); makes errors go to the browser. Without it, you'd never know about them unless you look in apache's error log.