Re: Redirect page (newbie)
by Masem (Monsignor) on May 04, 2001 at 20:42 UTC
|
The redirect must happen instead of the header (as it's basically a special HTTP header), which means that you can't call it after you've printed the CGI header. The easy way to fix it in your script is move the call to submit_parameters just before the cgi->header line.
Dr. Michael K. Neylon - mneylon-pm@masemware.com
||
"You've left the lens cap of your mind on again, Pinky" - The Brain
| [reply] |
|
|
Perfect! (muchas thanks). Now I would never have dreamed of moving the submit_parameters line before the cgi->header line because I assume the form itself won't print to the screen if cgi->header has not been processed first. Ouch: I don't understand why this fix works!
laura.guimauve
| [reply] |
|
|
First, ever web page that is sent, static or dynamic, must begin with the HTTP editor, typcially as simple as:
Content-Type: text/html
(eg, ending with two \n\n); this tells the browser how to 'render' the given page. If you were sending, say, a PDF file, the server should send "Content-Type: application/pdf\n\n", and the browser says "Hey, that's a PDF file, let me launch the PDF plug-in". The HTTP header is a way for content negotiation. But also, if you want to redirect the user without using META commands, you can use the HTTP header line "Redirect: <url>" (I believe that's the format), instead of sending a Content-Type, so that the browser recognizes that you want to send the user elsewhere. If the browser saw the Content-Type line first, it will ignore the Redirect, since it's expecting only data from here out. (The header also contains any other negotiated data that might be sent, such as cookies to be retrieved, or cookies to be sent). Thus, you can only print the HTTP header once, whether it be a Content-Type, a Redirect, or the other limited forms that HTTP standards allow.
CGI.pm of course makes this easy to do since it provides ->header() and ->redirect() functions. But the same logic applies: you can only call any one of these once for a given page; once it's printed, further header functions will have no effect.
So in your case, you only want the header to print if the login is (still) invalid, otherwise you will redirect the user. So the logic that you almost had correct would be to check the login first, then if validated, print the ->redirect(), otherwise, print the ->header() and the login form again. In either case, you only use one header function during the printing of the page, and that will be the first thing printed, triggering the right effects at the end browser.
Dr. Michael K. Neylon - mneylon-pm@masemware.com
||
"You've left the lens cap of your mind on again, Pinky" - The Brain
| [reply] [d/l] |
|
|
Re: Redirect page (newbie)
by chipmunk (Parson) on May 04, 2001 at 20:46 UTC
|
By the time you're ready to print the redirect, you've already printed an HTTP header at the top of the script:
print $query->header;
You need to determine whether you're displaying the form or doing a redirect before you print anything. Do the parameter check first, then print the redirect if every checks out, or print the form otherwise. | [reply] [d/l] |
Re: Redirect page (newbie)
by deryni (Beadle) on May 04, 2001 at 21:15 UTC
|
I'm writing a similar program and I have this code:
#!/usr/local/bin/perl -w
use strict;
use CGI;
my $q = CGI::new();
$q->use_named_parameters();
open (PASSWD, ".PASSWORD") or die "Couldn't open file";
my $matched= 0;
my $queried_user = $q->param(-name=>"user");
my $queried_pass = $q->param(-name=>"pass");
while (<PASSWD>) {
my ($user,$pass) = split(/\s/,$_);
if (($queried_user eq $user) and ($queried_pass eq $pass)) {
$matched = 1;
$q->redirect("works.html");
}
}
if (!$matched) {
print $q->header() . $q->start_html;
print "Bad Username/Password combination<br>";
print $q->end_html;
}
but every time I try to run it I get an internal server error it's not
my system so I can't easily check the server logs for the specific error
Any ideas?
both .PASSWORD and works.html are in the same directory as the script
one more question, when I run this program in interactive
mode from the command line am I supposed to be seeing the
redirected website print out or what? right now I get nothing
Thanks for the help
-Etan | [reply] [d/l] |
|
|
| [reply] [d/l] |
|
|
Thanks -= Ozzy =-, I'm not sure how I missed that.
I still need help with the Internal Server Error though.
-Etan
P.S. code is as above but "$q->redirect("works.html");" changed to
"print $q->redirect("works.html");"
and added "close PASSWD;" after the end of the while loop
| [reply] |
|
|
Try a print in front of the redirect().
| [reply] |
Re: Redirect page (newbie)
by Anonymous Monk on May 04, 2001 at 21:09 UTC
|
The redirect isn't working because you have already printed a webpage.
When you redirect you must print the redirect header as
the only output of the script and then exit with no other output.
You should either print the form OR call the submit_parameters function. | [reply] |
|
|
Actually, you can (and, perhaps, "should") print a web page after a Redirect. The *original* reason was for ancient browsers which might not understand the redirection command. Nowadays, that's mostly limited to a few "dumb" robots and so forth, so the page will generally be ignored. The idea is that the HTML should say something like:
Sorry, you're at the wrong place. Click me to get where you want to be.
| [reply] |
|
|
Some webservers send out their own headers for cgi. This
problem bit me on a win32 based webserver once. You may
want to telnet to port 80 and GET /path/to/your/script.pl
and check what headers are returned.
| [reply] |
Re: Redirect page (newbie)
by DrZaius (Monk) on May 04, 2001 at 21:47 UTC
|
You've already printed the header. This means you are getting two headers.
If you want to redirect, you have to only print the redirect header.
Why are constructing your html with perl? You could make your setup infinitely better by turning this script into two parts. First, put your login form in a static html page and then have your cgi script do the validating and redirecting.
For example, you go to login.html which you put your username/password in. When you submit your form, you go to cgi-bin/login.cgi which authenticates your credentials and redirects to myview.cgi.
Also, how is your myview.cgi authenticating? Can I bypass your security by going staight to myview.cgi? | [reply] |
|
|
I'm constructing the html with perl because once I discovered one could it seemed more efficient. Until now, when a problem like this pops up and shows a good reason for not doing so.
As for your thornier question about authentication (which I'm grateful for by the way), my shameful answer is yes--one can go straight to myview.cgi anyway. I know: this is ridiculous. But as a newbie, I'm overcoming programming hurdles step by step. It's going to be a long road...
So, what should I be looking up here at the site to find out everything I need to know about authentication?
laura.guimauve
| [reply] |
|
|
| [reply] |
|
|
Oh hey - another comment that may help you. If you want to password protect a web page on a Unix based system, you should read about htpasswd.
Here is one explanation of how to set it up.
It's really simple to set up, and is quite secure. No worries about someone bypassing authentication and loading a web page they shouldn't see.
| [reply] |
|
|
|
|
Re: Redirect page (newbie)
by Galen (Beadle) on May 04, 2001 at 23:43 UTC
|
Give this a try....an easy way to redirect.
print "Location:myview.cgi";
| [reply] [d/l] |
Re: Redirect page (newbie)
by Anonymous Monk on May 06, 2001 at 23:37 UTC
|
The "redirect" instruction forms a HTTP header, but you're
already printing an HTTP header in your script, before you
check the password value. perldoc CGI says:
# The redirect() function redirects the browser to a
# different URL. If you use redirection like this, you
# should not print out a header as well.
I suggest you move the &submit_parameters routine up to just
below $query = new CGI. Bear in mind that you're invoking the
script srice, once to print what's effectively a static page,
and once to process the result; you might want to consider
using a static HTML page to contain the form, and restricting
your script's functionality to input-checking and redirection
Hope this is of some help.
Roger Burton West | [reply] |
Re: Redirect page (newbie)
by mattr (Curate) on May 07, 2001 at 16:42 UTC
|
When I'm debugging something like this (just did a biggy)
I print "Content-type; text/html\n\n"; at the top of the
program even before "use" statements. Then you can see what
is getting printed.
One problem you may see if you follow this track long enough
is that cookies and redirecting don't like each other.
Another headers problem. My solutions were,
1) keep track of how many times you print $q->header
2) to keep sane, slurp in a file and print it out instead of
redirecting to it, if you are going insane
3) do cookies in Javascript.. and write variables into the
javascript at runtime by using a template which you've actually
slurped in with (2) above.
4) if you must do cookies in perl, get all your functions that
do cookies and put them all together into a couple of
functions like doallmycookies(). Or better yet stick everything
inside one cookie. I got away with a heavily javascripting
page that opens up first and finds out who's knocking on the
door, but that's only because a client asked for lots of
functions that wanted to use cookies at the end of the project..
I believe you can even roll your own comlicated headers in text
but I prefer CGI to keep sane.. maybe you want to read the
RFC if you get really into it.
P.S. If anyone knows about a non-mod_perl way to do
clickpath tracking, so that the cookie gets into the apache
log file, I'm interested! (no to webbugs..) I've done mod_perl
but this is for a server where it isn't so easy to turn it
on and off and shake it around in the air.
Hope this helps.
| [reply] |