PDA

View Full Version : Really basic (read 'dumb') cgi problem


Disco_troll
02-09-2005, 11:58 AM
Hi -

I've got the most basic cgi problem and it's driving me round the bend!

I am able to access the cgi scripts in my cgi-bin folder with no problems (i.e. run a simple 'hello world' statement) but when it comes to any script that needs to execute anything such as a mail-send or even display the date and time from the server, I get an error.

I've set permissions on everything to 755, as instructed, and this happens on several different commercial servers.

What on earth am I missing here??

I know it's really dumb but I could do with some help on this!

Thanks,

DT.

mlseim
02-09-2005, 12:51 PM
Give a an example of one your scripts that fails.
Actually post the whole script on this forum.

Disco_troll
02-09-2005, 01:01 PM
Okay - this is a form-mail script that has been auto-generated so I assume it works fine:

#!/usr/bin/perl
#
######################################################################
# #
# Xpert MailForm Version 1.0.5 #
# #
# By Xpert Software. Do not edit without #
# permission. Thank you. #
# #
# #
# Get updates at: #
# http://www.xpert-software.com #
# #
# #
# What it does: #
# Xpert Mail Form is an advanced form mailer script that can take #
# any number of fields as input and doesn't need to be #
# configured for each one. Xpert Mail Form figures out what #
# fields are being sent and sends that data in an e-mail. #
# Xpert MailForm can require certain fields, or all fields, and #
# can do e-mail address entry checks. #
# #
# How to set up: #
# 1) chmod 755 the .cgi file. #
# #
######################################################################
# Configure the following variables.

# This should be the path to sendmail on this system.
$mail = "/usr/sbin/sendmail";

# The address that e-mail should be sent to. Remember to put a \ before
# the @ in the address. This is needed for the script to run.
$youremail = "info\@mysite.com";

# Path to the date program on your system.
$dateprog = "/bin/date";

# URL of the page that users should be sent to after they fill out the
# form.
$url = "http://www.mysite.com";

# Require all fields. Select this option to make this CGI require all
# existing form fields to be filled in. If you wish to select only some
# fields to be required, don't turn this option on, but set the next one.
# (0/1)
$require_all = 0;

# If you wish to require only some fields to be filled in, then list the
# NAMES of those fields here. The names ARE case-sensitive. If you do
# not want to have this option on, then leave the list blank like this:
# @require = ("");
@require = ("email","name");

# Require correct e-mail address? (Only works if one of your fields is
# called 'email')
$require_email = 1;
$parse_commands = 0;

# MAIN PROGRAM STARTS HERE. Please don't edit past this point without
# permission.

foreach $referer (@referers) {
print "$referer = $ENV{'HTTP_REFERER'}";
}
foreach $referer (@referers) {
print "$referer = $ENV{'REMOTE_ADDR'}";
}

%in = &getcgi;
if (-x $dateprog) {
$date = `$dateprog \'+%m/%d/%Y\'`;
chop($date);
}

@tester = keys(%in);
if ($tester[0] eq "") {
&htmlheader;
print "<html><head><title>Error</title></head><body bgcolor=white
text=black>\n";
print "Please supply some form elements to the script. This
script requires atleast one form element to be submitted for it to
function.\n</body></html>";
exit;
}


if ($require_all == 1) {
foreach $key (keys(%in)) {
if ($in{$key} eq "") {
&requirefields;
}
}
}

sub requirefields {
&htmlheader;
print "<html><head><title>Error</title></head><body bgcolor=white
text=black>\n";
print "Please go back and fill in all the required fields. Thank
you.\n";
exit;
return 1;
}

sub has {
local($tocheck) = $_[0];
foreach $key (keys(%in)) {
if ($key eq $tocheck) {
return 1;
}
}
return 0;
}

if ($require[0] ne "") {
foreach $check (@require) {
if (&has($check) == 1) {
if ($in{$check} eq "") {
&requirefields;
}
}
}
}


foreach $key (keys(%in)) {
if ($key =~ m/Email/i) {
$emailholder = $key;
}
}
if ($emailholder ne "") {
$in{$emailholder} =~ s/[^a-zA-Z0-9\@\.]//g;
if (($require_email == 1) and ($in{$emailholder} !~ m/.*\@.*\..*/i)) {
&htmlheader;
print "Please enter a correct e-mail address. Thank you.\n";
exit;
}
}

if (-x $mail) {
open(SM, "|$mail $youremail");
print SM "From: $in{'email'}\n";
print SM "Subject: test email 3 ($date)\n\n";
foreach $key (@order_array) {
print SM "$key: $in{$key}\n";
}
print SM "Message sent on $date by XpertMailForm by ";
print SM "Xpert Software (http://www.xpert-software.com).\n";
print SM "Message complete.\n";
print SM "From: $ENV{'HTTP_REFERER'}\n";
print SM "IP: $ENV{'REMOTE_ADDR'}\n";
close(SM);
} else {
&htmlheader;
print "Sorry, unable to send form.<p>Error: Sendmail not found at
$mail<p>Please tell the site admin.\n";
exit;
}

print "Location: $url\n\n";


sub getcgi {
local($in, %in);
local($name, $value);

# If REQUEST_METHOD is POST, use CONTENT_LENGTH. Else, use QUERY_STRING.
if ($ENV{'REQUEST_METHOD'} eq 'POST') {
if ($ENV{'CONTENT_TYPE'}=~ m#^application/x-www-form-urlencoded#i) {
read(STDIN, $in, $ENV{'CONTENT_LENGTH'});
}
}
else {
$in= $ENV{'QUERY_STRING'};
}
# Resolve and unencode name/value pairs into %in
foreach (split('&', $in)) {
s/\+/ /g;
($name, $value)= split('=', $_, 2);
$name=~ s/%(..)/sprintf("%c",hex($1))/ge;
$value=~ s/%(..)/sprintf("%c",hex($1))/ge;
@order_array = (@order_array,$name);
$in{$name}.= $value;
}
return %in;
}


sub htmlheader {
print "Content-type: text/html\n\n";
return 1;
}

mlseim
02-09-2005, 01:39 PM
I copied the script you provided, uploaded it to my webhost (ipowerweb)
and ran it successfully, no errors.

You did say that you ran other Perl scripts OK?

Maybe it's the version of Perl they are using ... it should be at least Perl 5?

You did the CHMOD thing (755), and I also assume you uploaded it
in ASCII mode (not Binary, which is the default of most FTP programs).

... very strange ...
This might be something you need to contact your webhost about.

--max--

Disco_troll
02-09-2005, 03:00 PM
Thanks Max -

I'll check the version of Perl (just to make sure) but this has happened with a couple of different service providers (that is why I started doubting my code).

A typical 'Hello World' script like this:

#!/usr/bin/perl -wT
print "Content-type: text/html\n\n";
print "Hello, world!\n";

works fine but nothing else seems to want to work. I did the CHMOD thing and uploaded in ASCII so that's all covered.

Just one thought, things seem to play-up when I need to call the cgi script from a web page (i.e. a reply form). I wonder if this is where my problems lie...

mlseim
02-09-2005, 04:04 PM
What is the exact error message?

Disco_troll
02-09-2005, 04:26 PM
The on-screen error message is a very unhelpful:

-----------------

500 Internal Server Error

Internal Server Error
The server encountered an internal error or misconfiguration and was unable to complete your request.
Please contact the server administrator, and inform them of the time the error occurred and anything you might have done that may have caused the error.

More information about this error may be available in the server error log.

--------------

I have gone to the error logs and this gives me:

[Wed Feb 9 17:07:36 2005] [error] [client 81.3.115.130] Premature end of script headers: /home/httpd/vhosts/mysite.com/cgi-bin/test1.cgi

--------------

Does this shed any light?

mlseim
02-09-2005, 07:54 PM
Give us a link to your form ... maybe something will pop into my head.

Disco_troll
02-10-2005, 09:30 AM
There's a test form here:


http://www.designer-guide.com/testcgi3.htm

My initial thought was that the location of the cgi-bin was incorrect but according to my ISP it's written exactly as it should be.

Thanks for anything you can dig-up on this.

mlseim
02-10-2005, 12:54 PM
You currently are using GET:

<Form method=GET action="/cgi-bin/test1.cgi">

Have you tried POST yet?

<Form method="POST" action="/cgi-bin/test1.cgi">

It really shouldn't matter, but it's just another
thing to try ...

Disco_troll
02-10-2005, 04:57 PM
Well... i gave it a go but no difference. I know I'm doing something really stupid somewhere down the line but I just can't see what it is.

:(

mlseim
02-10-2005, 05:35 PM
OK, let's get something easy to do ...

Copy and paste these two things into your site:
Install the "test2.cgi" and do the CHMOD(755) thing.
See if you can get it to work ...
note, you'll have to fill in a few details on the "test2.cgi" script (email, etc).

First, a simple HTML form:
==========================================================

<html>
<head>
<TITLE>Mail Form Test</title>
</head>
<BODY>

<center>
<table border="0">

<tr><td>

<Form method="POST" action="/cgi-bin/test2.cgi">
<center>
<table border="0">
<tr>
<td><font face="Arial" color="#000000">Name<font size="3"
color="#0000FF">*</font>:</font></td>
<td><input type="text" size="26" name="name" maxlength="50"></td>
</tr>
<tr>

<td><font face="Arial" color="#000000">Email<font size="3"
color="#0000FF">*</font>:</font></td>
<td><input type="text" size="26" name="email" maxlength="50"></td>
</tr>
<tr>
<td><font face="Arial" color="#000000">Notes or Comments:<br>
</font></td>
<td><textarea name="description" rows="3" cols="35" wrap maxlength="500">

</textarea></td>
</tr>
</table>
</center>
<div align="center"><center><p>
<font size=+1><b><input type="submit" value="Submit"> <input

type="reset" value="Reset"></b></font></p>
</div>
</form>
</td>
</tr>

</table>
</center>
<br><br></BODY></HTML>

=========================================================


Then, a test script called: test2.cgi

=========================================================

#!/usr/bin/perl

use CGI ':standard';

###################################################
#
# Change these things for your site:
#
#
#
# Email address where the form should be sent.
# Put the back-slash in front of "@" symbol.

$myemail = "billsmith\@aol.com";

#
# The location of your webhost's sendmail program.
# This is the most common... but if it doesn't work,
# you'll need to ask your webhost what it should be.
# Leave this one as-is for now.

$mailprogram = "/usr/sbin/sendmail";

#
# The webpage where they should be sent after they
# submit the form. Like a thankyou page.

$success = "http://www.mysite.com/thankyou.htm";

###############################################
#
# Read in the Variables from the form:
#
my $name = param('name');
my $email = param('email');
my $description = param('description');

################################################
# Send the E-mail

open (MAIL, "|$mailprogram -t") or die "Can't fork sendmail.\n";
print MAIL "To: $myemail\n";
print MAIL "From: $email\n";
print MAIL "Subject: Email Form Test\n";
print MAIL "\n\n";
print MAIL "Name: $name\n\n";
print MAIL "Description: $description\n\n";
print MAIL "=====================================================\n";
close(MAIL);

##################################################
# Go To the Success Page

print "Location: $success\n\n";

Disco_troll
02-16-2005, 03:50 PM
And so it goes on... :confused:

Okay - the code that was kindly provided above *does* work on a site hosted on a Windows server, running a cgi-bin for form processing, etc, but it wont work on my unix box.

My ISP has confirmed that the cgi-bin and cgi location in the code are all correct in the script but it simply wont work. Arrghgghhhh!! :eek:

Really not sure where to go with this now.....

mlseim
02-16-2005, 04:53 PM
I've got another hunch ...

-------------------------
Change:
use CGI ':standard';

To:
use CGI qw(:standard :form);

-------------------------

Change:
my $name = param('name');
my $email = param('email');
my $description = param('description');


To:
my $query = new CGI;
my $name = $query->param('name');
my $email = $query->param('email');
my $description = $query->param('description');

Disco_troll
02-24-2005, 05:31 PM
SUCCESS! But then again, failure!! :confused: :rolleyes: :confused:

Okay - the success is a script that runs fine on everything (omitting a "/" from infront of the "@" symbol in the email address amoungst other things) and this works very nicely.

The failure is something I have also experienced with PHP on the same client's site. Their email is hosted completely separately from their website and for some reason the sendmail will send to any email address that you tell it, apart from any that belong to the client, like it can't believe the email is separate and will only look on the local server for it.

Is this right and is it something I can get round? What a pain!!

DT

mlseim
02-24-2005, 06:44 PM
I don't quite understand the question ...

Is the problem the email (example: johnsmith@aol.com)

or the sendmail: (example: $mailprogram = "/usr/sbin/sendmail";)

You should be able to send the email to anybody.
How would the script know that the person is on the same server?

Make sure that the customer's email isn't getting put into a
bulk email bin (spam bucket) with a spam filter. That could be
why you are not seeing the email show up.

netroact
02-25-2005, 05:48 AM
#!/usr/bin/perl -wT
print "Content-type: text/html\n\n";
print "Hello, world!\n";


If you use the top line on this code you posted for a hello world it will always work just fine. It won't work for any script that receives data from a form, unless you clean up the data first. The T on the top line means taint mode. You will need to check any incoming data with a conditional statement.

http://www.google.com/search?hl=en&q=taint+mode+for+perl+script

I'm lazy :)

Also, if you want a more specific error message use fatals to browser:


#!/usr/bin/perl
print "Content-type: text/html\n\n";
use CGI::Carp qw(fatalsToBrowser);
print "I love fat women";


Help this hopes!