View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2016 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  
19  package org.eclipse.jetty.server.session;
20  
21  import java.lang.ref.WeakReference;
22  import java.util.ArrayList;
23  import java.util.Collection;
24  import java.util.Collections;
25  import java.util.HashMap;
26  import java.util.HashSet;
27  import java.util.Iterator;
28  import java.util.Map;
29  import java.util.Random;
30  import java.util.Set;
31  
32  import javax.servlet.http.HttpServletRequest;
33  import javax.servlet.http.HttpSession;
34  
35  import org.eclipse.jetty.server.SessionIdManager;
36  
37  /* ------------------------------------------------------------ */
38  /**
39   * HashSessionIdManager. An in-memory implementation of the session ID manager.
40   */
41  public 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       * @param id the id of the session
68       * @return Collection of Sessions for the passed session ID
69       */
70      public Collection<HttpSession> getSession(String id)
71      {
72          ArrayList<HttpSession> sessions = new ArrayList<HttpSession>();
73          Set<WeakReference<HttpSession>> refs =_sessions.get(id);
74          if (refs!=null)
75          {
76              for (WeakReference<HttpSession> ref: refs)
77              {
78                  HttpSession session = ref.get();
79                  if (session!=null)
80                      sessions.add(session);
81              }
82          }
83          return sessions;
84      }
85      
86      /* ------------------------------------------------------------ */
87      @Override
88      protected void doStart() throws Exception
89      {
90          super.doStart();
91      }
92  
93      /* ------------------------------------------------------------ */
94      @Override
95      protected void doStop() throws Exception
96      {
97          _sessions.clear();
98          super.doStop();
99      }
100 
101     /* ------------------------------------------------------------ */
102     /**
103      * @see SessionIdManager#idInUse(String)
104      */
105     @Override
106     public boolean idInUse(String id)
107     {
108         synchronized (this)
109         {
110             return _sessions.containsKey(id);
111         }
112     }
113 
114     /* ------------------------------------------------------------ */
115     /**
116      * @see SessionIdManager#addSession(HttpSession)
117      */
118     @Override
119     public void addSession(HttpSession session)
120     {
121         String id = getClusterId(session.getId());
122         WeakReference<HttpSession> ref = new WeakReference<HttpSession>(session);
123 
124         synchronized (this)
125         {
126             Set<WeakReference<HttpSession>> sessions = _sessions.get(id);
127             if (sessions==null)
128             {
129                 sessions=new HashSet<WeakReference<HttpSession>>();
130                 _sessions.put(id,sessions);
131             }
132             sessions.add(ref);
133         }
134     }
135 
136     /* ------------------------------------------------------------ */
137     /**
138      * @see SessionIdManager#removeSession(HttpSession)
139      */
140     @Override
141     public void removeSession(HttpSession session)
142     {
143         String id = getClusterId(session.getId());
144 
145         synchronized (this)
146         {
147             Collection<WeakReference<HttpSession>> sessions = _sessions.get(id);
148             if (sessions!=null)
149             {
150                 for (Iterator<WeakReference<HttpSession>> iter = sessions.iterator(); iter.hasNext();)
151                 {
152                     WeakReference<HttpSession> ref = iter.next();
153                     HttpSession s=ref.get();
154                     if (s==null)
155                     {
156                         iter.remove();
157                         continue;
158                     }
159                     if (s==session)
160                     {
161                         iter.remove();
162                         break;
163                     }
164                 }
165                 if (sessions.isEmpty())
166                     _sessions.remove(id);
167             }
168         }
169     }
170 
171     /* ------------------------------------------------------------ */
172     /**
173      * @see SessionIdManager#invalidateAll(String)
174      */
175     @Override
176     public void invalidateAll(String id)
177     {
178         Collection<WeakReference<HttpSession>> sessions;
179         synchronized (this)
180         {
181             sessions = _sessions.remove(id);
182         }
183 
184         if (sessions!=null)
185         {
186             for (WeakReference<HttpSession> ref: sessions)
187             {
188                 AbstractSession session=(AbstractSession)ref.get();
189                 if (session!=null && session.isValid())
190                     session.invalidate();
191             }
192             sessions.clear();
193         }
194     }
195     
196     
197     /* ------------------------------------------------------------ */
198     @Override
199     public void renewSessionId (String oldClusterId, String oldNodeId, HttpServletRequest request)
200     {
201         //generate a new id
202         String newClusterId = newSessionId(request.hashCode());
203 
204 
205         synchronized (this)
206         {
207             Set<WeakReference<HttpSession>> sessions = _sessions.remove(oldClusterId); //get the list of sessions with same id from other contexts
208             if (sessions!=null)
209             {
210                 for (Iterator<WeakReference<HttpSession>> iter = sessions.iterator(); iter.hasNext();)
211                 {
212                     WeakReference<HttpSession> ref = iter.next();
213                     HttpSession s = ref.get();
214                     if (s == null)
215                     {
216                         continue;
217                     }
218                     else
219                     {
220                         if (s instanceof AbstractSession)
221                         {
222                             AbstractSession abstractSession = (AbstractSession)s;
223                             abstractSession.getSessionManager().renewSessionId(oldClusterId, oldNodeId, newClusterId, getNodeId(newClusterId, request));
224                         }
225                     }
226                 }
227                 _sessions.put(newClusterId, sessions);
228             }
229         }
230     }
231 
232 }