You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Christopher Schultz <ch...@christopherschultz.net> on 2008/04/28 23:09:29 UTC

Choosing the "right" session id

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

All,

I'm having a weird problem in production that I completely understand
but I'm not sure if there's a good way to fix it without re-locating one
of my applications.

I have 3 webapps running in separate VMs. One of them is running as ROOT
(context path '/'), and both of the others are running with a context
path of '/foo'. I am fronting the applications with Apache httpd which
determines which URLs go to the main /foo application and which go to an
instance of Apache Cocoon also running under /foo.

When users hit the Cocoon instance, we use their requested session id
(request param or cookie) to make a loopback call to the main /foo
application to get some XML for processing. This has the effect of
sharing a login across two applications because Cocoon masquerades as
the real user by using the session id from the original request to make
the loopback request. Cocoon never allocates sessions for any reason.

Now, here's the problem: the ROOT webapp and the /foo webapp both create
sessions and set cookies on the client. The ROOT webapp creates a cookie
path='/' while the /foo webapp creates a cookie with path='/foo'. This
means that, for users who are using both applications at once, all
requests to '/foo' have TWO values sent for the JSESSIONID cookie. It
appears that Tomcat will try both cookie ids and use the one that
actually works (because this dual-cookie thing doesn't seem to confuse
Tomcat). The problem is when a similar request goes to Cocoon (also
running on Tomcat).

Since the Cocoon instance does not use sessions, /both/ JSESSIONID
cookies are equally invalid, so Tomcat doesn't know which one to choose
when returning a value from HttpServletRequest.getRequestedSessionId. In
certain cases, it returns the "wrong" one (the one from path='/') and
the result is that Cocoon forwards the wrong session id to the real
application, and I get a "not logged in" error. :(

The obvious solution is not to deploy the ROOT application as ROOT, but
instead under some other prefix that does not confuse clients (and my
apps) in this way. I'm wondering if anyone has any other brilliant ideas.

Thanks!

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkgWPQkACgkQ9CaO5/Lv0PDQmwCgvjWloVZefgj0OC9tePmZRB7u
8NEAn35cU/VZRlS7+9n8Kn0woS4DoDJE
=zOO0
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Choosing the "right" session id

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Rainer,

Rainer Jung wrote:
| Christopher Schultz wrote:
|> Hmm... I took a look at the new code and it appears to be the same as
|> the old code for cookies (except that now JSESSIONID cookies are
|> completely ignored when cookies have been disabled application-wide).
|
| Yes, sorry, seems I'm adding more confusion instead of removing. Should
| have read the commit more carefully, but I remembered it had to do with
| Cookies coming from the parent context.

No problem... it got me to look up the cookie spec, so it was useful
after all. Thanks!

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkgXM/QACgkQ9CaO5/Lv0PAPrwCgpVXwYlAXswLFjFvy9BNi9atV
nGwAoIA48eZ+q8ENg7bEnPOENOxKxy9J
=BxZH
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Choosing the "right" session id

Posted by Rainer Jung <ra...@kippdata.de>.
Christopher Schultz wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> Rainer,
> 
> Rainer Jung wrote:
> | This is not a real answer to your question, but if you look at the code,
> | the behaviour w.r.t. multiple JSESSIONID cookies has been changed
> | between 5.5.25 and 5.5.26. There is an issue BZ 43839, and the patch has
> | been applied to TC 5.5 in r609463
> |
> | http://svn.apache.org/viewvc?view=rev&revision=609463
> 
> Hmm... I took a look at the new code and it appears to be the same as
> the old code for cookies (except that now JSESSIONID cookies are
> completely ignored when cookies have been disabled application-wide).

Yes, sorry, seems I'm adding more confusion instead of removing. Should 
have read the commit more carefully, but I remembered it had to do with 
Cookies coming from the parent context.

Regards,

Rainer

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Choosing the "right" session id

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Rainer,

Rainer Jung wrote:
| This is not a real answer to your question, but if you look at the code,
| the behaviour w.r.t. multiple JSESSIONID cookies has been changed
| between 5.5.25 and 5.5.26. There is an issue BZ 43839, and the patch has
| been applied to TC 5.5 in r609463
|
| http://svn.apache.org/viewvc?view=rev&revision=609463

Hmm... I took a look at the new code and it appears to be the same as
the old code for cookies (except that now JSESSIONID cookies are
completely ignored when cookies have been disabled application-wide).

I checked on the cookie specification (best resource I could find was
http://wp.netscape.com/newsref/std/cookie_spec.html) and under the
"Syntax of Cookie HTTP Request Headers" section it states:

"When sending cookies to a server, all cookies with a more specific path
mapping should be sent before cookies with less specific path mappings.
For example, a cookie "name1=foo" with a path mapping of "/" should be
sent after a cookie "name1=foo2" with a path mapping of "/bar" if they
are both to be sent."

That seems to be in line with what Tomcat's code expects: it tries all
cookies from most-specific path to least-specific path (because it
processes them from left to right). Unfortunately for me, the
most-specific path (first sent) is the one that I want, while the
least-specific path is the one used, even when it is not valid.

I think I have to move my application. :(

The good news is that most people who use the "real" /foo application
are never going to be using the ROOT context application just because of
the types of users served. So, while I wait for a convenient time to
move that application, not too many people will be affected. I also have
the option of having the /foo application kill the cookie from the ROOT
application if necessary.

Thanks for the info!
- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkgXIZcACgkQ9CaO5/Lv0PD88wCfdflf5eExQGeEaeqdBhOBB+EZ
9QMAn3PdalKv8P7MqeT4jWZ1FPGoowIU
=8HXI
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Choosing the "right" session id

Posted by Rainer Jung <ra...@kippdata.de>.
Hi Chris,

Christopher Schultz wrote:
> Christopher Schultz wrote:
> | This means that, for users who are using both applications at once,
> | all requests to '/foo' have TWO values sent for the JSESSIONID
> | cookie. It appears that Tomcat will try both cookie ids and use the
> | one that actually works (because this dual-cookie thing doesn't seem
> | to confuse Tomcat). The problem is when a similar request goes to
> | Cocoon (also running on Tomcat).
> 
> I checked the code for Tomcat (I'm using 5.5.23) and my assertion above
> appears to be supported by the code. I'm using the Coyote AJP13
> connector (which I believe is handled by
> org.apache.catalina.connector.CoyoteAdapter) and the code in play
> appears to be in parseSessionCookiesId:

This is not a real answer to your question, but if you look at the code, 
the behaviour w.r.t. multiple JSESSIONID cookies has been changed 
between 5.5.25 and 5.5.26. There is an issue BZ 43839, and the patch has 
been applied to TC 5.5 in r609463

http://svn.apache.org/viewvc?view=rev&revision=609463

Just wanted to prevent unnecessary confusion from differing code behaviour.

Regards,

Rainer

> 
> ~        Cookies serverCookies = req.getCookies();
> ~        int count = serverCookies.getCookieCount();
> ~        if (count <= 0)
> ~            return;
> 
> ~        for (int i = 0; i < count; i++) {
> ~            ServerCookie scookie = serverCookies.getCookie(i);
> ~            if (scookie.getName().equals(Globals.SESSION_COOKIE_NAME)) {
> ~                // Override anything requested in the URL
> ~                if (!request.isRequestedSessionIdFromCookie()) {
> ~                    // Accept only the first session id cookie
> ~                    convertMB(scookie.getValue());
> ~                    request.setRequestedSessionId
> ~                        (scookie.getValue().toString());
> ~                    request.setRequestedSessionCookie(true);
> ~                    request.setRequestedSessionURL(false);
> ~                    if (log.isDebugEnabled())
> ~                        log.debug(" Requested cookie session id is " +
> ~                            request.getRequestedSessionId());
> ~                } else {
> ~                    if (!request.isRequestedSessionIdValid()) {
> ~                        // Replace the session id until one is valid
> ~                        convertMB(scookie.getValue());
> ~                        request.setRequestedSessionId
> ~                            (scookie.getValue().toString());
> ~                    }
> ~                }
> ~            }
> ~        }
> 
> When there are multiple JSESSIONID cookies, the first cookie found
> causes any URL-encoded session id to be discarded and the cookie's
> JSESSIONID is used. Any subsequent JSESSIONID cookies will be ignored
> unless a JSESSIONID has not yet been found that is valid. Once a valid
> JSESSIONID is found, all other cookies are ignored.
> 
> Using LiveHTTPHeaders, I can see that the "correct" JSESSIONID (in my
> case) is being sent /first/, followed by the incorrect one. That
> arrangement of JSESSIONID cookies results in the first cookie being
> accepted, then discarded as the second one is accepted in its place
> (because the first one was apparently not valid).
> 
> It seems that I have two options:
> 1) Re-locate one of the applications -- which is not entirely trivial
> ~   since we have lots of links pointing to it
> 2) Change the cookie name used in one of the webapps (which violates
> ~   the servlet spec and is a PITA to implement)
> 
> Are there any other crazy options anyone can think of?
> 
> Thanks,
> - -chris

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Choosing the "right" session id

Posted by Mikolaj Rydzewski <mi...@ceti.pl>.
Christopher Schultz wrote:
> It seems that I have two options:
> 1) Re-locate one of the applications -- which is not entirely trivial
> ~   since we have lots of links pointing to it
I'd relocate root application and use mod_rewrite to make old links work.


-- 
Mikolaj Rydzewski <mi...@ceti.pl>


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: URL Import Question

Posted by Ken Bowen <kb...@als.com>.
Don't let it go.  Just use the top mail link at the bottom of every  
message.

On Apr 28, 2008, at 7:09 PM, Stephen Caine wrote:

> Mark,
>>
>> The correct procedure is to create a new message with a new subject.
>> This will start a new thread.
>
> Actually, this is what I thought I did.  My sincere apologies.   
> Would it be better for me to start a new thread or should I just let  
> this go?
>
> Stephen
>
> ---------------------------------------------------------------------
> To start a new topic, e-mail: users@tomcat.apache.org
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: URL Import Question

Posted by Mark Thomas <ma...@apache.org>.
Stephen Caine wrote:
> Mark,
>>
>> The correct procedure is to create a new message with a new subject.
>> This will start a new thread.
> 
> Actually, this is what I thought I did.  My sincere apologies.  Would it 
> be better for me to start a new thread or should I just let this go?

The headers never lie ;)

I'd start a new thread.

Mark


---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: URL Import Question

Posted by Stephen Caine <st...@commongrnd.com>.
Mark,
>
> The correct procedure is to create a new message with a new subject.
> This will start a new thread.

Actually, this is what I thought I did.  My sincere apologies.  Would  
it be better for me to start a new thread or should I just let this go?

Stephen

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: URL Import Question

Posted by Mark Thomas <ma...@apache.org>.
Stephen Caine wrote:
> All,
> 
> This question may not belong here, so let me apologize in advance if 
> this is posted inappropriately.
> 
When starting a new thread (ie sending a message to the list about a
new topic) please do not reply to an existing message and change the
subject line. This is known as thread hijacking and to many of the
list archiving services and mail clients used by list subscribers this
makes your new message appear as part of the old thread. This makes it
harder for other users to find relevant information when searching the
lists.

It should also be noted that many list subscribers automatically
ignore any messages that hijack another thread.

The correct procedure is to create a new message with a new subject.
This will start a new thread.

Thanks,

Mark

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


URL Import Question

Posted by Stephen Caine <st...@commongrnd.com>.
All,

This question may not belong here, so let me apologize in advance if  
this is posted inappropriately.

We are using a c:import url tag.  Under most circumstances this works  
just fine, but when it is iterated hundreds of times within the same  
page, it causes the java process to quickly exhaust threads.  This is  
on a 64 bit machine with a 2 gig heap size.  The number of thread  
quickly rise to over 2000.

My question is whether this is a java bug, Tomcat bug or just a  
limitation everyone knows about.

The source as well as the page being imported are complex and fairly  
large.

Thank you,

Stephen Caine
Soft Breeze Systems, LLC

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Choosing the "right" session id

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

All,

Christopher Schultz wrote:
| This means that, for users who are using both applications at once,
| all requests to '/foo' have TWO values sent for the JSESSIONID
| cookie. It appears that Tomcat will try both cookie ids and use the
| one that actually works (because this dual-cookie thing doesn't seem
| to confuse Tomcat). The problem is when a similar request goes to
| Cocoon (also running on Tomcat).

I checked the code for Tomcat (I'm using 5.5.23) and my assertion above
appears to be supported by the code. I'm using the Coyote AJP13
connector (which I believe is handled by
org.apache.catalina.connector.CoyoteAdapter) and the code in play
appears to be in parseSessionCookiesId:

~        Cookies serverCookies = req.getCookies();
~        int count = serverCookies.getCookieCount();
~        if (count <= 0)
~            return;

~        for (int i = 0; i < count; i++) {
~            ServerCookie scookie = serverCookies.getCookie(i);
~            if (scookie.getName().equals(Globals.SESSION_COOKIE_NAME)) {
~                // Override anything requested in the URL
~                if (!request.isRequestedSessionIdFromCookie()) {
~                    // Accept only the first session id cookie
~                    convertMB(scookie.getValue());
~                    request.setRequestedSessionId
~                        (scookie.getValue().toString());
~                    request.setRequestedSessionCookie(true);
~                    request.setRequestedSessionURL(false);
~                    if (log.isDebugEnabled())
~                        log.debug(" Requested cookie session id is " +
~                            request.getRequestedSessionId());
~                } else {
~                    if (!request.isRequestedSessionIdValid()) {
~                        // Replace the session id until one is valid
~                        convertMB(scookie.getValue());
~                        request.setRequestedSessionId
~                            (scookie.getValue().toString());
~                    }
~                }
~            }
~        }

When there are multiple JSESSIONID cookies, the first cookie found
causes any URL-encoded session id to be discarded and the cookie's
JSESSIONID is used. Any subsequent JSESSIONID cookies will be ignored
unless a JSESSIONID has not yet been found that is valid. Once a valid
JSESSIONID is found, all other cookies are ignored.

Using LiveHTTPHeaders, I can see that the "correct" JSESSIONID (in my
case) is being sent /first/, followed by the incorrect one. That
arrangement of JSESSIONID cookies results in the first cookie being
accepted, then discarded as the second one is accepted in its place
(because the first one was apparently not valid).

It seems that I have two options:
1) Re-locate one of the applications -- which is not entirely trivial
~   since we have lots of links pointing to it
2) Change the cookie name used in one of the webapps (which violates
~   the servlet spec and is a PITA to implement)

Are there any other crazy options anyone can think of?

Thanks,
- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkgWQrgACgkQ9CaO5/Lv0PB0rACfZ76lSFd34idI5j6OHlNq/8gY
fy4An1w47dePjdJfQFVVgbbbv2qLQgD8
=9Y3p
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: Choosing the "right" session id

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

All,

Christopher Schultz wrote:
| The obvious solution is not to deploy the ROOT application as ROOT, but
| instead under some other prefix that does not confuse clients (and my
| apps) in this way. I'm wondering if anyone has any other brilliant ideas.

I have come up with another idea, just in case anyone happens to be
interested.

The usage patterns of these applications together are such that the ROOT
web application is only used some of the time -- mostly, /foo is being
used. When the / application is used, it is used to completion, and then
the user goes back to /foo for the rest of their interactions with our
webapps. Returning to the / application is basically considered an
entirely new interaction, so any loss of the JSESSIONID from a previous
interactions is acceptable.

My solution is therefore to write a filter that kills any JSESSIONID
cookie with path="/" and install it on /foo. That should mitigate the
problem in the short term while I prepare to re-locate the ROOT webapp.

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkgaDmwACgkQ9CaO5/Lv0PD1EQCcC3eveoryc09yDD9ziKCJ9DSu
SRcAoJe8ULIv7gQV9zz6Aqc51h6UF0o9
=4hMr
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org