tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Christopher Schultz <>
Subject Re: HttpServletRequest - getHeaders() vs getCookies()
Date Tue, 15 Jul 2014 14:12:22 GMT
Hash: SHA256


On 7/9/14, 4:51 AM, Simon Kulessa wrote:
> I had a look at the documentation and the tomcat source to get a
> better understanding of what the
> '|org.apache.catalina.connector.RECYCLE_FACADE' parameter actually
> does.|
> I have seen that Tomcat objects like Cookies, Request etc. are
> designed to be reusable.

Requests, yes. I haven't looked to see if Cookies would be re-usable
but it seems plausible.

> What I currently do not understand is: In which scenario and what 
> context are they going to be reused? I see there are Endpoints
> classes (like NIOEndpoint) which are used to process the different
> requests. This seems to be the most likely entry point into the
> scenario.
> Maybe somebody can provide some general outline of how requests and
> the reusing of the object actually works together? Is there some
> kind of relation to the IP of an incoming request?

The client's IP is irrelevant: Tomcat uses a pool of objects and
re-fills each object with data from an incoming request. These
objects, as far as the web application should be concerned, should
have a valid lifetime equal to the request itself. The servlet spec
requires these semantics, so this isn't some weird Tomcat thing.
Tomcat has chosen to pool these objects for a small performance gain
when it comes to memory management and garbage collection.

If your application retains references to these objects after they
become invalid, they may contain invalid data or valid data from
another request after they should have become invalid form the
perspective of the original request.

If you need data from a request, cookie, etc. then you should copy it
somewhere safe before the request ends.

> In our code we hold a reference to the httpSession outside of the 
> request (in a application scoped map).

HttpSession objects should be cacheable in this way. You do have to be
careful that when the HttpSession expires, you remove those object
references from your application-scoped Map or you risk memory exhaustion.

> We use this session object to read the SessionId, to invalidate or
> to adjust the session timeout from outside a client request.

That should be okay. Are you storing request or response objects in a
similar way?

> I finally received the logs where the session itself was created: 
> Basically there is some communication ongoing between client and
> server, then the server receives an unexpected command and decides
> to invalidate the session because of this.

Good so far.

> Later another command of the client with the old cookie arrives and
> is rejected by our server.

Seems reasonable.

> After this any other request coming from the same IP fails.

Fails how? Exception? Unexpected behavior? Please be specific.

> As mentioned in the logs we see the httpHeader that does contain a 
> cookie with a different value, but the getCookies() method always
> provides the cookie value of the 'original session'.

How many cookies do you see? The client can provide more than one
JSESSIONID cookie. Also, when the request arrives with the "old"
JSESSIONID cookie, it does not mean that the old session id is valid.
It's just that the client still thinks the session is valid.

Are you using Tomcat-managed sessions, or are you doing your own
session management?

> Around the same time when the original session was still alive I
> found an error message in the Catalina log:
> ... org.apache.coyote.AbstractProtocol$AbstractConnectionHandler
> process SEVERE: null java.lang.IllegalStateException: Calling
> [asyncPostProcess()] is not valid for a request with Async state
> [STARTED] at 
> org.apache.coyote.AsyncStateMachine.asyncPostProcess(
>  at 
> org.apache.coyote.AbstractProcessor.asyncPostProcess(
>  at 
> org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(
>  at 
>  at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown
> Source) at
> java.util.concurrent.ThreadPoolExecutor$ Source) 
> at Source)
> I am not sure whether this is somewhat related to the problem
> scenario, but at least this looks like something that should not
> happen.

I believe there are some edge cases related to acync processing that
have been identified and fixed in the versions between yours (7.0.29)
and the current release version (7.0.54). You should really upgrade
regardless of whether or not this fixes your particular problem(s):
there have been many security fixes classified as "important" since
your version (which is nearly 2 years old).

- -chris
Version: GnuPG v1
Comment: GPGTools -
Comment: Using GnuPG with Thunderbird -


To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message