]> WPIA git - gigi.git/blob - lib/jetty/org/eclipse/jetty/server/session/AbstractSession.java
Update notes about password security
[gigi.git] / lib / jetty / org / eclipse / jetty / server / session / AbstractSession.java
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
19 package org.eclipse.jetty.server.session;
20
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.Enumeration;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Set;
28
29 import javax.servlet.ServletContext;
30 import javax.servlet.http.HttpServletRequest;
31 import javax.servlet.http.HttpSessionActivationListener;
32 import javax.servlet.http.HttpSessionBindingEvent;
33 import javax.servlet.http.HttpSessionBindingListener;
34 import javax.servlet.http.HttpSessionContext;
35 import javax.servlet.http.HttpSessionEvent;
36
37 import org.eclipse.jetty.server.SessionManager;
38 import org.eclipse.jetty.util.log.Logger;
39
40 /**
41  *
42  * <p>
43  * Implements {@link javax.servlet.http.HttpSession} from the <code>javax.servlet</code> package.
44  * </p>
45  *
46  */
47 @SuppressWarnings("deprecation")
48 public abstract class AbstractSession implements AbstractSessionManager.SessionIf
49 {
50     final static Logger LOG = SessionHandler.LOG;
51     public final static String SESSION_KNOWN_ONLY_TO_AUTHENTICATED="org.eclipse.jetty.security.sessionKnownOnlytoAuthenticated";
52     private  String _clusterId; // ID without any node (ie "worker") id appended
53     private  String _nodeId;    // ID of session with node(ie "worker") id appended
54     private final AbstractSessionManager _manager;
55     private boolean _idChanged;
56     private final long _created;
57     private long _cookieSet;
58     private long _accessed;         // the time of the last access
59     private long _lastAccessed;     // the time of the last access excluding this one
60     private boolean _invalid;
61     private boolean _doInvalidate;
62     private long _maxIdleMs;
63     private boolean _newSession;
64     private int _requests;
65
66
67
68     /* ------------------------------------------------------------- */
69     protected AbstractSession(AbstractSessionManager abstractSessionManager, HttpServletRequest request)
70     {
71         _manager = abstractSessionManager;
72
73         _newSession=true;
74         _created=System.currentTimeMillis();
75         _clusterId=_manager._sessionIdManager.newSessionId(request,_created);
76         _nodeId=_manager._sessionIdManager.getNodeId(_clusterId,request);
77         _accessed=_created;
78         _lastAccessed=_created;
79         _requests=1;
80         _maxIdleMs=_manager._dftMaxIdleSecs>0?_manager._dftMaxIdleSecs*1000L:-1;
81         if (LOG.isDebugEnabled())
82             LOG.debug("new session & id "+_nodeId+" "+_clusterId);
83     }
84
85     /* ------------------------------------------------------------- */
86     protected AbstractSession(AbstractSessionManager abstractSessionManager, long created, long accessed, String clusterId)
87     {
88         _manager = abstractSessionManager;
89         _created=created;
90         _clusterId=clusterId;
91         _nodeId=_manager._sessionIdManager.getNodeId(_clusterId,null);
92         _accessed=accessed;
93         _lastAccessed=accessed;
94         _requests=1;
95         _maxIdleMs=_manager._dftMaxIdleSecs>0?_manager._dftMaxIdleSecs*1000L:-1;
96         if (LOG.isDebugEnabled())
97             LOG.debug("new session "+_nodeId+" "+_clusterId);
98     }
99
100     /* ------------------------------------------------------------- */
101     /**
102      * asserts that the session is valid
103      */
104     protected void checkValid() throws IllegalStateException
105     {
106         if (_invalid)
107             throw new IllegalStateException();
108     }
109     
110     /* ------------------------------------------------------------- */
111     /** Check to see if session has expired as at the time given.
112      * @param time
113      * @return
114      */
115     protected boolean checkExpiry(long time)
116     {
117         if (_maxIdleMs>0 && _lastAccessed>0 && _lastAccessed + _maxIdleMs < time)
118             return true;
119         return false;
120     }
121
122     /* ------------------------------------------------------------- */
123     @Override
124     public AbstractSession getSession()
125     {
126         return this;
127     }
128
129     /* ------------------------------------------------------------- */
130     public long getAccessed()
131     {
132         synchronized (this)
133         {
134             return _accessed;
135         }
136     }
137
138     /* ------------------------------------------------------------- */
139     public abstract Map<String,Object> getAttributeMap();
140
141
142  
143     
144
145     /* ------------------------------------------------------------ */
146     public abstract int getAttributes();
147   
148
149  
150
151     /* ------------------------------------------------------------ */
152     public abstract Set<String> getNames();
153   
154
155     /* ------------------------------------------------------------- */
156     public long getCookieSetTime()
157     {
158         return _cookieSet;
159     }
160
161     /* ------------------------------------------------------------- */
162     @Override
163     public long getCreationTime() throws IllegalStateException
164     {
165         checkValid();
166         return _created;
167     }
168
169     /* ------------------------------------------------------------ */
170     @Override
171     public String getId() throws IllegalStateException
172     {
173         return _manager._nodeIdInSessionId?_nodeId:_clusterId;
174     }
175
176     /* ------------------------------------------------------------- */
177     public String getNodeId()
178     {
179         return _nodeId;
180     }
181
182     /* ------------------------------------------------------------- */
183     public String getClusterId()
184     {
185         return _clusterId;
186     }
187
188     /* ------------------------------------------------------------- */
189     @Override
190     public long getLastAccessedTime() throws IllegalStateException
191     {
192         checkValid();
193         return _lastAccessed;
194     }
195     
196     /* ------------------------------------------------------------- */
197     public void setLastAccessedTime(long time)
198     {
199         _lastAccessed = time;
200     }
201
202     /* ------------------------------------------------------------- */
203     @Override
204     public int getMaxInactiveInterval()
205     {
206         return (int)(_maxIdleMs/1000);
207     }
208
209     /* ------------------------------------------------------------ */
210     /*
211      * @see javax.servlet.http.HttpSession#getServletContext()
212      */
213     @Override
214     public ServletContext getServletContext()
215     {
216         return _manager._context;
217     }
218
219     /* ------------------------------------------------------------- */
220     @Deprecated
221     @Override
222     public HttpSessionContext getSessionContext() throws IllegalStateException
223     {
224         checkValid();
225         return AbstractSessionManager.__nullSessionContext;
226     }
227
228     /* ------------------------------------------------------------- */
229     /**
230      * @deprecated As of Version 2.2, this method is replaced by
231      *             {@link #getAttribute}
232      */
233     @Deprecated
234     @Override
235     public Object getValue(String name) throws IllegalStateException
236     {
237         return getAttribute(name);
238     }
239
240  
241
242     /* ------------------------------------------------------------ */
243     public void renewId(HttpServletRequest request)
244     {
245         _manager._sessionIdManager.renewSessionId(getClusterId(), getNodeId(), request); 
246         setIdChanged(true);
247     }
248        
249     /* ------------------------------------------------------------- */
250     public SessionManager getSessionManager()
251     {
252         return _manager;
253     }
254
255     /* ------------------------------------------------------------ */
256     protected void setClusterId (String clusterId)
257     {
258         _clusterId = clusterId;
259     }
260     
261     /* ------------------------------------------------------------ */
262     protected void setNodeId (String nodeId)
263     {
264         _nodeId = nodeId;
265     }
266     
267
268     /* ------------------------------------------------------------ */
269     protected boolean access(long time)
270     {
271         synchronized(this)
272         {
273             if (_invalid)
274                 return false;
275             _newSession=false;
276             _lastAccessed=_accessed;
277             _accessed=time;
278
279             if (checkExpiry(time))
280             {
281                 invalidate();
282                 return false;
283             }
284             _requests++;
285             return true;
286         }
287     }
288
289     /* ------------------------------------------------------------ */
290     protected void complete()
291     {
292         synchronized(this)
293         {
294             _requests--;
295             if (_doInvalidate && _requests<=0  )
296                 doInvalidate();
297         }
298     }
299
300
301     /* ------------------------------------------------------------- */
302     protected void timeout() throws IllegalStateException
303     {
304         // remove session from context and invalidate other sessions with same ID.
305         _manager.removeSession(this,true);
306
307         // Notify listeners and unbind values
308         boolean do_invalidate=false;
309         synchronized (this)
310         {
311             if (!_invalid)
312             {
313                 if (_requests<=0)
314                     do_invalidate=true;
315                 else
316                     _doInvalidate=true;
317             }
318         }
319         if (do_invalidate)
320             doInvalidate();
321     }
322
323     /* ------------------------------------------------------------- */
324     @Override
325     public void invalidate() throws IllegalStateException
326     {
327         checkValid();
328         // remove session from context and invalidate other sessions with same ID.
329         _manager.removeSession(this,true);
330         doInvalidate();
331     }
332
333     /* ------------------------------------------------------------- */
334     protected void doInvalidate() throws IllegalStateException
335     {
336         try
337         {
338             LOG.debug("invalidate {}",_clusterId);
339             if (isValid())
340                 clearAttributes();
341         }
342         finally
343         {
344             synchronized (this)
345             {
346                 // mark as invalid
347                 _invalid=true;
348             }
349         }
350     }
351
352     /* ------------------------------------------------------------- */
353     public abstract void clearAttributes();
354    
355
356     /* ------------------------------------------------------------- */
357     public boolean isIdChanged()
358     {
359         return _idChanged;
360     }
361
362     /* ------------------------------------------------------------- */
363     @Override
364     public boolean isNew() throws IllegalStateException
365     {
366         checkValid();
367         return _newSession;
368     }
369
370     /* ------------------------------------------------------------- */
371     /**
372      * @deprecated As of Version 2.2, this method is replaced by
373      *             {@link #setAttribute}
374      */
375     @Deprecated
376     @Override
377     public void putValue(java.lang.String name, java.lang.Object value) throws IllegalStateException
378     {
379         changeAttribute(name,value);
380     }
381
382     /* ------------------------------------------------------------ */
383     @Override
384     public void removeAttribute(String name)
385     {
386         setAttribute(name,null);
387     }
388
389     /* ------------------------------------------------------------- */
390     /**
391      * @deprecated As of Version 2.2, this method is replaced by
392      *             {@link #removeAttribute}
393      */
394     @Deprecated
395     @Override
396     public void removeValue(java.lang.String name) throws IllegalStateException
397     {
398         removeAttribute(name);
399     }
400     
401     /* ------------------------------------------------------------ */
402     @SuppressWarnings({ "unchecked" })
403     @Override
404     public Enumeration<String> getAttributeNames()
405     {
406         synchronized (this)
407         {
408             checkValid();
409             return doGetAttributeNames();
410         }
411     }
412     
413     /* ------------------------------------------------------------- */
414     /**
415      * @deprecated As of Version 2.2, this method is replaced by
416      *             {@link #getAttributeNames}
417      */
418     @Deprecated
419     @Override
420     public String[] getValueNames() throws IllegalStateException
421     {
422         synchronized(this)
423         {
424             checkValid();
425             Enumeration<String> anames = doGetAttributeNames();
426             if (anames == null)
427                 return new String[0];
428             ArrayList<String> names = new ArrayList<String>();
429             while (anames.hasMoreElements())
430                 names.add(anames.nextElement());
431             return names.toArray(new String[names.size()]);
432         }
433     }
434     
435
436     /* ------------------------------------------------------------ */
437     public abstract Object doPutOrRemove(String name, Object value);
438  
439
440     /* ------------------------------------------------------------ */
441     public abstract Object doGet(String name);
442     
443     
444     /* ------------------------------------------------------------ */
445     public abstract Enumeration<String> doGetAttributeNames();
446     
447     
448     /* ------------------------------------------------------------ */
449     @Override
450     public Object getAttribute(String name)
451     {
452         synchronized (this)
453         {
454             checkValid();
455             return doGet(name);
456         }
457     }
458    
459
460     /* ------------------------------------------------------------ */
461     @Override
462     public void setAttribute(String name, Object value)
463     {
464         changeAttribute(name,value);
465     }
466     
467     /* ------------------------------------------------------------ */
468     /**
469      * @param name
470      * @param value
471      * @deprecated use changeAttribute(String,Object) instead
472      * @return
473      */
474     protected boolean updateAttribute (String name, Object value)
475     {
476         Object old=null;
477         synchronized (this)
478         {
479             checkValid();
480             old=doPutOrRemove(name,value);
481         }
482
483         if (value==null || !value.equals(old))
484         {
485             if (old!=null)
486                 unbindValue(name,old);
487             if (value!=null)
488                 bindValue(name,value);
489
490             _manager.doSessionAttributeListeners(this,name,old,value);
491             return true;
492         }
493         return false;
494     }
495     
496     
497     /* ------------------------------------------------------------ */
498     /**
499      * Either set (perhaps replace) or remove the value of the attribute
500      * in the session. The appropriate session attribute listeners are
501      * also called.
502      * 
503      * @param name
504      * @param value
505      * @return
506      */
507     protected Object changeAttribute (String name, Object value)
508     {
509         Object old=null;
510         synchronized (this)
511         {
512             checkValid();
513             old=doPutOrRemove(name,value);
514         }
515
516         callSessionAttributeListeners(name, value, old);
517
518         return old;
519     }
520
521     /* ------------------------------------------------------------ */
522     /**
523      * Call binding and attribute listeners based on the new and old
524      * values of the attribute.
525      * 
526      * @param name name of the attribute
527      * @param newValue  new value of the attribute
528      * @param oldValue previous value of the attribute
529      */
530     protected void callSessionAttributeListeners (String name, Object newValue, Object oldValue)
531     {
532         if (newValue==null || !newValue.equals(oldValue))
533         {
534             if (oldValue!=null)
535                 unbindValue(name,oldValue);
536             if (newValue!=null)
537                 bindValue(name,newValue);
538
539             _manager.doSessionAttributeListeners(this,name,oldValue,newValue);
540         }
541     }
542   
543
544     /* ------------------------------------------------------------- */
545     public void setIdChanged(boolean changed)
546     {
547         _idChanged=changed;
548     }
549
550     /* ------------------------------------------------------------- */
551     @Override
552     public void setMaxInactiveInterval(int secs)
553     {
554         _maxIdleMs=(long)secs*1000L;
555     }
556
557     /* ------------------------------------------------------------- */
558     @Override
559     public String toString()
560     {
561         return this.getClass().getName()+":"+getId()+"@"+hashCode();
562     }
563
564     /* ------------------------------------------------------------- */
565     /** If value implements HttpSessionBindingListener, call valueBound() */
566     public void bindValue(java.lang.String name, Object value)
567     {
568         if (value!=null&&value instanceof HttpSessionBindingListener)
569             ((HttpSessionBindingListener)value).valueBound(new HttpSessionBindingEvent(this,name));
570     }
571
572     /* ------------------------------------------------------------ */
573     public boolean isValid()
574     {
575         return !_invalid;
576     }
577
578     /* ------------------------------------------------------------- */
579     protected void cookieSet()
580     {
581         synchronized (this)
582         {
583             _cookieSet=_accessed;
584         }
585     }
586
587     /* ------------------------------------------------------------ */
588     public int getRequests()
589     {
590         synchronized (this)
591         {
592             return _requests;
593         }
594     }
595
596     /* ------------------------------------------------------------ */
597     public void setRequests(int requests)
598     {
599         synchronized (this)
600         {
601             _requests=requests;
602         }
603     }
604
605     /* ------------------------------------------------------------- */
606     /** If value implements HttpSessionBindingListener, call valueUnbound() */
607     public void unbindValue(java.lang.String name, Object value)
608     {
609         if (value!=null&&value instanceof HttpSessionBindingListener)
610             ((HttpSessionBindingListener)value).valueUnbound(new HttpSessionBindingEvent(this,name));
611     }
612
613     /* ------------------------------------------------------------- */
614     public void willPassivate()
615     {
616         synchronized(this)
617         {
618             HttpSessionEvent event = new HttpSessionEvent(this);
619             for (Iterator<Object> iter = getAttributeMap().values().iterator(); iter.hasNext();)
620             {
621                 Object value = iter.next();
622                 if (value instanceof HttpSessionActivationListener)
623                 {
624                     HttpSessionActivationListener listener = (HttpSessionActivationListener) value;
625                     listener.sessionWillPassivate(event);
626                 }
627             }
628         }
629     }
630
631     /* ------------------------------------------------------------- */
632     public void didActivate()
633     {
634         synchronized(this)
635         {
636             HttpSessionEvent event = new HttpSessionEvent(this);
637             for (Iterator<Object> iter = getAttributeMap().values().iterator(); iter.hasNext();)
638             {
639                 Object value = iter.next();
640                 if (value instanceof HttpSessionActivationListener)
641                 {
642                     HttpSessionActivationListener listener = (HttpSessionActivationListener) value;
643                     listener.sessionDidActivate(event);
644                 }
645             }
646         }
647     }
648
649
650 }