sessionmanager.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 1,493 行 · 第 1/3 页
JAVA
1,493 行
} /** * Returns the session store. */ public Store getSessionStore() { return _sessionStore; } /** * Returns true if the session exists in this manager. */ public boolean containsSession(String id) { return _sessions.get(id) != null; } /** * Create a new session. * * @param oldId the id passed to the request. Reuse if possible. * @param now the current date * @param sessionGroup the srun index for this machine */ public SessionImpl createSession(String oldId, long now, HttpServletRequest request, boolean fromCookie) { String id = oldId; if (id == null || id.length() < 4 || ! reuseSessionId(fromCookie)) { // server/0175 // || ! _objectManager.isInSessionGroup(id) id = createSessionId(request, true); } SessionImpl session = create(id, now, true); if (session == null) return null; session.addUse(); synchronized (_statisticsLock) { _sessionCreateCount++; } synchronized (session) { if (_sessionStore != null && id.equals(oldId)) load(session, now, true); else session.create(now, true); } // after load so a reset doesn't clear any setting handleCreateListeners(session); return session; } /** * Creates a pseudo-random session id. If there's an old id and the * group matches, then use it because different webApps on the * same matchine should use the same cookie. * * @param sessionGroup possibly assigned by the web server */ public String createSessionId(HttpServletRequest request) { return createSessionId(request, false); } /** * Creates a pseudo-random session id. If there's an old id and the * group matches, then use it because different webApps on the * same machine should use the same cookie. * * @param sessionGroup possibly assigned by the web server */ public String createSessionId(HttpServletRequest request, boolean create) { String id; do { id = createSessionIdImpl(request); } while (create && getSession(id, 0, create, true) != null); if (id == null || id.equals("")) throw new RuntimeException(); return id; } public String createSessionIdImpl(HttpServletRequest request) { StringBuilder sb = new StringBuilder(); // this section is the host specific session index // the most random bit is the high bit int index = _selfIndex; // look at caucho.session-server-id for a hint of the owner Object owner = request.getAttribute("caucho.session-server-id"); if (owner == null) { } else if (owner instanceof Number) { index = ((Number) owner).intValue(); } else if (owner instanceof String) { ClusterServer server = _cluster.getServer((String) owner); if (server != null) index = server.getIndex(); } if (index < 0) index = 0; _cluster.generateBackup(sb, index); int length = _cookieLength; length -= sb.length(); long random = RandomUtil.getRandomLong(); for (int i = 0; i < 11 && length-- > 0; i++) { sb.append(convert(random)); random = random >> 6; } if (length > 0) { long time = Alarm.getCurrentTime(); for (int i = 0; i < 7 && length-- > 0; i++) { sb.append(convert(time)); time = time >> 6; } } while (length > 0) { random = RandomUtil.getRandomLong(); for (int i = 0; i < 11 && length-- > 0; i++) { sb.append(convert(random)); random = random >> 6; } } if (_isAppendServerIndex) { sb.append('.'); sb.append((index + 1)); } return sb.toString(); } /** * Returns a session from the session store, returning null if there's * no cached session. * * @param key the session id * @param now the time in milliseconds * * @return the cached session. */ public SessionImpl getSession(String key, long now, boolean create, boolean fromCookie) { SessionImpl session; boolean isNew = false; boolean killSession = false; if (_sessions == null) return null; session = _sessions.get(key); if (session != null && ! session.getId().equals(key)) throw new IllegalStateException(key + " != " + session.getId()); if (now <= 0) // just generating id return session; if (session != null && ! session.addUse()) { session = null; } if (session == null && _sessionStore != null) { if (! _objectManager.isInSessionGroup(key)) return null; session = create(key, now, create); if (! session.addUse()) session = null; isNew = true; } if (session == null) return null; if (isNew) { killSession = ! load(session, now, create); isNew = killSession; } else if (! session.load()) { // if the load failed, then the session died out from underneath session.reset(now); isNew = true; } if (killSession && (! create || ! reuseSessionId(fromCookie))) { // XXX: session.setClosed(); session.endUse(); _sessions.remove(key); // XXX: session._isValid = false; return null; } else if (isNew) handleCreateListeners(session); else session.setAccess(now); return session; } /** * Creates a session. It's already been established that the * key does not currently have a session. */ private SessionImpl create(String key, long now, boolean isCreate) { SessionImpl session = new SessionImpl(this, key, now); /* Store sessionStore = _sessionStore; if (sessionStore != null) { ClusterObject clusterObject = sessionStore.createClusterObject(key); session.setClusterObject(clusterObject); } */ // If another thread has created and stored a new session, // putIfNew will return the old session session = _sessions.putIfNew(key, session); if (! key.equals(session.getId())) throw new IllegalStateException(key + " != " + session.getId()); return session; } /** * Notification from the cluster. */ public void notifyRemove(String id) { SessionImpl session = _sessions.get(id); if (session != null) session.invalidateRemote(); } private void handleCreateListeners(SessionImpl session) { if (_listeners != null) { HttpSessionEvent event = new HttpSessionEvent(session); for (int i = 0; i < _listeners.size(); i++) { HttpSessionListener listener = _listeners.get(i); listener.sessionCreated(event); } } } /** * Loads the session from the backing store. The caller must synchronize * the session. * * @param session the session to load. * @param now current time in milliseconds. */ private boolean load(SessionImpl session, long now, boolean isCreate) { try { // XXX: session.setNeedsLoad(false); /* if (session.getUseCount() > 1) { // if used by more than just us, return true; } else*/ if (now <= 0) { return false; } else if (session.load()) { session.setAccess(now); return true; } else { session.create(now, isCreate); } } catch (Exception e) { log.log(Level.FINE, e.toString(), e); session.reset(now); } return false; } /** * Adds a session from the cache. */ void addSession(SessionImpl session) { _sessions.put(session.getId(), session); } /** * Removes a session from the cache. */ void removeSession(SessionImpl session) { _sessions.remove(session.getId()); } /** * Timeout for reaping old sessions * * @return number of live sessions for stats */ public void handleAlarm(Alarm alarm) { try { _sessionList.clear(); int liveSessions = 0; if (_isClosed) return; long now = Alarm.getCurrentTime(); long accessWindow = 0; if (_sessionStore != null) accessWindow = _sessionStore.getAccessWindowTime(); synchronized (_sessions) { _sessionIter = _sessions.values(_sessionIter); while (_sessionIter.hasNext()) { SessionImpl session = _sessionIter.next(); long maxIdleTime = session._maxInactiveInterval + accessWindow; if (session.inUse()) liveSessions++; else if (session._accessTime + maxIdleTime < now) _sessionList.add(session); else liveSessions++; } } synchronized (_statisticsLock) { _sessionTimeoutCount += _sessionList.size(); } for (int i = 0; i < _sessionList.size(); i++) { SessionImpl session = _sessionList.get(i); try { if (! session.isValid()) continue; if (_storeManager == null) { // if no persistent store then invalidate // XXX: server/12cg - single signon shouldn't logout session.invalidateTimeout(); } else if (session.getSrunIndex() != _selfIndex && _selfIndex >= 0) { if (log.isLoggable(Level.FINE)) log.fine(session + " timeout (backup)"); // if not the owner, then just remove _sessions.remove(session.getId()); } else { session.invalidateTimeout(); } } catch (Throwable e) { log.log(Level.FINE, e.toString(), e); } } } finally { if (! _isClosed) _alarm.queue(60000); } } /** * Cleans up the sessions when the WebApp shuts down gracefully. */ public void close() { synchronized (this) { if (_isClosed) return; _isClosed = true; } if (_sessions == null) return; _alarm.dequeue(); ArrayList<SessionImpl> list = new ArrayList<SessionImpl>(); boolean isError = false; // XXX: messy way of dealing with saveOnlyOnShutdown synchronized (_sessions) { _sessionIter = _sessions.values(_sessionIter); while (_sessionIter.hasNext()) { SessionImpl session = _sessionIter.next(); if (session.isValid()) list.add(session); } // XXX: if cleared here, will remove the session // _sessions.clear(); } for (int i = list.size() - 1; i >= 0; i--) { SessionImpl session = list.get(i); if (log.isLoggable(Level.FINE)) log.fine("close session " + session.getId()); try { if (session.isValid()) { synchronized (session) { // server/016i, server/018x if (! session.isEmpty()) session.saveOnShutdown(); } } _sessions.remove(session.getId()); } catch (Exception e) { if (! isError) log.log(Level.WARNING, "Can't store session: " + e, e); isError = true; } } if (_admin != null) _admin.unregister(); _sessionList = new ArrayList<SessionImpl>(); /* if (_clusterManager != null) _clusterManager.removeContext(_distributionId); */ } /** * Converts an integer to a printable character */ private static char convert(long code) { code = code & 0x3f; if (code < 26) return (char) ('a' + code); else if (code < 52) return (char) ('A' + code - 26); else if (code < 62) return (char) ('0' + code - 52); else if (code == 62) return '_'; else return '-'; } @Override public String toString() { return getClass().getSimpleName() + "[" + _webApp.getContextPath() + "]"; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?