comparison src/org/eclipse/jetty/server/session/AbstractSessionManager.java @ 802:3428c60d7cfc

replace jetty jars with source
author Franklin Schmidt <fschmidt@gmail.com>
date Wed, 07 Sep 2016 21:15:48 -0600
parents
children
comparison
equal deleted inserted replaced
801:6a21393191c1 802:3428c60d7cfc
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 static java.lang.Math.round;
22
23 import java.util.Arrays;
24 import java.util.Collections;
25 import java.util.Enumeration;
26 import java.util.EventListener;
27 import java.util.HashSet;
28 import java.util.HashMap;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.Set;
32 import java.util.concurrent.CopyOnWriteArrayList;
33
34 import javax.servlet.ServletRequest;
35 import javax.servlet.SessionCookieConfig;
36 import javax.servlet.SessionTrackingMode;
37 import javax.servlet.http.HttpServletRequest;
38 import javax.servlet.http.HttpSession;
39 import javax.servlet.http.HttpSessionAttributeListener;
40 import javax.servlet.http.HttpSessionBindingEvent;
41 import javax.servlet.http.HttpSessionContext;
42 import javax.servlet.http.HttpSessionEvent;
43 import javax.servlet.http.HttpSessionListener;
44
45 import org.eclipse.jetty.http.HttpCookie;
46 import org.eclipse.jetty.server.AbstractConnector;
47 import org.eclipse.jetty.server.Request;
48 import org.eclipse.jetty.server.Server;
49 import org.eclipse.jetty.server.SessionIdManager;
50 import org.eclipse.jetty.server.SessionManager;
51 import org.eclipse.jetty.server.handler.ContextHandler;
52 import org.eclipse.jetty.util.component.AbstractLifeCycle;
53 import org.eclipse.jetty.util.log.Logger;
54 import org.eclipse.jetty.util.statistic.CounterStatistic;
55 import org.eclipse.jetty.util.statistic.SampleStatistic;
56
57 /* ------------------------------------------------------------ */
58 /**
59 * An Abstract implementation of SessionManager. The partial implementation of
60 * SessionManager interface provides the majority of the handling required to
61 * implement a SessionManager. Concrete implementations of SessionManager based
62 * on AbstractSessionManager need only implement the newSession method to return
63 * a specialised version of the Session inner class that provides an attribute
64 * Map.
65 * <p>
66 */
67 @SuppressWarnings("deprecation")
68 public abstract class AbstractSessionManager extends AbstractLifeCycle implements SessionManager
69 {
70 final static Logger __log = SessionHandler.LOG;
71
72 public Set<SessionTrackingMode> __defaultSessionTrackingModes =
73 Collections.unmodifiableSet(
74 new HashSet<SessionTrackingMode>(
75 Arrays.asList(new SessionTrackingMode[]{SessionTrackingMode.COOKIE,SessionTrackingMode.URL})));
76
77 public final static String SESSION_KNOWN_ONLY_TO_AUTHENTICATED="org.eclipse.jetty.security.sessionKnownOnlytoAuthenticated";
78
79 /* ------------------------------------------------------------ */
80 public final static int __distantFuture=60*60*24*7*52*20;
81
82 static final HttpSessionContext __nullSessionContext=new HttpSessionContext()
83 {
84 public HttpSession getSession(String sessionId)
85 {
86 return null;
87 }
88
89 @SuppressWarnings({ "rawtypes", "unchecked" })
90 public Enumeration getIds()
91 {
92 return Collections.enumeration(Collections.EMPTY_LIST);
93 }
94 };
95
96 private boolean _usingCookies=true;
97
98 /* ------------------------------------------------------------ */
99 // Setting of max inactive interval for new sessions
100 // -1 means no timeout
101 protected int _dftMaxIdleSecs=-1;
102 protected SessionHandler _sessionHandler;
103 protected boolean _httpOnly=false;
104 protected SessionIdManager _sessionIdManager;
105 protected boolean _secureCookies=false;
106 protected boolean _secureRequestOnly=true;
107
108 protected final List<HttpSessionAttributeListener> _sessionAttributeListeners = new CopyOnWriteArrayList<HttpSessionAttributeListener>();
109 protected final List<HttpSessionListener> _sessionListeners= new CopyOnWriteArrayList<HttpSessionListener>();
110
111 protected ClassLoader _loader;
112 protected ContextHandler.Context _context;
113 protected String _sessionCookie=__DefaultSessionCookie;
114 protected String _sessionIdPathParameterName = __DefaultSessionIdPathParameterName;
115 protected String _sessionIdPathParameterNamePrefix =";"+ _sessionIdPathParameterName +"=";
116 protected String _sessionDomain;
117 protected String _sessionPath;
118 protected int _maxCookieAge=-1;
119 protected int _refreshCookieAge;
120 protected boolean _nodeIdInSessionId;
121 protected boolean _checkingRemoteSessionIdEncoding;
122 protected String _sessionComment;
123
124 public Set<SessionTrackingMode> _sessionTrackingModes;
125
126 private boolean _usingURLs;
127
128 protected final CounterStatistic _sessionsStats = new CounterStatistic();
129 protected final SampleStatistic _sessionTimeStats = new SampleStatistic();
130
131
132 /* ------------------------------------------------------------ */
133 public static HttpSession renewSession (HttpServletRequest request, HttpSession httpSession, boolean authenticated)
134 {
135 Map<String,Object> attributes = new HashMap<String, Object>();
136
137 for (Enumeration<String> e=httpSession.getAttributeNames();e.hasMoreElements();)
138 {
139 String name=e.nextElement();
140 attributes.put(name,httpSession.getAttribute(name));
141 httpSession.removeAttribute(name);
142 }
143
144 httpSession.invalidate();
145 httpSession = request.getSession(true);
146 if (authenticated)
147 httpSession.setAttribute(SESSION_KNOWN_ONLY_TO_AUTHENTICATED, Boolean.TRUE);
148 for (Map.Entry<String, Object> entry: attributes.entrySet())
149 httpSession.setAttribute(entry.getKey(),entry.getValue());
150 return httpSession;
151 }
152
153 /* ------------------------------------------------------------ */
154 public AbstractSessionManager()
155 {
156 setSessionTrackingModes(__defaultSessionTrackingModes);
157 }
158
159 /* ------------------------------------------------------------ */
160 public ContextHandler.Context getContext()
161 {
162 return _context;
163 }
164
165 /* ------------------------------------------------------------ */
166 public ContextHandler getContextHandler()
167 {
168 return _context.getContextHandler();
169 }
170
171 public String getSessionPath()
172 {
173 return _sessionPath;
174 }
175
176 public int getMaxCookieAge()
177 {
178 return _maxCookieAge;
179 }
180
181 /* ------------------------------------------------------------ */
182 public HttpCookie access(HttpSession session,boolean secure)
183 {
184 long now=System.currentTimeMillis();
185
186 AbstractSession s = ((SessionIf)session).getSession();
187
188 if (s.access(now))
189 {
190 // Do we need to refresh the cookie?
191 if (isUsingCookies() &&
192 (s.isIdChanged() ||
193 (getSessionCookieConfig().getMaxAge()>0 && getRefreshCookieAge()>0 && ((now-s.getCookieSetTime())/1000>getRefreshCookieAge()))
194 )
195 )
196 {
197 HttpCookie cookie=getSessionCookie(session,_context==null?"/":(_context.getContextPath()),secure);
198 s.cookieSet();
199 s.setIdChanged(false);
200 return cookie;
201 }
202 }
203 return null;
204 }
205
206 /* ------------------------------------------------------------ */
207 public void addEventListener(EventListener listener)
208 {
209 if (listener instanceof HttpSessionAttributeListener)
210 _sessionAttributeListeners.add((HttpSessionAttributeListener)listener);
211 if (listener instanceof HttpSessionListener)
212 _sessionListeners.add((HttpSessionListener)listener);
213 }
214
215 /* ------------------------------------------------------------ */
216 public void clearEventListeners()
217 {
218 _sessionAttributeListeners.clear();
219 _sessionListeners.clear();
220 }
221
222 /* ------------------------------------------------------------ */
223 public void complete(HttpSession session)
224 {
225 AbstractSession s = ((SessionIf)session).getSession();
226 s.complete();
227 }
228
229 /* ------------------------------------------------------------ */
230 @Override
231 public void doStart() throws Exception
232 {
233 _context=ContextHandler.getCurrentContext();
234 _loader=Thread.currentThread().getContextClassLoader();
235
236 if (_sessionIdManager==null)
237 {
238 final Server server=getSessionHandler().getServer();
239 synchronized (server)
240 {
241 _sessionIdManager=server.getSessionIdManager();
242 if (_sessionIdManager==null)
243 {
244 _sessionIdManager=new HashSessionIdManager();
245 server.setSessionIdManager(_sessionIdManager);
246 }
247 }
248 }
249 if (!_sessionIdManager.isStarted())
250 _sessionIdManager.start();
251
252 // Look for a session cookie name
253 if (_context!=null)
254 {
255 String tmp=_context.getInitParameter(SessionManager.__SessionCookieProperty);
256 if (tmp!=null)
257 _sessionCookie=tmp;
258
259 tmp=_context.getInitParameter(SessionManager.__SessionIdPathParameterNameProperty);
260 if (tmp!=null)
261 setSessionIdPathParameterName(tmp);
262
263 // set up the max session cookie age if it isn't already
264 if (_maxCookieAge==-1)
265 {
266 tmp=_context.getInitParameter(SessionManager.__MaxAgeProperty);
267 if (tmp!=null)
268 _maxCookieAge=Integer.parseInt(tmp.trim());
269 }
270
271 // set up the session domain if it isn't already
272 if (_sessionDomain==null)
273 _sessionDomain=_context.getInitParameter(SessionManager.__SessionDomainProperty);
274
275 // set up the sessionPath if it isn't already
276 if (_sessionPath==null)
277 _sessionPath=_context.getInitParameter(SessionManager.__SessionPathProperty);
278
279 tmp=_context.getInitParameter(SessionManager.__CheckRemoteSessionEncoding);
280 if (tmp!=null)
281 _checkingRemoteSessionIdEncoding=Boolean.parseBoolean(tmp);
282 }
283
284 super.doStart();
285 }
286
287 /* ------------------------------------------------------------ */
288 @Override
289 public void doStop() throws Exception
290 {
291 super.doStop();
292
293 invalidateSessions();
294
295 _loader=null;
296 }
297
298 /* ------------------------------------------------------------ */
299 /**
300 * @return Returns the httpOnly.
301 */
302 public boolean getHttpOnly()
303 {
304 return _httpOnly;
305 }
306
307 /* ------------------------------------------------------------ */
308 public HttpSession getHttpSession(String nodeId)
309 {
310 String cluster_id = getSessionIdManager().getClusterId(nodeId);
311
312 AbstractSession session = getSession(cluster_id);
313 if (session!=null && !session.getNodeId().equals(nodeId))
314 session.setIdChanged(true);
315 return session;
316 }
317
318 /* ------------------------------------------------------------ */
319 /**
320 * @return Returns the metaManager used for cross context session management
321 * @deprecated Use {@link #getSessionIdManager()}
322 */
323 public SessionIdManager getIdManager()
324 {
325 return getSessionIdManager();
326 }
327
328 /* ------------------------------------------------------------ */
329 /**
330 * @return Returns the SessionIdManager used for cross context session management
331 */
332 public SessionIdManager getSessionIdManager()
333 {
334 return _sessionIdManager;
335 }
336
337
338 /* ------------------------------------------------------------ */
339 /**
340 * @return seconds
341 */
342 @Override
343 public int getMaxInactiveInterval()
344 {
345 return _dftMaxIdleSecs;
346 }
347
348 /* ------------------------------------------------------------ */
349 /**
350 * @see #getSessionsMax()
351 */
352 @Deprecated
353 public int getMaxSessions()
354 {
355 return getSessionsMax();
356 }
357
358 /* ------------------------------------------------------------ */
359 /**
360 * @return maximum number of sessions
361 */
362 public int getSessionsMax()
363 {
364 return (int)_sessionsStats.getMax();
365 }
366
367 /* ------------------------------------------------------------ */
368 /**
369 * @return total number of sessions
370 */
371 public int getSessionsTotal()
372 {
373 return (int)_sessionsStats.getTotal();
374 }
375
376 /* ------------------------------------------------------------ */
377 /**
378 * @deprecated use {@link #getSessionIdManager()}
379 */
380 @Deprecated
381 public SessionIdManager getMetaManager()
382 {
383 return getSessionIdManager();
384 }
385
386 /* ------------------------------------------------------------ */
387 /**
388 * @deprecated always returns 0. no replacement available.
389 */
390 @Deprecated
391 public int getMinSessions()
392 {
393 return 0;
394 }
395
396 /* ------------------------------------------------------------ */
397 public int getRefreshCookieAge()
398 {
399 return _refreshCookieAge;
400 }
401
402
403 /* ------------------------------------------------------------ */
404 /**
405 * @return same as SessionCookieConfig.getSecure(). If true, session
406 * cookies are ALWAYS marked as secure. If false, a session cookie is
407 * ONLY marked as secure if _secureRequestOnly == true and it is a HTTPS request.
408 */
409 public boolean getSecureCookies()
410 {
411 return _secureCookies;
412 }
413
414 /* ------------------------------------------------------------ */
415 /**
416 * @return true if session cookie is to be marked as secure only on HTTPS requests
417 */
418 public boolean isSecureRequestOnly()
419 {
420 return _secureRequestOnly;
421 }
422
423
424 /* ------------------------------------------------------------ */
425 /**
426 * @return if true, session cookie will be marked as secure only iff
427 * HTTPS request. Can be overridden by setting SessionCookieConfig.setSecure(true),
428 * in which case the session cookie will be marked as secure on both HTTPS and HTTP.
429 */
430 public void setSecureRequestOnly(boolean secureRequestOnly)
431 {
432 _secureRequestOnly = secureRequestOnly;
433 }
434
435
436
437 /* ------------------------------------------------------------ */
438 public String getSessionCookie()
439 {
440 return _sessionCookie;
441 }
442
443 /* ------------------------------------------------------------ */
444 /**
445 * A sessioncookie is marked as secure IFF any of the following conditions are true:
446 * <ol>
447 * <li>SessionCookieConfig.setSecure == true</li>
448 * <li>SessionCookieConfig.setSecure == false && _secureRequestOnly==true && request is HTTPS</li>
449 * </ol>
450 * According to SessionCookieConfig javadoc, case 1 can be used when:
451 * "... even though the request that initiated the session came over HTTP,
452 * is to support a topology where the web container is front-ended by an
453 * SSL offloading load balancer. In this case, the traffic between the client
454 * and the load balancer will be over HTTPS, whereas the traffic between the
455 * load balancer and the web container will be over HTTP."
456 *
457 * For case 2, you can use _secureRequestOnly to determine if you want the
458 * Servlet Spec 3.0 default behaviour when SessionCookieConfig.setSecure==false,
459 * which is:
460 * "they shall be marked as secure only if the request that initiated the
461 * corresponding session was also secure"
462 *
463 * The default for _secureRequestOnly is true, which gives the above behaviour. If
464 * you set it to false, then a session cookie is NEVER marked as secure, even if
465 * the initiating request was secure.
466 *
467 * @see org.eclipse.jetty.server.SessionManager#getSessionCookie(javax.servlet.http.HttpSession, java.lang.String, boolean)
468 */
469 public HttpCookie getSessionCookie(HttpSession session, String contextPath, boolean requestIsSecure)
470 {
471 if (isUsingCookies())
472 {
473 String sessionPath = (_sessionPath==null) ? contextPath : _sessionPath;
474 sessionPath = (sessionPath==null||sessionPath.length()==0) ? "/" : sessionPath;
475 String id = getNodeId(session);
476 HttpCookie cookie = null;
477 if (_sessionComment == null)
478 {
479 cookie = new HttpCookie(
480 _sessionCookie,
481 id,
482 _sessionDomain,
483 sessionPath,
484 _cookieConfig.getMaxAge(),
485 _cookieConfig.isHttpOnly(),
486 _cookieConfig.isSecure() || (isSecureRequestOnly() && requestIsSecure));
487 }
488 else
489 {
490 cookie = new HttpCookie(
491 _sessionCookie,
492 id,
493 _sessionDomain,
494 sessionPath,
495 _cookieConfig.getMaxAge(),
496 _cookieConfig.isHttpOnly(),
497 _cookieConfig.isSecure() || (isSecureRequestOnly() && requestIsSecure),
498 _sessionComment,
499 1);
500 }
501
502 return cookie;
503 }
504 return null;
505 }
506
507 public String getSessionDomain()
508 {
509 return _sessionDomain;
510 }
511
512 /* ------------------------------------------------------------ */
513 /**
514 * @return Returns the sessionHandler.
515 */
516 public SessionHandler getSessionHandler()
517 {
518 return _sessionHandler;
519 }
520
521 /* ------------------------------------------------------------ */
522 /**
523 * @deprecated Need to review if it is needed.
524 */
525 @SuppressWarnings("rawtypes")
526 public Map getSessionMap()
527 {
528 throw new UnsupportedOperationException();
529 }
530
531
532
533 /* ------------------------------------------------------------ */
534 public int getSessions()
535 {
536 return (int)_sessionsStats.getCurrent();
537 }
538
539 /* ------------------------------------------------------------ */
540 public String getSessionIdPathParameterName()
541 {
542 return _sessionIdPathParameterName;
543 }
544
545 /* ------------------------------------------------------------ */
546 public String getSessionIdPathParameterNamePrefix()
547 {
548 return _sessionIdPathParameterNamePrefix;
549 }
550
551 /* ------------------------------------------------------------ */
552 /**
553 * @return Returns the usingCookies.
554 */
555 public boolean isUsingCookies()
556 {
557 return _usingCookies;
558 }
559
560 /* ------------------------------------------------------------ */
561 public boolean isValid(HttpSession session)
562 {
563 AbstractSession s = ((SessionIf)session).getSession();
564 return s.isValid();
565 }
566
567 /* ------------------------------------------------------------ */
568 public String getClusterId(HttpSession session)
569 {
570 AbstractSession s = ((SessionIf)session).getSession();
571 return s.getClusterId();
572 }
573
574 /* ------------------------------------------------------------ */
575 public String getNodeId(HttpSession session)
576 {
577 AbstractSession s = ((SessionIf)session).getSession();
578 return s.getNodeId();
579 }
580
581 /* ------------------------------------------------------------ */
582 /**
583 * Create a new HttpSession for a request
584 */
585 public HttpSession newHttpSession(HttpServletRequest request)
586 {
587 AbstractSession session=newSession(request);
588 session.setMaxInactiveInterval(_dftMaxIdleSecs);
589 addSession(session,true);
590 return session;
591 }
592
593 /* ------------------------------------------------------------ */
594 public void removeEventListener(EventListener listener)
595 {
596 if (listener instanceof HttpSessionAttributeListener)
597 _sessionAttributeListeners.remove(listener);
598 if (listener instanceof HttpSessionListener)
599 _sessionListeners.remove(listener);
600 }
601
602 /* ------------------------------------------------------------ */
603 /**
604 * @see #statsReset()
605 */
606 @Deprecated
607 public void resetStats()
608 {
609 statsReset();
610 }
611
612 /* ------------------------------------------------------------ */
613 /**
614 * Reset statistics values
615 */
616 public void statsReset()
617 {
618 _sessionsStats.reset(getSessions());
619 _sessionTimeStats.reset();
620 }
621
622 /* ------------------------------------------------------------ */
623 /**
624 * @param httpOnly
625 * The httpOnly to set.
626 */
627 public void setHttpOnly(boolean httpOnly)
628 {
629 _httpOnly=httpOnly;
630 }
631
632 /* ------------------------------------------------------------ */
633 /**
634 * @param metaManager The metaManager used for cross context session management.
635 * @deprecated use {@link #setSessionIdManager(SessionIdManager)}
636 */
637 public void setIdManager(SessionIdManager metaManager)
638 {
639 setSessionIdManager(metaManager);
640 }
641
642 /* ------------------------------------------------------------ */
643 /**
644 * @param metaManager The metaManager used for cross context session management.
645 */
646 public void setSessionIdManager(SessionIdManager metaManager)
647 {
648 _sessionIdManager=metaManager;
649 }
650
651
652
653 /* ------------------------------------------------------------ */
654 /**
655 * @param seconds
656 */
657 public void setMaxInactiveInterval(int seconds)
658 {
659 _dftMaxIdleSecs=seconds;
660 }
661
662
663 /* ------------------------------------------------------------ */
664 public void setRefreshCookieAge(int ageInSeconds)
665 {
666 _refreshCookieAge=ageInSeconds;
667 }
668
669
670
671 public void setSessionCookie(String cookieName)
672 {
673 _sessionCookie=cookieName;
674 }
675
676
677
678 /* ------------------------------------------------------------ */
679 /**
680 * @param sessionHandler
681 * The sessionHandler to set.
682 */
683 public void setSessionHandler(SessionHandler sessionHandler)
684 {
685 _sessionHandler=sessionHandler;
686 }
687
688
689 /* ------------------------------------------------------------ */
690 public void setSessionIdPathParameterName(String param)
691 {
692 _sessionIdPathParameterName =(param==null||"none".equals(param))?null:param;
693 _sessionIdPathParameterNamePrefix =(param==null||"none".equals(param))?null:(";"+ _sessionIdPathParameterName +"=");
694 }
695 /* ------------------------------------------------------------ */
696 /**
697 * @param usingCookies
698 * The usingCookies to set.
699 */
700 public void setUsingCookies(boolean usingCookies)
701 {
702 _usingCookies=usingCookies;
703 }
704
705
706 protected abstract void addSession(AbstractSession session);
707
708 /* ------------------------------------------------------------ */
709 /**
710 * Add the session Registers the session with this manager and registers the
711 * session ID with the sessionIDManager;
712 */
713 protected void addSession(AbstractSession session, boolean created)
714 {
715 synchronized (_sessionIdManager)
716 {
717 _sessionIdManager.addSession(session);
718 addSession(session);
719 }
720
721 if (created)
722 {
723 _sessionsStats.increment();
724 if (_sessionListeners!=null)
725 {
726 HttpSessionEvent event=new HttpSessionEvent(session);
727 for (HttpSessionListener listener : _sessionListeners)
728 listener.sessionCreated(event);
729 }
730 }
731 }
732
733 /* ------------------------------------------------------------ */
734 /**
735 * Get a known existing session
736 * @param idInCluster The session ID in the cluster, stripped of any worker name.
737 * @return A Session or null if none exists.
738 */
739 public abstract AbstractSession getSession(String idInCluster);
740
741 protected abstract void invalidateSessions() throws Exception;
742
743
744 /* ------------------------------------------------------------ */
745 /**
746 * Create a new session instance
747 * @param request
748 * @return the new session
749 */
750 protected abstract AbstractSession newSession(HttpServletRequest request);
751
752
753 /* ------------------------------------------------------------ */
754 /**
755 * @return true if the cluster node id (worker id) is returned as part of the session id by {@link HttpSession#getId()}. Default is false.
756 */
757 public boolean isNodeIdInSessionId()
758 {
759 return _nodeIdInSessionId;
760 }
761
762 /* ------------------------------------------------------------ */
763 /**
764 * @param nodeIdInSessionId true if the cluster node id (worker id) will be returned as part of the session id by {@link HttpSession#getId()}. Default is false.
765 */
766 public void setNodeIdInSessionId(boolean nodeIdInSessionId)
767 {
768 _nodeIdInSessionId=nodeIdInSessionId;
769 }
770
771 /* ------------------------------------------------------------ */
772 /** Remove session from manager
773 * @param session The session to remove
774 * @param invalidate True if {@link HttpSessionListener#sessionDestroyed(HttpSessionEvent)} and
775 * {@link SessionIdManager#invalidateAll(String)} should be called.
776 */
777 public void removeSession(HttpSession session, boolean invalidate)
778 {
779 AbstractSession s = ((SessionIf)session).getSession();
780 removeSession(s,invalidate);
781 }
782
783 /* ------------------------------------------------------------ */
784 /** Remove session from manager
785 * @param session The session to remove
786 * @param invalidate True if {@link HttpSessionListener#sessionDestroyed(HttpSessionEvent)} and
787 * {@link SessionIdManager#invalidateAll(String)} should be called.
788 */
789 public void removeSession(AbstractSession session, boolean invalidate)
790 {
791 // Remove session from context and global maps
792 boolean removed = removeSession(session.getClusterId());
793
794 if (removed)
795 {
796 _sessionsStats.decrement();
797 _sessionTimeStats.set(round((System.currentTimeMillis() - session.getCreationTime())/1000.0));
798
799 // Remove session from all context and global id maps
800 _sessionIdManager.removeSession(session);
801 if (invalidate)
802 _sessionIdManager.invalidateAll(session.getClusterId());
803
804 if (invalidate && _sessionListeners!=null)
805 {
806 HttpSessionEvent event=new HttpSessionEvent(session);
807 for (HttpSessionListener listener : _sessionListeners)
808 listener.sessionDestroyed(event);
809 }
810 }
811 }
812
813 /* ------------------------------------------------------------ */
814 protected abstract boolean removeSession(String idInCluster);
815
816 /* ------------------------------------------------------------ */
817 /**
818 * @return maximum amount of time session remained valid
819 */
820 public long getSessionTimeMax()
821 {
822 return _sessionTimeStats.getMax();
823 }
824
825 /* ------------------------------------------------------------ */
826 public Set<SessionTrackingMode> getDefaultSessionTrackingModes()
827 {
828 return __defaultSessionTrackingModes;
829 }
830
831 /* ------------------------------------------------------------ */
832 public Set<SessionTrackingMode> getEffectiveSessionTrackingModes()
833 {
834 return Collections.unmodifiableSet(_sessionTrackingModes);
835 }
836
837 /* ------------------------------------------------------------ */
838 @Override
839 public void setSessionTrackingModes(Set<SessionTrackingMode> sessionTrackingModes)
840 {
841 _sessionTrackingModes=new HashSet<SessionTrackingMode>(sessionTrackingModes);
842 _usingCookies=_sessionTrackingModes.contains(SessionTrackingMode.COOKIE);
843 _usingURLs=_sessionTrackingModes.contains(SessionTrackingMode.URL);
844 }
845
846 /* ------------------------------------------------------------ */
847 @Override
848 public boolean isUsingURLs()
849 {
850 return _usingURLs;
851 }
852
853
854 /* ------------------------------------------------------------ */
855 public SessionCookieConfig getSessionCookieConfig()
856 {
857 return _cookieConfig;
858 }
859
860 /* ------------------------------------------------------------ */
861 private SessionCookieConfig _cookieConfig =
862 new SessionCookieConfig()
863 {
864 @Override
865 public String getComment()
866 {
867 return _sessionComment;
868 }
869
870 @Override
871 public String getDomain()
872 {
873 return _sessionDomain;
874 }
875
876 @Override
877 public int getMaxAge()
878 {
879 return _maxCookieAge;
880 }
881
882 @Override
883 public String getName()
884 {
885 return _sessionCookie;
886 }
887
888 @Override
889 public String getPath()
890 {
891 return _sessionPath;
892 }
893
894 @Override
895 public boolean isHttpOnly()
896 {
897 return _httpOnly;
898 }
899
900 @Override
901 public boolean isSecure()
902 {
903 return _secureCookies;
904 }
905
906 @Override
907 public void setComment(String comment)
908 {
909 _sessionComment = comment;
910 }
911
912 @Override
913 public void setDomain(String domain)
914 {
915 _sessionDomain=domain;
916 }
917
918 @Override
919 public void setHttpOnly(boolean httpOnly)
920 {
921 _httpOnly=httpOnly;
922 }
923
924 @Override
925 public void setMaxAge(int maxAge)
926 {
927 _maxCookieAge=maxAge;
928 }
929
930 @Override
931 public void setName(String name)
932 {
933 _sessionCookie=name;
934 }
935
936 @Override
937 public void setPath(String path)
938 {
939 _sessionPath=path;
940 }
941
942 @Override
943 public void setSecure(boolean secure)
944 {
945 _secureCookies=secure;
946 }
947
948 };
949
950
951 /* ------------------------------------------------------------ */
952 /**
953 * @return total amount of time all sessions remained valid
954 */
955 public long getSessionTimeTotal()
956 {
957 return _sessionTimeStats.getTotal();
958 }
959
960 /* ------------------------------------------------------------ */
961 /**
962 * @return mean amount of time session remained valid
963 */
964 public double getSessionTimeMean()
965 {
966 return _sessionTimeStats.getMean();
967 }
968
969 /* ------------------------------------------------------------ */
970 /**
971 * @return standard deviation of amount of time session remained valid
972 */
973 public double getSessionTimeStdDev()
974 {
975 return _sessionTimeStats.getStdDev();
976 }
977
978 /* ------------------------------------------------------------ */
979 /**
980 * @see org.eclipse.jetty.server.SessionManager#isCheckingRemoteSessionIdEncoding()
981 */
982 public boolean isCheckingRemoteSessionIdEncoding()
983 {
984 return _checkingRemoteSessionIdEncoding;
985 }
986
987 /* ------------------------------------------------------------ */
988 /**
989 * @see org.eclipse.jetty.server.SessionManager#setCheckingRemoteSessionIdEncoding(boolean)
990 */
991 public void setCheckingRemoteSessionIdEncoding(boolean remote)
992 {
993 _checkingRemoteSessionIdEncoding=remote;
994 }
995
996 /* ------------------------------------------------------------ */
997 /* ------------------------------------------------------------ */
998 /* ------------------------------------------------------------ */
999 /**
1000 * Interface that any session wrapper should implement so that
1001 * SessionManager may access the Jetty session implementation.
1002 *
1003 */
1004 public interface SessionIf extends HttpSession
1005 {
1006 public AbstractSession getSession();
1007 }
1008
1009 public void doSessionAttributeListeners(AbstractSession session, String name, Object old, Object value)
1010 {
1011 if (!_sessionAttributeListeners.isEmpty())
1012 {
1013 HttpSessionBindingEvent event=new HttpSessionBindingEvent(session,name,old==null?value:old);
1014
1015 for (HttpSessionAttributeListener l : _sessionAttributeListeners)
1016 {
1017 if (old==null)
1018 l.attributeAdded(event);
1019 else if (value==null)
1020 l.attributeRemoved(event);
1021 else
1022 l.attributeReplaced(event);
1023 }
1024 }
1025 }
1026 }