IGNITE-2775: Fixed HttpRequest.changeSessionId() to create a new id. - Fixes #539.
Signed-off-by: shtykh_roman <rsht...@yahoo.com> Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/a8d16bd1 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/a8d16bd1 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/a8d16bd1 Branch: refs/heads/ignite-2791 Commit: a8d16bd1fbdd59d76454dbbce834f9ab87b54724 Parents: 5377dde Author: shtykh_roman <rsht...@yahoo.com> Authored: Thu Mar 10 16:38:10 2016 +0900 Committer: shtykh_roman <rsht...@yahoo.com> Committed: Thu Mar 10 16:38:10 2016 +0900 ---------------------------------------------------------------------- .../ignite/cache/websession/WebSession.java | 24 +++- .../cache/websession/WebSessionFilter.java | 41 +++++- .../internal/websession/WebSessionSelfTest.java | 136 +++++++++++++++++++ 3 files changed, 193 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/a8d16bd1/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSession.java ---------------------------------------------------------------------- diff --git a/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSession.java b/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSession.java index 8b944e5..5e0d49b 100644 --- a/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSession.java +++ b/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSession.java @@ -90,7 +90,7 @@ class WebSession implements HttpSession, Externalizable { private transient Collection<T2<String, Object>> updates; /** Genuine http session. */ - private transient HttpSession genuineSession; + private transient HttpSession genSes; /** * Required by {@link Externalizable}. @@ -123,8 +123,6 @@ class WebSession implements HttpSession, Externalizable { attrs.put(name, ses.getAttribute(name)); } - - genuineSession = ses; } /** @@ -139,6 +137,15 @@ class WebSession implements HttpSession, Externalizable { } /** + * Sets the genuine http session. + * + * @param genSes Genuine http session. + */ + protected void genSes(HttpSession genSes) { + this.genSes = genSes; + } + + /** * @param ctx Servlet context. */ public void servletContext(ServletContext ctx) { @@ -188,6 +195,15 @@ class WebSession implements HttpSession, Externalizable { return id; } + /** + * Sets a session id. + * + * @param id Session id. + */ + protected void setId(String id) { + this.id = id; + } + /** {@inheritDoc} */ @Override public ServletContext getServletContext() { return ctx; @@ -291,7 +307,7 @@ class WebSession implements HttpSession, Externalizable { lsnr.destroySession(id); - genuineSession.invalidate(); + genSes.invalidate(); isValid = false; } http://git-wip-us.apache.org/repos/asf/ignite/blob/a8d16bd1/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSessionFilter.java ---------------------------------------------------------------------- diff --git a/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSessionFilter.java b/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSessionFilter.java index 3dedee3..42de43b 100644 --- a/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSessionFilter.java +++ b/modules/web/src/main/java/org/apache/ignite/cache/websession/WebSessionFilter.java @@ -379,6 +379,7 @@ public class WebSessionFilter implements Filter { cached.servletContext(ctx); cached.listener(lsnr); cached.resetUpdates(); + cached.genSes(httpReq.getSession(false)); httpReq = new RequestWrapper(httpReq, cached); @@ -399,8 +400,10 @@ public class WebSessionFilter implements Filter { } /** - * @param httpReq HTTP request. - * @return Cached session. + * Creates a new session from http request. + * + * @param httpReq Request. + * @return New session. */ @SuppressWarnings("unchecked") private WebSession createSession(HttpServletRequest httpReq) { @@ -408,11 +411,25 @@ public class WebSessionFilter implements Filter { String sesId = sesIdTransformer != null ? sesIdTransformer.apply(ses.getId()) : ses.getId(); - if (log.isDebugEnabled()) - log.debug("Session created: " + sesId); + return createSession(ses, sesId); + } + /** + * Creates a new web session with the specified id. + * + * @param ses Base session. + * @param sesId Session id. + * @return New session. + */ + @SuppressWarnings("unchecked") + private WebSession createSession(HttpSession ses, String sesId) { WebSession cached = new WebSession(sesId, ses, true); + cached.genSes(ses); + + if (log.isDebugEnabled()) + log.debug("Session created: " + sesId); + for (int i = 0; i < retries; i++) { try { IgniteCache<String, WebSession> cache0; @@ -517,5 +534,21 @@ public class WebSessionFilter implements Filter { @Override public HttpSession getSession() { return getSession(true); } + + /** {@inheritDoc} */ + @Override public String changeSessionId() { + HttpServletRequest req = (HttpServletRequest)getRequest(); + + String newId = req.changeSessionId(); + + this.ses.setId(newId); + + this.ses = createSession(ses, newId); + this.ses.servletContext(ctx); + this.ses.listener(lsnr); + this.ses.resetUpdates(); + + return newId; + } } } http://git-wip-us.apache.org/repos/asf/ignite/blob/a8d16bd1/modules/web/src/test/java/org/apache/ignite/internal/websession/WebSessionSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/web/src/test/java/org/apache/ignite/internal/websession/WebSessionSelfTest.java b/modules/web/src/test/java/org/apache/ignite/internal/websession/WebSessionSelfTest.java index e2fda37..298baf1 100644 --- a/modules/web/src/test/java/org/apache/ignite/internal/websession/WebSessionSelfTest.java +++ b/modules/web/src/test/java/org/apache/ignite/internal/websession/WebSessionSelfTest.java @@ -202,6 +202,88 @@ public class WebSessionSelfTest extends GridCommonAbstractTest { } /** + * Tests session id change. + * + * @throws Exception Exception If failed. + */ + public void testChangeSessionId() throws Exception { + String newWebSesId; + Server srv = null; + + try { + srv = startServer(TEST_JETTY_PORT, "/modules/core/src/test/config/websession/example-cache.xml", + null, new SessionIdChangeServlet()); + + Ignite ignite = G.ignite(); + + URLConnection conn = new URL("http://localhost:" + TEST_JETTY_PORT + "/ignitetest/chngsesid").openConnection(); + + conn.connect(); + + try (BufferedReader rdr = new BufferedReader(new InputStreamReader(conn.getInputStream()))) { + + // checks if the old session object is invalidated. + String oldId = rdr.readLine(); + + assertNotNull(oldId); + + // id from genuine session + String newGenSesId = rdr.readLine(); + + assertNotNull(newGenSesId); + + assertFalse(newGenSesId.equals(oldId)); + + // id from replicated session + newWebSesId = rdr.readLine(); + + assertNotNull(newWebSesId); + + assertTrue(newGenSesId.equals(newWebSesId)); + + IgniteCache<String, HttpSession> cache = ignite.cache(getCacheName()); + + assertNotNull(cache); + + Thread.sleep(1000); + + HttpSession ses = cache.get(newWebSesId); + + assertNotNull(ses); + + assertEquals("val1", ses.getAttribute("key1")); + } + + conn = new URL("http://localhost:" + TEST_JETTY_PORT + "/ignitetest/simple").openConnection(); + + conn.addRequestProperty("Cookie", "JSESSIONID=" + newWebSesId); + + conn.connect(); + + try (BufferedReader rdr = new BufferedReader(new InputStreamReader(conn.getInputStream()))) { + + // checks if it can be handled with the subsequent request. + String sesId = rdr.readLine(); + + assertTrue(newWebSesId.equals(sesId)); + + String attr = rdr.readLine(); + + assertEquals("val1", attr); + + String reqSesValid = rdr.readLine(); + + assertEquals("true", reqSesValid); + + assertEquals("invalidated", rdr.readLine()); + } + } + finally { + stopServer(srv); + } + } + + /** * @throws Exception If failed. */ public void testRestarts() throws Exception { @@ -404,6 +486,9 @@ public class WebSessionSelfTest extends GridCommonAbstractTest { ses.invalidate(); res.getWriter().println(ses.getId()); + + // invalidates again. + req.getSession().invalidate(); } else if (req.getPathInfo().equals("/valid")) { X.println(">>>", "Created session: " + ses.getId(), ">>>"); @@ -418,6 +503,57 @@ public class WebSessionSelfTest extends GridCommonAbstractTest { } /** + * Test session behavior on id change. + */ + private static class SessionIdChangeServlet extends HttpServlet { + /** {@inheritDoc} */ + @Override protected void doGet(HttpServletRequest req, HttpServletResponse res) + throws ServletException, IOException { + HttpSession ses = req.getSession(); + + assertNotNull(ses); + + if (req.getPathInfo().equals("/chngsesid")) { + + ses.setAttribute("key1", "val1"); + + X.println(">>>", "Created session: " + ses.getId(), ">>>"); + + res.getWriter().println(req.getSession().getId()); + + String newId = req.changeSessionId(); + + // new id from genuine session. + res.getWriter().println(newId); + + // new id from WebSession. + res.getWriter().println(req.getSession().getId()); + + res.getWriter().flush(); + } + else if (req.getPathInfo().equals("/simple")) { + res.getWriter().println(req.getSession().getId()); + + res.getWriter().println(req.getSession().getAttribute("key1")); + + res.getWriter().println(req.isRequestedSessionIdValid()); + + try { + req.getSession().invalidate(); + res.getWriter().println("invalidated"); + } + catch (Exception e) { + res.getWriter().println("failed"); + } + + res.getWriter().flush(); + } + else + throw new ServletException("Nonexisting path: " + req.getPathInfo()); + } + } + + /** * Servlet for restarts test. */ private static class RestartsTestServlet extends HttpServlet {