Newbie Perl Question

B

Bryce

Can anyone help me modify this Perl script?

#!/usr/bin/perl
use CGI ':standard';
$query = new CGI;
print redirect($query->param("url"));

I need it to send a standard 404 response (instead of the standard redirect()
seen above) if the "url" GET parameter was non-existent or null, or if the HTTP
Referer didn't contain the case insensitive substring "mysite.com/thisurl.php".

I like helping myself and tried my best using tutorials to do this on my own.
Alas, my attempts have failed. Nothing but 500 server errors. E.g.:

#!/usr/bin/perl
use CGI ':standard';
$query = new CGI;

$destination = $query->param("url")
$origin = $ENV{'HTTP_REFERER'}

if ($destination !eq '' && $origin =~ /mysite\.com\/thisurl\.php/) {
print redirect($destination);
} else {
print "Status: 404 Not Found\n\n";
}

Many thanks, and apologizes in advance for my n00bness.
 
R

RedGrittyBrick

Bryce said:
Can anyone help me modify this Perl script?

#!/usr/bin/perl
use CGI ':standard';
$query = new CGI;
print redirect($query->param("url"));

I need it to send a standard 404 response (instead of the standard redirect()
seen above) if the "url" GET parameter was non-existent or null, or if the HTTP
Referer didn't contain the case insensitive substring "mysite.com/thisurl.php".

I like helping myself and tried my best using tutorials to do this on my own.
Alas, my attempts have failed. Nothing but 500 server errors. E.g.:

#!/usr/bin/perl
use CGI ':standard';
$query = new CGI;

$destination = $query->param("url")
$origin = $ENV{'HTTP_REFERER'}

if ($destination !eq '' && $origin =~ /mysite\.com\/thisurl\.php/) {
print redirect($destination);

redirect() is a procedure of CGI.pm.
} else {
print "Status: 404 Not Found\n\n";

That print does not use any procedure of CGI.pm

I expect your print statement places text in the body not in the
headers. A proper 404 response is part of the headers.
}

Many thanks, and apologizes in advance for my n00bness.

Generally I think it is a mistake to mix the use of CGI.pm with plain
print statements. I'd choose one approach and use it consistently
throughout.

CGI.pm can be used in procedural or object-oriented fashions. Choose one.

The documentation can be read by issuing the command
perldoc CGI

Somewhere in there are these examples:

print $query->header('image/gif');

-or-

print $query->header('text/html','204 No response');

-or-

print $query->header(-type=>'image/gif',
-nph=>1,
-status=>'402 Payment required',
-expires=>'+3d',
-cookie=>$cookie,
-charset=>'utf-7',
-attachment=>'foo.gif',
-Cost=>'$2.00');

Note that these are in object-oriented style. You should be able to work
out the equivalent procedural statements.

A '404 unavailable' response may not be appropriate - I'd review all the
other documented 400-499 responses to see if any of them are more
appropriate. You might want to use something like '403 Forbidden' instead.

I hope that helps.
 
B

Bryce

I hope that helps.

I appreciate your response, and yes, your advice would normally be helpful. :)

The problem is, I know nothing of Perl. I created the demonstration code in
my original post by falling back on my general knowledge of basic coding syntax,
and by gleaning hints from Perl code examples I discovered online. Admittedly,
that's a horrible way to write code. But when faced with performing a simple
task in a language one doesn't know, it sometimes works. ....and other times,
it doesn't. Like this time.

I hate asking others to write code for me. (I do learn the languages I'm most
often subject to.) Alas, asking for a free lunch was the essence of my plea in
this case. I assumed karma would excuse that, since this is only the second
time I've had to use -- and ask for help with -- Perl in five years.
A '404 unavailable' response may not be appropriate - I'd review all the
other documented 400-499 responses to see if any of them are more
appropriate. You might want to use something like '403 Forbidden' instead.

You're correct, except that in this case, the goal is making the script appear
to not exist if hit by someone coming from anything other than the desired HTTP
Referer, or if no &url= parameter is provided. (I'll spare you the unamusing
story of why this corny deception is necessary.)

Thanks for the reply.
 
J

Jürgen Exner

You're correct, except that in this case, the goal is making the script appear
to not exist if hit by someone coming from anything other than the desired HTTP
Referer, or if no &url= parameter is provided. (I'll spare you the unamusing
story of why this corny deception is necessary.)

Both of which can be faked trivially, of course.

jue
 
B

Bryce

Jürgen Exner said:
Both of which can be faked trivially, of course.

Of course. That's why I wouldn't be using this method if the Referer URL in
question were publicly known. Which it isn't.
 
R

RedGrittyBrick

Bryce said:
Alas, asking for a free lunch was the essence of my plea in this case.

Shame on you.

#!/usr/bin/perl
use strict;
use warnings;
use CGI ':standard';

my $query = new CGI;
my $destination = $query->param("url");
my $origin = $ENV{'HTTP_REFERER'};

if ($destination ne '' && $origin =~ m(mysite\.com/thisurl\.php)) {
print redirect($destination);
} else {
print
header(-status => '404 Not Found'),
start_html('Page Not Found'),
h1('Page Not Found'),
p('Please ignore the man behind the curtain.'),
end_html();
}

Shame on me :)

It's untested - if your free sandwich contains bugs, you're on your own.
 
G

Gunnar Hjalmarsson

Bryce said:
I like helping myself and tried my best using tutorials to do this on my own.
Alas, my attempts have failed. Nothing but 500 server errors. E.g.:

#!/usr/bin/perl
use CGI ':standard';
$query = new CGI;

$destination = $query->param("url")
$origin = $ENV{'HTTP_REFERER'}

if ($destination !eq '' && $origin =~ /mysite\.com\/thisurl\.php/) {
print redirect($destination);
} else {
print "Status: 404 Not Found\n\n";
}

Add this line to the beginning of the script, to get more useful error
messages displayed in the browser:

use CGI::Carp 'fatalsToBrowser';
 
T

Ted Zlatanov

R> use CGI ':standard';
....
R> my $query = new CGI;
....
R> my $origin = $ENV{'HTTP_REFERER'};

There is a referer() method for CGI queries. If you're bothering to
create the query object, you may as well use it.

Ted
 
T

Ted Zlatanov

GH> Add this line to the beginning of the script, to get more useful error
GH> messages displayed in the browser:

GH> use CGI::Carp 'fatalsToBrowser';

This can be very insecure :) I usually also advise "and remember to
turn it off in production."

Ted
 
B

Bryce

Shame on you.
[...]
Shame on me :)

It's untested - if your free sandwich contains bugs, you're on your own.

You're a saint, Mr. RGB! Works perfectly. A thousand blessings on your
compilers. :)

And thanks also to the others who responded:

Gunnar - "use CGI::Carp 'fatalsToBrowser';" proved infinitely useful while
making one customization I decided upon to RGB's script. Thanks!

Ted - Yes, I'd definitely #exclude it post-testing. :)

Joe - So noted. I always look for how to enable runtime error output for
problem-finding purposes. Unfortunately in this case, no shell access was
available to me. That's part of why I wound up in c.l.p.m begging help:
couldn't even diagnose *why* my own attempts at the script were failing.
Thanks also for the note on the matching. I love optimizations like that.
 
T

Tad J McClellan

Bryce said:
Gunnar - "use CGI::Carp 'fatalsToBrowser';" proved infinitely useful


There are lots of infinitely useful tips in the Perl FAQ.

If you are doing programming for the CGI, then you should
read all of the FAQs that mention it:


perldoc -q CGI

How can I make my CGI script more efficient?

Where can I learn about CGI or Web programming in Perl?

What is the correct form of response from a CGI script?

My CGI script runs from the command line but not the
browser. (500 Server Error)

How can I get better error messages from a CGI program?

How do I make sure users can't enter values into a form
that cause my CGI script to do bad things?

How do I decode a CGI form?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top