/* * Copyright 2011 Martin Grotzke * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package de.javakaffee.web.msm; import static de.javakaffee.web.msm.TranscoderService.decodeNum; import static de.javakaffee.web.msm.TranscoderService.encodeNum; import javax.annotation.Nonnull; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; /** * This class defines the format for session validity information stored in memcached for * non-sticky sessions. This information is used when the container (CoyoteAdapter) tries to * determine if a provided sessionId is valid when parsing the request. * <p> * The stored information contains the maxInactiveInterval (might be session specific), * lastAccessedTime (used by tomcat7 with STRICT_SERVLET_COMPLIANCE/LAST_ACCESS_AT_START) and * thisAccessedTime. * </p> * * @author <a href="mailto:martin.grotzke@javakaffee.de">Martin Grotzke</a> */ public class SessionValidityInfo { @SuppressWarnings( "unused" ) private static final Log LOG = LogFactory.getLog( SessionValidityInfo.class ); private final int _maxInactiveInterval; private final long _lastAccessedTime; private final long _thisAccessedTime; public SessionValidityInfo( final int maxInactiveInterval, final long lastAccessedTime, final long thisAccessedTime ) { _maxInactiveInterval = maxInactiveInterval; _lastAccessedTime = lastAccessedTime; _thisAccessedTime = thisAccessedTime; } /** * Encode the given information to a byte[], that can be decoded later via {@link #decode(byte[])}. */ @Nonnull public static byte[] encode( final long maxInactiveInterval, final long lastAccessedTime, final long thisAccessedTime ) { int idx = 0; final byte[] data = new byte[ 4 + 2 * 8 ]; encodeNum( maxInactiveInterval, data, idx, 4 ); encodeNum( lastAccessedTime, data, idx += 4, 8 ); encodeNum( thisAccessedTime, data, idx += 8, 8 ); return data; } /** * Decode the given byte[] that previously was created via {@link #encode(long, long, long)}. */ @Nonnull public static SessionValidityInfo decode( @Nonnull final byte[] data ) { int idx = 0; final int maxInactiveInterval = (int) decodeNum( data, idx, 4 ); final long lastAccessedTime = decodeNum( data, idx += 4, 8 ); final long thisAccessedTime = decodeNum( data, idx += 8, 8 ); return new SessionValidityInfo( maxInactiveInterval, lastAccessedTime, thisAccessedTime ); } public int getMaxInactiveInterval() { return _maxInactiveInterval; } public long getLastAccessedTime() { return _lastAccessedTime; } public long getThisAccessedTime() { return _thisAccessedTime; } public boolean isValid() { final long timeNow = System.currentTimeMillis(); final int timeIdle = (int) ((timeNow - _thisAccessedTime) / 1000L); // if tomcat session inactivity is negative or 0, session // should not expire return _maxInactiveInterval <= 0 || timeIdle < _maxInactiveInterval; } }