You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by bu...@apache.org on 2003/06/11 01:19:05 UTC

DO NOT REPLY [Bug 20667] New: - Sessions expire prematurely due to improperly updated lastAccessedTime

DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=20667>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=20667

Sessions expire prematurely due to improperly updated lastAccessedTime

           Summary: Sessions expire prematurely due to improperly updated
                    lastAccessedTime
           Product: Tomcat 4
           Version: 4.1.24
          Platform: All
        OS/Version: Windows NT/2K
            Status: NEW
          Severity: Normal
          Priority: Other
         Component: Catalina
        AssignedTo: tomcat-dev@jakarta.apache.org
        ReportedBy: djo_34@yahoo.com


I think this is the same as:

BUG# 15463
BUG# 18609

At each request, access() is called, setting the following:

lastAccessedTime = thisAccessedTime
thisAccessedTime = the current system time/request time

Which is fine except that session expiration is driven by lastAccessedTime and 
not thisAccessedTime as seen in processExpires().

So... lets say we have a 10 minute session timeout and a request comes in at 
12:00:00 PM.

lastAccessedTime = 12:00:00 PM ( milli equivalent )
thisAccessedTime = 12:00:00 PM

Session will expire at 12:10:00 PM ( equivalent to lastAccessedTime + 
maxInactiveInterval )

The next request is made at 12:09:00 PM... calls access()

lastAccessedTime = 12:00:00 PM ( previous thisAccessTime )
thisAccessedTime = 12:09:00 PM

Session will expire at 12:10:00 PM ( because processExpires() uses timeNow - 
session.getLastAccessedTime() )

---------------------------------------------------------------------------

StandardSession.access()

    /**
     * Update the accessed time information for this session.  This method
     * should be called by the context when a request comes in for a particular
     * session, even if the application does not reference it.
     */
    public void access() {

        this.isNew = false;
        this.lastAccessedTime = this.thisAccessedTime;
        this.thisAccessedTime = System.currentTimeMillis();

    }


StandardManager.processExpires()

    /**
     * Invalidate all sessions that have expired.
     */
    private void processExpires() {

        long timeNow = System.currentTimeMillis();
        Session sessions[] = findSessions();

        for (int i = 0; i < sessions.length; i++) {
            StandardSession session = (StandardSession) sessions[i];
            if (!session.isValid())
                continue;
            int maxInactiveInterval = session.getMaxInactiveInterval();
            if (maxInactiveInterval < 0)
                continue;
            int timeIdle = // Truncate, do not round up
                (int) ((timeNow - session.getLastAccessedTime()) / 1000L);
            if (timeIdle >= maxInactiveInterval) {
                try {
                    expiredSessions++;
                    session.expire();
                } catch (Throwable t) {
                    log(sm.getString("standardManager.expireException"), t);
                }
            }
        }

    }

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