Index: modules/web/src/main/java/org/apache/ignite/cache/websession/WebSessionV2.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- modules/web/src/main/java/org/apache/ignite/cache/websession/WebSessionV2.java (revision b911ff8eb6bc43d6e309758752f56c0147cae659) +++ modules/web/src/main/java/org/apache/ignite/cache/websession/WebSessionV2.java (revision ) @@ -400,6 +400,13 @@ } /** + * @return Genuine session. + */ + @Nullable public HttpSession genuineSession() { + return genuineSes; + } + + /** * Throw {@link IllegalStateException} if session was invalidated. */ private void assertValid() { Index: modules/web/src/main/java/org/apache/ignite/cache/websession/WebSessionFilter.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- modules/web/src/main/java/org/apache/ignite/cache/websession/WebSessionFilter.java (revision b911ff8eb6bc43d6e309758752f56c0147cae659) +++ modules/web/src/main/java/org/apache/ignite/cache/websession/WebSessionFilter.java (revision ) @@ -55,6 +55,7 @@ import org.apache.ignite.marshaller.Marshaller; import org.apache.ignite.startup.servlet.ServletContextListenerStartup; import org.apache.ignite.transactions.Transaction; +import org.jetbrains.annotations.Nullable; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static org.apache.ignite.cache.CacheAtomicityMode.ATOMIC; @@ -458,21 +459,17 @@ // Session was already invalidated. } } - - cached = createSession(httpReq); } } - else - cached = createSession(httpReq); - assert cached != null; - + if (cached != null) { - sesId = cached.getId(); + sesId = cached.getId(); - cached.servletContext(ctx); - cached.filter(this); - cached.resetUpdates(); - cached.genSes(httpReq.getSession(false)); + cached.servletContext(ctx); + cached.filter(this); + cached.resetUpdates(); + cached.genSes(httpReq.getSession(false)); + } httpReq = new RequestWrapper(httpReq, cached); @@ -484,7 +481,7 @@ Collection> updates = ((WebSession) ses).updates(); if (updates != null) - updateAttributes(transformSessionId(sesId), updates, ses.getMaxInactiveInterval()); + updateAttributes(transformSessionId(ses.getId()), updates, ses.getMaxInactiveInterval()); } return sesId; @@ -544,39 +541,53 @@ // Session was already invalidated. } } - - cached = createSessionV2(httpReq); } } - // No session was requested by the client, create new one and put in the request. - else - cached = createSessionV2(httpReq); - assert cached != null; - + if (cached != null) - sesId = cached.getId(); + sesId = cached.getId(); httpReq = new RequestWrapperV2(httpReq, cached); chain.doFilter(httpReq, res); - if (!cached.isValid()) - binaryCache.remove(cached.id()); - // Changed session ID. - else if (!cached.getId().equals(sesId)) { - final String oldId = cached.getId(); + final HttpSession userSes = httpReq.getSession(false); - cached.invalidate(); + if (userSes != null && userSes instanceof WebSessionV2) { + final WebSessionV2 userSesV2 = (WebSessionV2) userSes; - binaryCache.remove(oldId); - } + if (!userSesV2.isValid()) + removeInvalidated(userSesV2); - else + else - updateAttributesV2(cached.getId(), cached); + updateAttributesV2(userSesV2.getId(), userSesV2); + } return sesId; } /** + * Remove from cache all invalidated sessions recursively. + * + * @param ses Web session. + */ + private void removeInvalidated(WebSessionV2 ses) { + while (ses != null) { + if (!ses.isValid()) { + binaryCache.remove(ses.id()); + + final HttpSession genuineSes = ses.genuineSession(); + + if (genuineSes != null && genuineSes instanceof WebSessionV2) + ses = (WebSessionV2) genuineSes; + else + ses = null; + } + else + ses = null; + } + } + + /** * Log and process exception happened on loading session from cache. * * @param sesId Session ID. @@ -617,12 +628,12 @@ * @return New session. */ @SuppressWarnings("unchecked") - private WebSession createSession(HttpServletRequest httpReq) { + private WebSession createSessionV1(HttpServletRequest httpReq) { HttpSession ses = httpReq.getSession(true); String sesId = transformSessionId(ses.getId()); - return createSession(ses, sesId); + return createSessionV1(ses, sesId); } /** @@ -633,7 +644,7 @@ * @return New session. */ @SuppressWarnings("unchecked") - private WebSession createSession(HttpSession ses, String sesId) { + private WebSession createSessionV1(HttpSession ses, String sesId) { WebSession cached = new WebSession(sesId, ses, true); cached.genSes(ses); @@ -921,23 +932,19 @@ * @param req Request. * @param ses Session. */ - private RequestWrapper(HttpServletRequest req, WebSession ses) { + private RequestWrapper(HttpServletRequest req, @Nullable WebSession ses) { super(req); - assert ses != null; - this.ses = ses; } /** {@inheritDoc} */ @Override public HttpSession getSession(boolean create) { - if (!ses.isValid()) { - if (create) { - this.ses = createSession((HttpServletRequest)getRequest()); - this.ses.servletContext(ctx); - this.ses.filter(WebSessionFilter.this); - this.ses.resetUpdates(); - } + if (ses == null && create) + createSession(); + else if (ses != null && !ses.isValid()) { + if (create) + createSession(); else return null; } @@ -952,18 +959,38 @@ /** {@inheritDoc} */ @Override public String changeSessionId() { + if (ses == null) + throw new IllegalStateException("No session"); + HttpServletRequest req = (HttpServletRequest)getRequest(); String newId = req.changeSessionId(); - this.ses.setId(newId); + createSession(newId); - this.ses = createSession(ses, newId); + return newId; + } + + /** + * Create session. + */ + private void createSession() { + this.ses = createSessionV1((HttpServletRequest)getRequest()); this.ses.servletContext(ctx); this.ses.filter(WebSessionFilter.this); this.ses.resetUpdates(); + } - return newId; + /** + * Create session with specified ID. + * + * @param newId New session ID. + */ + private void createSession(final String newId) { + this.ses = createSessionV1(ses, newId); + this.ses.servletContext(ctx); + this.ses.filter(WebSessionFilter.this); + this.ses.resetUpdates(); } /** {@inheritDoc} */ @@ -976,7 +1003,7 @@ this.ses.setId(newId); - this.ses = createSession(ses, newId); + this.ses = createSessionV1(ses, newId); this.ses.servletContext(ctx); this.ses.filter(WebSessionFilter.this); this.ses.resetUpdates(); @@ -994,27 +1021,21 @@ * @param req Request. * @param ses Session. */ - private RequestWrapperV2(HttpServletRequest req, WebSessionV2 ses) { + private RequestWrapperV2(HttpServletRequest req, @Nullable WebSessionV2 ses) { super(req); - assert ses != null; - this.ses = ses; } /** {@inheritDoc} */ @Override public HttpSession getSession(boolean create) { - if (!ses.isValid()) { + if (ses == null && create) + createSession(); + else if (ses != null && !ses.isValid()) { binaryCache.remove(ses.id()); - if (create) { - try { - ses = createSessionV2((HttpServletRequest) getRequest()); - } - catch (IOException e) { - throw new IgniteException(e); - } - } + if (create) + createSession(); else return null; } @@ -1029,27 +1050,56 @@ /** {@inheritDoc} */ @Override public String changeSessionId() { + if (ses == null) + throw new IllegalStateException("No session"); + final HttpServletRequest req = (HttpServletRequest) getRequest(); final String newId = req.changeSessionId(); if (!F.eq(newId, ses.getId())) { + final WebSessionV2 old = this.ses; + + createSession(newId); + + // Old session should become unavailable from cache. + binaryCache.remove(old.id()); + } + + return newId; + } + + /** + * Create new session and add it to cache. + */ + private void createSession() { - try { + try { - ses = createSessionV2(ses, newId); + ses = createSessionV2((HttpServletRequest) getRequest()); - } - catch (IOException e) { - throw new IgniteException(e); - } - } + } + catch (IOException e) { + throw new IgniteException(e); + } + } - return newId; + /** + * Create new session with specified ID and add it to cache. + * + * @param sesId Session ID. + */ + private void createSession(final String sesId) { + try { + ses = createSessionV2(ses, sesId); - } + } + catch (IOException e) { + throw new IgniteException(e); + } + } /** {@inheritDoc} */ - @Override public void login(String username, String password) throws ServletException{ + @Override public void login(String username, String pwd) throws ServletException{ final HttpServletRequest req = (HttpServletRequest)getRequest(); - req.login(username, password); + req.login(username, pwd); final String newId = req.getSession(false).getId(); Index: modules/web/src/test/java/org/apache/ignite/internal/websession/WebSessionSelfTest.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- modules/web/src/test/java/org/apache/ignite/internal/websession/WebSessionSelfTest.java (revision b911ff8eb6bc43d6e309758752f56c0147cae659) +++ modules/web/src/test/java/org/apache/ignite/internal/websession/WebSessionSelfTest.java (revision ) @@ -905,23 +905,25 @@ * @return sesId */ private String getSessionIdFromCookie(URLConnection conn) { - String sessionCookieValue = null; + String sesCookieVal; + String sesId = null; - Map> headerFields = conn.getHeaderFields(); - Set headerFieldsSet = headerFields.keySet(); - Iterator hearerFieldsIter = headerFieldsSet.iterator(); - while (hearerFieldsIter.hasNext()) { - String headerFieldKey = hearerFieldsIter.next(); + Map> hdrFields = conn.getHeaderFields(); - if ("Set-Cookie".equalsIgnoreCase(headerFieldKey)) { - List headerFieldValue = headerFields.get(headerFieldKey); + Set hdrFieldsSet = hdrFields.keySet(); - for (String headerValue : headerFieldValue) { + for (final String hdrFieldKey : hdrFieldsSet) { + if ("Set-Cookie".equalsIgnoreCase(hdrFieldKey)) { + List hdrFieldVal = hdrFields.get(hdrFieldKey); + + for (String headerValue : hdrFieldVal) { String[] fields = headerValue.split(";"); - sessionCookieValue = fields[0]; - sesId = sessionCookieValue.substring(sessionCookieValue.indexOf("=")+1, - sessionCookieValue.length()); + + sesCookieVal = fields[0]; + + sesId = sesCookieVal.substring(sesCookieVal.indexOf("=") + 1, + sesCookieVal.length()); } } } @@ -1113,11 +1115,12 @@ res.getWriter().flush(); } else if (req.getPathInfo().equals("/simple")) { - HttpSession session = req.getSession(); - X.println(">>>", "Request session simple: " + session.getId(), ">>>"); + HttpSession ses = req.getSession(); - res.getWriter().write(session.getId()); + X.println(">>>", "Request session simple: " + ses.getId(), ">>>"); + res.getWriter().write(ses.getId()); + res.getWriter().flush(); } } @@ -1131,11 +1134,11 @@ X.printerrln("Login failed due to exception.", e); } - HttpSession session = req.getSession(); + HttpSession ses = req.getSession(); - X.println(">>>", "Logged In session: " + session.getId(), ">>>"); + X.println(">>>", "Logged In session: " + ses.getId(), ">>>"); - res.getWriter().write(session.getId()); + res.getWriter().write(ses.getId()); res.getWriter().flush(); }