Ok, very sorry for cluttering up the boards again. You know I ask my questions in twos. This one should tie me over for a bit.
One of the problems I traced all the problems in my life down to is the (apparently) infamous Set-cookie followed by Location header problem.
Jon, I know you mentioned that in an old post, and mentioned a work around for it. I can't find anything out there on it - could you advise me? I'm trying to avoid using CGI to spit out Javascript or anything really out there like that. Any ideas?
Muchos gracias, and good night.
Comments
: my questions in twos. This one should tie me over for a bit.
No worries...posts on the Perl board are a Good Thing. :-)
: One of the problems I traced all the problems in my life down to is
: the (apparently) infamous Set-cookie followed by Location header
: problem.
*groans*
: Jon, I know you mentioned that in an old post, and mentioned a work
: around for it. I can't find anything out there on it - could you
: advise me? I'm trying to avoid using CGI to spit out Javascript or
: anything really out there like that. Any ideas?
So far I've identified two situations where it seems to happen. The one where it's a big problem is under IIS. Apache doesn't seem to have a problem with it on the whole, though I did run into an issue the other day when using a combo of Apache, Perl, cookies, location headers and (this seems like the magic ingredient for my fun) mod_rewrite.
I don't know a real fix. All I've used is this:-
[code]#Print cookies here!
print "Content-type: text/html
";
print qq{meta http-equiv="refresh" content="0; url=/path/to/script.pl">};[/code]
Which is a hack and I really don't like it. I wonder if maybe printing a different header to do redirection would work, as there are choices besides the Location header. I also want to know exactly what IIS does send, and what headers are passed around. I'm also curious about the problem I ran into as well. So, when I find time I'll dig out my packet sniffer (uh...network protocol analyser) and try to see what on earth is going on.
Hope my little hack helps you out in the meantime, and if you find the solution or can offer any more insight, I'd really appreciate that.
Jonathan
###
for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
(tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
/(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");
You enter your login info and click submit, action is login.cgi. Login.cgi uses &authenticate to verify your l/p. From there it calls &session::add_user. This generates a key, writes that to a local file, and also prints out the "Set-cookie" header. Once returned to login.cgi, login prints the content-type header and the refresh hack you showed me (which worked great - thank you).
The sub in login.cgi that handles this:
sub login {
if(&authenticate ($in{"id"}, $in{"pass"})) {
my $redirect = "http://dreamjunky.com" . $paths::admin_page;
#this method sets a cookie with appropriate session data
&session::add_user;
print "Content-Type: text/html
";
print "'";
} else {
#generates an error page, no significance
}
}
The add_user sub:
sub add_user {
# LOCAL: add session key and IP address to beginning of local file
my ($key, $ip, $time, $line, @lines);
$key = &session::create_key;
$ip = $ENV{"REMOTE_ADDR"};
$time = gmtime time;
$line = "{time:$time} {key:$key} {ip:$ip} {access:FULL}";
open LOGGED, "$paths::logged_in_file";
chomp (@lines = );
close LOGGED;
#remove other lines with this IP
map { s/^.*$ip.*$// } @lines;
unshift @lines, $line;
open LOGGED, ">$paths::logged_in_file";
map { print LOGGED "$_
" if /^.+$/ } @lines;
close LOGGED;
# REMOTE: set cookie to expire at the end of this session and redirect to admin page
my $cookie = "key=$key; path=/";
print "Set-cookie: $cookie
";
}
Now just to get the simple stuff out of the way, there are a few things I am sure of:
1) no output is printed before the call to add_user, so "Set-cookie" is the first output.
2) the authenticate function works fine, the create_key works fine.
When I run this locally I'm able to log in, and out, no troubles. But once on the server, when I try to log in it does add the session info to a local file (so it IS making it into the add_user sub), and it even redirects like it's supposed to. The Set-cookie seems to be ignored. Am I missing something obvious here?
Ever appreciative of your endless fountain of knowledge,
Tvienti
: : Ok, very sorry for cluttering up the boards again. You know I ask
: : my questions in twos. This one should tie me over for a bit.
: No worries...posts on the Perl board are a Good Thing. :-)
:
: : One of the problems I traced all the problems in my life down to is
: : the (apparently) infamous Set-cookie followed by Location header
: : problem.
: *groans*
:
: : Jon, I know you mentioned that in an old post, and mentioned a work
: : around for it. I can't find anything out there on it - could you
: : advise me? I'm trying to avoid using CGI to spit out Javascript or
: : anything really out there like that. Any ideas?
: So far I've identified two situations where it seems to happen. The one where it's a big problem is under IIS. Apache doesn't seem to have a problem with it on the whole, though I did run into an issue the other day when using a combo of Apache, Perl, cookies, location headers and (this seems like the magic ingredient for my fun) mod_rewrite.
:
: I don't know a real fix. All I've used is this:-
:
: [code]#Print cookies here!
: print "Content-type: text/html
";
: print qq{meta http-equiv="refresh" content="0; url=/path/to/script.pl">};[/code]
:
: Which is a hack and I really don't like it. I wonder if maybe printing a different header to do redirection would work, as there are choices besides the Location header. I also want to know exactly what IIS does send, and what headers are passed around. I'm also curious about the problem I ran into as well. So, when I find time I'll dig out my packet sniffer (uh...network protocol analyser) and try to see what on earth is going on.
:
: Hope my little hack helps you out in the meantime, and if you find the solution or can offer any more insight, I'd really appreciate that.
:
: Jonathan
:
: ###
: for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
: (tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
: /(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");
:
:
: Maybe my problem's not where I thought it was. First off, for
: background, I'm writing on XP Pro (works fine) and uploading to
: Apache 1.3 (can't set the cookie). I'm just going to paste you my
: code that's relevant. First, the concept:
Background is always helpful...thanks for the info.
: You enter your login info and click submit, action is login.cgi.
: Login.cgi uses &authenticate to verify your l/p. From there it calls
: &session::add_user. This generates a key, writes that to a local
: file, and also prints out the "Set-cookie" header. Once returned to
: login.cgi, login prints the content-type header and the refresh hack
: you showed me (which worked great - thank you).
You're welcome. Good we got one thing fixed.
: The sub in login.cgi that handles this:
:
: sub login {
: if(&authenticate ($in{"id"}, $in{"pass"})) {
: my $redirect = "http://dreamjunky.com" . $paths::admin_page;
[red]One thought - make sure the login request is made to http://dreamjunky.com/ and not http://www.dreamjunky.com/ - that could be the cuase of your problems. Remember cookies happen on a per server basis, and as far as the web browser knows, dreamjunky.com is a different server to www.dreamjunky.com. You can always just redirect to $paths::admin_page; there's no requirement for a full URL.[/red]
: #this method sets a cookie with appropriate session data
: &session::add_user;
:
: print "Content-Type: text/html
";
: print "'";
: } else {
: #generates an error page, no significance
: }
: }
:
: The add_user sub:
:
: sub add_user {
: # LOCAL: add session key and IP address to beginning of local file
: my ($key, $ip, $time, $line, @lines);
: $key = &session::create_key;
: $ip = $ENV{"REMOTE_ADDR"};
: $time = gmtime time;
: $line = "{time:$time} {key:$key} {ip:$ip} {access:FULL}";
:
: open LOGGED, "$paths::logged_in_file";
: chomp (@lines = );
: close LOGGED;
:
: #remove other lines with this IP
: map { s/^.*$ip.*$// } @lines;
:
: unshift @lines, $line;
:
: open LOGGED, ">$paths::logged_in_file";
: map { print LOGGED "$_
" if /^.+$/ } @lines;
: close LOGGED;
:
: # REMOTE: set cookie to expire at the end of this session and redirect to admin page
: my $cookie = "key=$key; path=/";
: print "Set-cookie: $cookie
";
: }
Looks OK to me... Nice use of map {...}, I very rarely use that construct for some reason.
: Now just to get the simple stuff out of the way, there are a few
: things I am sure of:
:
: 1) no output is printed before the call to add_user, so "Set-cookie"
: is the first output.
: 2) the authenticate function works fine, the create_key works fine.
They're the obvious things to check.
: When I run this locally I'm able to log in, and out, no troubles.
Which kinda fits with my idea above...
: But once on the server, when I try to log in it does add the session
: info to a local file (so it IS making it into the add_user sub), and
: it even redirects like it's supposed to. The Set-cookie seems to be
: ignored. Am I missing something obvious here?
This is rather strange. In a script that should recieve the cookie, print out the environment variables:-
print "$_=$ENV{$_}
" for (sort keys %ENV);
Then you can see if anything (e.g. any cookie) is being sent with the request.
: Ever appreciative of your endless fountain of knowledge,
If these things don't help, the fountain is starting to run dry... I sense that this'll either be one of those "D'oh! How could I be so dumb" problems, or it'll actually work out to be a hard one to solve.
Hope this helps,
Jonathan
###
for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
(tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
/(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");
OmniHTTPD is more flexible in that "Set-cookie: $cookie" is acceptable. Apache isn't, and requires "Set-Cookie: $cookie". You put it best, D'oh! But at least we finally got this fixed. It was just barely worth the time and effort hehe.
Thanks again
Tvienti
: acceptable. Apache isn't, and requires "Set-Cookie: $cookie". You
: put it best, D'oh! But at least we finally got this fixed. It was
: just barely worth the time and effort hehe.
That's very strange! I wouldn't have expected Apache to be so fussy, then if the standards say it should be...I don't know that they do say, to be honest.
On a consistency note, Apache is perfectly happy with Content-type. Curious.
Pleased you got it sussed anyway.
Next... ;-)
Jonathan
###
for(74,117,115,116){$::a.=chr};(($_.='qwertyui')&&
(tr/yuiqwert/her anot/))for($::b);for($::c){$_.=$^X;
/(p.{2}l)/;$_=$1}$::b=~/(..)$/;print("$::a$::b $::c hack$1.");