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