Newbie Perl Question
am 22.01.2008 08:20:18 von zerospam
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.
Re: Newbie Perl Question
am 22.01.2008 11:45:10 von RedGrittyBrick
Bryce wrote:
> 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.
Re: Newbie Perl Question
am 23.01.2008 07:29:17 von zerospam
On Tue, 22 Jan 2008 10:45:10 +0000, RedGrittyBrick wrote:
> 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.
Re: Newbie Perl Question
am 23.01.2008 08:13:29 von jurgenex
zerospam@example.com (Bryce) wrote:
>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
Re: Newbie Perl Question
am 23.01.2008 11:34:39 von zerospam
Jürgen Exner wrote:
> zeros...@example.com (Bryce) wrote:
> >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.
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.
Re: Newbie Perl Question
am 23.01.2008 11:53:07 von RedGrittyBrick
Bryce wrote:
> 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.
Re: Newbie Perl Question
am 23.01.2008 12:08:42 von Gunnar Hjalmarsson
Bryce wrote:
> 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';
--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl
Re: Newbie Perl Question
am 23.01.2008 16:22:46 von Ted Zlatanov
On Wed, 23 Jan 2008 10:53:07 +0000 RedGrittyBrick wrote:
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
Re: Newbie Perl Question
am 23.01.2008 16:23:48 von Ted Zlatanov
On Wed, 23 Jan 2008 12:08:42 +0100 Gunnar Hjalmarsson wrote:
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
Re: Newbie Perl Question
am 24.01.2008 07:02:51 von Joe Smith
Bryce wrote:
> if ($destination !eq '' && $origin =~ /mysite\.com\/thisurl\.php/) {
That is not valid perl code.
> 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.:
The first thing in getting rid of "500 Server Error": you _MUST_ make sure
the code compiles correctly. Use perl's "-cw" command-line option to test that.
linux% cat test.cgi
if ($destination !eq '' && $origin =~ /mysite\.com\/thisurl\.php/) {
print "OK\n";
}
linux% perl -cw test.cgi
syntax error at test.cgi line 1, near "$destination !"
test.cgi had compilation errors.
linux%
The string inequality operator is "ne" (and also "not $string1 eq $string2").
> was non-existent or null, or if ... didn't contain the case insensitive substring
Case insensitivity is done with "i" after the regex. Since "0" is not a valid URL,
the test for non-null can be done in a more simple fashion.
if ($destination and $origin =~ /\bmysite\.com\/thisurl\.php/i) { ... }
The \b ensures that "foobar123mysite.com/thisurl.php" won't match.
-Joe
Re: Newbie Perl Question
am 25.01.2008 13:26:51 von zerospam
On Wed, 23 Jan 2008 10:53:07 +0000, RedGrittyBrick wrote:
> 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.
Re: Newbie Perl Question
am 26.01.2008 02:50:20 von Tad J McClellan
Bryce wrote:
> 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?
--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"