You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Konstantin Kolinko <kn...@gmail.com> on 2011/09/21 20:06:28 UTC

Session.getLastAccessTime() ticking

Hi!

I was reviewing the spec and the code with regards to the following issue:
https://issues.apache.org/bugzilla/show_bug.cgi?id=51812

Ch.7.6 of the Servlet specification (both 2.5 and 3.0 versions) says:
"The session is considered to be accessed when a request that is part
of the session is first
handled by the servlet container."

My understanding of the phrase is that
a) Regardless of whether request.getSession(..) was called or not, if
the request is part of a session the session access time must be
updated.

(Thus the use case reported in Bug 51812 cannot be implemented, unless
you move your servlet into an independent webapp): regardless of how
you try to avoid accessing the session in a servlet, the last accessed
time should be "ticket" by any request that appears to belong to this
session.

b) The access time should be when request processing started, i.e.
org.apache.coyote.Request#getStartTime()


My findings in the current trunk:
1. Access time ticking is effectively done by Request.doGetSession(...).

On first call if "(requestedSessionId != null)" it finds existing
session and calls session.access().
There are several other places where access time is updated, but I
think this is the main use case.

As code fragment in issue 51812 shows, this method is always called
when an Authenticator is
configured in the webapp and does not have its cache disabled.

(AccessLogValve can also access the session and thus tick its last
access time -- from AccessLogValve$SessionIdElement or
AccessLogValve$SessionAttributeElement, if it is configured to use
those elements in its pattern).

The first question that I have is that I do not see how last access is
ticked if there is no explicit request for a session. I think it
should be ticked regardless of whether getSession(..) has been called.


2. Access time in StandardSession is updated using System.currentTimeMillis();

The second question that I have is that it contradicts my "b)" point
from above. I think it is against the spec.

The third question is that there are a lot of places that call
access(), and every such call updates thisAccessedTime in
StandardSession.
It looks like not all such calls are associated with an actual
request, and strictly speaking they should not update the time.


The second question can be demonstrated. Steps to reproduce:
1. Add the following line to catalina.properties:
org.apache.catalina.STRICT_SERVLET_COMPLIANCE=true
2. Add the following JSP page to the ROOT webapp and start Tomcat:
sessionTest.jsp:
[[[
<%@page session="false" import="java.util.*"
contentType="text/plain;charset=UTF-8"%>
<%
  out.println("Time 1: " + new Date());
  Thread.sleep(2000);

  out.println("Time 2: " + new Date());
  HttpSession session = request.getSession(true);

  Thread.sleep(2000);
  out.println("Time 3: " + new Date());
  out.println("Last accessed: " + new Date(session.getLastAccessedTime()));
%>]]]

Open a new web browser and access the page three times.
First access:
Time 1: Wed Sep 21 21:36:25 MSD 2011
Time 2: Wed Sep 21 21:36:27 MSD 2011
Time 3: Wed Sep 21 21:36:29 MSD 2011
Last accessed: Wed Sep 21 21:36:27 MSD 2011 <- expected 21:36:25

Second access:
Time 1: Wed Sep 21 21:36:32 MSD 2011
Time 2: Wed Sep 21 21:36:34 MSD 2011
Time 3: Wed Sep 21 21:36:36 MSD 2011
Last accessed: Wed Sep 21 21:36:27 MSD 2011

Third access:
Time 1: Wed Sep 21 21:36:42 MSD 2011
Time 2: Wed Sep 21 21:36:44 MSD 2011
Time 3: Wed Sep 21 21:36:46 MSD 2011
Last accessed: Wed Sep 21 21:36:34 MSD 2011 <- expected 21:36:32

If I add the same jsp page into examples webapp, the behaviour becomes
different:
On first access: The same problem, System.currentTimeMillis() is used
for a new session
On third access: No problem: I see Time 1 from previous request, as expected.

I think that is because examples webapp has protected pages and thus
uses Authenticator. So if some webapp is used to test the difference
in lastAccessedTime, it wouldn't see any problems if it uses
Authenticator.


Regarding the bug 51812, I think that it makes sense, but because of
"a)" it cannot be implemented if Tomcat were strictly following the
spec.

Best regards,
Konstantin Kolinko

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: Session.getLastAccessTime() ticking

Posted by Rainer Jung <ra...@kippdata.de>.
On 21.09.2011 21:15, Mark Thomas wrote:
> On 21/09/2011 19:06, Konstantin Kolinko wrote:
> 
> <snip/>
>> The first question that I have is that I do not see how last access is
>> ticked if there is no explicit request for a session. I think it
>> should be ticked regardless of whether getSession(..) has been called.
> 
> StandardHostValve look for ACCESS_SESSION.
> 
>> 2. Access time in StandardSession is updated using System.currentTimeMillis();
>>
>> The second question that I have is that it contradicts my "b)" point
>> from above. I think it is against the spec.
> 
> On the surface, that looks like a reasonable thing to do but the session
> doesn't have access to the request so the change could be quite invasive.
> 
>> The third question is that there are a lot of places that call
>> access(), and every such call updates thisAccessedTime in
>> StandardSession.
>> It looks like not all such calls are associated with an actual
>> request, and strictly speaking they should not update the time.
> 
> Fair point, but see above.
> 
> Rainer went through all of this some time ago and I thought that he
> brought everything in line with the spec so I am surprised there are so
> many apparent differences. I'd be interested in his views.

I guess you are referring to a 2008 discussion here:

http://marc.info/?t=122582031400001&r=1&w=2

That wasn't driven by SPEC compliance but consistency in general.

The changes I applied after the very short discussion were:

http://svn.apache.org/viewvc?rev=711711&view=rev
http://svn.apache.org/viewvc?rev=711714&view=rev
http://svn.apache.org/viewvc?rev=711716&view=rev
http://svn.apache.org/viewvc?rev=711720&view=rev

The following backport proposal was added for TC 6 in March 2009 and
contains some more explanations:

* Backport cleanup of semantics of thisAccessedTime and
  lastAccessedTime for sessions:
  - preparational whitespace changes
    http://svn.apache.org/viewvc?rev=711695&view=rev
  - Give thisAccessedTime and lastAccessedTime for sessions
    a clear semantics:
    http://svn.apache.org/viewvc?rev=711711&view=rev
    - thisAccessedTime will be updated at the beginning and
      at the end of session use
    - lastAccessedTime will only be updated at the end of
      session use
    This means:
    - lastAccessedTime is the last access time of a session
      disregarding any request still being processed on.
      So this is good to use even from within a request
      to detect when its own session has been used last before.
    - thisAccessedTime already gets updated when a new request
      disregarding any request still being processed on.
      So this is better for any idleness check or information.
    - thisAccessedTime >= lastAccessedTime always
  - Port from StandardSession to DeltaSession
    http://svn.apache.org/viewvc?rev=711714&view=rev
  - Expose thisAccessedTime via the session interface
    and ManagerBase, so we can use it from outside the session.
    http://svn.apache.org/viewvc?rev=711716&view=rev
  - Make the classes checking session idleness use thisAccessedTime.
    http://svn.apache.org/viewvc?rev=711720&view=rev
    This is not for invalidation, only for displaying
    idle times and making persistance decisions.

I removed it in May, because there were too many objections.

Regards,

Rainer

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Re: Session.getLastAccessTime() ticking

Posted by Mark Thomas <ma...@apache.org>.
On 21/09/2011 19:06, Konstantin Kolinko wrote:

<snip/>
> The first question that I have is that I do not see how last access is
> ticked if there is no explicit request for a session. I think it
> should be ticked regardless of whether getSession(..) has been called.

StandardHostValve look for ACCESS_SESSION.

> 2. Access time in StandardSession is updated using System.currentTimeMillis();
> 
> The second question that I have is that it contradicts my "b)" point
> from above. I think it is against the spec.

On the surface, that looks like a reasonable thing to do but the session
doesn't have access to the request so the change could be quite invasive.

> The third question is that there are a lot of places that call
> access(), and every such call updates thisAccessedTime in
> StandardSession.
> It looks like not all such calls are associated with an actual
> request, and strictly speaking they should not update the time.

Fair point, but see above.

Rainer went through all of this some time ago and I thought that he
brought everything in line with the spec so I am surprised there are so
many apparent differences. I'd be interested in his views.

Mark

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org