Mailing List Archive

Perplexing Cookies - two issues
Greetings,

I have a couple of servers I've been working on. They run apache2 and
mod_perl, mostly doing Apache::ASP work. They work together to handle
the load, using a cisco localdirector.

We recently noted that one of the servers is handling about 500
threads, and the other 300. We modified the loaddirector to remove
the sticky flag on http port, and it immediately balanced 400/400.
But thats not what this email is about. this email is about what
happened to the cookies.

Essentially, the site sells subscriptions to content. Because there
is more than one system, instead of using sessions (as was implimented
when it was on windows, I translated it) I am using cookies. When a
user links into various galleries and gateways to enter the site, the
system sets cookies.

First, an apparent bug in the Response cookie method.

I originally simply used the $Response->Cookies(...) calls to do this,
but that wasn't working. Upon inspecting the code and doing some
debugging, I determined that the logic was just... wrong. There may
be code I couldn't find, but the Response->Cookies function did not
appear to be setting up the structure that is required when generating
the cookies - that is, all the values inside of a {Value} hash
reference, with Domain and Expires as members of the same hash...
essentially

$Response->Cookies('ccc', 'key', 'val') ;
$Response->Cookies('ccc', 'Domain', 'mydomain.com');

resulted in

$Response->{Cookies}{ccc}{key} = 'val';
$Response->{Cookies}{ccc}{Domain} = 'mydomain.com';

when it should have resulted in

$Response->{Cookies}{ccc}{Value}{key} = 'val';
$Response->{Cookies}{ccc}{Domain} = 'mydomain.com';

Did I miss a fix thats already been submitted? Is a fix needed to be
submitted to correct this problem? Am I using the method incorrectly?

I worked around it by populating the Response->{Cookies} hash manually for now.

Now the REAL perplexing problem.

As I mentioned we have two servers, which were running sticky. The
clients arrive, get their cookies, return the cookies when signing up,
and everybody is happy because they get their commissions. BUT, the
servers were not running balanced (and the more loaded one was running
into swap and slowing down response time) so we turned off session
sticky on port 80.

Despite personal tests that worked fine - cookies set when they were
supposed to be, returned, page logic showed everything was working -
things weren't. Joe Random User was somehow unable to get and/or
return the cookie values! Signup rate plunged, and what signups we
did get were without documentation as to from whence they came.

We turned sticky back on, and immediately signup rates turned to
normal, and were documented.

I've been puzzling over this for about two days now - usually I come
up with something after awhile, realizing some method I used was not
correct in all circumstances or something - but this one really
boggles me. Now that I've bounced it off of some other experts - What
do you think? Any questions about the setup, methods, or any of that?
Am I missing something that would be impacted by the user hopping
randomly between the servers?

Thanks for your time in reading this rather long detailed message, and
in advance for your thoughts.

Skylos

---------------------------------------------------------------------
To unsubscribe, e-mail: asp-unsubscribe@perl.apache.org
For additional commands, e-mail: asp-help@perl.apache.org
Re: Perplexing Cookies - two issues [ In reply to ]
Skylos wrote:
> ...
> $Response->Cookies('ccc', 'key', 'val') ;
> $Response->Cookies('ccc', 'Domain', 'mydomain.com');
>
> resulted in
>
> $Response->{Cookies}{ccc}{key} = 'val';
> $Response->{Cookies}{ccc}{Domain} = 'mydomain.com';
>

This should work fine. The function AddCookieHeaders() should
pick up this data correctly and do the right thing.

> when it should have resulted in
>
> $Response->{Cookies}{ccc}{Value}{key} = 'val';
> $Response->{Cookies}{ccc}{Domain} = 'mydomain.com';
>

Using Value is one way it could be represented internally.

> Did I miss a fix thats already been submitted? Is a fix needed to be
> submitted to correct this problem? Am I using the method incorrectly?
>

What is the bug exactly, that this code did not work for you?

$Response->{Cookies}{ccc}{key} = 'val';
$Response->{Cookies}{ccc}{Domain} = 'mydomain.com';

Note, you should use either the hash method directly, or the API call,
but not both. You might be tripping up something odd if you are switching
your method of access.

> I worked around it by populating the Response->{Cookies} hash manually for now.
>

That is a fine way to go.

> Now the REAL perplexing problem.
>
> As I mentioned we have two servers, which were running sticky. The
> clients arrive, get their cookies, return the cookies when signing up,
> and everybody is happy because they get their commissions. BUT, the
> servers were not running balanced (and the more loaded one was running
> into swap and slowing down response time) so we turned off session
> sticky on port 80.
>

A web server should never run into swap. It implies a too high MaxClients
setting, and/or not tuned well enough mod_perl.

> Despite personal tests that worked fine - cookies set when they were
> supposed to be, returned, page logic showed everything was working -
> things weren't. Joe Random User was somehow unable to get and/or
> return the cookie values! Signup rate plunged, and what signups we
> did get were without documentation as to from whence they came.
>
> We turned sticky back on, and immediately signup rates turned to
> normal, and were documented.
>
> I've been puzzling over this for about two days now - usually I come
> up with something after awhile, realizing some method I used was not
> correct in all circumstances or something - but this one really
> boggles me. Now that I've bounced it off of some other experts - What
> do you think? Any questions about the setup, methods, or any of that?
> Am I missing something that would be impacted by the user hopping
> randomly between the servers?
>

2 things come to mind ...

1) if there is $Session data that is relevant to the user, and that is
being stored on the local file system, then switching to another system
will not work, you'll need sticky sessions

2) if the load balancers are actually redirecting to a web server with a
new domain, then it may be that the browser is not sending the cookie
to the new server despite your Domain flag set above, and you might
this test.

Regards,

Josh

---------------------------------------------------------------------
To unsubscribe, e-mail: asp-unsubscribe@perl.apache.org
For additional commands, e-mail: asp-help@perl.apache.org
Re: Perplexing Cookies - two issues (down to one) [ In reply to ]
On Sun, 27 Feb 2005 19:11:03 -0800, Joshua Chamas <josh@chamas.com> wrote:
> Skylos wrote:
> > ...
> > $Response->Cookies('ccc', 'key', 'val') ;
> > $Response->Cookies('ccc', 'Domain', 'mydomain.com');
> >
> > resulted in
> >
> > $Response->{Cookies}{ccc}{key} = 'val';
> > $Response->{Cookies}{ccc}{Domain} = 'mydomain.com';
> >
>
> This should work fine. The function AddCookieHeaders() should
> pick up this data correctly and do the right thing.

Ahh, this is the part I couldn't figure from looking at the code.

> > when it should have resulted in
> >
> > $Response->{Cookies}{ccc}{Value}{key} = 'val';
> > $Response->{Cookies}{ccc}{Domain} = 'mydomain.com';
>
> Using Value is one way it could be represented internally.
>
> > Did I miss a fix thats already been submitted? Is a fix needed to be
> > submitted to correct this problem? Am I using the method incorrectly?
>
> What is the bug exactly, that this code did not work for you?
>
> $Response->{Cookies}{ccc}{key} = 'val';
> $Response->{Cookies}{ccc}{Domain} = 'mydomain.com';

Ack, I didn't explain it right. No... its that this...

$Response->Cookies("ccc", "refReferer", $ENV{HTTP_REFERER});
$Response->Cookies("ccc", "Domain", "colorclimax.com");
$Response->Cookies("ccc", "refCode", "d10200");

did not result in what I want - things would happen like, the
refReferer would be there, but the refCode would not be - or vice
versa if I changed the order. And sometimes the cookie wouldn't seem
to get set at all.

But after alot of struggle, I managed to extract the form of the hash
from the code analysis, and found that if I set it up using the hash
notation,it worked as I needed it to. This makes me think that
there's something funky goin on in that code, that there's a bug in
there somewhere...

I assume this function, AddCookieHeader or whatever it is - actually
has a list of 'special' key attributes, 'Domain', 'Path', 'Expires',
etc?

I also have a suspicion that it may be related to urlencoding - some
older browsers like safari don't handle non-urlencoded cookies very
well (I fought with this compatibility issue on another project)
getting confused about the multiple = signs in there, apparently. I
had to urlencode my cookie strings. So they looked more like this:

Set-Cookie: ccc=refCode%XXd10200%XXrefReferer%XX;
Domain=colorclimax.com; Path=/;

> Note, you should use either the hash method directly, or the API call,
> but not both. You might be tripping up something odd if you are switching
> your method of access.

I want to use the API call. This is how its 'supposed to be' in my
head. I'm using the ASP object model, I should not depend on internal
structures of objects.

> > I worked around it by populating the Response->{Cookies} hash manually for now.
>
> That is a fine way to go.

Its counter to my philosophy though. :P

> > Now the REAL perplexing problem.

This problem seems to have evaporated. They went to the non-sticky
configuration again (without telling me), and everything is working...
Gah, I hate it when there was a problem and I couldn't figure it. But
anyway...

> 2 things come to mind ...
>
> 1) if there is $Session data that is relevant to the user, and that is
> being stored on the local file system, then switching to another system
> will not work, you'll need sticky sessions

Sessions are turned off and not used. Multi-server setup makes them useless.

> 2) if the load balancers are actually redirecting to a web server with a
> new domain, then it may be that the browser is not sending the cookie
> to the new server despite your Domain flag set above, and you might
> this test.

Both web servers have the exact same configuration. - the config files
are rsynced between them.

Skylos

---------------------------------------------------------------------
To unsubscribe, e-mail: asp-unsubscribe@perl.apache.org
For additional commands, e-mail: asp-help@perl.apache.org
Re: Perplexing Cookies - two issues (down to one) [ In reply to ]
Skylos wrote:
> On Sun, 27 Feb 2005 19:11:03 -0800, Joshua Chamas <josh@chamas.com> wrote:
...
>
> Ack, I didn't explain it right. No... its that this...
>
> $Response->Cookies("ccc", "refReferer", $ENV{HTTP_REFERER});
> $Response->Cookies("ccc", "Domain", "colorclimax.com");
> $Response->Cookies("ccc", "refCode", "d10200");
>
> did not result in what I want - things would happen like, the
> refReferer would be there, but the refCode would not be - or vice
> versa if I changed the order. And sometimes the cookie wouldn't seem
> to get set at all.
>

I just tested this script bit...

<%
$Response->Cookies("ccc", "refReferer", "referrer");
$Response->Cookies("ccc", "Domain", "colorclimax.com");
$Response->Cookies("ccc", "refCode", "d10200");

And I get a header like this:

Content-Length: 9
Cache-Control: private
Set-Cookie: session-id=0f6a26f8de83908f97b6c10b9c5efe91; path=/eg/; domain=apache-asp.com; secure
Set-Cookie: ccc=refCode=d10200&refReferer=referrer; path=/; domain=colorclimax.com';

So it seems to me to be working correctly.

> I assume this function, AddCookieHeader or whatever it is - actually
> has a list of 'special' key attributes, 'Domain', 'Path', 'Expires',
> etc?

Yes. Everything else is treated as Value data.

Regards,

Josh

>
> I also have a suspicion that it may be related to urlencoding - some
> older browsers like safari don't handle non-urlencoded cookies very
> well (I fought with this compatibility issue on another project)
> getting confused about the multiple = signs in there, apparently. I
> had to urlencode my cookie strings. So they looked more like this:
>
> Set-Cookie: ccc=refCode%XXd10200%XXrefReferer%XX;
> Domain=colorclimax.com; Path=/;
>

Interesting. This is the first I have heard of this issue, certainly does
not seem cookie spec conformant. ; is the delimiter there.

>
> I want to use the API call. This is how its 'supposed to be' in my
> head. I'm using the ASP object model, I should not depend on internal
> structures of objects.
>

OK. The HASH method is documented and will stay. In particular, if one
is doing a lot of cookie manipulation, using the HASH methods may seem
cleaner for the code and will be faster besides.

>
> This problem seems to have evaporated. They went to the non-sticky
> configuration again (without telling me), and everything is working...
> Gah, I hate it when there was a problem and I couldn't figure it. But
> anyway...
>

Good news!

Regards,

Josh

---------------------------------------------------------------------
To unsubscribe, e-mail: asp-unsubscribe@perl.apache.org
For additional commands, e-mail: asp-help@perl.apache.org