Mercurial Hosting > luan
changeset 809:09d518d313b7
remove SessionManager
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 08 Sep 2016 16:38:30 -0600 |
parents | b3176fd168bf |
children | 022ff91bde60 |
files | src/luan/modules/http/Server.luan src/org/eclipse/jetty/server/Request.java src/org/eclipse/jetty/server/Response.java src/org/eclipse/jetty/server/SessionManager.java src/org/eclipse/jetty/server/session/AbstractSession.java src/org/eclipse/jetty/server/session/AbstractSessionIdManager.java src/org/eclipse/jetty/server/session/AbstractSessionManager.java src/org/eclipse/jetty/server/session/HashSessionIdManager.java src/org/eclipse/jetty/server/session/HashSessionManager.java src/org/eclipse/jetty/server/session/HashedSession.java src/org/eclipse/jetty/server/session/JDBCSessionIdManager.java src/org/eclipse/jetty/server/session/JDBCSessionManager.java src/org/eclipse/jetty/server/session/SessionHandler.java |
diffstat | 13 files changed, 1845 insertions(+), 7763 deletions(-) [+] |
line wrap: on
line diff
--- a/src/luan/modules/http/Server.luan Thu Sep 08 16:13:27 2016 -0600 +++ b/src/luan/modules/http/Server.luan Thu Sep 08 16:38:30 2016 -0600 @@ -23,7 +23,6 @@ local ContextHandler = require "java:org.eclipse.jetty.server.handler.ContextHandler" local GzipHandler = require "java:org.eclipse.jetty.server.handler.GzipHandler" local HandlerWrapper = require "java:org.eclipse.jetty.server.handler.HandlerWrapper" -local SessionHandler = require "java:org.eclipse.jetty.server.session.SessionHandler" local AuthenticationHandler = require "java:luan.modules.http.AuthenticationHandler" local LuanHandler = require "java:luan.modules.http.LuanHandler" local NotFound = require "java:luan.modules.http.NotFound" @@ -74,7 +73,7 @@ end local hc = HandlerCollection.new() -hc.setHandlers { SessionHandler.new(), M.handler_wrapper, DefaultHandler.new(), M.log_handler } +hc.setHandlers { M.handler_wrapper, DefaultHandler.new(), M.log_handler } function M.init(dir)
--- a/src/org/eclipse/jetty/server/Request.java Thu Sep 08 16:13:27 2016 -0600 +++ b/src/org/eclipse/jetty/server/Request.java Thu Sep 08 16:38:30 2016 -0600 @@ -127,2078 +127,2034 @@ */ public class Request implements HttpServletRequest { - public static final String __MULTIPART_CONFIG_ELEMENT = "org.eclipse.multipartConfig"; - public static final String __MULTIPART_INPUT_STREAM = "org.eclipse.multiPartInputStream"; - public static final String __MULTIPART_CONTEXT = "org.eclipse.multiPartContext"; - private static final Logger LOG = Log.getLogger(Request.class); + public static final String __MULTIPART_CONFIG_ELEMENT = "org.eclipse.multipartConfig"; + public static final String __MULTIPART_INPUT_STREAM = "org.eclipse.multiPartInputStream"; + public static final String __MULTIPART_CONTEXT = "org.eclipse.multiPartContext"; + private static final Logger LOG = Log.getLogger(Request.class); - private static final String __ASYNC_FWD = "org.eclipse.asyncfwd"; - private static final Collection __defaultLocale = Collections.singleton(Locale.getDefault()); - private static final int __NONE = 0, _STREAM = 1, __READER = 2; + private static final String __ASYNC_FWD = "org.eclipse.asyncfwd"; + private static final Collection __defaultLocale = Collections.singleton(Locale.getDefault()); + private static final int __NONE = 0, _STREAM = 1, __READER = 2; - public static class MultiPartCleanerListener implements ServletRequestListener - { + public static class MultiPartCleanerListener implements ServletRequestListener + { - @Override - public void requestDestroyed(ServletRequestEvent sre) - { - //Clean up any tmp files created by MultiPartInputStream - MultiPartInputStream mpis = (MultiPartInputStream)sre.getServletRequest().getAttribute(__MULTIPART_INPUT_STREAM); - if (mpis != null) - { - ContextHandler.Context context = (ContextHandler.Context)sre.getServletRequest().getAttribute(__MULTIPART_CONTEXT); + @Override + public void requestDestroyed(ServletRequestEvent sre) + { + //Clean up any tmp files created by MultiPartInputStream + MultiPartInputStream mpis = (MultiPartInputStream)sre.getServletRequest().getAttribute(__MULTIPART_INPUT_STREAM); + if (mpis != null) + { + ContextHandler.Context context = (ContextHandler.Context)sre.getServletRequest().getAttribute(__MULTIPART_CONTEXT); - //Only do the cleanup if we are exiting from the context in which a servlet parsed the multipart files - if (context == sre.getServletContext()) - { - try - { - mpis.deleteParts(); - } - catch (MultiException e) - { - sre.getServletContext().log("Errors deleting multipart tmp files", e); - } - } - } - } + //Only do the cleanup if we are exiting from the context in which a servlet parsed the multipart files + if (context == sre.getServletContext()) + { + try + { + mpis.deleteParts(); + } + catch (MultiException e) + { + sre.getServletContext().log("Errors deleting multipart tmp files", e); + } + } + } + } - @Override - public void requestInitialized(ServletRequestEvent sre) - { - //nothing to do, multipart config set up by ServletHolder.handle() - } - - } - - - /* ------------------------------------------------------------ */ - public static Request getRequest(HttpServletRequest request) - { - if (request instanceof Request) - return (Request)request; + @Override + public void requestInitialized(ServletRequestEvent sre) + { + //nothing to do, multipart config set up by ServletHolder.handle() + } + + } + + + /* ------------------------------------------------------------ */ + public static Request getRequest(HttpServletRequest request) + { + if (request instanceof Request) + return (Request)request; - return AbstractHttpConnection.getCurrentConnection().getRequest(); - } - protected final AsyncContinuation _async = new AsyncContinuation(); - private boolean _asyncSupported = true; - private volatile Attributes _attributes; - private Authentication _authentication; - private MultiMap<String> _baseParameters; - private String _characterEncoding; - protected AbstractHttpConnection _connection; - private ContextHandler.Context _context; - private boolean _newContext; - private String _contextPath; - private CookieCutter _cookies; - private boolean _cookiesExtracted = false; - private DispatcherType _dispatcherType; - private boolean _dns = false; - private EndPoint _endp; - private boolean _handled = false; - private int _inputState = __NONE; - private String _method; - private MultiMap<String> _parameters; - private boolean _paramsExtracted; - private String _pathInfo; - private int _port; - private String _protocol = HttpVersions.HTTP_1_1; - private String _queryEncoding; - private String _queryString; - private BufferedReader _reader; - private String _readerEncoding; - private String _remoteAddr; - private String _remoteHost; - private Object _requestAttributeListeners; - private String _requestedSessionId; - private boolean _requestedSessionIdFromCookie = false; - private String _requestURI; - private Map<Object, HttpSession> _savedNewSessions; - private String _scheme = URIUtil.HTTP; - private UserIdentity.Scope _scope; - private String _serverName; - private String _servletPath; - private HttpSession _session; - private SessionManager _sessionManager; - private long _timeStamp; - private long _dispatchTime; + return AbstractHttpConnection.getCurrentConnection().getRequest(); + } + protected final AsyncContinuation _async = new AsyncContinuation(); + private boolean _asyncSupported = true; + private volatile Attributes _attributes; + private Authentication _authentication; + private MultiMap<String> _baseParameters; + private String _characterEncoding; + protected AbstractHttpConnection _connection; + private ContextHandler.Context _context; + private boolean _newContext; + private String _contextPath; + private CookieCutter _cookies; + private boolean _cookiesExtracted = false; + private DispatcherType _dispatcherType; + private boolean _dns = false; + private EndPoint _endp; + private boolean _handled = false; + private int _inputState = __NONE; + private String _method; + private MultiMap<String> _parameters; + private boolean _paramsExtracted; + private String _pathInfo; + private int _port; + private String _protocol = HttpVersions.HTTP_1_1; + private String _queryEncoding; + private String _queryString; + private BufferedReader _reader; + private String _readerEncoding; + private String _remoteAddr; + private String _remoteHost; + private Object _requestAttributeListeners; + private String _requestedSessionId; + private boolean _requestedSessionIdFromCookie = false; + private String _requestURI; + private Map<Object, HttpSession> _savedNewSessions; + private String _scheme = URIUtil.HTTP; + private UserIdentity.Scope _scope; + private String _serverName; + private String _servletPath; + private HttpSession _session; + private long _timeStamp; + private long _dispatchTime; - private Buffer _timeStampBuffer; - private HttpURI _uri; - - private MultiPartInputStream _multiPartInputStream; //if the request is a multi-part mime - - /* ------------------------------------------------------------ */ - public Request() - { - } + private Buffer _timeStampBuffer; + private HttpURI _uri; + + private MultiPartInputStream _multiPartInputStream; //if the request is a multi-part mime + + /* ------------------------------------------------------------ */ + public Request() + { + } - /* ------------------------------------------------------------ */ - public Request(AbstractHttpConnection connection) - { - setConnection(connection); - } + /* ------------------------------------------------------------ */ + public Request(AbstractHttpConnection connection) + { + setConnection(connection); + } - /* ------------------------------------------------------------ */ - public void addEventListener(final EventListener listener) - { - if (listener instanceof ServletRequestAttributeListener) - _requestAttributeListeners = LazyList.add(_requestAttributeListeners,listener); - if (listener instanceof ContinuationListener) - throw new IllegalArgumentException(listener.getClass().toString()); - if (listener instanceof AsyncListener) - throw new IllegalArgumentException(listener.getClass().toString()); - } + /* ------------------------------------------------------------ */ + public void addEventListener(final EventListener listener) + { + if (listener instanceof ServletRequestAttributeListener) + _requestAttributeListeners = LazyList.add(_requestAttributeListeners,listener); + if (listener instanceof ContinuationListener) + throw new IllegalArgumentException(listener.getClass().toString()); + if (listener instanceof AsyncListener) + throw new IllegalArgumentException(listener.getClass().toString()); + } - /* ------------------------------------------------------------ */ - /** - * Extract Parameters from query string and/or form _content. - */ - public void extractParameters() - { - if (_baseParameters == null) - _baseParameters = new MultiMap(16); + /* ------------------------------------------------------------ */ + /** + * Extract Parameters from query string and/or form _content. + */ + public void extractParameters() + { + if (_baseParameters == null) + _baseParameters = new MultiMap(16); - if (_paramsExtracted) - { - if (_parameters == null) - _parameters = _baseParameters; - return; - } + if (_paramsExtracted) + { + if (_parameters == null) + _parameters = _baseParameters; + return; + } - _paramsExtracted = true; + _paramsExtracted = true; - try - { - // Handle query string - if (_uri != null && _uri.hasQuery()) - { - if (_queryEncoding == null) - _uri.decodeQueryTo(_baseParameters); - else - { - try - { - _uri.decodeQueryTo(_baseParameters,_queryEncoding); - } - catch (UnsupportedEncodingException e) - { - if (LOG.isDebugEnabled()) - LOG.warn(e); - else - LOG.warn(e.toString()); - } - } - } - - // handle any _content. - String encoding = getCharacterEncoding(); - String content_type = getContentType(); - if (content_type != null && content_type.length() > 0) - { - content_type = HttpFields.valueParameters(content_type,null); + try + { + // Handle query string + if (_uri != null && _uri.hasQuery()) + { + if (_queryEncoding == null) + _uri.decodeQueryTo(_baseParameters); + else + { + try + { + _uri.decodeQueryTo(_baseParameters,_queryEncoding); + } + catch (UnsupportedEncodingException e) + { + if (LOG.isDebugEnabled()) + LOG.warn(e); + else + LOG.warn(e.toString()); + } + } + } - if (MimeTypes.FORM_ENCODED.equalsIgnoreCase(content_type) && _inputState == __NONE - && (HttpMethods.POST.equals(getMethod()) || HttpMethods.PUT.equals(getMethod()))) - { - int content_length = getContentLength(); - if (content_length != 0) - { - try - { - int maxFormContentSize = -1; - int maxFormKeys = -1; + // handle any _content. + String encoding = getCharacterEncoding(); + String content_type = getContentType(); + if (content_type != null && content_type.length() > 0) + { + content_type = HttpFields.valueParameters(content_type,null); - if (_context != null) - { - maxFormContentSize = _context.getContextHandler().getMaxFormContentSize(); - maxFormKeys = _context.getContextHandler().getMaxFormKeys(); - } - - if (maxFormContentSize < 0) - { - Object obj = _connection.getConnector().getServer().getAttribute("org.eclipse.jetty.server.Request.maxFormContentSize"); - if (obj == null) - maxFormContentSize = 200000; - else if (obj instanceof Number) - { - Number size = (Number)obj; - maxFormContentSize = size.intValue(); - } - else if (obj instanceof String) - { - maxFormContentSize = Integer.valueOf((String)obj); - } - } - - if (maxFormKeys < 0) - { - Object obj = _connection.getConnector().getServer().getAttribute("org.eclipse.jetty.server.Request.maxFormKeys"); - if (obj == null) - maxFormKeys = 1000; - else if (obj instanceof Number) - { - Number keys = (Number)obj; - maxFormKeys = keys.intValue(); - } - else if (obj instanceof String) - { - maxFormKeys = Integer.valueOf((String)obj); - } - } + if (MimeTypes.FORM_ENCODED.equalsIgnoreCase(content_type) && _inputState == __NONE + && (HttpMethods.POST.equals(getMethod()) || HttpMethods.PUT.equals(getMethod()))) + { + int content_length = getContentLength(); + if (content_length != 0) + { + try + { + int maxFormContentSize = -1; + int maxFormKeys = -1; - if (content_length > maxFormContentSize && maxFormContentSize > 0) - { - throw new IllegalStateException("Form too large " + content_length + ">" + maxFormContentSize); - } - InputStream in = getInputStream(); + if (_context != null) + { + maxFormContentSize = _context.getContextHandler().getMaxFormContentSize(); + maxFormKeys = _context.getContextHandler().getMaxFormKeys(); + } + + if (maxFormContentSize < 0) + { + Object obj = _connection.getConnector().getServer().getAttribute("org.eclipse.jetty.server.Request.maxFormContentSize"); + if (obj == null) + maxFormContentSize = 200000; + else if (obj instanceof Number) + { + Number size = (Number)obj; + maxFormContentSize = size.intValue(); + } + else if (obj instanceof String) + { + maxFormContentSize = Integer.valueOf((String)obj); + } + } + + if (maxFormKeys < 0) + { + Object obj = _connection.getConnector().getServer().getAttribute("org.eclipse.jetty.server.Request.maxFormKeys"); + if (obj == null) + maxFormKeys = 1000; + else if (obj instanceof Number) + { + Number keys = (Number)obj; + maxFormKeys = keys.intValue(); + } + else if (obj instanceof String) + { + maxFormKeys = Integer.valueOf((String)obj); + } + } - // Add form params to query params - UrlEncoded.decodeTo(in,_baseParameters,encoding,content_length < 0?maxFormContentSize:-1,maxFormKeys); - } - catch (IOException e) - { - if (LOG.isDebugEnabled()) - LOG.warn(e); - else - LOG.warn(e.toString()); - } - } - } - - } - - if (_parameters == null) - _parameters = _baseParameters; - else if (_parameters != _baseParameters) - { - // Merge parameters (needed if parameters extracted after a forward). - Iterator iter = _baseParameters.entrySet().iterator(); - while (iter.hasNext()) - { - Map.Entry entry = (Map.Entry)iter.next(); - String name = (String)entry.getKey(); - Object values = entry.getValue(); - for (int i = 0; i < LazyList.size(values); i++) - _parameters.add(name,LazyList.get(values,i)); - } - } + if (content_length > maxFormContentSize && maxFormContentSize > 0) + { + throw new IllegalStateException("Form too large " + content_length + ">" + maxFormContentSize); + } + InputStream in = getInputStream(); - if (content_type != null && content_type.length()>0 && content_type.startsWith("multipart/form-data") && getAttribute(__MULTIPART_CONFIG_ELEMENT)!=null) - { - try - { - getParts(); - } - catch (IOException e) - { - if (LOG.isDebugEnabled()) - LOG.warn(e); - else - LOG.warn(e.toString()); - } - catch (ServletException e) - { - if (LOG.isDebugEnabled()) - LOG.warn(e); - else - LOG.warn(e.toString()); - } - } - } - finally - { - // ensure params always set (even if empty) after extraction - if (_parameters == null) - _parameters = _baseParameters; - } - } + // Add form params to query params + UrlEncoded.decodeTo(in,_baseParameters,encoding,content_length < 0?maxFormContentSize:-1,maxFormKeys); + } + catch (IOException e) + { + if (LOG.isDebugEnabled()) + LOG.warn(e); + else + LOG.warn(e.toString()); + } + } + } + + } + + if (_parameters == null) + _parameters = _baseParameters; + else if (_parameters != _baseParameters) + { + // Merge parameters (needed if parameters extracted after a forward). + Iterator iter = _baseParameters.entrySet().iterator(); + while (iter.hasNext()) + { + Map.Entry entry = (Map.Entry)iter.next(); + String name = (String)entry.getKey(); + Object values = entry.getValue(); + for (int i = 0; i < LazyList.size(values); i++) + _parameters.add(name,LazyList.get(values,i)); + } + } - /* ------------------------------------------------------------ */ - public AsyncContext getAsyncContext() - { - if (_async.isInitial() && !_async.isAsyncStarted()) - throw new IllegalStateException(_async.getStatusString()); - return _async; - } + if (content_type != null && content_type.length()>0 && content_type.startsWith("multipart/form-data") && getAttribute(__MULTIPART_CONFIG_ELEMENT)!=null) + { + try + { + getParts(); + } + catch (IOException e) + { + if (LOG.isDebugEnabled()) + LOG.warn(e); + else + LOG.warn(e.toString()); + } + catch (ServletException e) + { + if (LOG.isDebugEnabled()) + LOG.warn(e); + else + LOG.warn(e.toString()); + } + } + } + finally + { + // ensure params always set (even if empty) after extraction + if (_parameters == null) + _parameters = _baseParameters; + } + } - /* ------------------------------------------------------------ */ - public AsyncContinuation getAsyncContinuation() - { - return _async; - } - - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.ServletRequest#getAttribute(java.lang.String) - */ - public Object getAttribute(String name) - { - if ("org.eclipse.jetty.io.EndPoint.maxIdleTime".equalsIgnoreCase(name)) - return new Long(getConnection().getEndPoint().getMaxIdleTime()); + /* ------------------------------------------------------------ */ + public AsyncContext getAsyncContext() + { + if (_async.isInitial() && !_async.isAsyncStarted()) + throw new IllegalStateException(_async.getStatusString()); + return _async; + } - Object attr = (_attributes == null)?null:_attributes.getAttribute(name); - if (attr == null && Continuation.ATTRIBUTE.equals(name)) - return _async; - return attr; - } + /* ------------------------------------------------------------ */ + public AsyncContinuation getAsyncContinuation() + { + return _async; + } + + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.ServletRequest#getAttribute(java.lang.String) + */ + public Object getAttribute(String name) + { + if ("org.eclipse.jetty.io.EndPoint.maxIdleTime".equalsIgnoreCase(name)) + return new Long(getConnection().getEndPoint().getMaxIdleTime()); - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.ServletRequest#getAttributeNames() - */ - public Enumeration getAttributeNames() - { - if (_attributes == null) - return Collections.enumeration(Collections.EMPTY_LIST); + Object attr = (_attributes == null)?null:_attributes.getAttribute(name); + if (attr == null && Continuation.ATTRIBUTE.equals(name)) + return _async; + return attr; + } - return AttributesMap.getAttributeNamesCopy(_attributes); - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.ServletRequest#getAttributeNames() + */ + public Enumeration getAttributeNames() + { + if (_attributes == null) + return Collections.enumeration(Collections.EMPTY_LIST); - /* ------------------------------------------------------------ */ - /* - */ - public Attributes getAttributes() - { - if (_attributes == null) - _attributes = new AttributesMap(); - return _attributes; - } + return AttributesMap.getAttributeNamesCopy(_attributes); + } - /* ------------------------------------------------------------ */ - /** - * Get the authentication. - * - * @return the authentication - */ - public Authentication getAuthentication() - { - return _authentication; - } + /* ------------------------------------------------------------ */ + /* + */ + public Attributes getAttributes() + { + if (_attributes == null) + _attributes = new AttributesMap(); + return _attributes; + } + + /* ------------------------------------------------------------ */ + /** + * Get the authentication. + * + * @return the authentication + */ + public Authentication getAuthentication() + { + return _authentication; + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.http.HttpServletRequest#getAuthType() - */ - public String getAuthType() - { - if (_authentication instanceof Authentication.Deferred) - setAuthentication(((Authentication.Deferred)_authentication).authenticate(this)); - - if (_authentication instanceof Authentication.User) - return ((Authentication.User)_authentication).getAuthMethod(); - return null; - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.http.HttpServletRequest#getAuthType() + */ + public String getAuthType() + { + if (_authentication instanceof Authentication.Deferred) + setAuthentication(((Authentication.Deferred)_authentication).authenticate(this)); + + if (_authentication instanceof Authentication.User) + return ((Authentication.User)_authentication).getAuthMethod(); + return null; + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.ServletRequest#getCharacterEncoding() - */ - public String getCharacterEncoding() - { - return _characterEncoding; - } - - /* ------------------------------------------------------------ */ - /** - * @return Returns the connection. - */ - public AbstractHttpConnection getConnection() - { - return _connection; - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.ServletRequest#getCharacterEncoding() + */ + public String getCharacterEncoding() + { + return _characterEncoding; + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.ServletRequest#getContentLength() - */ - public int getContentLength() - { - return (int)_connection.getRequestFields().getLongField(HttpHeaders.CONTENT_LENGTH_BUFFER); - } - - public long getContentRead() - { - if (_connection == null || _connection.getParser() == null) - return -1; - - return ((HttpParser)_connection.getParser()).getContentRead(); - } + /* ------------------------------------------------------------ */ + /** + * @return Returns the connection. + */ + public AbstractHttpConnection getConnection() + { + return _connection; + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.ServletRequest#getContentType() - */ - public String getContentType() - { - return _connection.getRequestFields().getStringField(HttpHeaders.CONTENT_TYPE_BUFFER); - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.ServletRequest#getContentLength() + */ + public int getContentLength() + { + return (int)_connection.getRequestFields().getLongField(HttpHeaders.CONTENT_LENGTH_BUFFER); + } - /* ------------------------------------------------------------ */ - /** - * @return The current {@link Context context} used for this request, or <code>null</code> if {@link #setContext} has not yet been called. - */ - public Context getContext() - { - return _context; - } + public long getContentRead() + { + if (_connection == null || _connection.getParser() == null) + return -1; + + return ((HttpParser)_connection.getParser()).getContentRead(); + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.http.HttpServletRequest#getContextPath() - */ - public String getContextPath() - { - return _contextPath; - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.ServletRequest#getContentType() + */ + public String getContentType() + { + return _connection.getRequestFields().getStringField(HttpHeaders.CONTENT_TYPE_BUFFER); + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.http.HttpServletRequest#getCookies() - */ - public Cookie[] getCookies() - { - if (_cookiesExtracted) - return _cookies == null?null:_cookies.getCookies(); + /* ------------------------------------------------------------ */ + /** + * @return The current {@link Context context} used for this request, or <code>null</code> if {@link #setContext} has not yet been called. + */ + public Context getContext() + { + return _context; + } - _cookiesExtracted = true; - - Enumeration enm = _connection.getRequestFields().getValues(HttpHeaders.COOKIE_BUFFER); - - // Handle no cookies - if (enm != null) - { - if (_cookies == null) - _cookies = new CookieCutter(); + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.http.HttpServletRequest#getContextPath() + */ + public String getContextPath() + { + return _contextPath; + } - while (enm.hasMoreElements()) - { - String c = (String)enm.nextElement(); - _cookies.addCookieField(c); - } - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.http.HttpServletRequest#getCookies() + */ + public Cookie[] getCookies() + { + if (_cookiesExtracted) + return _cookies == null?null:_cookies.getCookies(); - return _cookies == null?null:_cookies.getCookies(); - } + _cookiesExtracted = true; + + Enumeration enm = _connection.getRequestFields().getValues(HttpHeaders.COOKIE_BUFFER); - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.http.HttpServletRequest#getDateHeader(java.lang.String) - */ - public long getDateHeader(String name) - { - return _connection.getRequestFields().getDateField(name); - } + // Handle no cookies + if (enm != null) + { + if (_cookies == null) + _cookies = new CookieCutter(); - /* ------------------------------------------------------------ */ - public DispatcherType getDispatcherType() - { - return _dispatcherType; - } + while (enm.hasMoreElements()) + { + String c = (String)enm.nextElement(); + _cookies.addCookieField(c); + } + } + + return _cookies == null?null:_cookies.getCookies(); + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.http.HttpServletRequest#getHeader(java.lang.String) - */ - public String getHeader(String name) - { - return _connection.getRequestFields().getStringField(name); - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.http.HttpServletRequest#getDateHeader(java.lang.String) + */ + public long getDateHeader(String name) + { + return _connection.getRequestFields().getDateField(name); + } + + /* ------------------------------------------------------------ */ + public DispatcherType getDispatcherType() + { + return _dispatcherType; + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.http.HttpServletRequest#getHeaderNames() - */ - public Enumeration getHeaderNames() - { - return _connection.getRequestFields().getFieldNames(); - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.http.HttpServletRequest#getHeader(java.lang.String) + */ + public String getHeader(String name) + { + return _connection.getRequestFields().getStringField(name); + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.http.HttpServletRequest#getHeaders(java.lang.String) - */ - public Enumeration getHeaders(String name) - { - Enumeration e = _connection.getRequestFields().getValues(name); - if (e == null) - return Collections.enumeration(Collections.EMPTY_LIST); - return e; - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.http.HttpServletRequest#getHeaderNames() + */ + public Enumeration getHeaderNames() + { + return _connection.getRequestFields().getFieldNames(); + } - /* ------------------------------------------------------------ */ - /** - * @return Returns the inputState. - */ - public int getInputState() - { - return _inputState; - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.http.HttpServletRequest#getHeaders(java.lang.String) + */ + public Enumeration getHeaders(String name) + { + Enumeration e = _connection.getRequestFields().getValues(name); + if (e == null) + return Collections.enumeration(Collections.EMPTY_LIST); + return e; + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.ServletRequest#getInputStream() - */ - public ServletInputStream getInputStream() throws IOException - { - if (_inputState != __NONE && _inputState != _STREAM) - throw new IllegalStateException("READER"); - _inputState = _STREAM; - return _connection.getInputStream(); - } + /* ------------------------------------------------------------ */ + /** + * @return Returns the inputState. + */ + public int getInputState() + { + return _inputState; + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.http.HttpServletRequest#getIntHeader(java.lang.String) - */ - public int getIntHeader(String name) - { - return (int)_connection.getRequestFields().getLongField(name); - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.ServletRequest#getInputStream() + */ + public ServletInputStream getInputStream() throws IOException + { + if (_inputState != __NONE && _inputState != _STREAM) + throw new IllegalStateException("READER"); + _inputState = _STREAM; + return _connection.getInputStream(); + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.ServletRequest#getLocalAddr() - */ - public String getLocalAddr() - { - return _endp == null?null:_endp.getLocalAddr(); - } - - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.ServletRequest#getLocale() - */ - public Locale getLocale() - { - Enumeration enm = _connection.getRequestFields().getValues(HttpHeaders.ACCEPT_LANGUAGE,HttpFields.__separators); + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.http.HttpServletRequest#getIntHeader(java.lang.String) + */ + public int getIntHeader(String name) + { + return (int)_connection.getRequestFields().getLongField(name); + } - // handle no locale - if (enm == null || !enm.hasMoreElements()) - return Locale.getDefault(); + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.ServletRequest#getLocalAddr() + */ + public String getLocalAddr() + { + return _endp == null?null:_endp.getLocalAddr(); + } - // sort the list in quality order - List acceptLanguage = HttpFields.qualityList(enm); - if (acceptLanguage.size() == 0) - return Locale.getDefault(); + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.ServletRequest#getLocale() + */ + public Locale getLocale() + { + Enumeration enm = _connection.getRequestFields().getValues(HttpHeaders.ACCEPT_LANGUAGE,HttpFields.__separators); - int size = acceptLanguage.size(); + // handle no locale + if (enm == null || !enm.hasMoreElements()) + return Locale.getDefault(); - if (size > 0) - { - String language = (String)acceptLanguage.get(0); - language = HttpFields.valueParameters(language,null); - String country = ""; - int dash = language.indexOf('-'); - if (dash > -1) - { - country = language.substring(dash + 1).trim(); - language = language.substring(0,dash).trim(); - } - return new Locale(language,country); - } + // sort the list in quality order + List acceptLanguage = HttpFields.qualityList(enm); + if (acceptLanguage.size() == 0) + return Locale.getDefault(); + + int size = acceptLanguage.size(); - return Locale.getDefault(); - } - - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.ServletRequest#getLocales() - */ - public Enumeration getLocales() - { - - Enumeration enm = _connection.getRequestFields().getValues(HttpHeaders.ACCEPT_LANGUAGE,HttpFields.__separators); - - // handle no locale - if (enm == null || !enm.hasMoreElements()) - return Collections.enumeration(__defaultLocale); + if (size > 0) + { + String language = (String)acceptLanguage.get(0); + language = HttpFields.valueParameters(language,null); + String country = ""; + int dash = language.indexOf('-'); + if (dash > -1) + { + country = language.substring(dash + 1).trim(); + language = language.substring(0,dash).trim(); + } + return new Locale(language,country); + } - // sort the list in quality order - List acceptLanguage = HttpFields.qualityList(enm); + return Locale.getDefault(); + } + + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.ServletRequest#getLocales() + */ + public Enumeration getLocales() + { - if (acceptLanguage.size() == 0) - return Collections.enumeration(__defaultLocale); + Enumeration enm = _connection.getRequestFields().getValues(HttpHeaders.ACCEPT_LANGUAGE,HttpFields.__separators); + + // handle no locale + if (enm == null || !enm.hasMoreElements()) + return Collections.enumeration(__defaultLocale); - Object langs = null; - int size = acceptLanguage.size(); + // sort the list in quality order + List acceptLanguage = HttpFields.qualityList(enm); + + if (acceptLanguage.size() == 0) + return Collections.enumeration(__defaultLocale); - // convert to locals - for (int i = 0; i < size; i++) - { - String language = (String)acceptLanguage.get(i); - language = HttpFields.valueParameters(language,null); - String country = ""; - int dash = language.indexOf('-'); - if (dash > -1) - { - country = language.substring(dash + 1).trim(); - language = language.substring(0,dash).trim(); - } - langs = LazyList.ensureSize(langs,size); - langs = LazyList.add(langs,new Locale(language,country)); - } + Object langs = null; + int size = acceptLanguage.size(); - if (LazyList.size(langs) == 0) - return Collections.enumeration(__defaultLocale); - - return Collections.enumeration(LazyList.getList(langs)); - } + // convert to locals + for (int i = 0; i < size; i++) + { + String language = (String)acceptLanguage.get(i); + language = HttpFields.valueParameters(language,null); + String country = ""; + int dash = language.indexOf('-'); + if (dash > -1) + { + country = language.substring(dash + 1).trim(); + language = language.substring(0,dash).trim(); + } + langs = LazyList.ensureSize(langs,size); + langs = LazyList.add(langs,new Locale(language,country)); + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.ServletRequest#getLocalName() - */ - public String getLocalName() - { - if (_endp == null) - return null; - if (_dns) - return _endp.getLocalHost(); + if (LazyList.size(langs) == 0) + return Collections.enumeration(__defaultLocale); - String local = _endp.getLocalAddr(); - if (local != null && local.indexOf(':') >= 0) - local = "[" + local + "]"; - return local; - } + return Collections.enumeration(LazyList.getList(langs)); + } + + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.ServletRequest#getLocalName() + */ + public String getLocalName() + { + if (_endp == null) + return null; + if (_dns) + return _endp.getLocalHost(); - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.ServletRequest#getLocalPort() - */ - public int getLocalPort() - { - return _endp == null?0:_endp.getLocalPort(); - } + String local = _endp.getLocalAddr(); + if (local != null && local.indexOf(':') >= 0) + local = "[" + local + "]"; + return local; + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.http.HttpServletRequest#getMethod() - */ - public String getMethod() - { - return _method; - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.ServletRequest#getLocalPort() + */ + public int getLocalPort() + { + return _endp == null?0:_endp.getLocalPort(); + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.ServletRequest#getParameter(java.lang.String) - */ - public String getParameter(String name) - { - if (!_paramsExtracted) - extractParameters(); - return (String)_parameters.getValue(name,0); - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.http.HttpServletRequest#getMethod() + */ + public String getMethod() + { + return _method; + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.ServletRequest#getParameterMap() - */ - public Map getParameterMap() - { - if (!_paramsExtracted) - extractParameters(); + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.ServletRequest#getParameter(java.lang.String) + */ + public String getParameter(String name) + { + if (!_paramsExtracted) + extractParameters(); + return (String)_parameters.getValue(name,0); + } - return Collections.unmodifiableMap(_parameters.toStringArrayMap()); - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.ServletRequest#getParameterMap() + */ + public Map getParameterMap() + { + if (!_paramsExtracted) + extractParameters(); - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.ServletRequest#getParameterNames() - */ - public Enumeration getParameterNames() - { - if (!_paramsExtracted) - extractParameters(); - return Collections.enumeration(_parameters.keySet()); - } + return Collections.unmodifiableMap(_parameters.toStringArrayMap()); + } - /* ------------------------------------------------------------ */ - /** - * @return Returns the parameters. - */ - public MultiMap<String> getParameters() - { - return _parameters; - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.ServletRequest#getParameterNames() + */ + public Enumeration getParameterNames() + { + if (!_paramsExtracted) + extractParameters(); + return Collections.enumeration(_parameters.keySet()); + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.ServletRequest#getParameterValues(java.lang.String) - */ - public String[] getParameterValues(String name) - { - if (!_paramsExtracted) - extractParameters(); - List<Object> vals = _parameters.getValues(name); - if (vals == null) - return null; - return vals.toArray(new String[vals.size()]); - } + /* ------------------------------------------------------------ */ + /** + * @return Returns the parameters. + */ + public MultiMap<String> getParameters() + { + return _parameters; + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.http.HttpServletRequest#getPathInfo() - */ - public String getPathInfo() - { - return _pathInfo; - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.ServletRequest#getParameterValues(java.lang.String) + */ + public String[] getParameterValues(String name) + { + if (!_paramsExtracted) + extractParameters(); + List<Object> vals = _parameters.getValues(name); + if (vals == null) + return null; + return vals.toArray(new String[vals.size()]); + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.http.HttpServletRequest#getPathTranslated() - */ - public String getPathTranslated() - { - if (_pathInfo == null || _context == null) - return null; - return _context.getRealPath(_pathInfo); - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.http.HttpServletRequest#getPathInfo() + */ + public String getPathInfo() + { + return _pathInfo; + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.ServletRequest#getProtocol() - */ - public String getProtocol() - { - return _protocol; - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.http.HttpServletRequest#getPathTranslated() + */ + public String getPathTranslated() + { + if (_pathInfo == null || _context == null) + return null; + return _context.getRealPath(_pathInfo); + } - /* ------------------------------------------------------------ */ - public String getQueryEncoding() - { - return _queryEncoding; - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.ServletRequest#getProtocol() + */ + public String getProtocol() + { + return _protocol; + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.http.HttpServletRequest#getQueryString() - */ - public String getQueryString() - { - if (_queryString == null && _uri != null) - { - if (_queryEncoding == null) - _queryString = _uri.getQuery(); - else - _queryString = _uri.getQuery(_queryEncoding); - } - return _queryString; - } + /* ------------------------------------------------------------ */ + public String getQueryEncoding() + { + return _queryEncoding; + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.ServletRequest#getReader() - */ - public BufferedReader getReader() throws IOException - { - if (_inputState != __NONE && _inputState != __READER) - throw new IllegalStateException("STREAMED"); - - if (_inputState == __READER) - return _reader; - - String encoding = getCharacterEncoding(); - if (encoding == null) - encoding = StringUtil.__ISO_8859_1; + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.http.HttpServletRequest#getQueryString() + */ + public String getQueryString() + { + if (_queryString == null && _uri != null) + { + if (_queryEncoding == null) + _queryString = _uri.getQuery(); + else + _queryString = _uri.getQuery(_queryEncoding); + } + return _queryString; + } - if (_reader == null || !encoding.equalsIgnoreCase(_readerEncoding)) - { - final ServletInputStream in = getInputStream(); - _readerEncoding = encoding; - _reader = new BufferedReader(new InputStreamReader(in,encoding)) - { - @Override - public void close() throws IOException - { - in.close(); - } - }; - } - _inputState = __READER; - return _reader; - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.ServletRequest#getReader() + */ + public BufferedReader getReader() throws IOException + { + if (_inputState != __NONE && _inputState != __READER) + throw new IllegalStateException("STREAMED"); + + if (_inputState == __READER) + return _reader; + + String encoding = getCharacterEncoding(); + if (encoding == null) + encoding = StringUtil.__ISO_8859_1; - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.ServletRequest#getRealPath(java.lang.String) - */ - public String getRealPath(String path) - { - if (_context == null) - return null; - return _context.getRealPath(path); - } + if (_reader == null || !encoding.equalsIgnoreCase(_readerEncoding)) + { + final ServletInputStream in = getInputStream(); + _readerEncoding = encoding; + _reader = new BufferedReader(new InputStreamReader(in,encoding)) + { + @Override + public void close() throws IOException + { + in.close(); + } + }; + } + _inputState = __READER; + return _reader; + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.ServletRequest#getRemoteAddr() - */ - public String getRemoteAddr() - { - if (_remoteAddr != null) - return _remoteAddr; - return _endp == null?null:_endp.getRemoteAddr(); - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.ServletRequest#getRealPath(java.lang.String) + */ + public String getRealPath(String path) + { + if (_context == null) + return null; + return _context.getRealPath(path); + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.ServletRequest#getRemoteHost() - */ - public String getRemoteHost() - { - if (_dns) - { - if (_remoteHost != null) - { - return _remoteHost; - } - return _endp == null?null:_endp.getRemoteHost(); - } - return getRemoteAddr(); - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.ServletRequest#getRemoteAddr() + */ + public String getRemoteAddr() + { + if (_remoteAddr != null) + return _remoteAddr; + return _endp == null?null:_endp.getRemoteAddr(); + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.ServletRequest#getRemotePort() - */ - public int getRemotePort() - { - return _endp == null?0:_endp.getRemotePort(); - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.ServletRequest#getRemoteHost() + */ + public String getRemoteHost() + { + if (_dns) + { + if (_remoteHost != null) + { + return _remoteHost; + } + return _endp == null?null:_endp.getRemoteHost(); + } + return getRemoteAddr(); + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.http.HttpServletRequest#getRemoteUser() - */ - public String getRemoteUser() - { - Principal p = getUserPrincipal(); - if (p == null) - return null; - return p.getName(); - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.ServletRequest#getRemotePort() + */ + public int getRemotePort() + { + return _endp == null?0:_endp.getRemotePort(); + } + + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.http.HttpServletRequest#getRemoteUser() + */ + public String getRemoteUser() + { + Principal p = getUserPrincipal(); + if (p == null) + return null; + return p.getName(); + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.ServletRequest#getRequestDispatcher(java.lang.String) - */ - public RequestDispatcher getRequestDispatcher(String path) - { - if (path == null || _context == null) - return null; + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.ServletRequest#getRequestDispatcher(java.lang.String) + */ + public RequestDispatcher getRequestDispatcher(String path) + { + if (path == null || _context == null) + return null; - // handle relative path - if (!path.startsWith("/")) - { - String relTo = URIUtil.addPaths(_servletPath,_pathInfo); - int slash = relTo.lastIndexOf("/"); - if (slash > 1) - relTo = relTo.substring(0,slash + 1); - else - relTo = "/"; - path = URIUtil.addPaths(relTo,path); - } - - return _context.getRequestDispatcher(path); - } + // handle relative path + if (!path.startsWith("/")) + { + String relTo = URIUtil.addPaths(_servletPath,_pathInfo); + int slash = relTo.lastIndexOf("/"); + if (slash > 1) + relTo = relTo.substring(0,slash + 1); + else + relTo = "/"; + path = URIUtil.addPaths(relTo,path); + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.http.HttpServletRequest#getRequestedSessionId() - */ - public String getRequestedSessionId() - { - return _requestedSessionId; - } + return _context.getRequestDispatcher(path); + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.http.HttpServletRequest#getRequestURI() - */ - public String getRequestURI() - { - if (_requestURI == null && _uri != null) - _requestURI = _uri.getPathAndParam(); - return _requestURI; - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.http.HttpServletRequest#getRequestedSessionId() + */ + public String getRequestedSessionId() + { + return _requestedSessionId; + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.http.HttpServletRequest#getRequestURL() - */ - public StringBuffer getRequestURL() - { - final StringBuffer url = new StringBuffer(48); - synchronized (url) - { - String scheme = getScheme(); - int port = getServerPort(); + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.http.HttpServletRequest#getRequestURI() + */ + public String getRequestURI() + { + if (_requestURI == null && _uri != null) + _requestURI = _uri.getPathAndParam(); + return _requestURI; + } - url.append(scheme); - url.append("://"); - url.append(getServerName()); - if (_port > 0 && ((scheme.equalsIgnoreCase(URIUtil.HTTP) && port != 80) || (scheme.equalsIgnoreCase(URIUtil.HTTPS) && port != 443))) - { - url.append(':'); - url.append(_port); - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.http.HttpServletRequest#getRequestURL() + */ + public StringBuffer getRequestURL() + { + final StringBuffer url = new StringBuffer(48); + synchronized (url) + { + String scheme = getScheme(); + int port = getServerPort(); - url.append(getRequestURI()); - return url; - } - } - - /* ------------------------------------------------------------ */ - public Response getResponse() - { - return _connection._response; - } + url.append(scheme); + url.append("://"); + url.append(getServerName()); + if (_port > 0 && ((scheme.equalsIgnoreCase(URIUtil.HTTP) && port != 80) || (scheme.equalsIgnoreCase(URIUtil.HTTPS) && port != 443))) + { + url.append(':'); + url.append(_port); + } - /* ------------------------------------------------------------ */ - /** - * Reconstructs the URL the client used to make the request. The returned URL contains a protocol, server name, port number, and, but it does not include a - * path. - * <p> - * Because this method returns a <code>StringBuffer</code>, not a string, you can modify the URL easily, for example, to append path and query parameters. - * - * This method is useful for creating redirect messages and for reporting errors. - * - * @return "scheme://host:port" - */ - public StringBuilder getRootURL() - { - StringBuilder url = new StringBuilder(48); - String scheme = getScheme(); - int port = getServerPort(); + url.append(getRequestURI()); + return url; + } + } + + /* ------------------------------------------------------------ */ + public Response getResponse() + { + return _connection._response; + } - url.append(scheme); - url.append("://"); - url.append(getServerName()); + /* ------------------------------------------------------------ */ + /** + * Reconstructs the URL the client used to make the request. The returned URL contains a protocol, server name, port number, and, but it does not include a + * path. + * <p> + * Because this method returns a <code>StringBuffer</code>, not a string, you can modify the URL easily, for example, to append path and query parameters. + * + * This method is useful for creating redirect messages and for reporting errors. + * + * @return "scheme://host:port" + */ + public StringBuilder getRootURL() + { + StringBuilder url = new StringBuilder(48); + String scheme = getScheme(); + int port = getServerPort(); - if (port > 0 && ((scheme.equalsIgnoreCase("http") && port != 80) || (scheme.equalsIgnoreCase("https") && port != 443))) - { - url.append(':'); - url.append(port); - } - return url; - } + url.append(scheme); + url.append("://"); + url.append(getServerName()); - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.ServletRequest#getScheme() - */ - public String getScheme() - { - return _scheme; - } + if (port > 0 && ((scheme.equalsIgnoreCase("http") && port != 80) || (scheme.equalsIgnoreCase("https") && port != 443))) + { + url.append(':'); + url.append(port); + } + return url; + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.ServletRequest#getServerName() - */ - public String getServerName() - { - // Return already determined host - if (_serverName != null) - return _serverName; + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.ServletRequest#getScheme() + */ + public String getScheme() + { + return _scheme; + } - if (_uri == null) - throw new IllegalStateException("No uri"); - - // Return host from absolute URI - _serverName = _uri.getHost(); - _port = _uri.getPort(); - if (_serverName != null) - return _serverName; + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.ServletRequest#getServerName() + */ + public String getServerName() + { + // Return already determined host + if (_serverName != null) + return _serverName; - // Return host from header field - Buffer hostPort = _connection.getRequestFields().get(HttpHeaders.HOST_BUFFER); - if (hostPort != null) - { - loop: for (int i = hostPort.putIndex(); i-- > hostPort.getIndex();) - { - char ch = (char)(0xff & hostPort.peek(i)); - switch (ch) - { - case ']': - break loop; + if (_uri == null) + throw new IllegalStateException("No uri"); + + // Return host from absolute URI + _serverName = _uri.getHost(); + _port = _uri.getPort(); + if (_serverName != null) + return _serverName; - case ':': - _serverName = BufferUtil.to8859_1_String(hostPort.peek(hostPort.getIndex(),i - hostPort.getIndex())); - try - { - _port = BufferUtil.toInt(hostPort.peek(i + 1,hostPort.putIndex() - i - 1)); - } - catch (NumberFormatException e) - { - try - { - if (_connection != null) - _connection._generator.sendError(HttpStatus.BAD_REQUEST_400,"Bad Host header",null,true); - } - catch (IOException e1) - { - throw new RuntimeException(e1); - } - } - return _serverName; - } - } - if (_serverName == null || _port < 0) - { - _serverName = BufferUtil.to8859_1_String(hostPort); - _port = 0; - } + // Return host from header field + Buffer hostPort = _connection.getRequestFields().get(HttpHeaders.HOST_BUFFER); + if (hostPort != null) + { + loop: for (int i = hostPort.putIndex(); i-- > hostPort.getIndex();) + { + char ch = (char)(0xff & hostPort.peek(i)); + switch (ch) + { + case ']': + break loop; - return _serverName; - } - - // Return host from connection - if (_connection != null) - { - _serverName = getLocalName(); - _port = getLocalPort(); - if (_serverName != null && !StringUtil.ALL_INTERFACES.equals(_serverName)) - return _serverName; - } + case ':': + _serverName = BufferUtil.to8859_1_String(hostPort.peek(hostPort.getIndex(),i - hostPort.getIndex())); + try + { + _port = BufferUtil.toInt(hostPort.peek(i + 1,hostPort.putIndex() - i - 1)); + } + catch (NumberFormatException e) + { + try + { + if (_connection != null) + _connection._generator.sendError(HttpStatus.BAD_REQUEST_400,"Bad Host header",null,true); + } + catch (IOException e1) + { + throw new RuntimeException(e1); + } + } + return _serverName; + } + } + if (_serverName == null || _port < 0) + { + _serverName = BufferUtil.to8859_1_String(hostPort); + _port = 0; + } - // Return the local host - try - { - _serverName = InetAddress.getLocalHost().getHostAddress(); - } - catch (java.net.UnknownHostException e) - { - LOG.ignore(e); - } - return _serverName; - } + return _serverName; + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.ServletRequest#getServerPort() - */ - public int getServerPort() - { - if (_port <= 0) - { - if (_serverName == null) - getServerName(); + // Return host from connection + if (_connection != null) + { + _serverName = getLocalName(); + _port = getLocalPort(); + if (_serverName != null && !StringUtil.ALL_INTERFACES.equals(_serverName)) + return _serverName; + } - if (_port <= 0) - { - if (_serverName != null && _uri != null) - _port = _uri.getPort(); - else - _port = _endp == null?0:_endp.getLocalPort(); - } - } + // Return the local host + try + { + _serverName = InetAddress.getLocalHost().getHostAddress(); + } + catch (java.net.UnknownHostException e) + { + LOG.ignore(e); + } + return _serverName; + } - if (_port <= 0) - { - if (getScheme().equalsIgnoreCase(URIUtil.HTTPS)) - return 443; - return 80; - } - return _port; - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.ServletRequest#getServerPort() + */ + public int getServerPort() + { + if (_port <= 0) + { + if (_serverName == null) + getServerName(); - /* ------------------------------------------------------------ */ - public ServletContext getServletContext() - { - return _context; - } - - /* ------------------------------------------------------------ */ - /* - */ - public String getServletName() - { - if (_scope != null) - return _scope.getName(); - return null; - } + if (_port <= 0) + { + if (_serverName != null && _uri != null) + _port = _uri.getPort(); + else + _port = _endp == null?0:_endp.getLocalPort(); + } + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.http.HttpServletRequest#getServletPath() - */ - public String getServletPath() - { - if (_servletPath == null) - _servletPath = ""; - return _servletPath; - } + if (_port <= 0) + { + if (getScheme().equalsIgnoreCase(URIUtil.HTTPS)) + return 443; + return 80; + } + return _port; + } - /* ------------------------------------------------------------ */ - public ServletResponse getServletResponse() - { - return _connection.getResponse(); - } + /* ------------------------------------------------------------ */ + public ServletContext getServletContext() + { + return _context; + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.http.HttpServletRequest#getSession() - */ - public HttpSession getSession() - { - return getSession(true); - } + /* ------------------------------------------------------------ */ + /* + */ + public String getServletName() + { + if (_scope != null) + return _scope.getName(); + return null; + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.http.HttpServletRequest#getSession(boolean) - */ - public HttpSession getSession(boolean create) - { - if (_session != null) - { - if (_sessionManager != null && !_sessionManager.isValid(_session)) - _session = null; - else - return _session; - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.http.HttpServletRequest#getServletPath() + */ + public String getServletPath() + { + if (_servletPath == null) + _servletPath = ""; + return _servletPath; + } - if (!create) - return null; - - if (_sessionManager == null) - throw new IllegalStateException("No SessionManager"); + /* ------------------------------------------------------------ */ + public ServletResponse getServletResponse() + { + return _connection.getResponse(); + } - _session = _sessionManager.newHttpSession(this); - HttpCookie cookie = _sessionManager.getSessionCookie(_session,getContextPath(),isSecure()); - if (cookie != null) - _connection.getResponse().addCookie(cookie); - - return _session; - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.http.HttpServletRequest#getSession() + */ + public HttpSession getSession() + { + return getSession(true); + } - /* ------------------------------------------------------------ */ - /** - * @return Returns the sessionManager. - */ - public SessionManager getSessionManager() - { - return _sessionManager; - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.http.HttpServletRequest#getSession(boolean) + */ + public HttpSession getSession(boolean create) + { + throw new UnsupportedOperationException(); + } - /* ------------------------------------------------------------ */ - /** - * Get Request TimeStamp - * - * @return The time that the request was received. - */ - public long getTimeStamp() - { - return _timeStamp; - } + /* ------------------------------------------------------------ */ + /** + * Get Request TimeStamp + * + * @return The time that the request was received. + */ + public long getTimeStamp() + { + return _timeStamp; + } - /* ------------------------------------------------------------ */ - /** - * Get Request TimeStamp - * - * @return The time that the request was received. - */ - public Buffer getTimeStampBuffer() - { - if (_timeStampBuffer == null && _timeStamp > 0) - _timeStampBuffer = HttpFields.__dateCache.formatBuffer(_timeStamp); - return _timeStampBuffer; - } + /* ------------------------------------------------------------ */ + /** + * Get Request TimeStamp + * + * @return The time that the request was received. + */ + public Buffer getTimeStampBuffer() + { + if (_timeStampBuffer == null && _timeStamp > 0) + _timeStampBuffer = HttpFields.__dateCache.formatBuffer(_timeStamp); + return _timeStampBuffer; + } - /* ------------------------------------------------------------ */ - /** - * @return Returns the uri. - */ - public HttpURI getUri() - { - return _uri; - } + /* ------------------------------------------------------------ */ + /** + * @return Returns the uri. + */ + public HttpURI getUri() + { + return _uri; + } - /* ------------------------------------------------------------ */ - public UserIdentity getUserIdentity() - { - if (_authentication instanceof Authentication.Deferred) - setAuthentication(((Authentication.Deferred)_authentication).authenticate(this)); + /* ------------------------------------------------------------ */ + public UserIdentity getUserIdentity() + { + if (_authentication instanceof Authentication.Deferred) + setAuthentication(((Authentication.Deferred)_authentication).authenticate(this)); - if (_authentication instanceof Authentication.User) - return ((Authentication.User)_authentication).getUserIdentity(); - return null; - } + if (_authentication instanceof Authentication.User) + return ((Authentication.User)_authentication).getUserIdentity(); + return null; + } - /* ------------------------------------------------------------ */ - /** - * @return The resolved user Identity, which may be null if the {@link Authentication} is not {@link Authentication.User} (eg. - * {@link Authentication.Deferred}). - */ - public UserIdentity getResolvedUserIdentity() - { - if (_authentication instanceof Authentication.User) - return ((Authentication.User)_authentication).getUserIdentity(); - return null; - } + /* ------------------------------------------------------------ */ + /** + * @return The resolved user Identity, which may be null if the {@link Authentication} is not {@link Authentication.User} (eg. + * {@link Authentication.Deferred}). + */ + public UserIdentity getResolvedUserIdentity() + { + if (_authentication instanceof Authentication.User) + return ((Authentication.User)_authentication).getUserIdentity(); + return null; + } - /* ------------------------------------------------------------ */ - public UserIdentity.Scope getUserIdentityScope() - { - return _scope; - } + /* ------------------------------------------------------------ */ + public UserIdentity.Scope getUserIdentityScope() + { + return _scope; + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.http.HttpServletRequest#getUserPrincipal() - */ - public Principal getUserPrincipal() - { - if (_authentication instanceof Authentication.Deferred) - setAuthentication(((Authentication.Deferred)_authentication).authenticate(this)); + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.http.HttpServletRequest#getUserPrincipal() + */ + public Principal getUserPrincipal() + { + if (_authentication instanceof Authentication.Deferred) + setAuthentication(((Authentication.Deferred)_authentication).authenticate(this)); - if (_authentication instanceof Authentication.User) - { - UserIdentity user = ((Authentication.User)_authentication).getUserIdentity(); - return user.getUserPrincipal(); - } - - return null; - } + if (_authentication instanceof Authentication.User) + { + UserIdentity user = ((Authentication.User)_authentication).getUserIdentity(); + return user.getUserPrincipal(); + } + + return null; + } - /* ------------------------------------------------------------ */ - /** - * Get timestamp of the request dispatch - * - * @return timestamp - */ - public long getDispatchTime() - { - return _dispatchTime; - } + /* ------------------------------------------------------------ */ + /** + * Get timestamp of the request dispatch + * + * @return timestamp + */ + public long getDispatchTime() + { + return _dispatchTime; + } - /* ------------------------------------------------------------ */ - public boolean isHandled() - { - return _handled; - } + /* ------------------------------------------------------------ */ + public boolean isHandled() + { + return _handled; + } - public boolean isAsyncStarted() - { - return _async.isAsyncStarted(); - } + public boolean isAsyncStarted() + { + return _async.isAsyncStarted(); + } - /* ------------------------------------------------------------ */ - public boolean isAsyncSupported() - { - return _asyncSupported; - } + /* ------------------------------------------------------------ */ + public boolean isAsyncSupported() + { + return _asyncSupported; + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromCookie() - */ - public boolean isRequestedSessionIdFromCookie() - { - return _requestedSessionId != null && _requestedSessionIdFromCookie; - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromCookie() + */ + public boolean isRequestedSessionIdFromCookie() + { + return _requestedSessionId != null && _requestedSessionIdFromCookie; + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromUrl() - */ - public boolean isRequestedSessionIdFromUrl() - { - return _requestedSessionId != null && !_requestedSessionIdFromCookie; - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromUrl() + */ + public boolean isRequestedSessionIdFromUrl() + { + return _requestedSessionId != null && !_requestedSessionIdFromCookie; + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromURL() - */ - public boolean isRequestedSessionIdFromURL() - { - return _requestedSessionId != null && !_requestedSessionIdFromCookie; - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdFromURL() + */ + public boolean isRequestedSessionIdFromURL() + { + return _requestedSessionId != null && !_requestedSessionIdFromCookie; + } + + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdValid() + */ + public boolean isRequestedSessionIdValid() + { + throw new UnsupportedOperationException(); + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.http.HttpServletRequest#isRequestedSessionIdValid() - */ - public boolean isRequestedSessionIdValid() - { - if (_requestedSessionId == null) - return false; + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.ServletRequest#isSecure() + */ + public boolean isSecure() + { + return _connection.isConfidential(this); + } - HttpSession session = getSession(false); - return (session != null && _sessionManager.getSessionIdManager().getClusterId(_requestedSessionId).equals(_sessionManager.getClusterId(session))); - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.http.HttpServletRequest#isUserInRole(java.lang.String) + */ + public boolean isUserInRole(String role) + { + if (_authentication instanceof Authentication.Deferred) + setAuthentication(((Authentication.Deferred)_authentication).authenticate(this)); - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.ServletRequest#isSecure() - */ - public boolean isSecure() - { - return _connection.isConfidential(this); - } + if (_authentication instanceof Authentication.User) + return ((Authentication.User)_authentication).isUserInRole(_scope,role); + return false; + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.http.HttpServletRequest#isUserInRole(java.lang.String) - */ - public boolean isUserInRole(String role) - { - if (_authentication instanceof Authentication.Deferred) - setAuthentication(((Authentication.Deferred)_authentication).authenticate(this)); + /* ------------------------------------------------------------ */ + public HttpSession recoverNewSession(Object key) + { + if (_savedNewSessions == null) + return null; + return _savedNewSessions.get(key); + } - if (_authentication instanceof Authentication.User) - return ((Authentication.User)_authentication).isUserInRole(_scope,role); - return false; - } - - /* ------------------------------------------------------------ */ - public HttpSession recoverNewSession(Object key) - { - if (_savedNewSessions == null) - return null; - return _savedNewSessions.get(key); - } + /* ------------------------------------------------------------ */ + protected void recycle() + { + if (_inputState == __READER) + { + try + { + int r = _reader.read(); + while (r != -1) + r = _reader.read(); + } + catch (Exception e) + { + LOG.ignore(e); + _reader = null; + } + } - /* ------------------------------------------------------------ */ - protected void recycle() - { - if (_inputState == __READER) - { - try - { - int r = _reader.read(); - while (r != -1) - r = _reader.read(); - } - catch (Exception e) - { - LOG.ignore(e); - _reader = null; - } - } + setAuthentication(Authentication.NOT_CHECKED); + _async.recycle(); + _asyncSupported = true; + _handled = false; + if (_context != null) + throw new IllegalStateException("Request in context!"); + if (_attributes != null) + _attributes.clearAttributes(); + _characterEncoding = null; + _contextPath = null; + if (_cookies != null) + _cookies.reset(); + _cookiesExtracted = false; + _context = null; + _serverName = null; + _method = null; + _pathInfo = null; + _port = 0; + _protocol = HttpVersions.HTTP_1_1; + _queryEncoding = null; + _queryString = null; + _requestedSessionId = null; + _requestedSessionIdFromCookie = false; + _session = null; + _requestURI = null; + _scope = null; + _scheme = URIUtil.HTTP; + _servletPath = null; + _timeStamp = 0; + _timeStampBuffer = null; + _uri = null; + if (_baseParameters != null) + _baseParameters.clear(); + _parameters = null; + _paramsExtracted = false; + _inputState = __NONE; - setAuthentication(Authentication.NOT_CHECKED); - _async.recycle(); - _asyncSupported = true; - _handled = false; - if (_context != null) - throw new IllegalStateException("Request in context!"); - if (_attributes != null) - _attributes.clearAttributes(); - _characterEncoding = null; - _contextPath = null; - if (_cookies != null) - _cookies.reset(); - _cookiesExtracted = false; - _context = null; - _serverName = null; - _method = null; - _pathInfo = null; - _port = 0; - _protocol = HttpVersions.HTTP_1_1; - _queryEncoding = null; - _queryString = null; - _requestedSessionId = null; - _requestedSessionIdFromCookie = false; - _session = null; - _sessionManager = null; - _requestURI = null; - _scope = null; - _scheme = URIUtil.HTTP; - _servletPath = null; - _timeStamp = 0; - _timeStampBuffer = null; - _uri = null; - if (_baseParameters != null) - _baseParameters.clear(); - _parameters = null; - _paramsExtracted = false; - _inputState = __NONE; + if (_savedNewSessions != null) + _savedNewSessions.clear(); + _savedNewSessions=null; + _multiPartInputStream = null; + } + + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.ServletRequest#removeAttribute(java.lang.String) + */ + public void removeAttribute(String name) + { + Object old_value = _attributes == null?null:_attributes.getAttribute(name); - if (_savedNewSessions != null) - _savedNewSessions.clear(); - _savedNewSessions=null; - _multiPartInputStream = null; - } + if (_attributes != null) + _attributes.removeAttribute(name); - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.ServletRequest#removeAttribute(java.lang.String) - */ - public void removeAttribute(String name) - { - Object old_value = _attributes == null?null:_attributes.getAttribute(name); - - if (_attributes != null) - _attributes.removeAttribute(name); + if (old_value != null) + { + if (_requestAttributeListeners != null) + { + final ServletRequestAttributeEvent event = new ServletRequestAttributeEvent(_context,this,name,old_value); + final int size = LazyList.size(_requestAttributeListeners); + for (int i = 0; i < size; i++) + { + final EventListener listener = (ServletRequestAttributeListener)LazyList.get(_requestAttributeListeners,i); + if (listener instanceof ServletRequestAttributeListener) + { + final ServletRequestAttributeListener l = (ServletRequestAttributeListener)listener; + l.attributeRemoved(event); + } + } + } + } + } - if (old_value != null) - { - if (_requestAttributeListeners != null) - { - final ServletRequestAttributeEvent event = new ServletRequestAttributeEvent(_context,this,name,old_value); - final int size = LazyList.size(_requestAttributeListeners); - for (int i = 0; i < size; i++) - { - final EventListener listener = (ServletRequestAttributeListener)LazyList.get(_requestAttributeListeners,i); - if (listener instanceof ServletRequestAttributeListener) - { - final ServletRequestAttributeListener l = (ServletRequestAttributeListener)listener; - l.attributeRemoved(event); - } - } - } - } - } + /* ------------------------------------------------------------ */ + public void removeEventListener(final EventListener listener) + { + _requestAttributeListeners = LazyList.remove(_requestAttributeListeners,listener); + } + + /* ------------------------------------------------------------ */ + public void saveNewSession(Object key, HttpSession session) + { + if (_savedNewSessions == null) + _savedNewSessions = new HashMap<Object, HttpSession>(); + _savedNewSessions.put(key,session); + } - /* ------------------------------------------------------------ */ - public void removeEventListener(final EventListener listener) - { - _requestAttributeListeners = LazyList.remove(_requestAttributeListeners,listener); - } + /* ------------------------------------------------------------ */ + public void setAsyncSupported(boolean supported) + { + _asyncSupported = supported; + } - /* ------------------------------------------------------------ */ - public void saveNewSession(Object key, HttpSession session) - { - if (_savedNewSessions == null) - _savedNewSessions = new HashMap<Object, HttpSession>(); - _savedNewSessions.put(key,session); - } - - /* ------------------------------------------------------------ */ - public void setAsyncSupported(boolean supported) - { - _asyncSupported = supported; - } + /* ------------------------------------------------------------ */ + /* + * Set a request attribute. if the attribute name is "org.eclipse.jetty.server.server.Request.queryEncoding" then the value is also passed in a call to + * {@link #setQueryEncoding}. <p> if the attribute name is "org.eclipse.jetty.server.server.ResponseBuffer", then the response buffer is flushed with @{link + * #flushResponseBuffer} <p> if the attribute name is "org.eclipse.jetty.io.EndPoint.maxIdleTime", then the value is passed to the associated {@link + * EndPoint#setMaxIdleTime}. + * + * @see javax.servlet.ServletRequest#setAttribute(java.lang.String, java.lang.Object) + */ + public void setAttribute(String name, Object value) + { + Object old_value = _attributes == null?null:_attributes.getAttribute(name); - /* ------------------------------------------------------------ */ - /* - * Set a request attribute. if the attribute name is "org.eclipse.jetty.server.server.Request.queryEncoding" then the value is also passed in a call to - * {@link #setQueryEncoding}. <p> if the attribute name is "org.eclipse.jetty.server.server.ResponseBuffer", then the response buffer is flushed with @{link - * #flushResponseBuffer} <p> if the attribute name is "org.eclipse.jetty.io.EndPoint.maxIdleTime", then the value is passed to the associated {@link - * EndPoint#setMaxIdleTime}. - * - * @see javax.servlet.ServletRequest#setAttribute(java.lang.String, java.lang.Object) - */ - public void setAttribute(String name, Object value) - { - Object old_value = _attributes == null?null:_attributes.getAttribute(name); + if (name.startsWith("org.eclipse.jetty.")) + { + if ("org.eclipse.jetty.server.Request.queryEncoding".equals(name)) + setQueryEncoding(value == null?null:value.toString()); + else if ("org.eclipse.jetty.server.sendContent".equals(name)) + { + try + { + ((AbstractHttpConnection.Output)getServletResponse().getOutputStream()).sendContent(value); + } + catch (IOException e) + { + throw new RuntimeException(e); + } + } + else if ("org.eclipse.jetty.server.ResponseBuffer".equals(name)) + { + try + { + final ByteBuffer byteBuffer = (ByteBuffer)value; + synchronized (byteBuffer) + { + NIOBuffer buffer = byteBuffer.isDirect()?new DirectNIOBuffer(byteBuffer,true):new IndirectNIOBuffer(byteBuffer,true); + ((AbstractHttpConnection.Output)getServletResponse().getOutputStream()).sendResponse(buffer); + } + } + catch (IOException e) + { + throw new RuntimeException(e); + } + } + else if ("org.eclipse.jetty.io.EndPoint.maxIdleTime".equalsIgnoreCase(name)) + { + try + { + getConnection().getEndPoint().setMaxIdleTime(Integer.valueOf(value.toString())); + } + catch (IOException e) + { + throw new RuntimeException(e); + } + } + } - if (name.startsWith("org.eclipse.jetty.")) - { - if ("org.eclipse.jetty.server.Request.queryEncoding".equals(name)) - setQueryEncoding(value == null?null:value.toString()); - else if ("org.eclipse.jetty.server.sendContent".equals(name)) - { - try - { - ((AbstractHttpConnection.Output)getServletResponse().getOutputStream()).sendContent(value); - } - catch (IOException e) - { - throw new RuntimeException(e); - } - } - else if ("org.eclipse.jetty.server.ResponseBuffer".equals(name)) - { - try - { - final ByteBuffer byteBuffer = (ByteBuffer)value; - synchronized (byteBuffer) - { - NIOBuffer buffer = byteBuffer.isDirect()?new DirectNIOBuffer(byteBuffer,true):new IndirectNIOBuffer(byteBuffer,true); - ((AbstractHttpConnection.Output)getServletResponse().getOutputStream()).sendResponse(buffer); - } - } - catch (IOException e) - { - throw new RuntimeException(e); - } - } - else if ("org.eclipse.jetty.io.EndPoint.maxIdleTime".equalsIgnoreCase(name)) - { - try - { - getConnection().getEndPoint().setMaxIdleTime(Integer.valueOf(value.toString())); - } - catch (IOException e) - { - throw new RuntimeException(e); - } - } - } + if (_attributes == null) + _attributes = new AttributesMap(); + _attributes.setAttribute(name,value); + + if (_requestAttributeListeners != null) + { + final ServletRequestAttributeEvent event = new ServletRequestAttributeEvent(_context,this,name,old_value == null?value:old_value); + final int size = LazyList.size(_requestAttributeListeners); + for (int i = 0; i < size; i++) + { + final EventListener listener = (ServletRequestAttributeListener)LazyList.get(_requestAttributeListeners,i); + if (listener instanceof ServletRequestAttributeListener) + { + final ServletRequestAttributeListener l = (ServletRequestAttributeListener)listener; - if (_attributes == null) - _attributes = new AttributesMap(); - _attributes.setAttribute(name,value); - - if (_requestAttributeListeners != null) - { - final ServletRequestAttributeEvent event = new ServletRequestAttributeEvent(_context,this,name,old_value == null?value:old_value); - final int size = LazyList.size(_requestAttributeListeners); - for (int i = 0; i < size; i++) - { - final EventListener listener = (ServletRequestAttributeListener)LazyList.get(_requestAttributeListeners,i); - if (listener instanceof ServletRequestAttributeListener) - { - final ServletRequestAttributeListener l = (ServletRequestAttributeListener)listener; + if (old_value == null) + l.attributeAdded(event); + else if (value == null) + l.attributeRemoved(event); + else + l.attributeReplaced(event); + } + } + } + } - if (old_value == null) - l.attributeAdded(event); - else if (value == null) - l.attributeRemoved(event); - else - l.attributeReplaced(event); - } - } - } - } + /* ------------------------------------------------------------ */ + /* + */ + public void setAttributes(Attributes attributes) + { + _attributes = attributes; + } + + /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ - /* - */ - public void setAttributes(Attributes attributes) - { - _attributes = attributes; - } - - /* ------------------------------------------------------------ */ - - /* ------------------------------------------------------------ */ - /** - * Set the authentication. - * - * @param authentication - * the authentication to set - */ - public void setAuthentication(Authentication authentication) - { - _authentication = authentication; - } + /* ------------------------------------------------------------ */ + /** + * Set the authentication. + * + * @param authentication + * the authentication to set + */ + public void setAuthentication(Authentication authentication) + { + _authentication = authentication; + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.ServletRequest#setCharacterEncoding(java.lang.String) - */ - public void setCharacterEncoding(String encoding) throws UnsupportedEncodingException - { - if (_inputState != __NONE) - return; + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.ServletRequest#setCharacterEncoding(java.lang.String) + */ + public void setCharacterEncoding(String encoding) throws UnsupportedEncodingException + { + if (_inputState != __NONE) + return; - _characterEncoding = encoding; + _characterEncoding = encoding; - // check encoding is supported - if (!StringUtil.isUTF8(encoding)) - // noinspection ResultOfMethodCallIgnored - "".getBytes(encoding); - } + // check encoding is supported + if (!StringUtil.isUTF8(encoding)) + // noinspection ResultOfMethodCallIgnored + "".getBytes(encoding); + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.ServletRequest#setCharacterEncoding(java.lang.String) - */ - public void setCharacterEncodingUnchecked(String encoding) - { - _characterEncoding = encoding; - } + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.ServletRequest#setCharacterEncoding(java.lang.String) + */ + public void setCharacterEncodingUnchecked(String encoding) + { + _characterEncoding = encoding; + } - /* ------------------------------------------------------------ */ - // final so we can safely call this from constructor - protected final void setConnection(AbstractHttpConnection connection) - { - _connection = connection; - _async.setConnection(connection); - _endp = connection.getEndPoint(); - _dns = connection.getResolveNames(); - } + /* ------------------------------------------------------------ */ + // final so we can safely call this from constructor + protected final void setConnection(AbstractHttpConnection connection) + { + _connection = connection; + _async.setConnection(connection); + _endp = connection.getEndPoint(); + _dns = connection.getResolveNames(); + } - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.ServletRequest#getContentType() - */ - public void setContentType(String contentType) - { - _connection.getRequestFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,contentType); + /* ------------------------------------------------------------ */ + /* + * @see javax.servlet.ServletRequest#getContentType() + */ + public void setContentType(String contentType) + { + _connection.getRequestFields().put(HttpHeaders.CONTENT_TYPE_BUFFER,contentType); - } + } - /* ------------------------------------------------------------ */ - /** - * Set request context - * - * @param context - * context object - */ - public void setContext(Context context) - { - _newContext = _context != context; - _context = context; - } + /* ------------------------------------------------------------ */ + /** + * Set request context + * + * @param context + * context object + */ + public void setContext(Context context) + { + _newContext = _context != context; + _context = context; + } - /* ------------------------------------------------------------ */ - /** - * @return True if this is the first call of {@link #takeNewContext()} since the last - * {@link #setContext(org.eclipse.jetty.server.handler.ContextHandler.Context)} call. - */ - public boolean takeNewContext() - { - boolean nc = _newContext; - _newContext = false; - return nc; - } + /* ------------------------------------------------------------ */ + /** + * @return True if this is the first call of {@link #takeNewContext()} since the last + * {@link #setContext(org.eclipse.jetty.server.handler.ContextHandler.Context)} call. + */ + public boolean takeNewContext() + { + boolean nc = _newContext; + _newContext = false; + return nc; + } - /* ------------------------------------------------------------ */ - /** - * Sets the "context path" for this request - * - * @see HttpServletRequest#getContextPath() - */ - public void setContextPath(String contextPath) - { - _contextPath = contextPath; - } + /* ------------------------------------------------------------ */ + /** + * Sets the "context path" for this request + * + * @see HttpServletRequest#getContextPath() + */ + public void setContextPath(String contextPath) + { + _contextPath = contextPath; + } - /* ------------------------------------------------------------ */ - /** - * @param cookies - * The cookies to set. - */ - public void setCookies(Cookie[] cookies) - { - if (_cookies == null) - _cookies = new CookieCutter(); - _cookies.setCookies(cookies); - } + /* ------------------------------------------------------------ */ + /** + * @param cookies + * The cookies to set. + */ + public void setCookies(Cookie[] cookies) + { + if (_cookies == null) + _cookies = new CookieCutter(); + _cookies.setCookies(cookies); + } - /* ------------------------------------------------------------ */ - public void setDispatcherType(DispatcherType type) - { - _dispatcherType = type; - } + /* ------------------------------------------------------------ */ + public void setDispatcherType(DispatcherType type) + { + _dispatcherType = type; + } - /* ------------------------------------------------------------ */ - public void setHandled(boolean h) - { - _handled = h; - } + /* ------------------------------------------------------------ */ + public void setHandled(boolean h) + { + _handled = h; + } - /* ------------------------------------------------------------ */ - /** - * @param method - * The method to set. - */ - public void setMethod(String method) - { - _method = method; - } + /* ------------------------------------------------------------ */ + /** + * @param method + * The method to set. + */ + public void setMethod(String method) + { + _method = method; + } - /* ------------------------------------------------------------ */ - /** - * @param parameters - * The parameters to set. - */ - public void setParameters(MultiMap<String> parameters) - { - _parameters = (parameters == null)?_baseParameters:parameters; - if (_paramsExtracted && _parameters == null) - throw new IllegalStateException(); - } + /* ------------------------------------------------------------ */ + /** + * @param parameters + * The parameters to set. + */ + public void setParameters(MultiMap<String> parameters) + { + _parameters = (parameters == null)?_baseParameters:parameters; + if (_paramsExtracted && _parameters == null) + throw new IllegalStateException(); + } - /* ------------------------------------------------------------ */ - /** - * @param pathInfo - * The pathInfo to set. - */ - public void setPathInfo(String pathInfo) - { - _pathInfo = pathInfo; - } + /* ------------------------------------------------------------ */ + /** + * @param pathInfo + * The pathInfo to set. + */ + public void setPathInfo(String pathInfo) + { + _pathInfo = pathInfo; + } - /* ------------------------------------------------------------ */ - /** - * @param protocol - * The protocol to set. - */ - public void setProtocol(String protocol) - { - _protocol = protocol; - } + /* ------------------------------------------------------------ */ + /** + * @param protocol + * The protocol to set. + */ + public void setProtocol(String protocol) + { + _protocol = protocol; + } - /* ------------------------------------------------------------ */ - /** - * Set the character encoding used for the query string. This call will effect the return of getQueryString and getParamaters. It must be called before any - * geParameter methods. - * - * The request attribute "org.eclipse.jetty.server.server.Request.queryEncoding" may be set as an alternate method of calling setQueryEncoding. - * - * @param queryEncoding - */ - public void setQueryEncoding(String queryEncoding) - { - _queryEncoding = queryEncoding; - _queryString = null; - } + /* ------------------------------------------------------------ */ + /** + * Set the character encoding used for the query string. This call will effect the return of getQueryString and getParamaters. It must be called before any + * geParameter methods. + * + * The request attribute "org.eclipse.jetty.server.server.Request.queryEncoding" may be set as an alternate method of calling setQueryEncoding. + * + * @param queryEncoding + */ + public void setQueryEncoding(String queryEncoding) + { + _queryEncoding = queryEncoding; + _queryString = null; + } - /* ------------------------------------------------------------ */ - /** - * @param queryString - * The queryString to set. - */ - public void setQueryString(String queryString) - { - _queryString = queryString; - _queryEncoding = null; //assume utf-8 - } + /* ------------------------------------------------------------ */ + /** + * @param queryString + * The queryString to set. + */ + public void setQueryString(String queryString) + { + _queryString = queryString; + _queryEncoding = null; //assume utf-8 + } - /* ------------------------------------------------------------ */ - /** - * @param addr - * The address to set. - */ - public void setRemoteAddr(String addr) - { - _remoteAddr = addr; - } + /* ------------------------------------------------------------ */ + /** + * @param addr + * The address to set. + */ + public void setRemoteAddr(String addr) + { + _remoteAddr = addr; + } - /* ------------------------------------------------------------ */ - /** - * @param host - * The host to set. - */ - public void setRemoteHost(String host) - { - _remoteHost = host; - } + /* ------------------------------------------------------------ */ + /** + * @param host + * The host to set. + */ + public void setRemoteHost(String host) + { + _remoteHost = host; + } - /* ------------------------------------------------------------ */ - /** - * @param requestedSessionId - * The requestedSessionId to set. - */ - public void setRequestedSessionId(String requestedSessionId) - { - _requestedSessionId = requestedSessionId; - } + /* ------------------------------------------------------------ */ + /** + * @param requestedSessionId + * The requestedSessionId to set. + */ + public void setRequestedSessionId(String requestedSessionId) + { + _requestedSessionId = requestedSessionId; + } - /* ------------------------------------------------------------ */ - /** - * @param requestedSessionIdCookie - * The requestedSessionIdCookie to set. - */ - public void setRequestedSessionIdFromCookie(boolean requestedSessionIdCookie) - { - _requestedSessionIdFromCookie = requestedSessionIdCookie; - } + /* ------------------------------------------------------------ */ + /** + * @param requestedSessionIdCookie + * The requestedSessionIdCookie to set. + */ + public void setRequestedSessionIdFromCookie(boolean requestedSessionIdCookie) + { + _requestedSessionIdFromCookie = requestedSessionIdCookie; + } - /* ------------------------------------------------------------ */ - /** - * @param requestURI - * The requestURI to set. - */ - public void setRequestURI(String requestURI) - { - _requestURI = requestURI; - } + /* ------------------------------------------------------------ */ + /** + * @param requestURI + * The requestURI to set. + */ + public void setRequestURI(String requestURI) + { + _requestURI = requestURI; + } - /* ------------------------------------------------------------ */ - /** - * @param scheme - * The scheme to set. - */ - public void setScheme(String scheme) - { - _scheme = scheme; - } + /* ------------------------------------------------------------ */ + /** + * @param scheme + * The scheme to set. + */ + public void setScheme(String scheme) + { + _scheme = scheme; + } - /* ------------------------------------------------------------ */ - /** - * @param host - * The host to set. - */ - public void setServerName(String host) - { - _serverName = host; - } + /* ------------------------------------------------------------ */ + /** + * @param host + * The host to set. + */ + public void setServerName(String host) + { + _serverName = host; + } - /* ------------------------------------------------------------ */ - /** - * @param port - * The port to set. - */ - public void setServerPort(int port) - { - _port = port; - } + /* ------------------------------------------------------------ */ + /** + * @param port + * The port to set. + */ + public void setServerPort(int port) + { + _port = port; + } - /* ------------------------------------------------------------ */ - /** - * @param servletPath - * The servletPath to set. - */ - public void setServletPath(String servletPath) - { - _servletPath = servletPath; - } + /* ------------------------------------------------------------ */ + /** + * @param servletPath + * The servletPath to set. + */ + public void setServletPath(String servletPath) + { + _servletPath = servletPath; + } - /* ------------------------------------------------------------ */ - /** - * @param session - * The session to set. - */ - public void setSession(HttpSession session) - { - _session = session; - } + /* ------------------------------------------------------------ */ + /** + * @param session + * The session to set. + */ + public void setSession(HttpSession session) + { + _session = session; + } + + /* ------------------------------------------------------------ */ + public void setTimeStamp(long ts) + { + _timeStamp = ts; + } - /* ------------------------------------------------------------ */ - /** - * @param sessionManager - * The sessionManager to set. - */ - public void setSessionManager(SessionManager sessionManager) - { - _sessionManager = sessionManager; - } - - /* ------------------------------------------------------------ */ - public void setTimeStamp(long ts) - { - _timeStamp = ts; - } + /* ------------------------------------------------------------ */ + /** + * @param uri + * The uri to set. + */ + public void setUri(HttpURI uri) + { + _uri = uri; + } - /* ------------------------------------------------------------ */ - /** - * @param uri - * The uri to set. - */ - public void setUri(HttpURI uri) - { - _uri = uri; - } + /* ------------------------------------------------------------ */ + public void setUserIdentityScope(UserIdentity.Scope scope) + { + _scope = scope; + } - /* ------------------------------------------------------------ */ - public void setUserIdentityScope(UserIdentity.Scope scope) - { - _scope = scope; - } + /* ------------------------------------------------------------ */ + /** + * Set timetstamp of request dispatch + * + * @param value + * timestamp + */ + public void setDispatchTime(long value) + { + _dispatchTime = value; + } - /* ------------------------------------------------------------ */ - /** - * Set timetstamp of request dispatch - * - * @param value - * timestamp - */ - public void setDispatchTime(long value) - { - _dispatchTime = value; - } + /* ------------------------------------------------------------ */ + public AsyncContext startAsync() throws IllegalStateException + { + if (!_asyncSupported) + throw new IllegalStateException("!asyncSupported"); + _async.startAsync(); + return _async; + } + + /* ------------------------------------------------------------ */ + public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) throws IllegalStateException + { + if (!_asyncSupported) + throw new IllegalStateException("!asyncSupported"); + _async.startAsync(_context,servletRequest,servletResponse); + return _async; + } - /* ------------------------------------------------------------ */ - public AsyncContext startAsync() throws IllegalStateException - { - if (!_asyncSupported) - throw new IllegalStateException("!asyncSupported"); - _async.startAsync(); - return _async; - } + /* ------------------------------------------------------------ */ + @Override + public String toString() + { + return (_handled?"[":"(") + getMethod() + " " + _uri + (_handled?"]@":")@") + hashCode() + " " + super.toString(); + } - /* ------------------------------------------------------------ */ - public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) throws IllegalStateException - { - if (!_asyncSupported) - throw new IllegalStateException("!asyncSupported"); - _async.startAsync(_context,servletRequest,servletResponse); - return _async; - } + /* ------------------------------------------------------------ */ + public boolean authenticate(HttpServletResponse response) throws IOException, ServletException + { + if (_authentication instanceof Authentication.Deferred) + { + setAuthentication(((Authentication.Deferred)_authentication).authenticate(this,response)); + return !(_authentication instanceof Authentication.ResponseSent); + } + response.sendError(HttpStatus.UNAUTHORIZED_401); + return false; + } - /* ------------------------------------------------------------ */ - @Override - public String toString() - { - return (_handled?"[":"(") + getMethod() + " " + _uri + (_handled?"]@":")@") + hashCode() + " " + super.toString(); - } + /* ------------------------------------------------------------ */ + public Part getPart(String name) throws IOException, ServletException + { + getParts(); + return _multiPartInputStream.getPart(name); + } - /* ------------------------------------------------------------ */ - public boolean authenticate(HttpServletResponse response) throws IOException, ServletException - { - if (_authentication instanceof Authentication.Deferred) - { - setAuthentication(((Authentication.Deferred)_authentication).authenticate(this,response)); - return !(_authentication instanceof Authentication.ResponseSent); - } - response.sendError(HttpStatus.UNAUTHORIZED_401); - return false; - } - - /* ------------------------------------------------------------ */ - public Part getPart(String name) throws IOException, ServletException - { - getParts(); - return _multiPartInputStream.getPart(name); - } + /* ------------------------------------------------------------ */ + public Collection<Part> getParts() throws IOException, ServletException + { + if (getContentType() == null || !getContentType().startsWith("multipart/form-data")) + throw new ServletException("Content-Type != multipart/form-data"); + + if (_multiPartInputStream == null) + _multiPartInputStream = (MultiPartInputStream)getAttribute(__MULTIPART_INPUT_STREAM); + + if (_multiPartInputStream == null) + { + MultipartConfigElement config = (MultipartConfigElement)getAttribute(__MULTIPART_CONFIG_ELEMENT); + + if (config == null) + throw new IllegalStateException("No multipart config for servlet"); + + _multiPartInputStream = new MultiPartInputStream(getInputStream(), + getContentType(), config, + (_context != null?(File)_context.getAttribute("javax.servlet.context.tempdir"):null)); + + setAttribute(__MULTIPART_INPUT_STREAM, _multiPartInputStream); + setAttribute(__MULTIPART_CONTEXT, _context); + Collection<Part> parts = _multiPartInputStream.getParts(); //causes parsing + for (Part p:parts) + { + MultiPartInputStream.MultiPart mp = (MultiPartInputStream.MultiPart)p; + if (mp.getContentDispositionFilename() == null) + { + //Servlet Spec 3.0 pg 23, parts without filenames must be put into init params + String charset = null; + if (mp.getContentType() != null) + charset = MimeTypes.getCharsetFromContentType(new ByteArrayBuffer(mp.getContentType())); - /* ------------------------------------------------------------ */ - public Collection<Part> getParts() throws IOException, ServletException - { - if (getContentType() == null || !getContentType().startsWith("multipart/form-data")) - throw new ServletException("Content-Type != multipart/form-data"); - - if (_multiPartInputStream == null) - _multiPartInputStream = (MultiPartInputStream)getAttribute(__MULTIPART_INPUT_STREAM); - - if (_multiPartInputStream == null) - { - MultipartConfigElement config = (MultipartConfigElement)getAttribute(__MULTIPART_CONFIG_ELEMENT); - - if (config == null) - throw new IllegalStateException("No multipart config for servlet"); - - _multiPartInputStream = new MultiPartInputStream(getInputStream(), - getContentType(), config, - (_context != null?(File)_context.getAttribute("javax.servlet.context.tempdir"):null)); - - setAttribute(__MULTIPART_INPUT_STREAM, _multiPartInputStream); - setAttribute(__MULTIPART_CONTEXT, _context); - Collection<Part> parts = _multiPartInputStream.getParts(); //causes parsing - for (Part p:parts) - { - MultiPartInputStream.MultiPart mp = (MultiPartInputStream.MultiPart)p; - if (mp.getContentDispositionFilename() == null) - { - //Servlet Spec 3.0 pg 23, parts without filenames must be put into init params - String charset = null; - if (mp.getContentType() != null) - charset = MimeTypes.getCharsetFromContentType(new ByteArrayBuffer(mp.getContentType())); + ByteArrayOutputStream os = null; + InputStream is = mp.getInputStream(); //get the bytes regardless of being in memory or in temp file + try + { + os = new ByteArrayOutputStream(); + IO.copy(is, os); + String content=new String(os.toByteArray(),charset==null?StringUtil.__UTF8:charset); + getParameter(""); //cause params to be evaluated + getParameters().add(mp.getName(), content); + } + finally + { + IO.close(os); + IO.close(is); + } + } + } + } + + return _multiPartInputStream.getParts(); + } - ByteArrayOutputStream os = null; - InputStream is = mp.getInputStream(); //get the bytes regardless of being in memory or in temp file - try - { - os = new ByteArrayOutputStream(); - IO.copy(is, os); - String content=new String(os.toByteArray(),charset==null?StringUtil.__UTF8:charset); - getParameter(""); //cause params to be evaluated - getParameters().add(mp.getName(), content); - } - finally - { - IO.close(os); - IO.close(is); - } - } - } - } - - return _multiPartInputStream.getParts(); - } + /* ------------------------------------------------------------ */ + public void login(String username, String password) throws ServletException + { + if (_authentication instanceof Authentication.Deferred) + { + _authentication=((Authentication.Deferred)_authentication).login(username,password,this); + if (_authentication == null) + throw new ServletException(); + } + else + { + throw new ServletException("Authenticated as "+_authentication); + } + } - /* ------------------------------------------------------------ */ - public void login(String username, String password) throws ServletException - { - if (_authentication instanceof Authentication.Deferred) - { - _authentication=((Authentication.Deferred)_authentication).login(username,password,this); - if (_authentication == null) - throw new ServletException(); - } - else - { - throw new ServletException("Authenticated as "+_authentication); - } - } + /* ------------------------------------------------------------ */ + public void logout() throws ServletException + { + if (_authentication instanceof Authentication.User) + ((Authentication.User)_authentication).logout(); + _authentication=Authentication.UNAUTHENTICATED; + } + + /* ------------------------------------------------------------ */ + /** + * Merge in a new query string. The query string is merged with the existing parameters and {@link #setParameters(MultiMap)} and + * {@link #setQueryString(String)} are called with the result. The merge is according to the rules of the servlet dispatch forward method. + * + * @param query + * The query string to merge into the request. + */ + public void mergeQueryString(String query) + { + // extract parameters from dispatch query + MultiMap<String> parameters = new MultiMap<String>(); + UrlEncoded.decodeTo(query,parameters, StringUtil.__UTF8); //have to assume UTF-8 because we can't know otherwise - /* ------------------------------------------------------------ */ - public void logout() throws ServletException - { - if (_authentication instanceof Authentication.User) - ((Authentication.User)_authentication).logout(); - _authentication=Authentication.UNAUTHENTICATED; - } - - /* ------------------------------------------------------------ */ - /** - * Merge in a new query string. The query string is merged with the existing parameters and {@link #setParameters(MultiMap)} and - * {@link #setQueryString(String)} are called with the result. The merge is according to the rules of the servlet dispatch forward method. - * - * @param query - * The query string to merge into the request. - */ - public void mergeQueryString(String query) - { - // extract parameters from dispatch query - MultiMap<String> parameters = new MultiMap<String>(); - UrlEncoded.decodeTo(query,parameters, StringUtil.__UTF8); //have to assume UTF-8 because we can't know otherwise + boolean merge_old_query = false; - boolean merge_old_query = false; + // Have we evaluated parameters + if (!_paramsExtracted) + extractParameters(); - // Have we evaluated parameters - if (!_paramsExtracted) - extractParameters(); + // Are there any existing parameters? + if (_parameters != null && _parameters.size() > 0) + { + // Merge parameters; new parameters of the same name take precedence. + Iterator<Entry<String, Object>> iter = _parameters.entrySet().iterator(); + while (iter.hasNext()) + { + Map.Entry<String, Object> entry = iter.next(); + String name = entry.getKey(); - // Are there any existing parameters? - if (_parameters != null && _parameters.size() > 0) - { - // Merge parameters; new parameters of the same name take precedence. - Iterator<Entry<String, Object>> iter = _parameters.entrySet().iterator(); - while (iter.hasNext()) - { - Map.Entry<String, Object> entry = iter.next(); - String name = entry.getKey(); + // If the names match, we will need to remake the query string + if (parameters.containsKey(name)) + merge_old_query = true; - // If the names match, we will need to remake the query string - if (parameters.containsKey(name)) - merge_old_query = true; - - // Add the old values to the new parameter map - Object values = entry.getValue(); - for (int i = 0; i < LazyList.size(values); i++) - parameters.add(name,LazyList.get(values,i)); - } - } + // Add the old values to the new parameter map + Object values = entry.getValue(); + for (int i = 0; i < LazyList.size(values); i++) + parameters.add(name,LazyList.get(values,i)); + } + } - if (_queryString != null && _queryString.length() > 0) - { - if (merge_old_query) - { - StringBuilder overridden_query_string = new StringBuilder(); - MultiMap<String> overridden_old_query = new MultiMap<String>(); - UrlEncoded.decodeTo(_queryString,overridden_old_query,getQueryEncoding());//decode using any queryencoding set for the request - - - MultiMap<String> overridden_new_query = new MultiMap<String>(); - UrlEncoded.decodeTo(query,overridden_new_query,StringUtil.__UTF8); //have to assume utf8 as we cannot know otherwise + if (_queryString != null && _queryString.length() > 0) + { + if (merge_old_query) + { + StringBuilder overridden_query_string = new StringBuilder(); + MultiMap<String> overridden_old_query = new MultiMap<String>(); + UrlEncoded.decodeTo(_queryString,overridden_old_query,getQueryEncoding());//decode using any queryencoding set for the request + + + MultiMap<String> overridden_new_query = new MultiMap<String>(); + UrlEncoded.decodeTo(query,overridden_new_query,StringUtil.__UTF8); //have to assume utf8 as we cannot know otherwise - Iterator<Entry<String, Object>> iter = overridden_old_query.entrySet().iterator(); - while (iter.hasNext()) - { - Map.Entry<String, Object> entry = iter.next(); - String name = entry.getKey(); - if (!overridden_new_query.containsKey(name)) - { - Object values = entry.getValue(); - for (int i = 0; i < LazyList.size(values); i++) - { - overridden_query_string.append("&").append(name).append("=").append((Object)LazyList.get(values,i)); - } - } - } + Iterator<Entry<String, Object>> iter = overridden_old_query.entrySet().iterator(); + while (iter.hasNext()) + { + Map.Entry<String, Object> entry = iter.next(); + String name = entry.getKey(); + if (!overridden_new_query.containsKey(name)) + { + Object values = entry.getValue(); + for (int i = 0; i < LazyList.size(values); i++) + { + overridden_query_string.append("&").append(name).append("=").append((Object)LazyList.get(values,i)); + } + } + } - query = query + overridden_query_string; - } - else - { - query = query + "&" + _queryString; - } - } + query = query + overridden_query_string; + } + else + { + query = query + "&" + _queryString; + } + } - setParameters(parameters); - setQueryString(query); - } + setParameters(parameters); + setQueryString(query); + } }
--- a/src/org/eclipse/jetty/server/Response.java Thu Sep 08 16:13:27 2016 -0600 +++ b/src/org/eclipse/jetty/server/Response.java Thu Sep 08 16:38:30 2016 -0600 @@ -187,96 +187,7 @@ */ public String encodeURL(String url) { - final Request request=_connection.getRequest(); - SessionManager sessionManager = request.getSessionManager(); - if (sessionManager==null) - return url; - - HttpURI uri = null; - if (sessionManager.isCheckingRemoteSessionIdEncoding() && URIUtil.hasScheme(url)) - { - uri = new HttpURI(url); - String path = uri.getPath(); - path = (path == null?"":path); - int port=uri.getPort(); - if (port<0) - port = HttpSchemes.HTTPS.equalsIgnoreCase(uri.getScheme())?443:80; - if (!request.getServerName().equalsIgnoreCase(uri.getHost()) || - request.getServerPort()!=port || - !path.startsWith(request.getContextPath())) //TODO the root context path is "", with which every non null string starts - return url; - } - - String sessionURLPrefix = sessionManager.getSessionIdPathParameterNamePrefix(); - if (sessionURLPrefix==null) - return url; - - if (url==null) - return null; - - // should not encode if cookies in evidence - if ((sessionManager.isUsingCookies() && request.isRequestedSessionIdFromCookie()) || !sessionManager.isUsingURLs()) - { - int prefix=url.indexOf(sessionURLPrefix); - if (prefix!=-1) - { - int suffix=url.indexOf("?",prefix); - if (suffix<0) - suffix=url.indexOf("#",prefix); - - if (suffix<=prefix) - return url.substring(0,prefix); - return url.substring(0,prefix)+url.substring(suffix); - } - return url; - } - - // get session; - HttpSession session=request.getSession(false); - - // no session - if (session == null) - return url; - - // invalid session - if (!sessionManager.isValid(session)) - return url; - - String id=sessionManager.getNodeId(session); - - if (uri == null) - uri = new HttpURI(url); - - - // Already encoded - int prefix=url.indexOf(sessionURLPrefix); - if (prefix!=-1) - { - int suffix=url.indexOf("?",prefix); - if (suffix<0) - suffix=url.indexOf("#",prefix); - - if (suffix<=prefix) - return url.substring(0,prefix+sessionURLPrefix.length())+id; - return url.substring(0,prefix+sessionURLPrefix.length())+id+ - url.substring(suffix); - } - - // edit the session - int suffix=url.indexOf('?'); - if (suffix<0) - suffix=url.indexOf('#'); - if (suffix<0) - { - return url+ - ((HttpSchemes.HTTPS.equalsIgnoreCase(uri.getScheme()) || HttpSchemes.HTTP.equalsIgnoreCase(uri.getScheme())) && uri.getPath()==null?"/":"") + //if no path, insert the root path - sessionURLPrefix+id; - } - - - return url.substring(0,suffix)+ - ((HttpSchemes.HTTPS.equalsIgnoreCase(uri.getScheme()) || HttpSchemes.HTTP.equalsIgnoreCase(uri.getScheme())) && uri.getPath()==null?"/":"")+ //if no path so insert the root path - sessionURLPrefix+id+url.substring(suffix); + throw new UnsupportedOperationException(); } /* ------------------------------------------------------------ */
--- a/src/org/eclipse/jetty/server/SessionManager.java Thu Sep 08 16:13:27 2016 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,307 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server; - -import java.util.EventListener; -import java.util.Set; - -import javax.servlet.SessionCookieConfig; -import javax.servlet.SessionTrackingMode; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; - -import org.eclipse.jetty.http.HttpCookie; -import org.eclipse.jetty.server.session.SessionHandler; -import org.eclipse.jetty.util.component.LifeCycle; - -/* --------------------------------------------------------------------- */ -/** - * Session Manager. - * The API required to manage sessions for a servlet context. - * - */ - -/* ------------------------------------------------------------ */ -/** - */ -public interface SessionManager extends LifeCycle -{ - /* ------------------------------------------------------------ */ - /** - * Session cookie name. - * Defaults to <code>JSESSIONID</code>, but can be set with the - * <code>org.eclipse.jetty.servlet.SessionCookie</code> context init parameter. - */ - public final static String __SessionCookieProperty = "org.eclipse.jetty.servlet.SessionCookie"; - public final static String __DefaultSessionCookie = "JSESSIONID"; - - - /* ------------------------------------------------------------ */ - /** - * Session id path parameter name. - * Defaults to <code>jsessionid</code>, but can be set with the - * <code>org.eclipse.jetty.servlet.SessionIdPathParameterName</code> context init parameter. - * If set to null or "none" no URL rewriting will be done. - */ - public final static String __SessionIdPathParameterNameProperty = "org.eclipse.jetty.servlet.SessionIdPathParameterName"; - public final static String __DefaultSessionIdPathParameterName = "jsessionid"; - public final static String __CheckRemoteSessionEncoding = "org.eclipse.jetty.servlet.CheckingRemoteSessionIdEncoding"; - - - /* ------------------------------------------------------------ */ - /** - * Session Domain. - * If this property is set as a ServletContext InitParam, then it is - * used as the domain for session cookies. If it is not set, then - * no domain is specified for the session cookie. - */ - public final static String __SessionDomainProperty = "org.eclipse.jetty.servlet.SessionDomain"; - public final static String __DefaultSessionDomain = null; - - - /* ------------------------------------------------------------ */ - /** - * Session Path. - * If this property is set as a ServletContext InitParam, then it is - * used as the path for the session cookie. If it is not set, then - * the context path is used as the path for the cookie. - */ - public final static String __SessionPathProperty = "org.eclipse.jetty.servlet.SessionPath"; - - /* ------------------------------------------------------------ */ - /** - * Session Max Age. - * If this property is set as a ServletContext InitParam, then it is - * used as the max age for the session cookie. If it is not set, then - * a max age of -1 is used. - */ - public final static String __MaxAgeProperty = "org.eclipse.jetty.servlet.MaxAge"; - - /* ------------------------------------------------------------ */ - /** - * Returns the <code>HttpSession</code> with the given session id - * - * @param id the session id - * @return the <code>HttpSession</code> with the corresponding id or null if no session with the given id exists - */ - public HttpSession getHttpSession(String id); - - /* ------------------------------------------------------------ */ - /** - * Creates a new <code>HttpSession</code>. - * - * @param request the HttpServletRequest containing the requested session id - * @return the new <code>HttpSession</code> - */ - public HttpSession newHttpSession(HttpServletRequest request); - - - /* ------------------------------------------------------------ */ - /** - * @return true if session cookies should be HTTP-only (Microsoft extension) - * @see org.eclipse.jetty.http.HttpCookie#isHttpOnly() - */ - public boolean getHttpOnly(); - - /* ------------------------------------------------------------ */ - /** - * @return the max period of inactivity, after which the session is invalidated, in seconds. - * @see #setMaxInactiveInterval(int) - */ - public int getMaxInactiveInterval(); - - /* ------------------------------------------------------------ */ - /** - * Sets the max period of inactivity, after which the session is invalidated, in seconds. - * - * @param seconds the max inactivity period, in seconds. - * @see #getMaxInactiveInterval() - */ - public void setMaxInactiveInterval(int seconds); - - /* ------------------------------------------------------------ */ - /** - * Sets the {@link SessionHandler}. - * - * @param handler the <code>SessionHandler</code> object - */ - public void setSessionHandler(SessionHandler handler); - - /* ------------------------------------------------------------ */ - /** - * Adds an event listener for session-related events. - * - * @param listener the session event listener to add - * Individual SessionManagers implementations may accept arbitrary listener types, - * but they are expected to at least handle HttpSessionActivationListener, - * HttpSessionAttributeListener, HttpSessionBindingListener and HttpSessionListener. - * @see #removeEventListener(EventListener) - */ - public void addEventListener(EventListener listener); - - /* ------------------------------------------------------------ */ - /** - * Removes an event listener for for session-related events. - * - * @param listener the session event listener to remove - * @see #addEventListener(EventListener) - */ - public void removeEventListener(EventListener listener); - - /* ------------------------------------------------------------ */ - /** - * Removes all event listeners for session-related events. - * - * @see #removeEventListener(EventListener) - */ - public void clearEventListeners(); - - /* ------------------------------------------------------------ */ - /** - * Gets a Cookie for a session. - * - * @param session the session to which the cookie should refer. - * @param contextPath the context to which the cookie should be linked. - * The client will only send the cookie value when requesting resources under this path. - * @param requestIsSecure whether the client is accessing the server over a secure protocol (i.e. HTTPS). - * @return if this <code>SessionManager</code> uses cookies, then this method will return a new - * {@link Cookie cookie object} that should be set on the client in order to link future HTTP requests - * with the <code>session</code>. If cookies are not in use, this method returns <code>null</code>. - */ - public HttpCookie getSessionCookie(HttpSession session, String contextPath, boolean requestIsSecure); - - /* ------------------------------------------------------------ */ - /** - * @return the cross context session id manager. - * @see #setSessionIdManager(SessionIdManager) - */ - public SessionIdManager getSessionIdManager(); - - /* ------------------------------------------------------------ */ - /** - * @return the cross context session id manager. - * @deprecated use {@link #getSessionIdManager()} - */ - @Deprecated - public SessionIdManager getMetaManager(); - - /* ------------------------------------------------------------ */ - /** - * Sets the cross context session id manager - * - * @param idManager the cross context session id manager. - * @see #getSessionIdManager() - */ - public void setSessionIdManager(SessionIdManager idManager); - - /* ------------------------------------------------------------ */ - /** - * @param session the session to test for validity - * @return whether the given session is valid, that is, it has not been invalidated. - */ - public boolean isValid(HttpSession session); - - /* ------------------------------------------------------------ */ - /** - * @param session the session object - * @return the unique id of the session within the cluster, extended with an optional node id. - * @see #getClusterId(HttpSession) - */ - public String getNodeId(HttpSession session); - - /* ------------------------------------------------------------ */ - /** - * @param session the session object - * @return the unique id of the session within the cluster (without a node id extension) - * @see #getNodeId(HttpSession) - */ - public String getClusterId(HttpSession session); - - /* ------------------------------------------------------------ */ - /** - * Called by the {@link SessionHandler} when a session is first accessed by a request. - * - * @param session the session object - * @param secure whether the request is secure or not - * @return the session cookie. If not null, this cookie should be set on the response to either migrate - * the session or to refresh a session cookie that may expire. - * @see #complete(HttpSession) - */ - public HttpCookie access(HttpSession session, boolean secure); - - /* ------------------------------------------------------------ */ - /** - * Called by the {@link SessionHandler} when a session is last accessed by a request. - * - * @param session the session object - * @see #access(HttpSession, boolean) - */ - public void complete(HttpSession session); - - /** - * Sets the session id URL path parameter name. - * - * @param parameterName the URL path parameter name for session id URL rewriting (null or "none" for no rewriting). - * @see #getSessionIdPathParameterName() - * @see #getSessionIdPathParameterNamePrefix() - */ - public void setSessionIdPathParameterName(String parameterName); - - /** - * @return the URL path parameter name for session id URL rewriting, by default "jsessionid". - * @see #setSessionIdPathParameterName(String) - */ - public String getSessionIdPathParameterName(); - - /** - * @return a formatted version of {@link #getSessionIdPathParameterName()}, by default - * ";" + sessionIdParameterName + "=", for easier lookup in URL strings. - * @see #getSessionIdPathParameterName() - */ - public String getSessionIdPathParameterNamePrefix(); - - /** - * @return whether the session management is handled via cookies. - */ - public boolean isUsingCookies(); - - /** - * @return whether the session management is handled via URLs. - */ - public boolean isUsingURLs(); - - public Set<SessionTrackingMode> getDefaultSessionTrackingModes(); - - public Set<SessionTrackingMode> getEffectiveSessionTrackingModes(); - - public void setSessionTrackingModes(Set<SessionTrackingMode> sessionTrackingModes); - - public SessionCookieConfig getSessionCookieConfig(); - - /** - * @return True if absolute URLs are check for remoteness before being session encoded. - */ - public boolean isCheckingRemoteSessionIdEncoding(); - - /** - * @param remote True if absolute URLs are check for remoteness before being session encoded. - */ - public void setCheckingRemoteSessionIdEncoding(boolean remote); -}
--- a/src/org/eclipse/jetty/server/session/AbstractSession.java Thu Sep 08 16:13:27 2016 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,568 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server.session; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSessionActivationListener; -import javax.servlet.http.HttpSessionBindingEvent; -import javax.servlet.http.HttpSessionBindingListener; -import javax.servlet.http.HttpSessionContext; -import javax.servlet.http.HttpSessionEvent; - -import org.eclipse.jetty.util.log.Logger; - -/** - * - * <p> - * Implements {@link javax.servlet.http.HttpSession} from the <code>javax.servlet</code> package. - * </p> - * - */ -@SuppressWarnings("deprecation") -public abstract class AbstractSession implements AbstractSessionManager.SessionIf -{ - final static Logger LOG = SessionHandler.LOG; - - private final AbstractSessionManager _manager; - private final String _clusterId; // ID unique within cluster - private final String _nodeId; // ID unique within node - private final Map<String,Object> _attributes=new HashMap<String, Object>(); - private boolean _idChanged; - private final long _created; - private long _cookieSet; - private long _accessed; // the time of the last access - private long _lastAccessed; // the time of the last access excluding this one - private boolean _invalid; - private boolean _doInvalidate; - private long _maxIdleMs; - private boolean _newSession; - private int _requests; - - - - /* ------------------------------------------------------------- */ - protected AbstractSession(AbstractSessionManager abstractSessionManager, HttpServletRequest request) - { - _manager = abstractSessionManager; - - _newSession=true; - _created=System.currentTimeMillis(); - _clusterId=_manager._sessionIdManager.newSessionId(request,_created); - _nodeId=_manager._sessionIdManager.getNodeId(_clusterId,request); - _accessed=_created; - _lastAccessed=_created; - _requests=1; - _maxIdleMs=_manager._dftMaxIdleSecs>0?_manager._dftMaxIdleSecs*1000L:-1; - if (LOG.isDebugEnabled()) - LOG.debug("new session & id "+_nodeId+" "+_clusterId); - } - - /* ------------------------------------------------------------- */ - protected AbstractSession(AbstractSessionManager abstractSessionManager, long created, long accessed, String clusterId) - { - _manager = abstractSessionManager; - _created=created; - _clusterId=clusterId; - _nodeId=_manager._sessionIdManager.getNodeId(_clusterId,null); - _accessed=accessed; - _lastAccessed=accessed; - _requests=1; - _maxIdleMs=_manager._dftMaxIdleSecs>0?_manager._dftMaxIdleSecs*1000L:-1; - if (LOG.isDebugEnabled()) - LOG.debug("new session "+_nodeId+" "+_clusterId); - } - - /* ------------------------------------------------------------- */ - /** - * asserts that the session is valid - */ - protected void checkValid() throws IllegalStateException - { - if (_invalid) - throw new IllegalStateException(); - } - - /* ------------------------------------------------------------- */ - public AbstractSession getSession() - { - return this; - } - - /* ------------------------------------------------------------- */ - public long getAccessed() - { - synchronized (this) - { - return _accessed; - } - } - - /* ------------------------------------------------------------ */ - public Object getAttribute(String name) - { - synchronized (this) - { - checkValid(); - return _attributes.get(name); - } - } - - /* ------------------------------------------------------------ */ - public int getAttributes() - { - synchronized (this) - { - checkValid(); - return _attributes.size(); - } - } - - /* ------------------------------------------------------------ */ - @SuppressWarnings({ "unchecked" }) - public Enumeration<String> getAttributeNames() - { - synchronized (this) - { - checkValid(); - List<String> names=_attributes==null?Collections.EMPTY_LIST:new ArrayList<String>(_attributes.keySet()); - return Collections.enumeration(names); - } - } - - /* ------------------------------------------------------------ */ - public Set<String> getNames() - { - synchronized (this) - { - return new HashSet<String>(_attributes.keySet()); - } - } - - /* ------------------------------------------------------------- */ - public long getCookieSetTime() - { - return _cookieSet; - } - - /* ------------------------------------------------------------- */ - public long getCreationTime() throws IllegalStateException - { - return _created; - } - - /* ------------------------------------------------------------ */ - public String getId() throws IllegalStateException - { - return _manager._nodeIdInSessionId?_nodeId:_clusterId; - } - - /* ------------------------------------------------------------- */ - public String getNodeId() - { - return _nodeId; - } - - /* ------------------------------------------------------------- */ - public String getClusterId() - { - return _clusterId; - } - - /* ------------------------------------------------------------- */ - public long getLastAccessedTime() throws IllegalStateException - { - checkValid(); - return _lastAccessed; - } - - /* ------------------------------------------------------------- */ - public void setLastAccessedTime(long time) - { - _lastAccessed = time; - } - - /* ------------------------------------------------------------- */ - public int getMaxInactiveInterval() - { - checkValid(); - return (int)(_maxIdleMs/1000); - } - - /* ------------------------------------------------------------ */ - /* - * @see javax.servlet.http.HttpSession#getServletContext() - */ - public ServletContext getServletContext() - { - return _manager._context; - } - - /* ------------------------------------------------------------- */ - @Deprecated - public HttpSessionContext getSessionContext() throws IllegalStateException - { - checkValid(); - return AbstractSessionManager.__nullSessionContext; - } - - /* ------------------------------------------------------------- */ - /** - * @deprecated As of Version 2.2, this method is replaced by - * {@link #getAttribute} - */ - @Deprecated - public Object getValue(String name) throws IllegalStateException - { - return getAttribute(name); - } - - /* ------------------------------------------------------------- */ - /** - * @deprecated As of Version 2.2, this method is replaced by - * {@link #getAttributeNames} - */ - @Deprecated - public String[] getValueNames() throws IllegalStateException - { - synchronized(this) - { - checkValid(); - if (_attributes==null) - return new String[0]; - String[] a=new String[_attributes.size()]; - return (String[])_attributes.keySet().toArray(a); - } - } - - /* ------------------------------------------------------------ */ - protected Map<String,Object> getAttributeMap () - { - return _attributes; - } - - /* ------------------------------------------------------------ */ - protected void addAttributes(Map<String,Object> map) - { - _attributes.putAll(map); - } - - /* ------------------------------------------------------------ */ - protected boolean access(long time) - { - synchronized(this) - { - if (_invalid) - return false; - _newSession=false; - _lastAccessed=_accessed; - _accessed=time; - - if (_maxIdleMs>0 && _lastAccessed>0 && _lastAccessed + _maxIdleMs < time) - { - invalidate(); - return false; - } - _requests++; - return true; - } - } - - /* ------------------------------------------------------------ */ - protected void complete() - { - synchronized(this) - { - _requests--; - if (_doInvalidate && _requests<=0 ) - doInvalidate(); - } - } - - - /* ------------------------------------------------------------- */ - protected void timeout() throws IllegalStateException - { - // remove session from context and invalidate other sessions with same ID. - _manager.removeSession(this,true); - - // Notify listeners and unbind values - boolean do_invalidate=false; - synchronized (this) - { - if (!_invalid) - { - if (_requests<=0) - do_invalidate=true; - else - _doInvalidate=true; - } - } - if (do_invalidate) - doInvalidate(); - } - - /* ------------------------------------------------------------- */ - public void invalidate() throws IllegalStateException - { - // remove session from context and invalidate other sessions with same ID. - _manager.removeSession(this,true); - doInvalidate(); - } - - /* ------------------------------------------------------------- */ - protected void doInvalidate() throws IllegalStateException - { - try - { - LOG.debug("invalidate {}",_clusterId); - if (isValid()) - clearAttributes(); - } - finally - { - synchronized (this) - { - // mark as invalid - _invalid=true; - } - } - } - - /* ------------------------------------------------------------- */ - public void clearAttributes() - { - while (_attributes!=null && _attributes.size()>0) - { - ArrayList<String> keys; - synchronized(this) - { - keys=new ArrayList<String>(_attributes.keySet()); - } - - Iterator<String> iter=keys.iterator(); - while (iter.hasNext()) - { - String key=(String)iter.next(); - - Object value; - synchronized(this) - { - value=doPutOrRemove(key,null); - } - unbindValue(key,value); - - _manager.doSessionAttributeListeners(this,key,value,null); - } - } - if (_attributes!=null) - _attributes.clear(); - } - - /* ------------------------------------------------------------- */ - public boolean isIdChanged() - { - return _idChanged; - } - - /* ------------------------------------------------------------- */ - public boolean isNew() throws IllegalStateException - { - checkValid(); - return _newSession; - } - - /* ------------------------------------------------------------- */ - /** - * @deprecated As of Version 2.2, this method is replaced by - * {@link #setAttribute} - */ - @Deprecated - public void putValue(java.lang.String name, java.lang.Object value) throws IllegalStateException - { - setAttribute(name,value); - } - - /* ------------------------------------------------------------ */ - public void removeAttribute(String name) - { - setAttribute(name,null); - } - - /* ------------------------------------------------------------- */ - /** - * @deprecated As of Version 2.2, this method is replaced by - * {@link #removeAttribute} - */ - @Deprecated - public void removeValue(java.lang.String name) throws IllegalStateException - { - removeAttribute(name); - } - - /* ------------------------------------------------------------ */ - protected Object doPutOrRemove(String name, Object value) - { - return value==null?_attributes.remove(name):_attributes.put(name,value); - } - - /* ------------------------------------------------------------ */ - protected Object doGet(String name) - { - return _attributes.get(name); - } - - /* ------------------------------------------------------------ */ - public void setAttribute(String name, Object value) - { - Object old=null; - synchronized (this) - { - checkValid(); - old=doPutOrRemove(name,value); - } - - if (value==null || !value.equals(old)) - { - if (old!=null) - unbindValue(name,old); - if (value!=null) - bindValue(name,value); - - _manager.doSessionAttributeListeners(this,name,old,value); - - } - } - - /* ------------------------------------------------------------- */ - public void setIdChanged(boolean changed) - { - _idChanged=changed; - } - - /* ------------------------------------------------------------- */ - public void setMaxInactiveInterval(int secs) - { - _maxIdleMs=(long)secs*1000L; - } - - /* ------------------------------------------------------------- */ - @Override - public String toString() - { - return this.getClass().getName()+":"+getId()+"@"+hashCode(); - } - - /* ------------------------------------------------------------- */ - /** If value implements HttpSessionBindingListener, call valueBound() */ - public void bindValue(java.lang.String name, Object value) - { - if (value!=null&&value instanceof HttpSessionBindingListener) - ((HttpSessionBindingListener)value).valueBound(new HttpSessionBindingEvent(this,name)); - } - - /* ------------------------------------------------------------ */ - public boolean isValid() - { - return !_invalid; - } - - /* ------------------------------------------------------------- */ - protected void cookieSet() - { - synchronized (this) - { - _cookieSet=_accessed; - } - } - - /* ------------------------------------------------------------ */ - public int getRequests() - { - synchronized (this) - { - return _requests; - } - } - - /* ------------------------------------------------------------ */ - public void setRequests(int requests) - { - synchronized (this) - { - _requests=requests; - } - } - - /* ------------------------------------------------------------- */ - /** If value implements HttpSessionBindingListener, call valueUnbound() */ - public void unbindValue(java.lang.String name, Object value) - { - if (value!=null&&value instanceof HttpSessionBindingListener) - ((HttpSessionBindingListener)value).valueUnbound(new HttpSessionBindingEvent(this,name)); - } - - /* ------------------------------------------------------------- */ - public void willPassivate() - { - synchronized(this) - { - HttpSessionEvent event = new HttpSessionEvent(this); - for (Iterator<Object> iter = _attributes.values().iterator(); iter.hasNext();) - { - Object value = iter.next(); - if (value instanceof HttpSessionActivationListener) - { - HttpSessionActivationListener listener = (HttpSessionActivationListener) value; - listener.sessionWillPassivate(event); - } - } - } - } - - /* ------------------------------------------------------------- */ - public void didActivate() - { - synchronized(this) - { - HttpSessionEvent event = new HttpSessionEvent(this); - for (Iterator<Object> iter = _attributes.values().iterator(); iter.hasNext();) - { - Object value = iter.next(); - if (value instanceof HttpSessionActivationListener) - { - HttpSessionActivationListener listener = (HttpSessionActivationListener) value; - listener.sessionDidActivate(event); - } - } - } - } - - -}
--- a/src/org/eclipse/jetty/server/session/AbstractSessionIdManager.java Thu Sep 08 16:13:27 2016 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,220 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server.session; - -import java.security.SecureRandom; -import java.util.Random; - -import javax.servlet.http.HttpServletRequest; - -import org.eclipse.jetty.server.SessionIdManager; -import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -public abstract class AbstractSessionIdManager extends AbstractLifeCycle implements SessionIdManager -{ - private static final Logger LOG = Log.getLogger(AbstractSessionIdManager.class); - - private final static String __NEW_SESSION_ID="org.eclipse.jetty.server.newSessionId"; - - protected Random _random; - protected boolean _weakRandom; - protected String _workerName; - protected long _reseed=100000L; - - /* ------------------------------------------------------------ */ - public AbstractSessionIdManager() - { - } - - /* ------------------------------------------------------------ */ - public AbstractSessionIdManager(Random random) - { - _random=random; - } - - - /* ------------------------------------------------------------ */ - /** - * @return the reseed probability - */ - public long getReseed() - { - return _reseed; - } - - /* ------------------------------------------------------------ */ - /** Set the reseed probability. - * @param reseed If non zero then when a random long modulo the reseed value == 1, the {@link SecureRandom} will be reseeded. - */ - public void setReseed(long reseed) - { - _reseed = reseed; - } - - /* ------------------------------------------------------------ */ - /** - * Get the workname. If set, the workername is dot appended to the session - * ID and can be used to assist session affinity in a load balancer. - * - * @return String or null - */ - public String getWorkerName() - { - return _workerName; - } - - /* ------------------------------------------------------------ */ - /** - * Set the workname. If set, the workername is dot appended to the session - * ID and can be used to assist session affinity in a load balancer. - * - * @param workerName - */ - public void setWorkerName(String workerName) - { - if (workerName.contains(".")) - throw new IllegalArgumentException("Name cannot contain '.'"); - _workerName=workerName; - } - - /* ------------------------------------------------------------ */ - public Random getRandom() - { - return _random; - } - - /* ------------------------------------------------------------ */ - public synchronized void setRandom(Random random) - { - _random=random; - _weakRandom=false; - } - - /* ------------------------------------------------------------ */ - /** - * Create a new session id if necessary. - * - * @see org.eclipse.jetty.server.SessionIdManager#newSessionId(javax.servlet.http.HttpServletRequest, long) - */ - public String newSessionId(HttpServletRequest request, long created) - { - synchronized (this) - { - if (request!=null) - { - // A requested session ID can only be used if it is in use already. - String requested_id=request.getRequestedSessionId(); - if (requested_id!=null) - { - String cluster_id=getClusterId(requested_id); - if (idInUse(cluster_id)) - return cluster_id; - } - - // Else reuse any new session ID already defined for this request. - String new_id=(String)request.getAttribute(__NEW_SESSION_ID); - if (new_id!=null&&idInUse(new_id)) - return new_id; - } - - // pick a new unique ID! - String id=null; - while (id==null||id.length()==0||idInUse(id)) - { - long r0=_weakRandom - ?(hashCode()^Runtime.getRuntime().freeMemory()^_random.nextInt()^(((long)request.hashCode())<<32)) - :_random.nextLong(); - if (r0<0) - r0=-r0; - - // random chance to reseed - if (_reseed>0 && (r0%_reseed)== 1L) - { - LOG.debug("Reseeding {}",this); - if (_random instanceof SecureRandom) - { - SecureRandom secure = (SecureRandom)_random; - secure.setSeed(secure.generateSeed(8)); - } - else - { - _random.setSeed(_random.nextLong()^System.currentTimeMillis()^request.hashCode()^Runtime.getRuntime().freeMemory()); - } - } - - long r1=_weakRandom - ?(hashCode()^Runtime.getRuntime().freeMemory()^_random.nextInt()^(((long)request.hashCode())<<32)) - :_random.nextLong(); - if (r1<0) - r1=-r1; - id=Long.toString(r0,36)+Long.toString(r1,36); - - //add in the id of the node to ensure unique id across cluster - //NOTE this is different to the node suffix which denotes which node the request was received on - if (_workerName!=null) - id=_workerName + id; - } - - request.setAttribute(__NEW_SESSION_ID,id); - return id; - } - } - - /* ------------------------------------------------------------ */ - @Override - protected void doStart() throws Exception - { - initRandom(); - } - - /* ------------------------------------------------------------ */ - @Override - protected void doStop() throws Exception - { - } - - /* ------------------------------------------------------------ */ - /** - * Set up a random number generator for the sessionids. - * - * By preference, use a SecureRandom but allow to be injected. - */ - public void initRandom () - { - if (_random==null) - { - try - { - _random=new SecureRandom(); - } - catch (Exception e) - { - LOG.warn("Could not generate SecureRandom for session-id randomness",e); - _random=new Random(); - _weakRandom=true; - } - } - else - _random.setSeed(_random.nextLong()^System.currentTimeMillis()^hashCode()^Runtime.getRuntime().freeMemory()); - } - - -}
--- a/src/org/eclipse/jetty/server/session/AbstractSessionManager.java Thu Sep 08 16:13:27 2016 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1026 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server.session; - -import static java.lang.Math.round; - -import java.util.Arrays; -import java.util.Collections; -import java.util.Enumeration; -import java.util.EventListener; -import java.util.HashSet; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.CopyOnWriteArrayList; - -import javax.servlet.ServletRequest; -import javax.servlet.SessionCookieConfig; -import javax.servlet.SessionTrackingMode; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; -import javax.servlet.http.HttpSessionAttributeListener; -import javax.servlet.http.HttpSessionBindingEvent; -import javax.servlet.http.HttpSessionContext; -import javax.servlet.http.HttpSessionEvent; -import javax.servlet.http.HttpSessionListener; - -import org.eclipse.jetty.http.HttpCookie; -import org.eclipse.jetty.server.AbstractConnector; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.SessionIdManager; -import org.eclipse.jetty.server.SessionManager; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.util.component.AbstractLifeCycle; -import org.eclipse.jetty.util.log.Logger; -import org.eclipse.jetty.util.statistic.CounterStatistic; -import org.eclipse.jetty.util.statistic.SampleStatistic; - -/* ------------------------------------------------------------ */ -/** - * An Abstract implementation of SessionManager. The partial implementation of - * SessionManager interface provides the majority of the handling required to - * implement a SessionManager. Concrete implementations of SessionManager based - * on AbstractSessionManager need only implement the newSession method to return - * a specialised version of the Session inner class that provides an attribute - * Map. - * <p> - */ -@SuppressWarnings("deprecation") -public abstract class AbstractSessionManager extends AbstractLifeCycle implements SessionManager -{ - final static Logger __log = SessionHandler.LOG; - - public Set<SessionTrackingMode> __defaultSessionTrackingModes = - Collections.unmodifiableSet( - new HashSet<SessionTrackingMode>( - Arrays.asList(new SessionTrackingMode[]{SessionTrackingMode.COOKIE,SessionTrackingMode.URL}))); - - public final static String SESSION_KNOWN_ONLY_TO_AUTHENTICATED="org.eclipse.jetty.security.sessionKnownOnlytoAuthenticated"; - - /* ------------------------------------------------------------ */ - public final static int __distantFuture=60*60*24*7*52*20; - - static final HttpSessionContext __nullSessionContext=new HttpSessionContext() - { - public HttpSession getSession(String sessionId) - { - return null; - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - public Enumeration getIds() - { - return Collections.enumeration(Collections.EMPTY_LIST); - } - }; - - private boolean _usingCookies=true; - - /* ------------------------------------------------------------ */ - // Setting of max inactive interval for new sessions - // -1 means no timeout - protected int _dftMaxIdleSecs=-1; - protected SessionHandler _sessionHandler; - protected boolean _httpOnly=false; - protected SessionIdManager _sessionIdManager; - protected boolean _secureCookies=false; - protected boolean _secureRequestOnly=true; - - protected final List<HttpSessionAttributeListener> _sessionAttributeListeners = new CopyOnWriteArrayList<HttpSessionAttributeListener>(); - protected final List<HttpSessionListener> _sessionListeners= new CopyOnWriteArrayList<HttpSessionListener>(); - - protected ClassLoader _loader; - protected ContextHandler.Context _context; - protected String _sessionCookie=__DefaultSessionCookie; - protected String _sessionIdPathParameterName = __DefaultSessionIdPathParameterName; - protected String _sessionIdPathParameterNamePrefix =";"+ _sessionIdPathParameterName +"="; - protected String _sessionDomain; - protected String _sessionPath; - protected int _maxCookieAge=-1; - protected int _refreshCookieAge; - protected boolean _nodeIdInSessionId; - protected boolean _checkingRemoteSessionIdEncoding; - protected String _sessionComment; - - public Set<SessionTrackingMode> _sessionTrackingModes; - - private boolean _usingURLs; - - protected final CounterStatistic _sessionsStats = new CounterStatistic(); - protected final SampleStatistic _sessionTimeStats = new SampleStatistic(); - - - /* ------------------------------------------------------------ */ - public static HttpSession renewSession (HttpServletRequest request, HttpSession httpSession, boolean authenticated) - { - Map<String,Object> attributes = new HashMap<String, Object>(); - - for (Enumeration<String> e=httpSession.getAttributeNames();e.hasMoreElements();) - { - String name=e.nextElement(); - attributes.put(name,httpSession.getAttribute(name)); - httpSession.removeAttribute(name); - } - - httpSession.invalidate(); - httpSession = request.getSession(true); - if (authenticated) - httpSession.setAttribute(SESSION_KNOWN_ONLY_TO_AUTHENTICATED, Boolean.TRUE); - for (Map.Entry<String, Object> entry: attributes.entrySet()) - httpSession.setAttribute(entry.getKey(),entry.getValue()); - return httpSession; - } - - /* ------------------------------------------------------------ */ - public AbstractSessionManager() - { - setSessionTrackingModes(__defaultSessionTrackingModes); - } - - /* ------------------------------------------------------------ */ - public ContextHandler.Context getContext() - { - return _context; - } - - /* ------------------------------------------------------------ */ - public ContextHandler getContextHandler() - { - return _context.getContextHandler(); - } - - public String getSessionPath() - { - return _sessionPath; - } - - public int getMaxCookieAge() - { - return _maxCookieAge; - } - - /* ------------------------------------------------------------ */ - public HttpCookie access(HttpSession session,boolean secure) - { - long now=System.currentTimeMillis(); - - AbstractSession s = ((SessionIf)session).getSession(); - - if (s.access(now)) - { - // Do we need to refresh the cookie? - if (isUsingCookies() && - (s.isIdChanged() || - (getSessionCookieConfig().getMaxAge()>0 && getRefreshCookieAge()>0 && ((now-s.getCookieSetTime())/1000>getRefreshCookieAge())) - ) - ) - { - HttpCookie cookie=getSessionCookie(session,_context==null?"/":(_context.getContextPath()),secure); - s.cookieSet(); - s.setIdChanged(false); - return cookie; - } - } - return null; - } - - /* ------------------------------------------------------------ */ - public void addEventListener(EventListener listener) - { - if (listener instanceof HttpSessionAttributeListener) - _sessionAttributeListeners.add((HttpSessionAttributeListener)listener); - if (listener instanceof HttpSessionListener) - _sessionListeners.add((HttpSessionListener)listener); - } - - /* ------------------------------------------------------------ */ - public void clearEventListeners() - { - _sessionAttributeListeners.clear(); - _sessionListeners.clear(); - } - - /* ------------------------------------------------------------ */ - public void complete(HttpSession session) - { - AbstractSession s = ((SessionIf)session).getSession(); - s.complete(); - } - - /* ------------------------------------------------------------ */ - @Override - public void doStart() throws Exception - { - _context=ContextHandler.getCurrentContext(); - _loader=Thread.currentThread().getContextClassLoader(); - - if (_sessionIdManager==null) - { - final Server server=getSessionHandler().getServer(); - synchronized (server) - { - _sessionIdManager=server.getSessionIdManager(); - if (_sessionIdManager==null) - { - _sessionIdManager=new HashSessionIdManager(); - server.setSessionIdManager(_sessionIdManager); - } - } - } - if (!_sessionIdManager.isStarted()) - _sessionIdManager.start(); - - // Look for a session cookie name - if (_context!=null) - { - String tmp=_context.getInitParameter(SessionManager.__SessionCookieProperty); - if (tmp!=null) - _sessionCookie=tmp; - - tmp=_context.getInitParameter(SessionManager.__SessionIdPathParameterNameProperty); - if (tmp!=null) - setSessionIdPathParameterName(tmp); - - // set up the max session cookie age if it isn't already - if (_maxCookieAge==-1) - { - tmp=_context.getInitParameter(SessionManager.__MaxAgeProperty); - if (tmp!=null) - _maxCookieAge=Integer.parseInt(tmp.trim()); - } - - // set up the session domain if it isn't already - if (_sessionDomain==null) - _sessionDomain=_context.getInitParameter(SessionManager.__SessionDomainProperty); - - // set up the sessionPath if it isn't already - if (_sessionPath==null) - _sessionPath=_context.getInitParameter(SessionManager.__SessionPathProperty); - - tmp=_context.getInitParameter(SessionManager.__CheckRemoteSessionEncoding); - if (tmp!=null) - _checkingRemoteSessionIdEncoding=Boolean.parseBoolean(tmp); - } - - super.doStart(); - } - - /* ------------------------------------------------------------ */ - @Override - public void doStop() throws Exception - { - super.doStop(); - - invalidateSessions(); - - _loader=null; - } - - /* ------------------------------------------------------------ */ - /** - * @return Returns the httpOnly. - */ - public boolean getHttpOnly() - { - return _httpOnly; - } - - /* ------------------------------------------------------------ */ - public HttpSession getHttpSession(String nodeId) - { - String cluster_id = getSessionIdManager().getClusterId(nodeId); - - AbstractSession session = getSession(cluster_id); - if (session!=null && !session.getNodeId().equals(nodeId)) - session.setIdChanged(true); - return session; - } - - /* ------------------------------------------------------------ */ - /** - * @return Returns the metaManager used for cross context session management - * @deprecated Use {@link #getSessionIdManager()} - */ - public SessionIdManager getIdManager() - { - return getSessionIdManager(); - } - - /* ------------------------------------------------------------ */ - /** - * @return Returns the SessionIdManager used for cross context session management - */ - public SessionIdManager getSessionIdManager() - { - return _sessionIdManager; - } - - - /* ------------------------------------------------------------ */ - /** - * @return seconds - */ - @Override - public int getMaxInactiveInterval() - { - return _dftMaxIdleSecs; - } - - /* ------------------------------------------------------------ */ - /** - * @see #getSessionsMax() - */ - @Deprecated - public int getMaxSessions() - { - return getSessionsMax(); - } - - /* ------------------------------------------------------------ */ - /** - * @return maximum number of sessions - */ - public int getSessionsMax() - { - return (int)_sessionsStats.getMax(); - } - - /* ------------------------------------------------------------ */ - /** - * @return total number of sessions - */ - public int getSessionsTotal() - { - return (int)_sessionsStats.getTotal(); - } - - /* ------------------------------------------------------------ */ - /** - * @deprecated use {@link #getSessionIdManager()} - */ - @Deprecated - public SessionIdManager getMetaManager() - { - return getSessionIdManager(); - } - - /* ------------------------------------------------------------ */ - /** - * @deprecated always returns 0. no replacement available. - */ - @Deprecated - public int getMinSessions() - { - return 0; - } - - /* ------------------------------------------------------------ */ - public int getRefreshCookieAge() - { - return _refreshCookieAge; - } - - - /* ------------------------------------------------------------ */ - /** - * @return same as SessionCookieConfig.getSecure(). If true, session - * cookies are ALWAYS marked as secure. If false, a session cookie is - * ONLY marked as secure if _secureRequestOnly == true and it is a HTTPS request. - */ - public boolean getSecureCookies() - { - return _secureCookies; - } - - /* ------------------------------------------------------------ */ - /** - * @return true if session cookie is to be marked as secure only on HTTPS requests - */ - public boolean isSecureRequestOnly() - { - return _secureRequestOnly; - } - - - /* ------------------------------------------------------------ */ - /** - * @return if true, session cookie will be marked as secure only iff - * HTTPS request. Can be overridden by setting SessionCookieConfig.setSecure(true), - * in which case the session cookie will be marked as secure on both HTTPS and HTTP. - */ - public void setSecureRequestOnly(boolean secureRequestOnly) - { - _secureRequestOnly = secureRequestOnly; - } - - - - /* ------------------------------------------------------------ */ - public String getSessionCookie() - { - return _sessionCookie; - } - - /* ------------------------------------------------------------ */ - /** - * A sessioncookie is marked as secure IFF any of the following conditions are true: - * <ol> - * <li>SessionCookieConfig.setSecure == true</li> - * <li>SessionCookieConfig.setSecure == false && _secureRequestOnly==true && request is HTTPS</li> - * </ol> - * According to SessionCookieConfig javadoc, case 1 can be used when: - * "... even though the request that initiated the session came over HTTP, - * is to support a topology where the web container is front-ended by an - * SSL offloading load balancer. In this case, the traffic between the client - * and the load balancer will be over HTTPS, whereas the traffic between the - * load balancer and the web container will be over HTTP." - * - * For case 2, you can use _secureRequestOnly to determine if you want the - * Servlet Spec 3.0 default behaviour when SessionCookieConfig.setSecure==false, - * which is: - * "they shall be marked as secure only if the request that initiated the - * corresponding session was also secure" - * - * The default for _secureRequestOnly is true, which gives the above behaviour. If - * you set it to false, then a session cookie is NEVER marked as secure, even if - * the initiating request was secure. - * - * @see org.eclipse.jetty.server.SessionManager#getSessionCookie(javax.servlet.http.HttpSession, java.lang.String, boolean) - */ - public HttpCookie getSessionCookie(HttpSession session, String contextPath, boolean requestIsSecure) - { - if (isUsingCookies()) - { - String sessionPath = (_sessionPath==null) ? contextPath : _sessionPath; - sessionPath = (sessionPath==null||sessionPath.length()==0) ? "/" : sessionPath; - String id = getNodeId(session); - HttpCookie cookie = null; - if (_sessionComment == null) - { - cookie = new HttpCookie( - _sessionCookie, - id, - _sessionDomain, - sessionPath, - _cookieConfig.getMaxAge(), - _cookieConfig.isHttpOnly(), - _cookieConfig.isSecure() || (isSecureRequestOnly() && requestIsSecure)); - } - else - { - cookie = new HttpCookie( - _sessionCookie, - id, - _sessionDomain, - sessionPath, - _cookieConfig.getMaxAge(), - _cookieConfig.isHttpOnly(), - _cookieConfig.isSecure() || (isSecureRequestOnly() && requestIsSecure), - _sessionComment, - 1); - } - - return cookie; - } - return null; - } - - public String getSessionDomain() - { - return _sessionDomain; - } - - /* ------------------------------------------------------------ */ - /** - * @return Returns the sessionHandler. - */ - public SessionHandler getSessionHandler() - { - return _sessionHandler; - } - - /* ------------------------------------------------------------ */ - /** - * @deprecated Need to review if it is needed. - */ - @SuppressWarnings("rawtypes") - public Map getSessionMap() - { - throw new UnsupportedOperationException(); - } - - - - /* ------------------------------------------------------------ */ - public int getSessions() - { - return (int)_sessionsStats.getCurrent(); - } - - /* ------------------------------------------------------------ */ - public String getSessionIdPathParameterName() - { - return _sessionIdPathParameterName; - } - - /* ------------------------------------------------------------ */ - public String getSessionIdPathParameterNamePrefix() - { - return _sessionIdPathParameterNamePrefix; - } - - /* ------------------------------------------------------------ */ - /** - * @return Returns the usingCookies. - */ - public boolean isUsingCookies() - { - return _usingCookies; - } - - /* ------------------------------------------------------------ */ - public boolean isValid(HttpSession session) - { - AbstractSession s = ((SessionIf)session).getSession(); - return s.isValid(); - } - - /* ------------------------------------------------------------ */ - public String getClusterId(HttpSession session) - { - AbstractSession s = ((SessionIf)session).getSession(); - return s.getClusterId(); - } - - /* ------------------------------------------------------------ */ - public String getNodeId(HttpSession session) - { - AbstractSession s = ((SessionIf)session).getSession(); - return s.getNodeId(); - } - - /* ------------------------------------------------------------ */ - /** - * Create a new HttpSession for a request - */ - public HttpSession newHttpSession(HttpServletRequest request) - { - AbstractSession session=newSession(request); - session.setMaxInactiveInterval(_dftMaxIdleSecs); - addSession(session,true); - return session; - } - - /* ------------------------------------------------------------ */ - public void removeEventListener(EventListener listener) - { - if (listener instanceof HttpSessionAttributeListener) - _sessionAttributeListeners.remove(listener); - if (listener instanceof HttpSessionListener) - _sessionListeners.remove(listener); - } - - /* ------------------------------------------------------------ */ - /** - * @see #statsReset() - */ - @Deprecated - public void resetStats() - { - statsReset(); - } - - /* ------------------------------------------------------------ */ - /** - * Reset statistics values - */ - public void statsReset() - { - _sessionsStats.reset(getSessions()); - _sessionTimeStats.reset(); - } - - /* ------------------------------------------------------------ */ - /** - * @param httpOnly - * The httpOnly to set. - */ - public void setHttpOnly(boolean httpOnly) - { - _httpOnly=httpOnly; - } - - /* ------------------------------------------------------------ */ - /** - * @param metaManager The metaManager used for cross context session management. - * @deprecated use {@link #setSessionIdManager(SessionIdManager)} - */ - public void setIdManager(SessionIdManager metaManager) - { - setSessionIdManager(metaManager); - } - - /* ------------------------------------------------------------ */ - /** - * @param metaManager The metaManager used for cross context session management. - */ - public void setSessionIdManager(SessionIdManager metaManager) - { - _sessionIdManager=metaManager; - } - - - - /* ------------------------------------------------------------ */ - /** - * @param seconds - */ - public void setMaxInactiveInterval(int seconds) - { - _dftMaxIdleSecs=seconds; - } - - - /* ------------------------------------------------------------ */ - public void setRefreshCookieAge(int ageInSeconds) - { - _refreshCookieAge=ageInSeconds; - } - - - - public void setSessionCookie(String cookieName) - { - _sessionCookie=cookieName; - } - - - - /* ------------------------------------------------------------ */ - /** - * @param sessionHandler - * The sessionHandler to set. - */ - public void setSessionHandler(SessionHandler sessionHandler) - { - _sessionHandler=sessionHandler; - } - - - /* ------------------------------------------------------------ */ - public void setSessionIdPathParameterName(String param) - { - _sessionIdPathParameterName =(param==null||"none".equals(param))?null:param; - _sessionIdPathParameterNamePrefix =(param==null||"none".equals(param))?null:(";"+ _sessionIdPathParameterName +"="); - } - /* ------------------------------------------------------------ */ - /** - * @param usingCookies - * The usingCookies to set. - */ - public void setUsingCookies(boolean usingCookies) - { - _usingCookies=usingCookies; - } - - - protected abstract void addSession(AbstractSession session); - - /* ------------------------------------------------------------ */ - /** - * Add the session Registers the session with this manager and registers the - * session ID with the sessionIDManager; - */ - protected void addSession(AbstractSession session, boolean created) - { - synchronized (_sessionIdManager) - { - _sessionIdManager.addSession(session); - addSession(session); - } - - if (created) - { - _sessionsStats.increment(); - if (_sessionListeners!=null) - { - HttpSessionEvent event=new HttpSessionEvent(session); - for (HttpSessionListener listener : _sessionListeners) - listener.sessionCreated(event); - } - } - } - - /* ------------------------------------------------------------ */ - /** - * Get a known existing session - * @param idInCluster The session ID in the cluster, stripped of any worker name. - * @return A Session or null if none exists. - */ - public abstract AbstractSession getSession(String idInCluster); - - protected abstract void invalidateSessions() throws Exception; - - - /* ------------------------------------------------------------ */ - /** - * Create a new session instance - * @param request - * @return the new session - */ - protected abstract AbstractSession newSession(HttpServletRequest request); - - - /* ------------------------------------------------------------ */ - /** - * @return true if the cluster node id (worker id) is returned as part of the session id by {@link HttpSession#getId()}. Default is false. - */ - public boolean isNodeIdInSessionId() - { - return _nodeIdInSessionId; - } - - /* ------------------------------------------------------------ */ - /** - * @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. - */ - public void setNodeIdInSessionId(boolean nodeIdInSessionId) - { - _nodeIdInSessionId=nodeIdInSessionId; - } - - /* ------------------------------------------------------------ */ - /** Remove session from manager - * @param session The session to remove - * @param invalidate True if {@link HttpSessionListener#sessionDestroyed(HttpSessionEvent)} and - * {@link SessionIdManager#invalidateAll(String)} should be called. - */ - public void removeSession(HttpSession session, boolean invalidate) - { - AbstractSession s = ((SessionIf)session).getSession(); - removeSession(s,invalidate); - } - - /* ------------------------------------------------------------ */ - /** Remove session from manager - * @param session The session to remove - * @param invalidate True if {@link HttpSessionListener#sessionDestroyed(HttpSessionEvent)} and - * {@link SessionIdManager#invalidateAll(String)} should be called. - */ - public void removeSession(AbstractSession session, boolean invalidate) - { - // Remove session from context and global maps - boolean removed = removeSession(session.getClusterId()); - - if (removed) - { - _sessionsStats.decrement(); - _sessionTimeStats.set(round((System.currentTimeMillis() - session.getCreationTime())/1000.0)); - - // Remove session from all context and global id maps - _sessionIdManager.removeSession(session); - if (invalidate) - _sessionIdManager.invalidateAll(session.getClusterId()); - - if (invalidate && _sessionListeners!=null) - { - HttpSessionEvent event=new HttpSessionEvent(session); - for (HttpSessionListener listener : _sessionListeners) - listener.sessionDestroyed(event); - } - } - } - - /* ------------------------------------------------------------ */ - protected abstract boolean removeSession(String idInCluster); - - /* ------------------------------------------------------------ */ - /** - * @return maximum amount of time session remained valid - */ - public long getSessionTimeMax() - { - return _sessionTimeStats.getMax(); - } - - /* ------------------------------------------------------------ */ - public Set<SessionTrackingMode> getDefaultSessionTrackingModes() - { - return __defaultSessionTrackingModes; - } - - /* ------------------------------------------------------------ */ - public Set<SessionTrackingMode> getEffectiveSessionTrackingModes() - { - return Collections.unmodifiableSet(_sessionTrackingModes); - } - - /* ------------------------------------------------------------ */ - @Override - public void setSessionTrackingModes(Set<SessionTrackingMode> sessionTrackingModes) - { - _sessionTrackingModes=new HashSet<SessionTrackingMode>(sessionTrackingModes); - _usingCookies=_sessionTrackingModes.contains(SessionTrackingMode.COOKIE); - _usingURLs=_sessionTrackingModes.contains(SessionTrackingMode.URL); - } - - /* ------------------------------------------------------------ */ - @Override - public boolean isUsingURLs() - { - return _usingURLs; - } - - - /* ------------------------------------------------------------ */ - public SessionCookieConfig getSessionCookieConfig() - { - return _cookieConfig; - } - - /* ------------------------------------------------------------ */ - private SessionCookieConfig _cookieConfig = - new SessionCookieConfig() - { - @Override - public String getComment() - { - return _sessionComment; - } - - @Override - public String getDomain() - { - return _sessionDomain; - } - - @Override - public int getMaxAge() - { - return _maxCookieAge; - } - - @Override - public String getName() - { - return _sessionCookie; - } - - @Override - public String getPath() - { - return _sessionPath; - } - - @Override - public boolean isHttpOnly() - { - return _httpOnly; - } - - @Override - public boolean isSecure() - { - return _secureCookies; - } - - @Override - public void setComment(String comment) - { - _sessionComment = comment; - } - - @Override - public void setDomain(String domain) - { - _sessionDomain=domain; - } - - @Override - public void setHttpOnly(boolean httpOnly) - { - _httpOnly=httpOnly; - } - - @Override - public void setMaxAge(int maxAge) - { - _maxCookieAge=maxAge; - } - - @Override - public void setName(String name) - { - _sessionCookie=name; - } - - @Override - public void setPath(String path) - { - _sessionPath=path; - } - - @Override - public void setSecure(boolean secure) - { - _secureCookies=secure; - } - - }; - - - /* ------------------------------------------------------------ */ - /** - * @return total amount of time all sessions remained valid - */ - public long getSessionTimeTotal() - { - return _sessionTimeStats.getTotal(); - } - - /* ------------------------------------------------------------ */ - /** - * @return mean amount of time session remained valid - */ - public double getSessionTimeMean() - { - return _sessionTimeStats.getMean(); - } - - /* ------------------------------------------------------------ */ - /** - * @return standard deviation of amount of time session remained valid - */ - public double getSessionTimeStdDev() - { - return _sessionTimeStats.getStdDev(); - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.server.SessionManager#isCheckingRemoteSessionIdEncoding() - */ - public boolean isCheckingRemoteSessionIdEncoding() - { - return _checkingRemoteSessionIdEncoding; - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.server.SessionManager#setCheckingRemoteSessionIdEncoding(boolean) - */ - public void setCheckingRemoteSessionIdEncoding(boolean remote) - { - _checkingRemoteSessionIdEncoding=remote; - } - - /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ - /** - * Interface that any session wrapper should implement so that - * SessionManager may access the Jetty session implementation. - * - */ - public interface SessionIf extends HttpSession - { - public AbstractSession getSession(); - } - - public void doSessionAttributeListeners(AbstractSession session, String name, Object old, Object value) - { - if (!_sessionAttributeListeners.isEmpty()) - { - HttpSessionBindingEvent event=new HttpSessionBindingEvent(session,name,old==null?value:old); - - for (HttpSessionAttributeListener l : _sessionAttributeListeners) - { - if (old==null) - l.attributeAdded(event); - else if (value==null) - l.attributeRemoved(event); - else - l.attributeReplaced(event); - } - } - } -}
--- a/src/org/eclipse/jetty/server/session/HashSessionIdManager.java Thu Sep 08 16:13:27 2016 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,222 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server.session; - -import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Random; -import java.util.Set; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; - -import org.eclipse.jetty.server.SessionIdManager; - -/* ------------------------------------------------------------ */ -/** - * HashSessionIdManager. An in-memory implementation of the session ID manager. - */ -public class HashSessionIdManager extends AbstractSessionIdManager -{ - private final Map<String, Set<WeakReference<HttpSession>>> _sessions = new HashMap<String, Set<WeakReference<HttpSession>>>(); - - /* ------------------------------------------------------------ */ - public HashSessionIdManager() - { - } - - /* ------------------------------------------------------------ */ - public HashSessionIdManager(Random random) - { - super(random); - } - - /* ------------------------------------------------------------ */ - /** - * @return Collection of String session IDs - */ - public Collection<String> getSessions() - { - return Collections.unmodifiableCollection(_sessions.keySet()); - } - - /* ------------------------------------------------------------ */ - /** - * @return Collection of Sessions for the passed session ID - */ - public Collection<HttpSession> getSession(String id) - { - ArrayList<HttpSession> sessions = new ArrayList<HttpSession>(); - Set<WeakReference<HttpSession>> refs =_sessions.get(id); - if (refs!=null) - { - for (WeakReference<HttpSession> ref: refs) - { - HttpSession session = ref.get(); - if (session!=null) - sessions.add(session); - } - } - return sessions; - } - /* ------------------------------------------------------------ */ - /** Get the session ID with any worker ID. - * - * @param clusterId - * @param request - * @return sessionId plus any worker ID. - */ - public String getNodeId(String clusterId,HttpServletRequest request) - { - // used in Ajp13Parser - String worker=request==null?null:(String)request.getAttribute("org.eclipse.jetty.ajp.JVMRoute"); - if (worker!=null) - return clusterId+'.'+worker; - - if (_workerName!=null) - return clusterId+'.'+_workerName; - - return clusterId; - } - - /* ------------------------------------------------------------ */ - /** Get the session ID without any worker ID. - * - * @param nodeId the node id - * @return sessionId without any worker ID. - */ - public String getClusterId(String nodeId) - { - int dot=nodeId.lastIndexOf('.'); - return (dot>0)?nodeId.substring(0,dot):nodeId; - } - - /* ------------------------------------------------------------ */ - @Override - protected void doStart() throws Exception - { - super.doStart(); - } - - /* ------------------------------------------------------------ */ - @Override - protected void doStop() throws Exception - { - _sessions.clear(); - super.doStop(); - } - - /* ------------------------------------------------------------ */ - /** - * @see SessionIdManager#idInUse(String) - */ - public boolean idInUse(String id) - { - synchronized (this) - { - return _sessions.containsKey(id); - } - } - - /* ------------------------------------------------------------ */ - /** - * @see SessionIdManager#addSession(HttpSession) - */ - public void addSession(HttpSession session) - { - String id = getClusterId(session.getId()); - WeakReference<HttpSession> ref = new WeakReference<HttpSession>(session); - - synchronized (this) - { - Set<WeakReference<HttpSession>> sessions = _sessions.get(id); - if (sessions==null) - { - sessions=new HashSet<WeakReference<HttpSession>>(); - _sessions.put(id,sessions); - } - sessions.add(ref); - } - } - - /* ------------------------------------------------------------ */ - /** - * @see SessionIdManager#removeSession(HttpSession) - */ - public void removeSession(HttpSession session) - { - String id = getClusterId(session.getId()); - - synchronized (this) - { - Collection<WeakReference<HttpSession>> sessions = _sessions.get(id); - if (sessions!=null) - { - for (Iterator<WeakReference<HttpSession>> iter = sessions.iterator(); iter.hasNext();) - { - WeakReference<HttpSession> ref = iter.next(); - HttpSession s=ref.get(); - if (s==null) - { - iter.remove(); - continue; - } - if (s==session) - { - iter.remove(); - break; - } - } - if (sessions.isEmpty()) - _sessions.remove(id); - } - } - } - - /* ------------------------------------------------------------ */ - /** - * @see SessionIdManager#invalidateAll(String) - */ - public void invalidateAll(String id) - { - Collection<WeakReference<HttpSession>> sessions; - synchronized (this) - { - sessions = _sessions.remove(id); - } - - if (sessions!=null) - { - for (WeakReference<HttpSession> ref: sessions) - { - AbstractSession session=(AbstractSession)ref.get(); - if (session!=null && session.isValid()) - session.invalidate(); - } - sessions.clear(); - } - } - -}
--- a/src/org/eclipse/jetty/server/session/HashSessionManager.java Thu Sep 08 16:13:27 2016 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,640 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server.session; - -import java.io.DataInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.ObjectInputStream; -import java.net.URI; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; -import java.util.Timer; -import java.util.TimerTask; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; - -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; - -import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.log.Logger; - - -/* ------------------------------------------------------------ */ -/** - * HashSessionManager - * - * An in-memory implementation of SessionManager. - * <p> - * This manager supports saving sessions to disk, either periodically or at shutdown. - * Sessions can also have their content idle saved to disk to reduce the memory overheads of large idle sessions. - * <p> - * This manager will create it's own Timer instance to scavenge threads, unless it discovers a shared Timer instance - * set as the "org.eclipse.jetty.server.session.timer" attribute of the ContextHandler. - * - */ -public class HashSessionManager extends AbstractSessionManager -{ - final static Logger __log = SessionHandler.LOG; - - protected final ConcurrentMap<String,HashedSession> _sessions=new ConcurrentHashMap<String,HashedSession>(); - private static int __id; - private Timer _timer; - private boolean _timerStop=false; - private TimerTask _task; - long _scavengePeriodMs=30000; - long _savePeriodMs=0; //don't do period saves by default - long _idleSavePeriodMs = 0; // don't idle save sessions by default. - private TimerTask _saveTask; - File _storeDir; - private boolean _lazyLoad=false; - private volatile boolean _sessionsLoaded=false; - private boolean _deleteUnrestorableSessions=false; - - - - - /* ------------------------------------------------------------ */ - public HashSessionManager() - { - super(); - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.servlet.AbstractSessionManager#doStart() - */ - @Override - public void doStart() throws Exception - { - super.doStart(); - - _timerStop=false; - ServletContext context = ContextHandler.getCurrentContext(); - if (context!=null) - _timer=(Timer)context.getAttribute("org.eclipse.jetty.server.session.timer"); - if (_timer==null) - { - _timerStop=true; - _timer=new Timer("HashSessionScavenger-"+__id++, true); - } - - setScavengePeriod(getScavengePeriod()); - - if (_storeDir!=null) - { - if (!_storeDir.exists()) - _storeDir.mkdirs(); - - if (!_lazyLoad) - restoreSessions(); - } - - setSavePeriod(getSavePeriod()); - } - - /* ------------------------------------------------------------ */ - /** - * @see org.eclipse.jetty.servlet.AbstractSessionManager#doStop() - */ - @Override - public void doStop() throws Exception - { - // stop the scavengers - synchronized(this) - { - if (_saveTask!=null) - _saveTask.cancel(); - _saveTask=null; - if (_task!=null) - _task.cancel(); - _task=null; - if (_timer!=null && _timerStop) - _timer.cancel(); - _timer=null; - } - - // This will callback invalidate sessions - where we decide if we will save - super.doStop(); - - _sessions.clear(); - - } - - /* ------------------------------------------------------------ */ - /** - * @return the period in seconds at which a check is made for sessions to be invalidated. - */ - public int getScavengePeriod() - { - return (int)(_scavengePeriodMs/1000); - } - - - /* ------------------------------------------------------------ */ - @Override - public int getSessions() - { - int sessions=super.getSessions(); - if (__log.isDebugEnabled()) - { - if (_sessions.size()!=sessions) - __log.warn("sessions: "+_sessions.size()+"!="+sessions); - } - return sessions; - } - - /* ------------------------------------------------------------ */ - /** - * @return seconds Idle period after which a session is saved - */ - public int getIdleSavePeriod() - { - if (_idleSavePeriodMs <= 0) - return 0; - - return (int)(_idleSavePeriodMs / 1000); - } - - /* ------------------------------------------------------------ */ - /** - * Configures the period in seconds after which a session is deemed idle and saved - * to save on session memory. - * - * The session is persisted, the values attribute map is cleared and the session set to idled. - * - * @param seconds Idle period after which a session is saved - */ - public void setIdleSavePeriod(int seconds) - { - _idleSavePeriodMs = seconds * 1000L; - } - - /* ------------------------------------------------------------ */ - @Override - public void setMaxInactiveInterval(int seconds) - { - super.setMaxInactiveInterval(seconds); - if (_dftMaxIdleSecs>0&&_scavengePeriodMs>_dftMaxIdleSecs*1000L) - setScavengePeriod((_dftMaxIdleSecs+9)/10); - } - - /* ------------------------------------------------------------ */ - /** - * @param seconds the period is seconds at which sessions are periodically saved to disk - */ - public void setSavePeriod (int seconds) - { - long period = (seconds * 1000L); - if (period < 0) - period=0; - _savePeriodMs=period; - - if (_timer!=null) - { - synchronized (this) - { - if (_saveTask!=null) - _saveTask.cancel(); - if (_savePeriodMs > 0 && _storeDir!=null) //only save if we have a directory configured - { - _saveTask = new TimerTask() - { - @Override - public void run() - { - try - { - saveSessions(true); - } - catch (Exception e) - { - __log.warn(e); - } - } - }; - _timer.schedule(_saveTask,_savePeriodMs,_savePeriodMs); - } - } - } - } - - /* ------------------------------------------------------------ */ - /** - * @return the period in seconds at which sessions are periodically saved to disk - */ - public int getSavePeriod () - { - if (_savePeriodMs<=0) - return 0; - - return (int)(_savePeriodMs/1000); - } - - /* ------------------------------------------------------------ */ - /** - * @param seconds the period in seconds at which a check is made for sessions to be invalidated. - */ - public void setScavengePeriod(int seconds) - { - if (seconds==0) - seconds=60; - - long old_period=_scavengePeriodMs; - long period=seconds*1000L; - if (period>60000) - period=60000; - if (period<1000) - period=1000; - - _scavengePeriodMs=period; - - if (_timer!=null && (period!=old_period || _task==null)) - { - synchronized (this) - { - if (_task!=null) - _task.cancel(); - _task = new TimerTask() - { - @Override - public void run() - { - scavenge(); - } - }; - _timer.schedule(_task,_scavengePeriodMs,_scavengePeriodMs); - } - } - } - - /* -------------------------------------------------------------- */ - /** - * Find sessions that have timed out and invalidate them. This runs in the - * SessionScavenger thread. - */ - protected void scavenge() - { - //don't attempt to scavenge if we are shutting down - if (isStopping() || isStopped()) - return; - - Thread thread=Thread.currentThread(); - ClassLoader old_loader=thread.getContextClassLoader(); - try - { - if (_loader!=null) - thread.setContextClassLoader(_loader); - - // For each session - long now=System.currentTimeMillis(); - - for (Iterator<HashedSession> i=_sessions.values().iterator(); i.hasNext();) - { - HashedSession session=i.next(); - long idleTime=session.getMaxInactiveInterval()*1000L; - if (idleTime>0&&session.getAccessed()+idleTime<now) - { - // Found a stale session, add it to the list - try - { - session.timeout(); - } - catch (Exception e) - { - __log.warn("Problem scavenging sessions", e); - } - } - else if (_idleSavePeriodMs > 0 && session.getAccessed()+_idleSavePeriodMs < now) - { - try - { - session.idle(); - } - catch (Exception e) - { - __log.warn("Problem idling session "+ session.getId(), e); - } - } - } - } - finally - { - thread.setContextClassLoader(old_loader); - } - } - - /* ------------------------------------------------------------ */ - @Override - protected void addSession(AbstractSession session) - { - if (isRunning()) - _sessions.put(session.getClusterId(),(HashedSession)session); - } - - /* ------------------------------------------------------------ */ - @Override - public AbstractSession getSession(String idInCluster) - { - if ( _lazyLoad && !_sessionsLoaded) - { - try - { - restoreSessions(); - } - catch(Exception e) - { - __log.warn(e); - } - } - - Map<String,HashedSession> sessions=_sessions; - if (sessions==null) - return null; - - HashedSession session = sessions.get(idInCluster); - - if (session == null && _lazyLoad) - session=restoreSession(idInCluster); - if (session == null) - return null; - - if (_idleSavePeriodMs!=0) - session.deIdle(); - - return session; - } - - /* ------------------------------------------------------------ */ - @Override - protected void invalidateSessions() throws Exception - { - // Invalidate all sessions to cause unbind events - ArrayList<HashedSession> sessions=new ArrayList<HashedSession>(_sessions.values()); - int loop=100; - while (sessions.size()>0 && loop-->0) - { - // If we are called from doStop - if (isStopping() && _storeDir != null && _storeDir.exists() && _storeDir.canWrite()) - { - // Then we only save and remove the session - it is not invalidated. - for (HashedSession session : sessions) - { - session.save(false); - removeSession(session,false); - } - } - else - { - for (HashedSession session : sessions) - session.invalidate(); - } - - // check that no new sessions were created while we were iterating - sessions=new ArrayList<HashedSession>(_sessions.values()); - } - } - - /* ------------------------------------------------------------ */ - @Override - protected AbstractSession newSession(HttpServletRequest request) - { - return new HashedSession(this, request); - } - - /* ------------------------------------------------------------ */ - protected AbstractSession newSession(long created, long accessed, String clusterId) - { - return new HashedSession(this, created,accessed, clusterId); - } - - /* ------------------------------------------------------------ */ - @Override - protected boolean removeSession(String clusterId) - { - return _sessions.remove(clusterId)!=null; - } - - /* ------------------------------------------------------------ */ - public void setStoreDirectory (File dir) throws IOException - { - // CanonicalFile is used to capture the base store directory in a way that will - // work on Windows. Case differences may through off later checks using this directory. - _storeDir=dir.getCanonicalFile(); - } - - /* ------------------------------------------------------------ */ - public File getStoreDirectory () - { - return _storeDir; - } - - /* ------------------------------------------------------------ */ - public void setLazyLoad(boolean lazyLoad) - { - _lazyLoad = lazyLoad; - } - - /* ------------------------------------------------------------ */ - public boolean isLazyLoad() - { - return _lazyLoad; - } - - /* ------------------------------------------------------------ */ - public boolean isDeleteUnrestorableSessions() - { - return _deleteUnrestorableSessions; - } - - /* ------------------------------------------------------------ */ - public void setDeleteUnrestorableSessions(boolean deleteUnrestorableSessions) - { - _deleteUnrestorableSessions = deleteUnrestorableSessions; - } - - /* ------------------------------------------------------------ */ - public void restoreSessions () throws Exception - { - _sessionsLoaded = true; - - if (_storeDir==null || !_storeDir.exists()) - { - return; - } - - if (!_storeDir.canRead()) - { - __log.warn ("Unable to restore Sessions: Cannot read from Session storage directory "+_storeDir.getAbsolutePath()); - return; - } - - String[] files = _storeDir.list(); - for (int i=0;files!=null&&i<files.length;i++) - { - restoreSession(files[i]); - } - } - - /* ------------------------------------------------------------ */ - protected synchronized HashedSession restoreSession(String idInCuster) - { - File file = new File(_storeDir,idInCuster); - - FileInputStream in = null; - Exception error = null; - try - { - if (file.exists()) - { - in = new FileInputStream(file); - HashedSession session = restoreSession(in, null); - addSession(session, false); - session.didActivate(); - return session; - } - } - catch (Exception e) - { - error = e; - } - finally - { - if (in != null) IO.close(in); - - if (error != null) - { - if (isDeleteUnrestorableSessions() && file.exists() && file.getParentFile().equals(_storeDir) ) - { - file.delete(); - __log.warn("Deleting file for unrestorable session "+idInCuster, error); - } - else - { - __log.warn("Problem restoring session "+idInCuster, error); - } - } - else - file.delete(); //delete successfully restored file - - } - return null; - } - - /* ------------------------------------------------------------ */ - public void saveSessions(boolean reactivate) throws Exception - { - if (_storeDir==null || !_storeDir.exists()) - { - return; - } - - if (!_storeDir.canWrite()) - { - __log.warn ("Unable to save Sessions: Session persistence storage directory "+_storeDir.getAbsolutePath()+ " is not writeable"); - return; - } - - for (HashedSession session : _sessions.values()) - session.save(true); - } - - /* ------------------------------------------------------------ */ - public HashedSession restoreSession (InputStream is, HashedSession session) throws Exception - { - /* - * Take care of this class's fields first by calling - * defaultReadObject - */ - DataInputStream in = new DataInputStream(is); - try - { - String clusterId = in.readUTF(); - in.readUTF(); // nodeId - long created = in.readLong(); - long accessed = in.readLong(); - int requests = in.readInt(); - - if (session == null) - session = (HashedSession)newSession(created, accessed, clusterId); - session.setRequests(requests); - int size = in.readInt(); - if (size>0) - { - ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(in); - try - { - for (int i=0; i<size;i++) - { - String key = ois.readUTF(); - Object value = ois.readObject(); - session.setAttribute(key,value); - } - } - finally - { - IO.close(ois); - } - } - return session; - } - finally - { - IO.close(in); - } - } - - - /* ------------------------------------------------------------ */ - /* ------------------------------------------------------------ */ - protected class ClassLoadingObjectInputStream extends ObjectInputStream - { - /* ------------------------------------------------------------ */ - public ClassLoadingObjectInputStream(java.io.InputStream in) throws IOException - { - super(in); - } - - /* ------------------------------------------------------------ */ - public ClassLoadingObjectInputStream () throws IOException - { - super(); - } - - /* ------------------------------------------------------------ */ - @Override - public Class<?> resolveClass (java.io.ObjectStreamClass cl) throws IOException, ClassNotFoundException - { - try - { - return Class.forName(cl.getName(), false, Thread.currentThread().getContextClassLoader()); - } - catch (ClassNotFoundException e) - { - return super.resolveClass(cl); - } - } - } -}
--- a/src/org/eclipse/jetty/server/session/HashedSession.java Thu Sep 08 16:13:27 2016 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,241 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server.session; - -import java.io.DataOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.ObjectOutputStream; -import java.io.OutputStream; -import java.util.Enumeration; - -import javax.servlet.http.HttpServletRequest; - -import org.eclipse.jetty.util.IO; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -public class HashedSession extends AbstractSession -{ - private static final Logger LOG = Log.getLogger(HashedSession.class); - - private final HashSessionManager _hashSessionManager; - - /** Whether the session has been saved because it has been deemed idle; - * in which case its attribute map will have been saved and cleared. */ - private transient boolean _idled = false; - - /** Whether there has already been an attempt to save this session - * which has failed. If there has, there will be no more save attempts - * for this session. This is to stop the logs being flooded with errors - * due to serialization failures that are most likely caused by user - * data stored in the session that is not serializable. */ - private transient boolean _saveFailed = false; - - /* ------------------------------------------------------------- */ - protected HashedSession(HashSessionManager hashSessionManager, HttpServletRequest request) - { - super(hashSessionManager,request); - _hashSessionManager = hashSessionManager; - } - - /* ------------------------------------------------------------- */ - protected HashedSession(HashSessionManager hashSessionManager, long created, long accessed, String clusterId) - { - super(hashSessionManager,created, accessed, clusterId); - _hashSessionManager = hashSessionManager; - } - - /* ------------------------------------------------------------- */ - protected void checkValid() - { - if (_hashSessionManager._idleSavePeriodMs!=0) - deIdle(); - super.checkValid(); - } - - /* ------------------------------------------------------------- */ - @Override - public void setMaxInactiveInterval(int secs) - { - super.setMaxInactiveInterval(secs); - if (getMaxInactiveInterval()>0&&(getMaxInactiveInterval()*1000L/10)<_hashSessionManager._scavengePeriodMs) - _hashSessionManager.setScavengePeriod((secs+9)/10); - } - - /* ------------------------------------------------------------ */ - @Override - protected void doInvalidate() - throws IllegalStateException - { - super.doInvalidate(); - - // Remove from the disk - if (_hashSessionManager._storeDir!=null && getId()!=null) - { - String id=getId(); - File f = new File(_hashSessionManager._storeDir, id); - f.delete(); - } - } - - /* ------------------------------------------------------------ */ - synchronized void save(boolean reactivate) - throws Exception - { - // Only idle the session if not already idled and no previous save/idle has failed - if (!isIdled() && !_saveFailed) - { - if (LOG.isDebugEnabled()) - LOG.debug("Saving {} {}",super.getId(),reactivate); - - File file = null; - FileOutputStream fos = null; - - try - { - file = new File(_hashSessionManager._storeDir, super.getId()); - - if (file.exists()) - file.delete(); - file.createNewFile(); - fos = new FileOutputStream(file); - willPassivate(); - save(fos); - IO.close(fos); - if (reactivate) - didActivate(); - else - clearAttributes(); - } - catch (Exception e) - { - saveFailed(); // We won't try again for this session - if (fos != null) IO.close(fos); - if (file != null) file.delete(); // No point keeping the file if we didn't save the whole session - throw e; - } - } - } - /* ------------------------------------------------------------ */ - public synchronized void save(OutputStream os) throws IOException - { - DataOutputStream out = new DataOutputStream(os); - out.writeUTF(getClusterId()); - out.writeUTF(getNodeId()); - out.writeLong(getCreationTime()); - out.writeLong(getAccessed()); - - /* Don't write these out, as they don't make sense to store because they - * either they cannot be true or their value will be restored in the - * Session constructor. - */ - //out.writeBoolean(_invalid); - //out.writeBoolean(_doInvalidate); - //out.writeLong(_maxIdleMs); - //out.writeBoolean( _newSession); - out.writeInt(getRequests()); - out.writeInt(getAttributes()); - ObjectOutputStream oos = new ObjectOutputStream(out); - Enumeration<String> e=getAttributeNames(); - while(e.hasMoreElements()) - { - String key=e.nextElement(); - oos.writeUTF(key); - oos.writeObject(doGet(key)); - } - oos.close(); - } - - /* ------------------------------------------------------------ */ - public synchronized void deIdle() - { - if (isIdled()) - { - // Access now to prevent race with idling period - access(System.currentTimeMillis()); - - if (LOG.isDebugEnabled()) - LOG.debug("De-idling " + super.getId()); - - FileInputStream fis = null; - - try - { - File file = new File(_hashSessionManager._storeDir, super.getId()); - if (!file.exists() || !file.canRead()) - throw new FileNotFoundException(file.getName()); - - fis = new FileInputStream(file); - _idled = false; - _hashSessionManager.restoreSession(fis, this); - IO.close(fis); - - didActivate(); - - // If we are doing period saves, then there is no point deleting at this point - if (_hashSessionManager._savePeriodMs == 0) - file.delete(); - } - catch (Exception e) - { - LOG.warn("Problem de-idling session " + super.getId(), e); - if (fis != null) IO.close(fis);//Must ensure closed before invalidate - invalidate(); - } - } - } - - - /* ------------------------------------------------------------ */ - /** - * Idle the session to reduce session memory footprint. - * - * The session is idled by persisting it, then clearing the session values attribute map and finally setting - * it to an idled state. - */ - public synchronized void idle() - throws Exception - { - save(false); - _idled = true; - } - - /* ------------------------------------------------------------ */ - public synchronized boolean isIdled() - { - return _idled; - } - - /* ------------------------------------------------------------ */ - public synchronized boolean isSaveFailed() - { - return _saveFailed; - } - - /* ------------------------------------------------------------ */ - public synchronized void saveFailed() - { - _saveFailed = true; - } - -}
--- a/src/org/eclipse/jetty/server/session/JDBCSessionIdManager.java Thu Sep 08 16:13:27 2016 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1040 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server.session; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.sql.Blob; -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.Driver; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Locale; -import java.util.Random; -import java.util.Timer; -import java.util.TimerTask; - -import javax.naming.InitialContext; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; -import javax.sql.DataSource; - -import org.eclipse.jetty.server.Handler; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.SessionManager; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.util.log.Logger; - - - -/** - * JDBCSessionIdManager - * - * SessionIdManager implementation that uses a database to store in-use session ids, - * to support distributed sessions. - * - */ -public class JDBCSessionIdManager extends AbstractSessionIdManager -{ - final static Logger LOG = SessionHandler.LOG; - - protected final HashSet<String> _sessionIds = new HashSet<String>(); - protected Server _server; - protected Driver _driver; - protected String _driverClassName; - protected String _connectionUrl; - protected DataSource _datasource; - protected String _jndiName; - protected String _sessionIdTable = "JettySessionIds"; - protected String _sessionTable = "JettySessions"; - protected String _sessionTableRowId = "rowId"; - - protected Timer _timer; //scavenge timer - protected TimerTask _task; //scavenge task - protected long _lastScavengeTime; - protected long _scavengeIntervalMs = 1000L * 60 * 10; //10mins - protected String _blobType; //if not set, is deduced from the type of the database at runtime - protected String _longType; //if not set, is deduced from the type of the database at runtime - - protected String _createSessionIdTable; - protected String _createSessionTable; - - protected String _selectBoundedExpiredSessions; - protected String _deleteOldExpiredSessions; - - protected String _insertId; - protected String _deleteId; - protected String _queryId; - - protected String _insertSession; - protected String _deleteSession; - protected String _updateSession; - protected String _updateSessionNode; - protected String _updateSessionAccessTime; - - protected DatabaseAdaptor _dbAdaptor; - - private String _selectExpiredSessions; - - - /** - * DatabaseAdaptor - * - * Handles differences between databases. - * - * Postgres uses the getBytes and setBinaryStream methods to access - * a "bytea" datatype, which can be up to 1Gb of binary data. MySQL - * is happy to use the "blob" type and getBlob() methods instead. - * - * TODO if the differences become more major it would be worthwhile - * refactoring this class. - */ - public class DatabaseAdaptor - { - String _dbName; - boolean _isLower; - boolean _isUpper; - - - - public DatabaseAdaptor (DatabaseMetaData dbMeta) - throws SQLException - { - _dbName = dbMeta.getDatabaseProductName().toLowerCase(Locale.ENGLISH); - LOG.debug ("Using database {}",_dbName); - _isLower = dbMeta.storesLowerCaseIdentifiers(); - _isUpper = dbMeta.storesUpperCaseIdentifiers(); - } - - /** - * Convert a camel case identifier into either upper or lower - * depending on the way the db stores identifiers. - * - * @param identifier - * @return the converted identifier - */ - public String convertIdentifier (String identifier) - { - if (_isLower) - return identifier.toLowerCase(Locale.ENGLISH); - if (_isUpper) - return identifier.toUpperCase(Locale.ENGLISH); - - return identifier; - } - - public String getDBName () - { - return _dbName; - } - - public String getBlobType () - { - if (_blobType != null) - return _blobType; - - if (_dbName.startsWith("postgres")) - return "bytea"; - - return "blob"; - } - - public String getLongType () - { - if (_longType != null) - return _longType; - - if (_dbName.startsWith("oracle")) - return "number(20)"; - - return "bigint"; - } - - public InputStream getBlobInputStream (ResultSet result, String columnName) - throws SQLException - { - if (_dbName.startsWith("postgres")) - { - byte[] bytes = result.getBytes(columnName); - return new ByteArrayInputStream(bytes); - } - - Blob blob = result.getBlob(columnName); - return blob.getBinaryStream(); - } - - /** - * rowId is a reserved word for Oracle, so change the name of this column - * @return - */ - public String getRowIdColumnName () - { - if (_dbName != null && _dbName.startsWith("oracle")) - return "srowId"; - - return "rowId"; - } - - - public boolean isEmptyStringNull () - { - return (_dbName.startsWith("oracle")); - } - - public PreparedStatement getLoadStatement (Connection connection, String rowId, String contextPath, String virtualHosts) - throws SQLException - { - if (contextPath == null || "".equals(contextPath)) - { - if (isEmptyStringNull()) - { - PreparedStatement statement = connection.prepareStatement("select * from "+_sessionTable+ - " where sessionId = ? and contextPath is null and virtualHost = ?"); - statement.setString(1, rowId); - statement.setString(2, virtualHosts); - - return statement; - } - } - - - - PreparedStatement statement = connection.prepareStatement("select * from "+_sessionTable+ - " where sessionId = ? and contextPath = ? and virtualHost = ?"); - statement.setString(1, rowId); - statement.setString(2, contextPath); - statement.setString(3, virtualHosts); - - return statement; - } - } - - - - public JDBCSessionIdManager(Server server) - { - super(); - _server=server; - } - - public JDBCSessionIdManager(Server server, Random random) - { - super(random); - _server=server; - } - - /** - * Configure jdbc connection information via a jdbc Driver - * - * @param driverClassName - * @param connectionUrl - */ - public void setDriverInfo (String driverClassName, String connectionUrl) - { - _driverClassName=driverClassName; - _connectionUrl=connectionUrl; - } - - /** - * Configure jdbc connection information via a jdbc Driver - * - * @param driverClass - * @param connectionUrl - */ - public void setDriverInfo (Driver driverClass, String connectionUrl) - { - _driver=driverClass; - _connectionUrl=connectionUrl; - } - - - public void setDatasource (DataSource ds) - { - _datasource = ds; - } - - public DataSource getDataSource () - { - return _datasource; - } - - public String getDriverClassName() - { - return _driverClassName; - } - - public String getConnectionUrl () - { - return _connectionUrl; - } - - public void setDatasourceName (String jndi) - { - _jndiName=jndi; - } - - public String getDatasourceName () - { - return _jndiName; - } - - public void setBlobType (String name) - { - _blobType = name; - } - - public String getBlobType () - { - return _blobType; - } - - - - public String getLongType() - { - return _longType; - } - - public void setLongType(String longType) - { - this._longType = longType; - } - - public void setScavengeInterval (long sec) - { - if (sec<=0) - sec=60; - - long old_period=_scavengeIntervalMs; - long period=sec*1000L; - - _scavengeIntervalMs=period; - - //add a bit of variability into the scavenge time so that not all - //nodes with the same scavenge time sync up - long tenPercent = _scavengeIntervalMs/10; - if ((System.currentTimeMillis()%2) == 0) - _scavengeIntervalMs += tenPercent; - - if (LOG.isDebugEnabled()) - LOG.debug("Scavenging every "+_scavengeIntervalMs+" ms"); - if (_timer!=null && (period!=old_period || _task==null)) - { - synchronized (this) - { - if (_task!=null) - _task.cancel(); - _task = new TimerTask() - { - @Override - public void run() - { - scavenge(); - } - }; - _timer.schedule(_task,_scavengeIntervalMs,_scavengeIntervalMs); - } - } - } - - public long getScavengeInterval () - { - return _scavengeIntervalMs/1000; - } - - - public void addSession(HttpSession session) - { - if (session == null) - return; - - synchronized (_sessionIds) - { - String id = ((JDBCSessionManager.Session)session).getClusterId(); - try - { - insert(id); - _sessionIds.add(id); - } - catch (Exception e) - { - LOG.warn("Problem storing session id="+id, e); - } - } - } - - public void removeSession(HttpSession session) - { - if (session == null) - return; - - removeSession(((JDBCSessionManager.Session)session).getClusterId()); - } - - - - public void removeSession (String id) - { - - if (id == null) - return; - - synchronized (_sessionIds) - { - if (LOG.isDebugEnabled()) - LOG.debug("Removing session id="+id); - try - { - _sessionIds.remove(id); - delete(id); - } - catch (Exception e) - { - LOG.warn("Problem removing session id="+id, e); - } - } - - } - - - /** - * Get the session id without any node identifier suffix. - * - * @see org.eclipse.jetty.server.SessionIdManager#getClusterId(java.lang.String) - */ - public String getClusterId(String nodeId) - { - int dot=nodeId.lastIndexOf('.'); - return (dot>0)?nodeId.substring(0,dot):nodeId; - } - - - /** - * Get the session id, including this node's id as a suffix. - * - * @see org.eclipse.jetty.server.SessionIdManager#getNodeId(java.lang.String, javax.servlet.http.HttpServletRequest) - */ - public String getNodeId(String clusterId, HttpServletRequest request) - { - if (_workerName!=null) - return clusterId+'.'+_workerName; - - return clusterId; - } - - - public boolean idInUse(String id) - { - if (id == null) - return false; - - String clusterId = getClusterId(id); - boolean inUse = false; - synchronized (_sessionIds) - { - inUse = _sessionIds.contains(clusterId); - } - - - if (inUse) - return true; //optimisation - if this session is one we've been managing, we can check locally - - //otherwise, we need to go to the database to check - try - { - return exists(clusterId); - } - catch (Exception e) - { - LOG.warn("Problem checking inUse for id="+clusterId, e); - return false; - } - } - - /** - * Invalidate the session matching the id on all contexts. - * - * @see org.eclipse.jetty.server.SessionIdManager#invalidateAll(java.lang.String) - */ - public void invalidateAll(String id) - { - //take the id out of the list of known sessionids for this node - removeSession(id); - - synchronized (_sessionIds) - { - //tell all contexts that may have a session object with this id to - //get rid of them - Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class); - for (int i=0; contexts!=null && i<contexts.length; i++) - { - SessionHandler sessionHandler = (SessionHandler)((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class); - if (sessionHandler != null) - { - SessionManager manager = sessionHandler.getSessionManager(); - - if (manager != null && manager instanceof JDBCSessionManager) - { - ((JDBCSessionManager)manager).invalidateSession(id); - } - } - } - } - } - - - /** - * Start up the id manager. - * - * Makes necessary database tables and starts a Session - * scavenger thread. - */ - @Override - public void doStart() - throws Exception - { - initializeDatabase(); - prepareTables(); - cleanExpiredSessions(); - super.doStart(); - if (LOG.isDebugEnabled()) - LOG.debug("Scavenging interval = "+getScavengeInterval()+" sec"); - _timer=new Timer("JDBCSessionScavenger", true); - setScavengeInterval(getScavengeInterval()); - } - - /** - * Stop the scavenger. - */ - @Override - public void doStop () - throws Exception - { - synchronized(this) - { - if (_task!=null) - _task.cancel(); - if (_timer!=null) - _timer.cancel(); - _timer=null; - } - _sessionIds.clear(); - super.doStop(); - } - - /** - * Get a connection from the driver or datasource. - * - * @return the connection for the datasource - * @throws SQLException - */ - protected Connection getConnection () - throws SQLException - { - if (_datasource != null) - return _datasource.getConnection(); - else - return DriverManager.getConnection(_connectionUrl); - } - - - - - - /** - * Set up the tables in the database - * @throws SQLException - */ - private void prepareTables() - throws SQLException - { - _createSessionIdTable = "create table "+_sessionIdTable+" (id varchar(120), primary key(id))"; - _selectBoundedExpiredSessions = "select * from "+_sessionTable+" where expiryTime >= ? and expiryTime <= ?"; - _selectExpiredSessions = "select * from "+_sessionTable+" where expiryTime >0 and expiryTime <= ?"; - _deleteOldExpiredSessions = "delete from "+_sessionTable+" where expiryTime >0 and expiryTime <= ?"; - - _insertId = "insert into "+_sessionIdTable+" (id) values (?)"; - _deleteId = "delete from "+_sessionIdTable+" where id = ?"; - _queryId = "select * from "+_sessionIdTable+" where id = ?"; - - Connection connection = null; - try - { - //make the id table - connection = getConnection(); - connection.setAutoCommit(true); - DatabaseMetaData metaData = connection.getMetaData(); - _dbAdaptor = new DatabaseAdaptor(metaData); - _sessionTableRowId = _dbAdaptor.getRowIdColumnName(); - - //checking for table existence is case-sensitive, but table creation is not - String tableName = _dbAdaptor.convertIdentifier(_sessionIdTable); - ResultSet result = metaData.getTables(null, null, tableName, null); - if (!result.next()) - { - //table does not exist, so create it - connection.createStatement().executeUpdate(_createSessionIdTable); - } - - //make the session table if necessary - tableName = _dbAdaptor.convertIdentifier(_sessionTable); - result = metaData.getTables(null, null, tableName, null); - if (!result.next()) - { - //table does not exist, so create it - String blobType = _dbAdaptor.getBlobType(); - String longType = _dbAdaptor.getLongType(); - _createSessionTable = "create table "+_sessionTable+" ("+_sessionTableRowId+" varchar(120), sessionId varchar(120), "+ - " contextPath varchar(60), virtualHost varchar(60), lastNode varchar(60), accessTime "+longType+", "+ - " lastAccessTime "+longType+", createTime "+longType+", cookieTime "+longType+", "+ - " lastSavedTime "+longType+", expiryTime "+longType+", map "+blobType+", primary key("+_sessionTableRowId+"))"; - connection.createStatement().executeUpdate(_createSessionTable); - } - - //make some indexes on the JettySessions table - String index1 = "idx_"+_sessionTable+"_expiry"; - String index2 = "idx_"+_sessionTable+"_session"; - - result = metaData.getIndexInfo(null, null, tableName, false, false); - boolean index1Exists = false; - boolean index2Exists = false; - while (result.next()) - { - String idxName = result.getString("INDEX_NAME"); - if (index1.equalsIgnoreCase(idxName)) - index1Exists = true; - else if (index2.equalsIgnoreCase(idxName)) - index2Exists = true; - } - if (!(index1Exists && index2Exists)) - { - Statement statement = connection.createStatement(); - try - { - if (!index1Exists) - statement.executeUpdate("create index "+index1+" on "+_sessionTable+" (expiryTime)"); - if (!index2Exists) - statement.executeUpdate("create index "+index2+" on "+_sessionTable+" (sessionId, contextPath)"); - } - finally - { - if (statement!=null) - { - try { statement.close(); } - catch(Exception e) { LOG.warn(e); } - } - } - } - - //set up some strings representing the statements for session manipulation - _insertSession = "insert into "+_sessionTable+ - " ("+_sessionTableRowId+", sessionId, contextPath, virtualHost, lastNode, accessTime, lastAccessTime, createTime, cookieTime, lastSavedTime, expiryTime, map) "+ - " values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; - - _deleteSession = "delete from "+_sessionTable+ - " where "+_sessionTableRowId+" = ?"; - - _updateSession = "update "+_sessionTable+ - " set lastNode = ?, accessTime = ?, lastAccessTime = ?, lastSavedTime = ?, expiryTime = ?, map = ? where "+_sessionTableRowId+" = ?"; - - _updateSessionNode = "update "+_sessionTable+ - " set lastNode = ? where "+_sessionTableRowId+" = ?"; - - _updateSessionAccessTime = "update "+_sessionTable+ - " set lastNode = ?, accessTime = ?, lastAccessTime = ?, lastSavedTime = ?, expiryTime = ? where "+_sessionTableRowId+" = ?"; - - - } - finally - { - if (connection != null) - connection.close(); - } - } - - /** - * Insert a new used session id into the table. - * - * @param id - * @throws SQLException - */ - private void insert (String id) - throws SQLException - { - Connection connection = null; - PreparedStatement statement = null; - PreparedStatement query = null; - try - { - connection = getConnection(); - connection.setAutoCommit(true); - query = connection.prepareStatement(_queryId); - query.setString(1, id); - ResultSet result = query.executeQuery(); - //only insert the id if it isn't in the db already - if (!result.next()) - { - statement = connection.prepareStatement(_insertId); - statement.setString(1, id); - statement.executeUpdate(); - } - } - finally - { - if (query!=null) - { - try { query.close(); } - catch(Exception e) { LOG.warn(e); } - } - - if (statement!=null) - { - try { statement.close(); } - catch(Exception e) { LOG.warn(e); } - } - - if (connection != null) - connection.close(); - } - } - - /** - * Remove a session id from the table. - * - * @param id - * @throws SQLException - */ - private void delete (String id) - throws SQLException - { - Connection connection = null; - PreparedStatement statement = null; - try - { - connection = getConnection(); - connection.setAutoCommit(true); - statement = connection.prepareStatement(_deleteId); - statement.setString(1, id); - statement.executeUpdate(); - } - finally - { - if (statement!=null) - { - try { statement.close(); } - catch(Exception e) { LOG.warn(e); } - } - - if (connection != null) - connection.close(); - } - } - - - /** - * Check if a session id exists. - * - * @param id - * @return - * @throws SQLException - */ - private boolean exists (String id) - throws SQLException - { - Connection connection = null; - PreparedStatement statement = null; - try - { - connection = getConnection(); - connection.setAutoCommit(true); - statement = connection.prepareStatement(_queryId); - statement.setString(1, id); - ResultSet result = statement.executeQuery(); - return result.next(); - } - finally - { - if (statement!=null) - { - try { statement.close(); } - catch(Exception e) { LOG.warn(e); } - } - - if (connection != null) - connection.close(); - } - } - - /** - * Look for sessions in the database that have expired. - * - * We do this in the SessionIdManager and not the SessionManager so - * that we only have 1 scavenger, otherwise if there are n SessionManagers - * there would be n scavengers, all contending for the database. - * - * We look first for sessions that expired in the previous interval, then - * for sessions that expired previously - these are old sessions that no - * node is managing any more and have become stuck in the database. - */ - private void scavenge () - { - Connection connection = null; - PreparedStatement statement = null; - List<String> expiredSessionIds = new ArrayList<String>(); - try - { - if (LOG.isDebugEnabled()) - LOG.debug("Scavenge sweep started at "+System.currentTimeMillis()); - if (_lastScavengeTime > 0) - { - connection = getConnection(); - connection.setAutoCommit(true); - //"select sessionId from JettySessions where expiryTime > (lastScavengeTime - scanInterval) and expiryTime < lastScavengeTime"; - statement = connection.prepareStatement(_selectBoundedExpiredSessions); - long lowerBound = (_lastScavengeTime - _scavengeIntervalMs); - long upperBound = _lastScavengeTime; - if (LOG.isDebugEnabled()) - LOG.debug (" Searching for sessions expired between "+lowerBound + " and "+upperBound); - - statement.setLong(1, lowerBound); - statement.setLong(2, upperBound); - ResultSet result = statement.executeQuery(); - while (result.next()) - { - String sessionId = result.getString("sessionId"); - expiredSessionIds.add(sessionId); - if (LOG.isDebugEnabled()) LOG.debug (" Found expired sessionId="+sessionId); - } - - //tell the SessionManagers to expire any sessions with a matching sessionId in memory - Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class); - for (int i=0; contexts!=null && i<contexts.length; i++) - { - - SessionHandler sessionHandler = (SessionHandler)((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class); - if (sessionHandler != null) - { - SessionManager manager = sessionHandler.getSessionManager(); - if (manager != null && manager instanceof JDBCSessionManager) - { - ((JDBCSessionManager)manager).expire(expiredSessionIds); - } - } - } - - //find all sessions that have expired at least a couple of scanIntervals ago and just delete them - upperBound = _lastScavengeTime - (2 * _scavengeIntervalMs); - if (upperBound > 0) - { - if (LOG.isDebugEnabled()) LOG.debug("Deleting old expired sessions expired before "+upperBound); - try - { - statement = connection.prepareStatement(_deleteOldExpiredSessions); - statement.setLong(1, upperBound); - int rows = statement.executeUpdate(); - if (LOG.isDebugEnabled()) LOG.debug("Deleted "+rows+" rows of old sessions expired before "+upperBound); - } - finally - { - if (statement!=null) - { - try { statement.close(); } - catch(Exception e) { LOG.warn(e); } - } - } - } - } - } - catch (Exception e) - { - if (isRunning()) - LOG.warn("Problem selecting expired sessions", e); - else - LOG.ignore(e); - } - finally - { - _lastScavengeTime=System.currentTimeMillis(); - if (LOG.isDebugEnabled()) LOG.debug("Scavenge sweep ended at "+_lastScavengeTime); - if (connection != null) - { - try - { - connection.close(); - } - catch (SQLException e) - { - LOG.warn(e); - } - } - } - } - - /** - * Get rid of sessions and sessionids from sessions that have already expired - * @throws Exception - */ - private void cleanExpiredSessions () - { - Connection connection = null; - PreparedStatement statement = null; - Statement sessionsTableStatement = null; - Statement sessionIdsTableStatement = null; - List<String> expiredSessionIds = new ArrayList<String>(); - try - { - connection = getConnection(); - connection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED); - connection.setAutoCommit(false); - - statement = connection.prepareStatement(_selectExpiredSessions); - long now = System.currentTimeMillis(); - if (LOG.isDebugEnabled()) LOG.debug ("Searching for sessions expired before {}", now); - - statement.setLong(1, now); - ResultSet result = statement.executeQuery(); - while (result.next()) - { - String sessionId = result.getString("sessionId"); - expiredSessionIds.add(sessionId); - if (LOG.isDebugEnabled()) LOG.debug ("Found expired sessionId={}", sessionId); - } - - sessionsTableStatement = null; - sessionIdsTableStatement = null; - - if (!expiredSessionIds.isEmpty()) - { - sessionsTableStatement = connection.createStatement(); - sessionsTableStatement.executeUpdate(createCleanExpiredSessionsSql("delete from "+_sessionTable+" where sessionId in ", expiredSessionIds)); - sessionIdsTableStatement = connection.createStatement(); - sessionIdsTableStatement.executeUpdate(createCleanExpiredSessionsSql("delete from "+_sessionIdTable+" where id in ", expiredSessionIds)); - } - connection.commit(); - - synchronized (_sessionIds) - { - _sessionIds.removeAll(expiredSessionIds); //in case they were in our local cache of session ids - } - } - catch (Exception e) - { - if (connection != null) - { - try - { - LOG.warn("Rolling back clean of expired sessions", e); - connection.rollback(); - } - catch (Exception x) { LOG.warn("Rollback of expired sessions failed", x);} - } - } - finally - { - if (sessionIdsTableStatement!=null) - { - try { sessionIdsTableStatement.close(); } - catch(Exception e) { LOG.warn(e); } - } - - if (sessionsTableStatement!=null) - { - try { sessionsTableStatement.close(); } - catch(Exception e) { LOG.warn(e); } - } - - if (statement!=null) - { - try { statement.close(); } - catch(Exception e) { LOG.warn(e); } - } - - try - { - if (connection != null) - connection.close(); - } - catch (SQLException e) - { - LOG.warn(e); - } - } - } - - - /** - * - * @param sql - * @param connection - * @param expiredSessionIds - * @throws Exception - */ - private String createCleanExpiredSessionsSql (String sql,Collection<String> expiredSessionIds) - throws Exception - { - StringBuffer buff = new StringBuffer(); - buff.append(sql); - buff.append("("); - Iterator<String> itor = expiredSessionIds.iterator(); - while (itor.hasNext()) - { - buff.append("'"+(itor.next())+"'"); - if (itor.hasNext()) - buff.append(","); - } - buff.append(")"); - - if (LOG.isDebugEnabled()) LOG.debug("Cleaning expired sessions with: {}", buff); - return buff.toString(); - } - - private void initializeDatabase () - throws Exception - { - if (_datasource != null) - return; //already set up - - if (_jndiName!=null) - { - InitialContext ic = new InitialContext(); - _datasource = (DataSource)ic.lookup(_jndiName); - } - else if ( _driver != null && _connectionUrl != null ) - { - DriverManager.registerDriver(_driver); - } - else if (_driverClassName != null && _connectionUrl != null) - { - Class.forName(_driverClassName); - } - else - throw new IllegalStateException("No database configured for sessions"); - } - - -}
--- a/src/org/eclipse/jetty/server/session/JDBCSessionManager.java Thu Sep 08 16:13:27 2016 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1174 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - - -package org.eclipse.jetty.server.session; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.HashMap; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.atomic.AtomicReference; - -import javax.servlet.SessionTrackingMode; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSessionEvent; -import javax.servlet.http.HttpSessionListener; - -import org.eclipse.jetty.server.SessionIdManager; -import org.eclipse.jetty.server.handler.ContextHandler; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -/** - * JDBCSessionManager - * - * SessionManager that persists sessions to a database to enable clustering. - * - * Session data is persisted to the JettySessions table: - * - * rowId (unique in cluster: webapp name/path + virtualhost + sessionId) - * contextPath (of the context owning the session) - * sessionId (unique in a context) - * lastNode (name of node last handled session) - * accessTime (time in milliseconds session was accessed) - * lastAccessTime (previous time in milliseconds session was accessed) - * createTime (time in milliseconds session created) - * cookieTime (time in milliseconds session cookie created) - * lastSavedTime (last time in milliseconds session access times were saved) - * expiryTime (time in milliseconds that the session is due to expire) - * map (attribute map) - * - * As an optimization, to prevent thrashing the database, we do not persist - * the accessTime and lastAccessTime every time the session is accessed. Rather, - * we write it out every so often. The frequency is controlled by the saveIntervalSec - * field. - */ -public class JDBCSessionManager extends AbstractSessionManager -{ - private static final Logger LOG = Log.getLogger(JDBCSessionManager.class); - - private ConcurrentHashMap<String, AbstractSession> _sessions; - protected JDBCSessionIdManager _jdbcSessionIdMgr = null; - protected long _saveIntervalSec = 60; //only persist changes to session access times every 60 secs - - - - - /** - * Session - * - * Session instance. - */ - public class Session extends AbstractSession - { - private static final long serialVersionUID = 5208464051134226143L; - - /** - * If dirty, session needs to be (re)persisted - */ - private boolean _dirty=false; - - - /** - * Time in msec since the epoch that a session cookie was set for this session - */ - private long _cookieSet; - - - /** - * Time in msec since the epoch that the session will expire - */ - private long _expiryTime; - - - /** - * Time in msec since the epoch that the session was last persisted - */ - private long _lastSaved; - - - /** - * Unique identifier of the last node to host the session - */ - private String _lastNode; - - - /** - * Virtual host for context (used to help distinguish 2 sessions with same id on different contexts) - */ - private String _virtualHost; - - - /** - * Unique row in db for session - */ - private String _rowId; - - - /** - * Mangled context name (used to help distinguish 2 sessions with same id on different contexts) - */ - private String _canonicalContext; - - - /** - * Session from a request. - * - * @param request - */ - protected Session (HttpServletRequest request) - { - super(JDBCSessionManager.this,request); - int maxInterval=getMaxInactiveInterval(); - _expiryTime = (maxInterval <= 0 ? 0 : (System.currentTimeMillis() + maxInterval*1000L)); - _virtualHost = JDBCSessionManager.getVirtualHost(_context); - _canonicalContext = canonicalize(_context.getContextPath()); - _lastNode = getSessionIdManager().getWorkerName(); - } - - - /** - * Session restored from database - * @param sessionId - * @param rowId - * @param created - * @param accessed - */ - protected Session (String sessionId, String rowId, long created, long accessed) - { - super(JDBCSessionManager.this, created, accessed, sessionId); - _rowId = rowId; - } - - - protected synchronized String getRowId() - { - return _rowId; - } - - protected synchronized void setRowId(String rowId) - { - _rowId = rowId; - } - - public synchronized void setVirtualHost (String vhost) - { - _virtualHost=vhost; - } - - public synchronized String getVirtualHost () - { - return _virtualHost; - } - - public synchronized long getLastSaved () - { - return _lastSaved; - } - - public synchronized void setLastSaved (long time) - { - _lastSaved=time; - } - - public synchronized void setExpiryTime (long time) - { - _expiryTime=time; - } - - public synchronized long getExpiryTime () - { - return _expiryTime; - } - - - public synchronized void setCanonicalContext(String str) - { - _canonicalContext=str; - } - - public synchronized String getCanonicalContext () - { - return _canonicalContext; - } - - public void setCookieSet (long ms) - { - _cookieSet = ms; - } - - public synchronized long getCookieSet () - { - return _cookieSet; - } - - public synchronized void setLastNode (String node) - { - _lastNode=node; - } - - public synchronized String getLastNode () - { - return _lastNode; - } - - @Override - public void setAttribute (String name, Object value) - { - super.setAttribute(name, value); - _dirty=true; - } - - @Override - public void removeAttribute (String name) - { - super.removeAttribute(name); - _dirty=true; - } - - @Override - protected void cookieSet() - { - _cookieSet = getAccessed(); - } - - /** - * Entry to session. - * Called by SessionHandler on inbound request and the session already exists in this node's memory. - * - * @see org.eclipse.jetty.server.session.AbstractSession#access(long) - */ - @Override - protected boolean access(long time) - { - synchronized (this) - { - if (super.access(time)) - { - int maxInterval=getMaxInactiveInterval(); - _expiryTime = (maxInterval <= 0 ? 0 : (time + maxInterval*1000L)); - return true; - } - return false; - } - } - - - - /** - * Exit from session - * @see org.eclipse.jetty.server.session.AbstractSession#complete() - */ - @Override - protected void complete() - { - synchronized (this) - { - super.complete(); - try - { - if (isValid()) - { - if (_dirty) - { - //The session attributes have changed, write to the db, ensuring - //http passivation/activation listeners called - willPassivate(); - updateSession(this); - didActivate(); - } - else if ((getAccessed() - _lastSaved) >= (getSaveInterval() * 1000L)) - { - updateSessionAccessTime(this); - } - } - } - catch (Exception e) - { - LOG.warn("Problem persisting changed session data id="+getId(), e); - } - finally - { - _dirty=false; - } - } - } - - @Override - protected void timeout() throws IllegalStateException - { - if (LOG.isDebugEnabled()) - LOG.debug("Timing out session id="+getClusterId()); - super.timeout(); - } - - @Override - public String toString () - { - return "Session rowId="+_rowId+",id="+getId()+",lastNode="+_lastNode+ - ",created="+getCreationTime()+",accessed="+getAccessed()+ - ",lastAccessed="+getLastAccessedTime()+",cookieSet="+_cookieSet+ - ",lastSaved="+_lastSaved+",expiry="+_expiryTime; - } - } - - - - - /** - * ClassLoadingObjectInputStream - * - * Used to persist the session attribute map - */ - protected class ClassLoadingObjectInputStream extends ObjectInputStream - { - public ClassLoadingObjectInputStream(java.io.InputStream in) throws IOException - { - super(in); - } - - public ClassLoadingObjectInputStream () throws IOException - { - super(); - } - - @Override - public Class<?> resolveClass (java.io.ObjectStreamClass cl) throws IOException, ClassNotFoundException - { - try - { - return Class.forName(cl.getName(), false, Thread.currentThread().getContextClassLoader()); - } - catch (ClassNotFoundException e) - { - return super.resolveClass(cl); - } - } - } - - - /** - * Set the time in seconds which is the interval between - * saving the session access time to the database. - * - * This is an optimization that prevents the database from - * being overloaded when a session is accessed very frequently. - * - * On session exit, if the session attributes have NOT changed, - * the time at which we last saved the accessed - * time is compared to the current accessed time. If the interval - * is at least saveIntervalSecs, then the access time will be - * persisted to the database. - * - * If any session attribute does change, then the attributes and - * the accessed time are persisted. - * - * @param sec - */ - public void setSaveInterval (long sec) - { - _saveIntervalSec=sec; - } - - public long getSaveInterval () - { - return _saveIntervalSec; - } - - - - /** - * A method that can be implemented in subclasses to support - * distributed caching of sessions. This method will be - * called whenever the session is written to the database - * because the session data has changed. - * - * This could be used eg with a JMS backplane to notify nodes - * that the session has changed and to delete the session from - * the node's cache, and re-read it from the database. - * @param session - */ - public void cacheInvalidate (Session session) - { - - } - - - /** - * A session has been requested by its id on this node. - * - * Load the session by id AND context path from the database. - * Multiple contexts may share the same session id (due to dispatching) - * but they CANNOT share the same contents. - * - * Check if last node id is my node id, if so, then the session we have - * in memory cannot be stale. If another node used the session last, then - * we need to refresh from the db. - * - * NOTE: this method will go to the database, so if you only want to check - * for the existence of a Session in memory, use _sessions.get(id) instead. - * - * @see org.eclipse.jetty.server.session.AbstractSessionManager#getSession(java.lang.String) - */ - @Override - public Session getSession(String idInCluster) - { - Session session = null; - Session memSession = (Session)_sessions.get(idInCluster); - - synchronized (this) - { - //check if we need to reload the session - - //as an optimization, don't reload on every access - //to reduce the load on the database. This introduces a window of - //possibility that the node may decide that the session is local to it, - //when the session has actually been live on another node, and then - //re-migrated to this node. This should be an extremely rare occurrence, - //as load-balancers are generally well-behaved and consistently send - //sessions to the same node, changing only iff that node fails. - //Session data = null; - long now = System.currentTimeMillis(); - if (LOG.isDebugEnabled()) - { - if (memSession==null) - LOG.debug("getSession("+idInCluster+"): not in session map,"+ - " now="+now+ - " lastSaved="+(memSession==null?0:memSession._lastSaved)+ - " interval="+(_saveIntervalSec * 1000L)); - else - LOG.debug("getSession("+idInCluster+"): in session map, "+ - " now="+now+ - " lastSaved="+(memSession==null?0:memSession._lastSaved)+ - " interval="+(_saveIntervalSec * 1000L)+ - " lastNode="+memSession._lastNode+ - " thisNode="+getSessionIdManager().getWorkerName()+ - " difference="+(now - memSession._lastSaved)); - } - - try - { - if (memSession==null) - { - LOG.debug("getSession("+idInCluster+"): no session in session map. Reloading session data from db."); - session = loadSession(idInCluster, canonicalize(_context.getContextPath()), getVirtualHost(_context)); - } - else if ((now - memSession._lastSaved) >= (_saveIntervalSec * 1000L)) - { - LOG.debug("getSession("+idInCluster+"): stale session. Reloading session data from db."); - session = loadSession(idInCluster, canonicalize(_context.getContextPath()), getVirtualHost(_context)); - } - else - { - LOG.debug("getSession("+idInCluster+"): session in session map"); - session = memSession; - } - } - catch (Exception e) - { - LOG.warn("Unable to load session "+idInCluster, e); - return null; - } - - - //If we have a session - if (session != null) - { - //If the session was last used on a different node, or session doesn't exist on this node - if (!session.getLastNode().equals(getSessionIdManager().getWorkerName()) || memSession==null) - { - //if session doesn't expire, or has not already expired, update it and put it in this nodes' memory - if (session._expiryTime <= 0 || session._expiryTime > now) - { - if (LOG.isDebugEnabled()) - LOG.debug("getSession("+idInCluster+"): lastNode="+session.getLastNode()+" thisNode="+getSessionIdManager().getWorkerName()); - - session.setLastNode(getSessionIdManager().getWorkerName()); - _sessions.put(idInCluster, session); - - //update in db: if unable to update, session will be scavenged later - try - { - updateSessionNode(session); - session.didActivate(); - } - catch (Exception e) - { - LOG.warn("Unable to update freshly loaded session "+idInCluster, e); - return null; - } - } - else - { - LOG.debug("getSession ({}): Session has expired", idInCluster); - session=null; - } - - } - else - { - //the session loaded from the db and the one in memory are the same, so keep using the one in memory - session = memSession; - LOG.debug("getSession({}): Session not stale {}", idInCluster,session); - } - } - else - { - //No session in db with matching id and context path. - LOG.debug("getSession({}): No session in database matching id={}",idInCluster,idInCluster); - } - - return session; - } - } - - /** - * Get the number of sessions. - * - * @see org.eclipse.jetty.server.session.AbstractSessionManager#getSessions() - */ - @Override - public int getSessions() - { - int size = 0; - synchronized (this) - { - size = _sessions.size(); - } - return size; - } - - - /** - * Start the session manager. - * - * @see org.eclipse.jetty.server.session.AbstractSessionManager#doStart() - */ - @Override - public void doStart() throws Exception - { - if (_sessionIdManager==null) - throw new IllegalStateException("No session id manager defined"); - - _jdbcSessionIdMgr = (JDBCSessionIdManager)_sessionIdManager; - - _sessions = new ConcurrentHashMap<String, AbstractSession>(); - - super.doStart(); - } - - - /** - * Stop the session manager. - * - * @see org.eclipse.jetty.server.session.AbstractSessionManager#doStop() - */ - @Override - public void doStop() throws Exception - { - _sessions.clear(); - _sessions = null; - - super.doStop(); - } - - @Override - protected void invalidateSessions() - { - //Do nothing - we don't want to remove and - //invalidate all the sessions because this - //method is called from doStop(), and just - //because this context is stopping does not - //mean that we should remove the session from - //any other nodes - } - - - /** - * Invalidate a session. - * - * @param idInCluster - */ - protected void invalidateSession (String idInCluster) - { - Session session = null; - synchronized (this) - { - session = (Session)_sessions.get(idInCluster); - } - - if (session != null) - { - session.invalidate(); - } - } - - /** - * Delete an existing session, both from the in-memory map and - * the database. - * - * @see org.eclipse.jetty.server.session.AbstractSessionManager#removeSession(java.lang.String) - */ - @Override - protected boolean removeSession(String idInCluster) - { - synchronized (this) - { - Session session = (Session)_sessions.remove(idInCluster); - try - { - if (session != null) - deleteSession(session); - } - catch (Exception e) - { - LOG.warn("Problem deleting session id="+idInCluster, e); - } - return session!=null; - } - } - - - /** - * Add a newly created session to our in-memory list for this node and persist it. - * - * @see org.eclipse.jetty.server.session.AbstractSessionManager#addSession(org.eclipse.jetty.server.session.AbstractSession) - */ - @Override - protected void addSession(AbstractSession session) - { - if (session==null) - return; - - synchronized (this) - { - _sessions.put(session.getClusterId(), session); - } - - //TODO or delay the store until exit out of session? If we crash before we store it - //then session data will be lost. - try - { - synchronized (session) - { - session.willPassivate(); - storeSession(((JDBCSessionManager.Session)session)); - session.didActivate(); - } - } - catch (Exception e) - { - LOG.warn("Unable to store new session id="+session.getId() , e); - } - } - - - /** - * Make a new Session. - * - * @see org.eclipse.jetty.server.session.AbstractSessionManager#newSession(javax.servlet.http.HttpServletRequest) - */ - @Override - protected AbstractSession newSession(HttpServletRequest request) - { - return new Session(request); - } - - /* ------------------------------------------------------------ */ - /** Remove session from manager - * @param session The session to remove - * @param invalidate True if {@link HttpSessionListener#sessionDestroyed(HttpSessionEvent)} and - * {@link SessionIdManager#invalidateAll(String)} should be called. - */ - @Override - public void removeSession(AbstractSession session, boolean invalidate) - { - // Remove session from context and global maps - boolean removed = false; - - synchronized (this) - { - //take this session out of the map of sessions for this context - if (getSession(session.getClusterId()) != null) - { - removed = true; - removeSession(session.getClusterId()); - } - } - - if (removed) - { - // Remove session from all context and global id maps - _sessionIdManager.removeSession(session); - - if (invalidate) - _sessionIdManager.invalidateAll(session.getClusterId()); - - if (invalidate && !_sessionListeners.isEmpty()) - { - HttpSessionEvent event=new HttpSessionEvent(session); - for (HttpSessionListener l : _sessionListeners) - l.sessionDestroyed(event); - } - if (!invalidate) - { - session.willPassivate(); - } - } - } - - - /** - * Expire any Sessions we have in memory matching the list of - * expired Session ids. - * - * @param sessionIds - */ - protected void expire (List<?> sessionIds) - { - //don't attempt to scavenge if we are shutting down - if (isStopping() || isStopped()) - return; - - //Remove any sessions we already have in memory that match the ids - Thread thread=Thread.currentThread(); - ClassLoader old_loader=thread.getContextClassLoader(); - ListIterator<?> itor = sessionIds.listIterator(); - - try - { - while (itor.hasNext()) - { - String sessionId = (String)itor.next(); - if (LOG.isDebugEnabled()) - LOG.debug("Expiring session id "+sessionId); - - Session session = (Session)_sessions.get(sessionId); - if (session != null) - { - session.timeout(); - itor.remove(); - } - else - { - if (LOG.isDebugEnabled()) - LOG.debug("Unrecognized session id="+sessionId); - } - } - } - catch (Throwable t) - { - LOG.warn("Problem expiring sessions", t); - } - finally - { - thread.setContextClassLoader(old_loader); - } - } - - - /** - * Load a session from the database - * @param id - * @return the session data that was loaded - * @throws Exception - */ - protected Session loadSession (final String id, final String canonicalContextPath, final String vhost) - throws Exception - { - final AtomicReference<Session> _reference = new AtomicReference<Session>(); - final AtomicReference<Exception> _exception = new AtomicReference<Exception>(); - Runnable load = new Runnable() - { - @SuppressWarnings("unchecked") - public void run() - { - Session session = null; - Connection connection=null; - PreparedStatement statement = null; - try - { - connection = getConnection(); - statement = _jdbcSessionIdMgr._dbAdaptor.getLoadStatement(connection, id, canonicalContextPath, vhost); - ResultSet result = statement.executeQuery(); - if (result.next()) - { - session = new Session(id, result.getString(_jdbcSessionIdMgr._sessionTableRowId), result.getLong("createTime"), result.getLong("accessTime")); - session.setCookieSet(result.getLong("cookieTime")); - session.setLastAccessedTime(result.getLong("lastAccessTime")); - session.setLastNode(result.getString("lastNode")); - session.setLastSaved(result.getLong("lastSavedTime")); - session.setExpiryTime(result.getLong("expiryTime")); - session.setCanonicalContext(result.getString("contextPath")); - session.setVirtualHost(result.getString("virtualHost")); - - InputStream is = ((JDBCSessionIdManager)getSessionIdManager())._dbAdaptor.getBlobInputStream(result, "map"); - ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream (is); - Object o = ois.readObject(); - session.addAttributes((Map<String,Object>)o); - ois.close(); - - if (LOG.isDebugEnabled()) - LOG.debug("LOADED session "+session); - } - _reference.set(session); - } - catch (Exception e) - { - _exception.set(e); - } - finally - { - if (statement!=null) - { - try { statement.close(); } - catch(Exception e) { LOG.warn(e); } - } - - if (connection!=null) - { - try { connection.close();} - catch(Exception e) { LOG.warn(e); } - } - } - } - }; - - if (_context==null) - load.run(); - else - _context.getContextHandler().handle(load); - - if (_exception.get()!=null) - { - //if the session could not be restored, take its id out of the pool of currently-in-use - //session ids - _jdbcSessionIdMgr.removeSession(id); - throw _exception.get(); - } - - return _reference.get(); - } - - /** - * Insert a session into the database. - * - * @param data - * @throws Exception - */ - protected void storeSession (Session session) - throws Exception - { - if (session==null) - return; - - //put into the database - Connection connection = getConnection(); - PreparedStatement statement = null; - try - { - String rowId = calculateRowId(session); - - long now = System.currentTimeMillis(); - connection.setAutoCommit(true); - statement = connection.prepareStatement(_jdbcSessionIdMgr._insertSession); - statement.setString(1, rowId); //rowId - statement.setString(2, session.getId()); //session id - statement.setString(3, session.getCanonicalContext()); //context path - statement.setString(4, session.getVirtualHost()); //first vhost - statement.setString(5, getSessionIdManager().getWorkerName());//my node id - statement.setLong(6, session.getAccessed());//accessTime - statement.setLong(7, session.getLastAccessedTime()); //lastAccessTime - statement.setLong(8, session.getCreationTime()); //time created - statement.setLong(9, session.getCookieSet());//time cookie was set - statement.setLong(10, now); //last saved time - statement.setLong(11, session.getExpiryTime()); - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream(baos); - oos.writeObject(session.getAttributeMap()); - byte[] bytes = baos.toByteArray(); - - ByteArrayInputStream bais = new ByteArrayInputStream(bytes); - statement.setBinaryStream(12, bais, bytes.length);//attribute map as blob - - statement.executeUpdate(); - session.setRowId(rowId); //set it on the in-memory data as well as in db - session.setLastSaved(now); - - - if (LOG.isDebugEnabled()) - LOG.debug("Stored session "+session); - } - finally - { - if (statement!=null) - { - try { statement.close(); } - catch(Exception e) { LOG.warn(e); } - } - - if (connection!=null) - connection.close(); - } - } - - - /** - * Update data on an existing persisted session. - * - * @param data the session - * @throws Exception - */ - protected void updateSession (Session data) - throws Exception - { - if (data==null) - return; - - Connection connection = getConnection(); - PreparedStatement statement = null; - try - { - long now = System.currentTimeMillis(); - connection.setAutoCommit(true); - statement = connection.prepareStatement(_jdbcSessionIdMgr._updateSession); - statement.setString(1, getSessionIdManager().getWorkerName());//my node id - statement.setLong(2, data.getAccessed());//accessTime - statement.setLong(3, data.getLastAccessedTime()); //lastAccessTime - statement.setLong(4, now); //last saved time - statement.setLong(5, data.getExpiryTime()); - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream(baos); - oos.writeObject(data.getAttributeMap()); - byte[] bytes = baos.toByteArray(); - ByteArrayInputStream bais = new ByteArrayInputStream(bytes); - - statement.setBinaryStream(6, bais, bytes.length);//attribute map as blob - statement.setString(7, data.getRowId()); //rowId - statement.executeUpdate(); - - data.setLastSaved(now); - if (LOG.isDebugEnabled()) - LOG.debug("Updated session "+data); - } - finally - { - if (statement!=null) - { - try { statement.close(); } - catch(Exception e) { LOG.warn(e); } - } - - if (connection!=null) - connection.close(); - } - } - - - /** - * Update the node on which the session was last seen to be my node. - * - * @param data the session - * @throws Exception - */ - protected void updateSessionNode (Session data) - throws Exception - { - String nodeId = getSessionIdManager().getWorkerName(); - Connection connection = getConnection(); - PreparedStatement statement = null; - try - { - connection.setAutoCommit(true); - statement = connection.prepareStatement(_jdbcSessionIdMgr._updateSessionNode); - statement.setString(1, nodeId); - statement.setString(2, data.getRowId()); - statement.executeUpdate(); - statement.close(); - if (LOG.isDebugEnabled()) - LOG.debug("Updated last node for session id="+data.getId()+", lastNode = "+nodeId); - } - finally - { - if (statement!=null) - { - try { statement.close(); } - catch(Exception e) { LOG.warn(e); } - } - - if (connection!=null) - connection.close(); - } - } - - /** - * Persist the time the session was last accessed. - * - * @param data the session - * @throws Exception - */ - private void updateSessionAccessTime (Session data) - throws Exception - { - Connection connection = getConnection(); - PreparedStatement statement = null; - try - { - long now = System.currentTimeMillis(); - connection.setAutoCommit(true); - statement = connection.prepareStatement(_jdbcSessionIdMgr._updateSessionAccessTime); - statement.setString(1, getSessionIdManager().getWorkerName()); - statement.setLong(2, data.getAccessed()); - statement.setLong(3, data.getLastAccessedTime()); - statement.setLong(4, now); - statement.setLong(5, data.getExpiryTime()); - statement.setString(6, data.getRowId()); - statement.executeUpdate(); - data.setLastSaved(now); - statement.close(); - if (LOG.isDebugEnabled()) - LOG.debug("Updated access time session id="+data.getId()); - } - finally - { - if (statement!=null) - { - try { statement.close(); } - catch(Exception e) { LOG.warn(e); } - } - - if (connection!=null) - connection.close(); - } - } - - - - - /** - * Delete a session from the database. Should only be called - * when the session has been invalidated. - * - * @param data - * @throws Exception - */ - protected void deleteSession (Session data) - throws Exception - { - Connection connection = getConnection(); - PreparedStatement statement = null; - try - { - connection.setAutoCommit(true); - statement = connection.prepareStatement(_jdbcSessionIdMgr._deleteSession); - statement.setString(1, data.getRowId()); - statement.executeUpdate(); - if (LOG.isDebugEnabled()) - LOG.debug("Deleted Session "+data); - } - finally - { - if (statement!=null) - { - try { statement.close(); } - catch(Exception e) { LOG.warn(e); } - } - - if (connection!=null) - connection.close(); - } - } - - - - /** - * Get a connection from the driver. - * @return - * @throws SQLException - */ - private Connection getConnection () - throws SQLException - { - return ((JDBCSessionIdManager)getSessionIdManager()).getConnection(); - } - - /** - * Calculate a unique id for this session across the cluster. - * - * Unique id is composed of: contextpath_virtualhost0_sessionid - * @param data - * @return - */ - private String calculateRowId (Session data) - { - String rowId = canonicalize(_context.getContextPath()); - rowId = rowId + "_" + getVirtualHost(_context); - rowId = rowId+"_"+data.getId(); - return rowId; - } - - /** - * Get the first virtual host for the context. - * - * Used to help identify the exact session/contextPath. - * - * @return 0.0.0.0 if no virtual host is defined - */ - private static String getVirtualHost (ContextHandler.Context context) - { - String vhost = "0.0.0.0"; - - if (context==null) - return vhost; - - String [] vhosts = context.getContextHandler().getVirtualHosts(); - if (vhosts==null || vhosts.length==0 || vhosts[0]==null) - return vhost; - - return vhosts[0]; - } - - /** - * Make an acceptable file name from a context path. - * - * @param path - * @return - */ - private static String canonicalize (String path) - { - if (path==null) - return ""; - - return path.replace('/', '_').replace('.','_').replace('\\','_'); - } -}
--- a/src/org/eclipse/jetty/server/session/SessionHandler.java Thu Sep 08 16:13:27 2016 -0600 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,346 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. -// ------------------------------------------------------------------------ -// All rights reserved. This program and the accompanying materials -// are made available under the terms of the Eclipse Public License v1.0 -// and Apache License v2.0 which accompanies this distribution. -// -// The Eclipse Public License is available at -// http://www.eclipse.org/legal/epl-v10.html -// -// The Apache License v2.0 is available at -// http://www.opensource.org/licenses/apache2.0.php -// -// You may elect to redistribute this code under either of these licenses. -// ======================================================================== -// - -package org.eclipse.jetty.server.session; - -import java.io.IOException; -import java.util.EnumSet; -import java.util.EventListener; -import javax.servlet.DispatcherType; -import javax.servlet.ServletException; -import javax.servlet.SessionTrackingMode; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.eclipse.jetty.http.HttpCookie; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.SessionManager; -import org.eclipse.jetty.server.handler.ScopedHandler; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -/* ------------------------------------------------------------ */ -/** - * SessionHandler. - */ -public class SessionHandler extends ScopedHandler -{ - final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session"); - - public final static EnumSet<SessionTrackingMode> DEFAULT_TRACKING = EnumSet.of(SessionTrackingMode.COOKIE,SessionTrackingMode.URL); - - /* -------------------------------------------------------------- */ - private SessionManager _sessionManager; - - /* ------------------------------------------------------------ */ - /** - * Constructor. Construct a SessionHandler witha a HashSessionManager with a standard java.util.Random generator is created. - */ - public SessionHandler() - { - this(new HashSessionManager()); - } - - /* ------------------------------------------------------------ */ - /** - * @param manager - * The session manager - */ - public SessionHandler(SessionManager manager) - { - setSessionManager(manager); - } - - /* ------------------------------------------------------------ */ - /** - * @return Returns the sessionManager. - */ - public SessionManager getSessionManager() - { - return _sessionManager; - } - - /* ------------------------------------------------------------ */ - /** - * @param sessionManager - * The sessionManager to set. - */ - public void setSessionManager(SessionManager sessionManager) - { - if (isStarted()) - throw new IllegalStateException(); - SessionManager old_session_manager = _sessionManager; - - if (getServer() != null) - getServer().getContainer().update(this,old_session_manager,sessionManager,"sessionManager",true); - - if (sessionManager != null) - sessionManager.setSessionHandler(this); - - _sessionManager = sessionManager; - - if (old_session_manager != null) - old_session_manager.setSessionHandler(null); - } - - /* ------------------------------------------------------------ */ - @Override - public void setServer(Server server) - { - Server old_server = getServer(); - if (old_server != null && old_server != server) - old_server.getContainer().update(this,_sessionManager,null,"sessionManager",true); - super.setServer(server); - if (server != null && server != old_server) - server.getContainer().update(this,null,_sessionManager,"sessionManager",true); - } - - /* ------------------------------------------------------------ */ - /* - * @see org.eclipse.thread.AbstractLifeCycle#doStart() - */ - @Override - protected void doStart() throws Exception - { - _sessionManager.start(); - super.doStart(); - } - - /* ------------------------------------------------------------ */ - /* - * @see org.eclipse.thread.AbstractLifeCycle#doStop() - */ - @Override - protected void doStop() throws Exception - { - // Destroy sessions before destroying servlets/filters see JETTY-1266 - _sessionManager.stop(); - super.doStop(); - } - - /* ------------------------------------------------------------ */ - /* - * @see org.eclipse.jetty.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int) - */ - @Override - public void doScope(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException - { - SessionManager old_session_manager = null; - HttpSession old_session = null; - HttpSession access = null; - try - { - old_session_manager = baseRequest.getSessionManager(); - old_session = baseRequest.getSession(false); - - if (old_session_manager != _sessionManager) - { - // new session context - baseRequest.setSessionManager(_sessionManager); - baseRequest.setSession(null); - checkRequestedSessionId(baseRequest,request); - } - - // access any existing session - HttpSession session = null; - if (_sessionManager != null) - { - session = baseRequest.getSession(false); - if (session != null) - { - if (session != old_session) - { - access = session; - HttpCookie cookie = _sessionManager.access(session,request.isSecure()); - if (cookie != null) // Handle changed ID or max-age refresh - baseRequest.getResponse().addCookie(cookie); - } - } - else - { - session = baseRequest.recoverNewSession(_sessionManager); - if (session != null) - baseRequest.setSession(session); - } - } - - if (LOG.isDebugEnabled()) - { - LOG.debug("sessionManager=" + _sessionManager); - LOG.debug("session=" + session); - } - - // start manual inline of nextScope(target,baseRequest,request,response); - if (_nextScope != null) - _nextScope.doScope(target,baseRequest,request,response); - else if (_outerScope != null) - _outerScope.doHandle(target,baseRequest,request,response); - else - doHandle(target,baseRequest,request,response); - // end manual inline (pathentic attempt to reduce stack depth) - - } - finally - { - if (access != null) - _sessionManager.complete(access); - - HttpSession session = baseRequest.getSession(false); - if (session != null && old_session == null && session != access) - _sessionManager.complete(session); - - if (old_session_manager != null && old_session_manager != _sessionManager) - { - baseRequest.setSessionManager(old_session_manager); - baseRequest.setSession(old_session); - } - } - } - - /* ------------------------------------------------------------ */ - /* - * @see org.eclipse.jetty.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int) - */ - @Override - public void doHandle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException - { - // start manual inline of nextHandle(target,baseRequest,request,response); - if (never()) - nextHandle(target,baseRequest,request,response); - else if (_nextScope != null && _nextScope == _handler) - _nextScope.doHandle(target,baseRequest,request,response); - else if (_handler != null) - _handler.handle(target,baseRequest,request,response); - // end manual inline - } - - /* ------------------------------------------------------------ */ - /** - * Look for a requested session ID in cookies and URI parameters - * - * @param baseRequest - * @param request - */ - protected void checkRequestedSessionId(Request baseRequest, HttpServletRequest request) - { - String requested_session_id = request.getRequestedSessionId(); - - SessionManager sessionManager = getSessionManager(); - - if (requested_session_id != null && sessionManager != null) - { - HttpSession session = sessionManager.getHttpSession(requested_session_id); - if (session != null && sessionManager.isValid(session)) - baseRequest.setSession(session); - return; - } - else if (!DispatcherType.REQUEST.equals(baseRequest.getDispatcherType())) - return; - - boolean requested_session_id_from_cookie = false; - HttpSession session = null; - - // Look for session id cookie - if (_sessionManager.isUsingCookies()) - { - Cookie[] cookies = request.getCookies(); - if (cookies != null && cookies.length > 0) - { - final String sessionCookie=sessionManager.getSessionCookieConfig().getName(); - for (int i = 0; i < cookies.length; i++) - { - if (sessionCookie.equalsIgnoreCase(cookies[i].getName())) - { - requested_session_id = cookies[i].getValue(); - requested_session_id_from_cookie = true; - - LOG.debug("Got Session ID {} from cookie",requested_session_id); - - if (requested_session_id != null) - { - session = sessionManager.getHttpSession(requested_session_id); - - if (session != null && sessionManager.isValid(session)) - { - break; - } - } - else - { - LOG.warn("null session id from cookie"); - } - } - } - } - } - - if (requested_session_id == null || session == null) - { - String uri = request.getRequestURI(); - - String prefix = sessionManager.getSessionIdPathParameterNamePrefix(); - if (prefix != null) - { - int s = uri.indexOf(prefix); - if (s >= 0) - { - s += prefix.length(); - int i = s; - while (i < uri.length()) - { - char c = uri.charAt(i); - if (c == ';' || c == '#' || c == '?' || c == '/') - break; - i++; - } - - requested_session_id = uri.substring(s,i); - requested_session_id_from_cookie = false; - session = sessionManager.getHttpSession(requested_session_id); - if (LOG.isDebugEnabled()) - LOG.debug("Got Session ID {} from URL",requested_session_id); - } - } - } - - baseRequest.setRequestedSessionId(requested_session_id); - baseRequest.setRequestedSessionIdFromCookie(requested_session_id != null && requested_session_id_from_cookie); - if (session != null && sessionManager.isValid(session)) - baseRequest.setSession(session); - } - - /* ------------------------------------------------------------ */ - /** - * @param listener - */ - public void addEventListener(EventListener listener) - { - if (_sessionManager != null) - _sessionManager.addEventListener(listener); - } - - /* ------------------------------------------------------------ */ - public void clearEventListeners() - { - if (_sessionManager != null) - _sessionManager.clearEventListeners(); - } -}