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 setAttribute(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 updateAttribute(name,value);
485 }
486
487
488 protected boolean updateAttribute (String name, Object value)
489 {
490 Object old=null;
491 synchronized (this)
492 {
493 checkValid();
494 old=doPutOrRemove(name,value);
495 }
496
497 if (value==null || !value.equals(old))
498 {
499 if (old!=null)
500 unbindValue(name,old);
501 if (value!=null)
502 bindValue(name,value);
503
504 _manager.doSessionAttributeListeners(this,name,old,value);
505 return true;
506 }
507 return false;
508 }
509
510
511 protected void addAttributes(Map<String,Object> map)
512 {
513 _attributes.putAll(map);
514 }
515
516
517 public void setIdChanged(boolean changed)
518 {
519 _idChanged=changed;
520 }
521
522
523 @Override
524 public void setMaxInactiveInterval(int secs)
525 {
526 _maxIdleMs=(long)secs*1000L;
527 }
528
529
530 @Override
531 public String toString()
532 {
533 return this.getClass().getName()+":"+getId()+"@"+hashCode();
534 }
535
536
537
538 public void bindValue(java.lang.String name, Object value)
539 {
540 if (value!=null&&value instanceof HttpSessionBindingListener)
541 ((HttpSessionBindingListener)value).valueBound(new HttpSessionBindingEvent(this,name));
542 }
543
544
545 public boolean isValid()
546 {
547 return !_invalid;
548 }
549
550
551 protected void cookieSet()
552 {
553 synchronized (this)
554 {
555 _cookieSet=_accessed;
556 }
557 }
558
559
560 public int getRequests()
561 {
562 synchronized (this)
563 {
564 return _requests;
565 }
566 }
567
568
569 public void setRequests(int requests)
570 {
571 synchronized (this)
572 {
573 _requests=requests;
574 }
575 }
576
577
578
579 public void unbindValue(java.lang.String name, Object value)
580 {
581 if (value!=null&&value instanceof HttpSessionBindingListener)
582 ((HttpSessionBindingListener)value).valueUnbound(new HttpSessionBindingEvent(this,name));
583 }
584
585
586 public void willPassivate()
587 {
588 synchronized(this)
589 {
590 HttpSessionEvent event = new HttpSessionEvent(this);
591 for (Iterator<Object> iter = _attributes.values().iterator(); iter.hasNext();)
592 {
593 Object value = iter.next();
594 if (value instanceof HttpSessionActivationListener)
595 {
596 HttpSessionActivationListener listener = (HttpSessionActivationListener) value;
597 listener.sessionWillPassivate(event);
598 }
599 }
600 }
601 }
602
603
604 public void didActivate()
605 {
606 synchronized(this)
607 {
608 HttpSessionEvent event = new HttpSessionEvent(this);
609 for (Iterator<Object> iter = _attributes.values().iterator(); iter.hasNext();)
610 {
611 Object value = iter.next();
612 if (value instanceof HttpSessionActivationListener)
613 {
614 HttpSessionActivationListener listener = (HttpSessionActivationListener) value;
615 listener.sessionDidActivate(event);
616 }
617 }
618 }
619 }
620
621
622 }