Bug 49158

Summary: More than one JSESSIONID cookie headers set
Product: Tomcat 6 Reporter: Filip Hanik <fhanik>
Component: CatalinaAssignee: Tomcat Developers Mailing List <dev>
Severity: major CC: dconnard69, stephan.zlatarev
Priority: P2    
Version: 6.0.26   
Target Milestone: default   
Hardware: PC   
OS: Linux   

Description Filip Hanik 2010-04-20 11:40:39 UTC
The following JSP

  session = request.getSession();
  session = request.getSession();

Generates this response from Apache Tomcat
HTTP/1.x 200 OK

Server: Apache-Coyote/1.1

Set-Cookie: JSESSIONID=8C65C3AB20B8BBD157866668B67983B1; Path=""; HttpOnly

Set-Cookie: JSESSIONID=498BD2E8B22C5121143B7305A0ECB249; Path=""; HttpOnly

Set-Cookie: JSESSIONID=49F58AE7833522293F8EAD2AB2D13F19; Path=""; HttpOnly

Content-Type: text/html;charset=ISO-8859-1

Content-Length: 7

Date: Tue, 20 Apr 2010 15:38:47 GMT
Comment 2 Mark Thomas 2010-04-20 13:12:34 UTC
48913 has a proposed patch. I'll look at committing it today.

*** This bug has been marked as a duplicate of bug 48913 ***
Comment 3 Filip Hanik 2010-04-20 13:14:26 UTC
Fixed in trunk in SVN r935998
Comment 4 Filip Hanik 2010-04-20 13:16:20 UTC
(In reply to comment #2)
> 48913 has a proposed patch. I'll look at committing it today.
> *** This bug has been marked as a duplicate of bug 48913 ***

Didn't see this until I had committed my patch. The patch in 48913 doesn't seem to capture the changeSessionId use case. But both patches do the same thing
Comment 5 Filip Hanik 2010-04-20 13:17:04 UTC
*** Bug 48913 has been marked as a duplicate of this bug. ***
Comment 6 Mark Thomas 2010-05-14 15:00:36 UTC
This has been fixed in 6.0.x and will be included in 6.0.27 onwards.
Comment 7 David Connard 2010-07-20 10:14:30 UTC

Your change doesn't actually do exactly what you think it does.

Your code - below - Response.java, line 992:

        for (int i = 0; i < n; i++) {
            if (headers.getName(i).toString().equals(headername)) {
                if (headers.getValue(i).toString().startsWith(startsWith)) {
-->                 headers.setValue(sb.toString());                      
                    set = true;

Yes, setValue(contents) appears to be a logical call... however, that call is actually setValue(name), and the returned contents are meant to be the reference to the header (to which you can then add the value).

The result of that call is to add a header named, say: 

  JSESSIONID=54EDEDA814975EB485C2D9D660346717; Domain=.domain.com; Path=/

This doesn't actually appear to result in any additional response header (presumably because the format was invalid, or the value was never set), and it doesn't change the value of the existing Set-Cookie header.  The following code appears to work fine instead:

        for (int i = 0; i < n; i++) {
            if (headers.getName(i).toString().equals(headername)) {
                if (headers.getValue(i).toString().startsWith(startsWith)) {
-->                 headers.getValue(i).setString(sb.toString());
                    set = true;

Note that you could probably optimise this (and avoid the set=true / later addHeader() call by calling instead:


This is proving to be critical to us (we manually invalidate sessions first time around when we haven't seen them before - to guard against sessions being presented from search engines), and we currently end up in an invalidation loop as the second JSESSIONID is never actually presented back to the browser.
Comment 8 Rainer Jung 2010-07-20 10:48:17 UTC
Thanks for the feedback.

This has been noticed independently a few days ago (see https://issues.apache.org/bugzilla/show_bug.cgi?id=49598) and has been fixed in in r964733.

We just now started voting for releasing 6.0.29 which will contain the fix.