Mercurial Hosting > luan
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 } |
