1// 2// ======================================================================== 3// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. 4// ------------------------------------------------------------------------ 5// All rights reserved. This program and the accompanying materials 6// are made available under the terms of the Eclipse Public License v1.0 7// and Apache License v2.0 which accompanies this distribution. 8// 9// The Eclipse Public License is available at 10// http://www.eclipse.org/legal/epl-v10.html 11// 12// The Apache License v2.0 is available at 13// http://www.opensource.org/licenses/apache2.0.php 14// 15// You may elect to redistribute this code under either of these licenses. 16// ======================================================================== 17// 18 19package org.eclipse.jetty.server.session; 20 21import java.lang.ref.WeakReference; 22import java.util.ArrayList; 23import java.util.Collection; 24import java.util.Collections; 25import java.util.HashMap; 26import java.util.HashSet; 27import java.util.Iterator; 28import java.util.Map; 29import java.util.Random; 30import java.util.Set; 31 32import javax.servlet.http.HttpServletRequest; 33import javax.servlet.http.HttpSession; 34 35import org.eclipse.jetty.server.SessionIdManager; 36 37/* ------------------------------------------------------------ */ 38/** 39 * HashSessionIdManager. An in-memory implementation of the session ID manager. 40 */ 41public class HashSessionIdManager extends AbstractSessionIdManager 42{ 43 private final Map<String, Set<WeakReference<HttpSession>>> _sessions = new HashMap<String, Set<WeakReference<HttpSession>>>(); 44 45 /* ------------------------------------------------------------ */ 46 public HashSessionIdManager() 47 { 48 } 49 50 /* ------------------------------------------------------------ */ 51 public HashSessionIdManager(Random random) 52 { 53 super(random); 54 } 55 56 /* ------------------------------------------------------------ */ 57 /** 58 * @return Collection of String session IDs 59 */ 60 public Collection<String> getSessions() 61 { 62 return Collections.unmodifiableCollection(_sessions.keySet()); 63 } 64 65 /* ------------------------------------------------------------ */ 66 /** 67 * @return Collection of Sessions for the passed session ID 68 */ 69 public Collection<HttpSession> getSession(String id) 70 { 71 ArrayList<HttpSession> sessions = new ArrayList<HttpSession>(); 72 Set<WeakReference<HttpSession>> refs =_sessions.get(id); 73 if (refs!=null) 74 { 75 for (WeakReference<HttpSession> ref: refs) 76 { 77 HttpSession session = ref.get(); 78 if (session!=null) 79 sessions.add(session); 80 } 81 } 82 return sessions; 83 } 84 /* ------------------------------------------------------------ */ 85 /** Get the session ID with any worker ID. 86 * 87 * @param clusterId 88 * @param request 89 * @return sessionId plus any worker ID. 90 */ 91 public String getNodeId(String clusterId,HttpServletRequest request) 92 { 93 // used in Ajp13Parser 94 String worker=request==null?null:(String)request.getAttribute("org.eclipse.jetty.ajp.JVMRoute"); 95 if (worker!=null) 96 return clusterId+'.'+worker; 97 98 if (_workerName!=null) 99 return clusterId+'.'+_workerName; 100 101 return clusterId; 102 } 103 104 /* ------------------------------------------------------------ */ 105 /** Get the session ID without any worker ID. 106 * 107 * @param nodeId the node id 108 * @return sessionId without any worker ID. 109 */ 110 public String getClusterId(String nodeId) 111 { 112 int dot=nodeId.lastIndexOf('.'); 113 return (dot>0)?nodeId.substring(0,dot):nodeId; 114 } 115 116 /* ------------------------------------------------------------ */ 117 @Override 118 protected void doStart() throws Exception 119 { 120 super.doStart(); 121 } 122 123 /* ------------------------------------------------------------ */ 124 @Override 125 protected void doStop() throws Exception 126 { 127 _sessions.clear(); 128 super.doStop(); 129 } 130 131 /* ------------------------------------------------------------ */ 132 /** 133 * @see SessionIdManager#idInUse(String) 134 */ 135 public boolean idInUse(String id) 136 { 137 synchronized (this) 138 { 139 return _sessions.containsKey(id); 140 } 141 } 142 143 /* ------------------------------------------------------------ */ 144 /** 145 * @see SessionIdManager#addSession(HttpSession) 146 */ 147 public void addSession(HttpSession session) 148 { 149 String id = getClusterId(session.getId()); 150 WeakReference<HttpSession> ref = new WeakReference<HttpSession>(session); 151 152 synchronized (this) 153 { 154 Set<WeakReference<HttpSession>> sessions = _sessions.get(id); 155 if (sessions==null) 156 { 157 sessions=new HashSet<WeakReference<HttpSession>>(); 158 _sessions.put(id,sessions); 159 } 160 sessions.add(ref); 161 } 162 } 163 164 /* ------------------------------------------------------------ */ 165 /** 166 * @see SessionIdManager#removeSession(HttpSession) 167 */ 168 public void removeSession(HttpSession session) 169 { 170 String id = getClusterId(session.getId()); 171 172 synchronized (this) 173 { 174 Collection<WeakReference<HttpSession>> sessions = _sessions.get(id); 175 if (sessions!=null) 176 { 177 for (Iterator<WeakReference<HttpSession>> iter = sessions.iterator(); iter.hasNext();) 178 { 179 WeakReference<HttpSession> ref = iter.next(); 180 HttpSession s=ref.get(); 181 if (s==null) 182 { 183 iter.remove(); 184 continue; 185 } 186 if (s==session) 187 { 188 iter.remove(); 189 break; 190 } 191 } 192 if (sessions.isEmpty()) 193 _sessions.remove(id); 194 } 195 } 196 } 197 198 /* ------------------------------------------------------------ */ 199 /** 200 * @see SessionIdManager#invalidateAll(String) 201 */ 202 public void invalidateAll(String id) 203 { 204 Collection<WeakReference<HttpSession>> sessions; 205 synchronized (this) 206 { 207 sessions = _sessions.remove(id); 208 } 209 210 if (sessions!=null) 211 { 212 for (WeakReference<HttpSession> ref: sessions) 213 { 214 AbstractSession session=(AbstractSession)ref.get(); 215 if (session!=null && session.isValid()) 216 session.invalidate(); 217 } 218 sessions.clear(); 219 } 220 } 221 222} 223