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 checkValid();
230 return (int)(_maxIdleMs/1000);
231 }
232
233
234
235
236
237 @Override
238 public ServletContext getServletContext()
239 {
240 return _manager._context;
241 }
242
243
244 @Deprecated
245 @Override
246 public HttpSessionContext getSessionContext() throws IllegalStateException
247 {
248 checkValid();
249 return AbstractSessionManager.__nullSessionContext;
250 }
251
252
253
254
255
256
257 @Deprecated
258 @Override
259 public Object getValue(String name) throws IllegalStateException
260 {
261 return getAttribute(name);
262 }
263
264
265
266
267
268
269 @Deprecated
270 @Override
271 public String[] getValueNames() throws IllegalStateException
272 {
273 synchronized(this)
274 {
275 checkValid();
276 if (_attributes==null)
277 return new String[0];
278 String[] a=new String[_attributes.size()];
279 return (String[])_attributes.keySet().toArray(a);
280 }
281 }
282
283
284
285 public void renewId(HttpServletRequest request)
286 {
287 _manager._sessionIdManager.renewSessionId(getClusterId(), getNodeId(), request);
288 setIdChanged(true);
289 }
290
291
292 public SessionManager getSessionManager()
293 {
294 return _manager;
295 }
296
297
298 protected void setClusterId (String clusterId)
299 {
300 _clusterId = clusterId;
301 }
302
303
304 protected void setNodeId (String nodeId)
305 {
306 _nodeId = nodeId;
307 }
308
309
310
311 protected boolean access(long time)
312 {
313 synchronized(this)
314 {
315 if (_invalid)
316 return false;
317 _newSession=false;
318 _lastAccessed=_accessed;
319 _accessed=time;
320
321 if (_maxIdleMs>0 && _lastAccessed>0 && _lastAccessed + _maxIdleMs < time)
322 {
323 invalidate();
324 return false;
325 }
326 _requests++;
327 return true;
328 }
329 }
330
331
332 protected void complete()
333 {
334 synchronized(this)
335 {
336 _requests--;
337 if (_doInvalidate && _requests<=0 )
338 doInvalidate();
339 }
340 }
341
342
343
344 protected void timeout() throws IllegalStateException
345 {
346
347 _manager.removeSession(this,true);
348
349
350 boolean do_invalidate=false;
351 synchronized (this)
352 {
353 if (!_invalid)
354 {
355 if (_requests<=0)
356 do_invalidate=true;
357 else
358 _doInvalidate=true;
359 }
360 }
361 if (do_invalidate)
362 doInvalidate();
363 }
364
365
366 @Override
367 public void invalidate() throws IllegalStateException
368 {
369 checkValid();
370
371 _manager.removeSession(this,true);
372 doInvalidate();
373 }
374
375
376 protected void doInvalidate() throws IllegalStateException
377 {
378 try
379 {
380 LOG.debug("invalidate {}",_clusterId);
381 if (isValid())
382 clearAttributes();
383 }
384 finally
385 {
386 synchronized (this)
387 {
388
389 _invalid=true;
390 }
391 }
392 }
393
394
395 public void clearAttributes()
396 {
397 while (_attributes!=null && _attributes.size()>0)
398 {
399 ArrayList<String> keys;
400 synchronized(this)
401 {
402 keys=new ArrayList<String>(_attributes.keySet());
403 }
404
405 Iterator<String> iter=keys.iterator();
406 while (iter.hasNext())
407 {
408 String key=(String)iter.next();
409
410 Object value;
411 synchronized(this)
412 {
413 value=doPutOrRemove(key,null);
414 }
415 unbindValue(key,value);
416
417 _manager.doSessionAttributeListeners(this,key,value,null);
418 }
419 }
420 if (_attributes!=null)
421 _attributes.clear();
422 }
423
424
425 public boolean isIdChanged()
426 {
427 return _idChanged;
428 }
429
430
431 @Override
432 public boolean isNew() throws IllegalStateException
433 {
434 checkValid();
435 return _newSession;
436 }
437
438
439
440
441
442
443 @Deprecated
444 @Override
445 public void putValue(java.lang.String name, java.lang.Object value) throws IllegalStateException
446 {
447 setAttribute(name,value);
448 }
449
450
451 @Override
452 public void removeAttribute(String name)
453 {
454 setAttribute(name,null);
455 }
456
457
458
459
460
461
462 @Deprecated
463 @Override
464 public void removeValue(java.lang.String name) throws IllegalStateException
465 {
466 removeAttribute(name);
467 }
468
469
470 protected Object doPutOrRemove(String name, Object value)
471 {
472 return value==null?_attributes.remove(name):_attributes.put(name,value);
473 }
474
475
476 protected Object doGet(String name)
477 {
478 return _attributes.get(name);
479 }
480
481
482 @Override
483 public void setAttribute(String name, Object value)
484 {
485 updateAttribute(name,value);
486 }
487
488
489 protected boolean updateAttribute (String name, Object value)
490 {
491 Object old=null;
492 synchronized (this)
493 {
494 checkValid();
495 old=doPutOrRemove(name,value);
496 }
497
498 if (value==null || !value.equals(old))
499 {
500 if (old!=null)
501 unbindValue(name,old);
502 if (value!=null)
503 bindValue(name,value);
504
505 _manager.doSessionAttributeListeners(this,name,old,value);
506 return true;
507 }
508 return false;
509 }
510
511
512 protected void addAttributes(Map<String,Object> map)
513 {
514 _attributes.putAll(map);
515 }
516
517
518 public void setIdChanged(boolean changed)
519 {
520 _idChanged=changed;
521 }
522
523
524 @Override
525 public void setMaxInactiveInterval(int secs)
526 {
527 _maxIdleMs=(long)secs*1000L;
528 }
529
530
531 @Override
532 public String toString()
533 {
534 return this.getClass().getName()+":"+getId()+"@"+hashCode();
535 }
536
537
538
539 public void bindValue(java.lang.String name, Object value)
540 {
541 if (value!=null&&value instanceof HttpSessionBindingListener)
542 ((HttpSessionBindingListener)value).valueBound(new HttpSessionBindingEvent(this,name));
543 }
544
545
546 public boolean isValid()
547 {
548 return !_invalid;
549 }
550
551
552 protected void cookieSet()
553 {
554 synchronized (this)
555 {
556 _cookieSet=_accessed;
557 }
558 }
559
560
561 public int getRequests()
562 {
563 synchronized (this)
564 {
565 return _requests;
566 }
567 }
568
569
570 public void setRequests(int requests)
571 {
572 synchronized (this)
573 {
574 _requests=requests;
575 }
576 }
577
578
579
580 public void unbindValue(java.lang.String name, Object value)
581 {
582 if (value!=null&&value instanceof HttpSessionBindingListener)
583 ((HttpSessionBindingListener)value).valueUnbound(new HttpSessionBindingEvent(this,name));
584 }
585
586
587 public void willPassivate()
588 {
589 synchronized(this)
590 {
591 HttpSessionEvent event = new HttpSessionEvent(this);
592 for (Iterator<Object> iter = _attributes.values().iterator(); iter.hasNext();)
593 {
594 Object value = iter.next();
595 if (value instanceof HttpSessionActivationListener)
596 {
597 HttpSessionActivationListener listener = (HttpSessionActivationListener) value;
598 listener.sessionWillPassivate(event);
599 }
600 }
601 }
602 }
603
604
605 public void didActivate()
606 {
607 synchronized(this)
608 {
609 HttpSessionEvent event = new HttpSessionEvent(this);
610 for (Iterator<Object> iter = _attributes.values().iterator(); iter.hasNext();)
611 {
612 Object value = iter.next();
613 if (value instanceof HttpSessionActivationListener)
614 {
615 HttpSessionActivationListener listener = (HttpSessionActivationListener) value;
616 listener.sessionDidActivate(event);
617 }
618 }
619 }
620 }
621
622
623 }