由于项目中涉及Session的实现, 简单的看了一下Tomcat的Session实现。 StandardManager.java /** * The background thread that checks for session timeouts and shutdown. */ public void run() ...{ // Loop until the termination semaphore is set while (!threadDone) ...{ threadSleep(); processExpires(); // 遍历所有session, 终止失效超时的session } } /** *//** * 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.getLastUsedTime()) / 1000L); if (timeIdle >= maxInactiveInterval) ...{ try ...{ expiredSessions++; session.expire(); // 终止超时的session } catch (Throwable t) ...{ log(sm.getString("standardManager.expireException"), t); } } } }
/** * Perform the internal processing required to invalidate this session, * without triggering an exception if the session has already expired. * * @param notify Should we notify listeners about the demise of * this session? */ public void expire(boolean notify) ...{ // Mark this session as "being expired" if needed if (expiring) return; expiring = true; setValid(false); // Remove this session from our manager''s active sessions if (manager != null) manager.remove(this); // 在StandardManager中删除该session // Unbind any objects associated with this session String keys[] = keys(); for (int i = 0; i < keys.length; i++) removeAttribute(keys[i], notify); //删除所有属性 // Notify interested session event listeners if (notify) ...{ fireSessionEvent(Session.SESSION_DESTROYED_EVENT, null); //触发session listener } // Notify interested application event listeners // FIXME - Assumes we call listeners in reverse order Context context = (Context) manager.getContainer(); Object listeners[] = context.getApplicationListeners(); if (notify && (listeners != null)) ...{ HttpSessionEvent event = new HttpSessionEvent(getSession()); for (int i = 0; i < listeners.length; i++) ...{ int j = (listeners.length - 1) - i; if (!(listeners[j] instanceof HttpSessionListener)) continue; HttpSessionListener listener = (HttpSessionListener) listeners[j]; try ...{ fireContainerEvent(context, "beforeSessionDestroyed", listener); listener.sessionDestroyed(event); fireContainerEvent(context, "afterSessionDestroyed", listener); } catch (Throwable t) ...{ try ...{ fireContainerEvent(context, "afterSessionDestroyed", listener); } catch (Exception e) ...{ ; } // FIXME - should we do anything besides log these? log(sm.getString("standardSession.sessionEvent"), t); } } } // We have completed expire of this session expiring = false; if ((manager != null) && (manager instanceof ManagerBase)) ...{ recycle(); } } 创建session的代码在ManagerBase里实现,ManagerBase是StandardManager的父类 /** * Construct and return a new session object, based on the default * settings specified by this Manager''s properties. The session * id will be assigned by this method, and available via the getId() * method of the returned session. If a new session cannot be created * for any reason, return <code>null</code>. * * @exception IllegalStateException if a new session cannot be * instantiated for any reason */ public Session createSession() { // Recycle or create a Session instance Session session = createEmptySession(); // Initialize the properties of the new session and return it session.setNew(true); session.setValid(true); session.setCreationTime(System.currentTimeMillis()); session.setMaxInactiveInterval(this.maxInactiveInterval); String sessionId = generateSessionId(); String jvmRoute = getJvmRoute(); // @todo Move appending of jvmRoute generateSessionId()??? if (jvmRoute != null) { sessionId += ''.'' + jvmRoute; } synchronized (sessions) { while (sessions.get(sessionId) != null){ // Guarantee uniqueness sessionId = generateSessionId(); duplicates++; // @todo Move appending of jvmRoute generateSessionId()??? if (jvmRoute != null) { sessionId += ''.'' + jvmRoute; } } } session.setId(sessionId); sessionCounter++; return (session); } /** * Generate and return a new session identifier. */ protected synchronized String generateSessionId() { // Generate a byte array containing a session identifier Random random = getRandom(); // 取随机数发生器, 默认是SecureRandom byte bytes[] = new byte[SESSION_ID_BYTES]; getRandom().nextBytes(bytes); //产生16字节的byte bytes = getDigest().digest(bytes); // 取摘要,默认是"MD5"算法 // Render the result as a String of hexadecimal digits StringBuffer result = new StringBuffer(); for (int i = 0; i < bytes.length; i++) { //转化为16进制字符串 byte b1 = (byte) ((bytes[i] & 0xf0) >> 4); byte b2 = (byte) (bytes[i] & 0x0f); if (b1 < 10) result.append((char) (''0'' + b1)); else result.append((char) (''A'' + (b1 - 10))); if (b2 < 10) result.append((char) (''0'' + b2)); else result.append((char) (''A'' + (b2 - 10))); } return (result.toString()); } |
|
来自: CevenCheng > 《Web安全-黑客》