(Ovid) Re: Stuck
by Ovid (Cardinal) on Dec 16, 2000 at 01:44 UTC
|
Update: ctweten pointed out that your URL is definitely legal. Thanks!
To be honest, I'm not sure that you're URL is legal. Try a url like the following:
http://lezar.org/path/to/script/myscript?where=someval
/path/to/script/myscript should be the path and name of your script. where=somval is a name value pair that gets passed to the query string.
Then, use CGI to get the name/value pairs. You also shoudl use taint checking (that's the -T switch on the shebang line) and use strict to catch all sorts of problems. Here's an updated version of what you want to do:
#!/usr/bin/perl -wT
use strict;
use CGI qw/:standard/;
my $taintedWhere = param( 'where' );
my $where = ( $taintedWhere =~ /(\w+)/ );
if ( $where eq 'Front' ) {
print header;
print <<" Mn";
Some HTML
Mn
} elsif ( $where eq 'WebMail' ) {
print header;
print <<" WbMl";
Some more HTML
WbMl
} else {
# $where is not what we expect, so we have an error routine here;
}
See perlsec for information on the security issues and you can also check out my online CGI course for further information. It's not complete, but it should give you a good start.
For easier debugging, try adding the following line to your script:
use CGI::Carp qw( fatalsToBrowser );
That will usually print useful debugging information to the browser. Just make sure that you remove this when you put the script on a production server! There's no sense proving crackers with additional information about how your script works.
Cheers,
Ovid
Join the Perlmonks Setiathome Group or just click on the the link and check out our stats. | [reply] [d/l] [select] |
|
Just out of curiosity, why are you worried about un-tainting $where if you're just using it for comparisons and no system operations? Or is this just a safety net in the event the original poster does wish to use $where in a risky way?
| [reply] [d/l] [select] |
|
That's a good question and it's just indicative of paranoia on my part. I tend to untaint data regardless of how it's going to be used at the present time. I don't know who will be maintaining my work in the future and what they're going to be doing with it, so rather than take any chances, I'd like to cover that up front. It's the same reason I turned on taint checking when it's not needed -- I never know who will use this script in the future.
Good question, though. It's a matter of style. I just prefer to be ultra paranoid -- after all, they're watching me ;)
Cheers,
Ovid
Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.
| [reply] |
|
FYI, that URL is most deffinitley legal. OTOH, I like your code much better.
--
Casey
I am a superhero.
| [reply] [d/l] |
Re: Stuck
by davorg (Chancellor) on Dec 16, 2000 at 01:40 UTC
|
What is the error that you get? Have you tried running
the script from the command line?
Adding -w and use strict; to the script
only throws up one small error, which is simple enough to
fix (my $where;). Other than that, your Perl seems
inelegant, but functional.
Maybe it is a problem with the way your web server is
set up. Telling us the exact error would help us to help
you.
--
<http://www.dave.org.uk>
"Perl makes the fun jobs fun
and the boring jobs bearable" - me
| [reply] |
Re: Stuck
by damian1301 (Curate) on Dec 16, 2000 at 02:12 UTC
|
In fact I was doing the same peice of coding a while ago and came up with something similarly simple and elegant. Well without delay here it is. It captures the referrer and logs it.
#!/usr/bin/perl
use CGI qw(param standard);
use strict;
my $query = new CGI;
my $referrer = $query->param("ref");
my $location = $query->param("place");
print $query->header;
if ($referrer){
$referrer =~ tr/A-Z/a-z/;
open(REF, ">>referrer.txt") or default('Cant open/write, $!');
print REF "$referrer\n";
close(REF);
}elsif ($ENV{'HTTP_REFERER'}) {
open(REF1, ">>referrer.txt") or default('Cant open/write, $!');
print REF1 "$ENV{'HTTP_REFERER'}\n";
close(REF1);
}
if (!$location){
&main
}elsif (lc($location) eq "misc"){
&misc
}elsif (lc($location) eq "links"){
&links
}else{
default('Where are you trying to go?');
}
sub links{
print "links\n";
}
sub misc{
print "misc\n";
}
sub default{
print "Theres an error: @_";
}
sub main{
print "this is sub main!";
}
Wanna be perl hacker. Dave AKA damian | [reply] [d/l] |
Re: Stuck
by c-era (Curate) on Dec 16, 2000 at 01:38 UTC
|
First off, you should use CGI, this will be very helpful to you. Also, if you insist on doing it this way (which you shouldn't) you can print out $where to see what it contains. | [reply] |
|
You should absolutely print out $where -- I thought for a moment that $ENV{'QUERY_STRING'} might also return the '?' but a quick test showed that no, it doesn't. Nevertheless, you might have a zero-space character after "Front" that is preventing the match and unless you print it out, you'll never know.
On a progammatic note, if you insist on writing our own output code and not using CGI, you should try to look form ways to reduce the duplication that is apparent in your code.
For instance, both sections clearly output the content-type and some basic header information, so why is that wrapped up in your if/else statement?
A good rule of thumb is that whenever you find yourself typing the exact same thing two or more times in a switch/subroutine sequence, you've probably got the switch/sub in the wrong place or it contains the wrong stuff.
| [reply] |
Re: Stuck
by cwest (Friar) on Dec 16, 2000 at 01:44 UTC
|
Without any idea of what the error could possibly be, without one little piece of information about what happens when you try to run this program or how you try to run this program I'm going o say that I don't have a friggin clue what's wrong!
Next, if you're actually trying to access this page from the web browser and you're getting a 500 error, I suggest:
- Review the web logs ( tail LOG_FILE , where LOG_FILE is a path to the log file which could be anywhere ).
- put use CGI::Carp qw(fatalsToBrowser); after your #! line.
- Run the program from the command line and watch the output.
Note: I ran this program locally without any trouble. In light of that, I would also: check permissions, make sure it's in the right place, try running it from the command line, make sure your web server is set up to run Perl programs, * ( read: c'mon man, give me a clue! ).
--
Casey
I am a superhero.
| [reply] |
Re: Stuck
by Fastolfe (Vicar) on Dec 16, 2000 at 06:05 UTC
|
I'm not going to repeat what others have said on this thread, but in the event you want to explore other ways of writing your URL's, consider using the PATH_INFO variable. This would let you construct traditional-looking URL's that are really comprised of script arguments:
http://www.example.com/one/two/three/four.html
You could create a script called 'one' in the web server's docroot, and your script would receive the following in its $ENV{PATH_INFO}:
/two/three/four.html
You could even go a step further and use this in conjunction with typical CGI arguments:
http://www.example.com/one/two.html?arg1=one&arg2=two
$ENV{PATH_INFO} is "/one/two.html"
$ENV{QUERY_STRING} is "arg1=one&arg2=two"
CGI.pm will do all of this for you in a friendly fashion. | [reply] [d/l] [select] |
|
There is at least one case I know of where you don't
really have a choice about using PATH_INFO.
If you want to download a
file on the fly to be read by Excel, with IE 4 and some
versions of Excel it will break horribly if IE knows that
it is dealing with a CGI script. The only workaround I
know of is to hide the fact of a CGI script using PATH_INFO.
(The actual bug is that the path to the temp file is split
on spaces before being passed to Excel. Since that path
often has "Temporary Internet Files" in it, this results in
Excel not finding the temporary file with your data.)
| [reply] |
|
Ok... so I didn't expect such a quick reply from you guys.. thanx a lot..
the problem is with my server I guess... I checked all the variables in the %ENV hash.. only the QUERY_STRING apprears empty, I don't know why..
and you guys who are telling me that it has repetitions.. I already know that.. and as you know I'm just testing..
viewing the log?? I tried it.. it says no recent errors so that's why I don't know what is happening... I want to know if there is a utility for Perl offline like the PWS for the .asp
and I said I am a newbie, so I don't know how to use CGI.pm I hope it works.. or else i will switch to JavaScript
| [reply] |
Re: Stuck
by jynx (Priest) on Dec 16, 2000 at 01:43 UTC
|
well,
This probably won't be as much help as you want, but you'll
hear it quite often if you get into perl significantly. Try not
to reinvent the wheel when it doesn't need it. There are two
major things about your code that i would change (imho):
First of all, you're printing the same things multiple times,
if you are absolutely going to be having the same title, print
it once at the top of your page and save the if...elsif...else
statements for code that will change. This will help simplify
where your errors are by breaking up your coding blocks into
manageable pieces as well.
Secondly, try looking into CGI.pm (from CPAN)
to do the parsing for you. While it is interesting to know what
needs to printed on a web page, and is good practice for understanding
things, if you don't need to do it, don't. CGI will do most of that
for you.
These are just my 2 cents worth, hope it works out,
jynx | [reply] |
Re: Stuck
by tune (Curate) on Dec 16, 2000 at 01:52 UTC
|
Insert this line into your code after the #!/usr/bin/perl:
use CGI;
use CGI::Carp 'fatalsToBrowser';
This will print the error messages into your browser window, and you can find out what the problem is.
--
tune | [reply] [d/l] [select] |
Re: Stuck
by Chady (Priest) on Dec 16, 2000 at 15:26 UTC
|
That's me the Anonymous Monk now with a name...
I tried to test the variables, it seems that the server is not getting the QUERY_STRING so I tried HTTP_REFERER, still with an error..
#!/usr/bin/perl
@all = split(/?/,$ENV{'HTTP_REFERER'});
$where = @all[1];
if ($where eq 'Front') {
print "Content-type: text/html\n\n";
print <<Mn;
<HTML>
<head>
<title>Lezar.org</title>
</head>
<body bgcolor="#FFFFFF" text="#000000" link="#666666" vlink="#666666"
+alink="#666666" style="overflow: hidden">
<table width="100%" height="100%">
<tr height="100%">
<td width="100%">
<div align="center">
<pre>Lezar.org<br><br>Coming soon</pre>
<font size="1" face="Verdana, Arial, Helvetica, sans-serif">for inform
+ation
contact <a href="mailto:info\@lezar.org">info\@lezar.org</a></font></d
+iv>
</table>
</body></HTML>
Mn
}
elsif ($where eq 'WebMail') {
print "Content-type: text/html\n\n";
print <<WbMl;
<HTML>
<head>
<title>Lezar.org</title>
</head>
<body>
<script language="JavaScript">
<!--
self.location = "http://lezar.virtualave.net/WebMail";
//-->
</script>
</body>
</html>
WbMl
}
else {
print "Content-type: text/html\n\n";
print "Query String is : $where \n";
}
#
try it yourselves at http://lezar.org/index2.cgi?whatever | [reply] [d/l] |
|
Hi Chady. You are having some trouble, and I can't give
you a straight, simple, do-one-thing answer (I don't think
anybody could). However, if you go back and read all the
informative and straightforward replies you got all day
from the other monks here, you could probably get a handle
on your situation.
Here are my own thoughts on your problem:
- Enable warnings by putting a -w
after 'perl' on the first line. Like so:
#!/usr/bin/perl
# no warnings
#!/usr/bin/perl -w
# warnings enabled
This will give you debugging information that will be
output into your Error_Log for Apache, or IIS, or whatever
you're using. As it stands, your code is VALID (as far as
I can see), it just doesn't do what you want it to. Turning
warnings on won't fix this problem directly, but it might
help you understand what's going on a little better.
- Simplify your code by removing the HTML and
tertiary functionality. This will help you narrow down
where the problem is. For example:
#!/usr/bin/perl -w
@all = split(/?/,$ENV{'HTTP_REFERER'});
$where = @all[1];
die $where;
Just running that snippet and checking the Error_Log will
let you determine if your split is running properly, if
you're using the correct environment variable, if you're
making your array call correctly, et cetera. Based on the
output value of $where you can figure out
where your (first) problem is.
- Environment variables are tricky. Some are only
defined under certain circumstances. For example,
QUERY_STRING will only be defined if there is a question
mark at the end of the URL path. For example:
A) http://www.host.com/cgi-bin/test-script.pl
B) http://www.host.com/cgi-bin/test-script.pl?param=value
C) http://www.host.com/cgi-bin/test-script.pl?param=value&color=blue
1: #!/usr/bin/perl -w
2:
3: warn $ENV{'QUERY_STRING'};
Line 3 returns:
A) blank (null string, no data)
B) param=value
C) param=value&color=blue
Keep this in mind.
- CGI.pm is great for dealing with different
parameter values. I know you're a newbie, but it's really
easy and intuitive. Here's some quick code for you:
#!/usr/bin/perl -w
use CGI;
use strict;
my $cgi = new CGI; # this creates a new CGI object
my $where = $cgi->param('where');
warn $where;
Now you can call this script like this:
/cgi-bin/locator.pl?where=Front
And 'Front' will be written to your Error_Log. Simple,
right?
Mostly I've just echoed what's already been written in
reply to your first post. There's not much more we can
give you.
Good luck.
'kaboo
PS - If you're having all this
trouble trying to do this in Perl, you're going to have a
seizure trying to do it in JavaScript. 'nuff said.
| [reply] [d/l] [select] |
|
well.. it seems that the server is f**ing with me... I don't know what is going on...
I tried to debug the code by using this code
foreach $key (sort(keys %ENV)) {
print "$key = $ENV{$key}<br>\n";
}
so I got this output:
DOCUMENT_ROOT = /data1/virtualave.net/lezar
GATEWAY_INTERFACE = CGI/1.1
HTTP_ACCEPT = */*
HTTP_ACCEPT_ENCODING = gzip, deflate
HTTP_ACCEPT_LANGUAGE = en-us
HTTP_CACHE_CONTROL = max-stale=0
HTTP_COOKIE = p_go2id=UE5dCG1Pd76kk/ZxDmBBgw
HTTP_HOST = lezar.virtualave.net
HTTP_REFERER = http://lezar.org/index2.cgi?Front
HTTP_USER_AGENT = Mozilla/4.0 (compatible; MSIE 5.0; Windows 98; DigEx
+t)
PATH = /usr/local/bin:/usr/bin:/bin
QUERY_STRING =
REMOTE_ADDR = 209.239.68.247
REMOTE_PORT = 34052
REQUEST_METHOD = GET
REQUEST_URI = /index2.cgi
SCRIPT_FILENAME = /data1/va/lezar/index2.cgi
SCRIPT_NAME = /index2.cgi
SCRIPT_URI = http://lezar.virtualave.net/index2.cgi
SCRIPT_URL = /index2.cgi
SERVER_ADMIN = webmaster@virtualave.net
SERVER_NAME = lezar.virtualave.net
SERVER_PORT = 80
SERVER_PROTOCOL = HTTP/1.0
SERVER_SOFTWARE = Apache/1.3.6 (Unix)
as you can see, the QUERY_STRING appears blank... I don't know what is really going on, it seems like something is wrong with Virtual Avenue
so before I go on and work on simplifying the code, I have to see what the heck is going on with the server, and their customer support is not quite satisfying
STILL STUCK
Chady
http://chady.net
| [reply] [d/l] [select] |
|