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