/* * Copyright (c) 2002-2012 Alibaba Group Holding Limited. * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.alibaba.citrus.service.requestcontext.session; import static com.alibaba.citrus.service.requestcontext.session.SessionConfig.*; import static com.alibaba.citrus.test.TestUtil.*; import static com.alibaba.citrus.util.ArrayUtil.*; import static com.alibaba.citrus.util.BasicConstant.*; import static com.alibaba.citrus.util.CollectionUtil.*; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.text.ParsePosition; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Enumeration; import java.util.List; import java.util.Locale; import java.util.Map; import javax.servlet.http.HttpSession; import com.alibaba.citrus.service.requestcontext.AbstractRequestContextsTests; import com.alibaba.citrus.service.requestcontext.session.impl.SessionAttribute; import com.alibaba.citrus.service.requestcontext.session.impl.SessionImpl; import com.alibaba.citrus.service.requestcontext.session.impl.SessionModelImpl; import com.alibaba.citrus.service.requestcontext.session.store.simple.impl.SimpleMemoryStoreImpl; import com.alibaba.citrus.service.requestcontext.util.CookieSupport; import org.junit.BeforeClass; import org.junit.Test; import org.springframework.beans.factory.BeanCreationException; /** 测试<code>Session</code>。 */ public class SessionTests extends AbstractRequestContextsTests<SessionRequestContext> { private long currentTime; private HttpSession session; private String sessionID; private long lastCreationTime; @BeforeClass public static void initFactory() { createBeanFactory("services-session.xml"); } @Override protected void afterInitRequestContext() { currentTime = System.currentTimeMillis(); session = requestContext.getRequest().getSession(); } /** * 没有配置任何store的情形。 * <p> * 由于SESSION MODEL也需要被保存在session中,因此报错。 * </p> */ @Test public void stores_noStore() throws Exception { invokeNoopServlet("/servlet"); try { initRequestContext("session-nostores"); fail(); } catch (BeanCreationException e) { assertThat( e, exception(IllegalArgumentException.class, "No storage configured for session model", "key=SESSION_MODEL")); } } /** * 仅配置了用于保存session model的store的情形。 * <p> * 当setAttribute和removeAttribute的时候报错。 * </p> */ @Test public void stores_modelOnly() throws Exception { invokeNoopServlet("/servlet"); initRequestContext("session-model-only"); assertEquals(true, session.isNew()); assertEquals(null, session.getAttribute("count")); try { session.setAttribute("count", 0); fail(); } catch (IllegalArgumentException e) { assertThat(e, exception("No storage configured for session attribute", "count")); } try { session.removeAttribute("count"); fail(); } catch (IllegalArgumentException e) { assertThat(e, exception("No storage configured for session attribute", "count")); } } @Test public void session_change_model() throws Exception { invokeNoopServlet("/servlet"); initRequestContext(); try { session.setAttribute("SESSION_MODEL", null); } catch (IllegalArgumentException e) { assertThat(e, exception("Cannot call method setAttribute with attribute SESSION_MODEL")); } try { session.removeAttribute("SESSION_MODEL"); } catch (IllegalArgumentException e) { assertThat(e, exception("Cannot call method removeAttribute with attribute SESSION_MODEL")); } } @Test public void session_exactMatchesOnly() throws Exception { invokeNoopServlet("/servlet"); try { initRequestContext("session_exact_match_only_wrong1"); fail(); } catch (BeanCreationException e) { assertThat( e, exception(IllegalArgumentException.class, "Session store exact1 only support exact matches to attribute names")); } try { initRequestContext("session_exact_match_only_wrong2"); fail(); } catch (BeanCreationException e) { assertThat( e, exception(IllegalArgumentException.class, "Session store exact2 only support exact matches to attribute names")); } initRequestContext("session_exact_match_only"); MyExactMatchesOnlySessionStore store = (MyExactMatchesOnlySessionStore) requestContext.getSessionConfig() .getStores().getStore("exact3"); assertArrayEquals(new String[] { "a", "b", "SESSION_MODEL" }, store.attrNames); } @Test public void session_attr() throws Exception { // request 1 - new request invokeNoopServlet("/servlet"); initRequestContext(); assertEquals(true, session.isNew()); @SuppressWarnings("unchecked") Map<String, SessionAttribute> attrs = getFieldValue(session, "attrs", Map.class); session.setAttribute("count", 0); SessionAttribute attr = attrs.get("count"); assertTrue(attr.isModified()); requestContexts.commitRequestContext(requestContext); assertSame(attr, attrs.get("count")); assertFalse(attr.isModified()); // 提交以后,modified被复位 } @Test public void session() throws Exception { // ====================== // request 1 invokeNoopServlet("/servlet"); initRequestContext(); // session.getServletContext assertSame(requestContext.getServletContext(), session.getServletContext()); // session.isNew assertEquals(true, session.isNew()); // session.getId sessionID = session.getId(); assertNotNull(sessionID); // session.getCreationTime assertTrue(session.getCreationTime() - currentTime < 1000); lastCreationTime = session.getCreationTime(); // session.getLastAccessedTime assertEquals(lastCreationTime, session.getLastAccessedTime()); // session.getMaxInactiveInterval assertEquals(0, session.getMaxInactiveInterval()); // session.getAttributeNames assertEnumeration(new Object[] { }, session.getAttributeNames()); // session.setAttribute/getAttribute session.setAttribute("count", 0); assertEquals(0, session.getAttribute("count")); // session.getAttributeNames assertEnumeration(new Object[] { "count" }, session.getAttributeNames()); // request.getRequestedSessionId assertEquals(null, newRequest.getRequestedSessionId()); // request.isRequestedSessionIdFromCookie assertEquals(false, newRequest.isRequestedSessionIdFromCookie()); // request.isRequestedSessionIdFromURL assertEquals(false, newRequest.isRequestedSessionIdFromURL()); // request.isRequestedSessionIdValid assertEquals(false, newRequest.isRequestedSessionIdValid()); // response.encodeURL/encodeRedirectURL: unchanged for urlEncodeEnabled=false assertEquals("http://localhost/servlet/", newResponse.encodeURL("http://localhost/servlet/")); assertEquals("http://localhost/servlet/", newResponse.encodeRedirectURL("http://localhost/servlet/")); requestContexts.commitRequestContext(requestContext); commitToClient(); assertEquals(sessionID, clientResponse.getNewCookieValue("JSESSIONID")); // new added cookie // ====================== // request 2 Thread.sleep(10); invokeNoopServlet("/servlet"); initRequestContext(); // session.isNew assertEquals(false, session.isNew()); // session.getId assertEquals(sessionID, session.getId()); // session.getCreationTime assertEquals(lastCreationTime, session.getCreationTime()); lastCreationTime = session.getCreationTime(); // session.getLastAccessedTime assertTrue(session.getLastAccessedTime() != session.getCreationTime()); assertTrue(session.getLastAccessedTime() - currentTime < 1000); // session.getMaxInactiveInterval assertEquals(0, session.getMaxInactiveInterval()); // session.getAttributeNames assertEnumeration(new Object[] { "count" }, session.getAttributeNames()); // session.removeAttribute/getAttribute assertEquals(0, session.getAttribute("count")); session.removeAttribute("count"); // session.getAttributeNames assertEnumeration(new Object[] { }, session.getAttributeNames()); // request.getRequestedSessionId assertEquals(sessionID, newRequest.getRequestedSessionId()); // request.isRequestedSessionIdFromCookie assertEquals(true, newRequest.isRequestedSessionIdFromCookie()); // request.isRequestedSessionIdFromURL assertEquals(false, newRequest.isRequestedSessionIdFromURL()); // request.isRequestedSessionIdValid assertEquals(true, newRequest.isRequestedSessionIdValid()); // response.encodeURL/encodeRedirectURL: unchanged for urlEncodeEnabled=false assertEquals("http://localhost/servlet/", newResponse.encodeURL("http://localhost/servlet/")); assertEquals("http://localhost/servlet/", newResponse.encodeRedirectURL("http://localhost/servlet/")); requestContexts.commitRequestContext(requestContext); commitToClient(); assertEquals(null, clientResponse.getNewCookieValue("JSESSIONID")); // no new cookie } @Test public void session_params_default() throws Exception { // ====================== // request 1 invokeNoopServlet("/servlet"); initRequestContext(); // session.getServletContext assertSame(requestContext.getServletContext(), session.getServletContext()); // session.isNew assertEquals(true, session.isNew()); // session.getId sessionID = session.getId(); assertNotNull(sessionID); assertTrue(sessionID.length() > 10); // uuid requestContexts.commitRequestContext(requestContext); commitToClient(); // 检查cookie String prefix = "JSESSIONID=" + sessionID + "; "; String path = "; Path=/"; String httpOnly = "; HttpOnly"; String secure = "; Secure"; String setCookie = clientResponse.getHeaderField("set-cookie"); assertThat(setCookie, startsWith(prefix)); assertThat(setCookie, containsString(path)); assertThat(setCookie, containsString(httpOnly)); assertThat(setCookie, not(containsString(secure))); assertEquals(sessionID, clientResponse.getNewCookieValue("JSESSIONID")); // new added cookie } @Test public void session_params() throws Exception { // ====================== // request 1 invokeNoopServlet("/servlet"); initRequestContext("session_all"); // session.getServletContext assertSame(requestContext.getServletContext(), session.getServletContext()); // session.isNew assertEquals(true, session.isNew()); // session.getId sessionID = session.getId(); assertNotNull(sessionID); assertEquals(20, sessionID.length()); // random id, length=20 // session.getCreationTime assertTrue(session.getCreationTime() - currentTime < 1000); lastCreationTime = session.getCreationTime(); // session.getLastAccessedTime assertEquals(lastCreationTime, session.getLastAccessedTime()); // session.getMaxInactiveInterval assertEquals(1, session.getMaxInactiveInterval()); // session.getAttributeNames assertEnumeration(new Object[] { }, session.getAttributeNames()); // session.setAttribute/getAttribute session.setAttribute("count", 0); assertEquals(0, session.getAttribute("count")); // session.getAttributeNames assertEnumeration(new Object[] { "count" }, session.getAttributeNames()); // request.getRequestedSessionId assertEquals(null, newRequest.getRequestedSessionId()); // request.isRequestedSessionIdFromCookie assertEquals(false, newRequest.isRequestedSessionIdFromCookie()); // request.isRequestedSessionIdFromURL assertEquals(false, newRequest.isRequestedSessionIdFromURL()); // request.isRequestedSessionIdValid assertEquals(false, newRequest.isRequestedSessionIdValid()); // response.encodeURL/encodeRedirectURL: unchanged for urlEncodeEnabled=false assertEquals("http://localhost/servlet/", newResponse.encodeURL("http://localhost/servlet/")); assertEquals("http://localhost/servlet/", newResponse.encodeRedirectURL("http://localhost/servlet/")); requestContexts.commitRequestContext(requestContext); commitToClient(); // 检查cookie,注意,配置文件中写的是taobao.com,但这里会被规格化成.taobao.com String prefix = "JSESSIONID=" + sessionID + "; Domain=.taobao.com; Expires="; String path = "; Path=/"; String httpOnly = "; HttpOnly"; String secure = "; Secure"; String setCookie = clientResponse.getHeaderField("set-cookie"); assertThat(setCookie, startsWith(prefix)); assertThat(setCookie, containsString(path)); assertThat(setCookie, not(containsString(httpOnly))); assertThat(setCookie, containsString(secure)); Date date = new SimpleDateFormat("EEE, dd-MMM-yyyy HH:mm:ss z", Locale.US).parse(setCookie, new ParsePosition( prefix.length())); assertTrue(date.getTime() - currentTime < 10 * 1000); assertEquals(sessionID, clientResponse.getNewCookieValue("JSESSIONID")); // new added cookie // ====================== // request 2 Thread.sleep(10); invokeNoopServlet("/servlet"); initRequestContext("session_all"); // session.isNew assertEquals(false, session.isNew()); // session.getId assertEquals(sessionID, session.getId()); // session.getCreationTime assertEquals(lastCreationTime, session.getCreationTime()); lastCreationTime = session.getCreationTime(); // session.getLastAccessedTime assertTrue(session.getLastAccessedTime() != session.getCreationTime()); assertTrue(session.getLastAccessedTime() - currentTime < 1000); // session.getMaxInactiveInterval assertEquals(1, session.getMaxInactiveInterval()); // session.getAttributeNames assertEnumeration(new Object[] { "count" }, session.getAttributeNames()); // session.removeAttribute/getAttribute assertEquals(0, session.getAttribute("count")); session.removeAttribute("count"); // session.getAttributeNames assertEnumeration(new Object[] { }, session.getAttributeNames()); // request.getRequestedSessionId assertEquals(sessionID, newRequest.getRequestedSessionId()); // request.isRequestedSessionIdFromCookie assertEquals(true, newRequest.isRequestedSessionIdFromCookie()); // request.isRequestedSessionIdFromURL assertEquals(false, newRequest.isRequestedSessionIdFromURL()); // request.isRequestedSessionIdValid assertEquals(true, newRequest.isRequestedSessionIdValid()); // response.encodeURL/encodeRedirectURL: unchanged for urlEncodeEnabled=false assertEquals("http://localhost/servlet/", newResponse.encodeURL("http://localhost/servlet/")); assertEquals("http://localhost/servlet/", newResponse.encodeRedirectURL("http://localhost/servlet/")); requestContexts.commitRequestContext(requestContext); commitToClient(); assertEquals(null, clientResponse.getNewCookieValue("JSESSIONID")); // no new cookie } @Test public void session_urlencode() throws Exception { // ====================== // request 1 invokeNoopServlet("/servlet"); initRequestContext("session_urlencode"); // session.getServletContext assertSame(requestContext.getServletContext(), session.getServletContext()); // session.isNew assertEquals(true, session.isNew()); // session.getId sessionID = session.getId(); assertNotNull(sessionID); // session.getCreationTime assertTrue(session.getCreationTime() - currentTime < 1000); lastCreationTime = session.getCreationTime(); // session.getLastAccessedTime assertEquals(lastCreationTime, session.getLastAccessedTime()); // session.getMaxInactiveInterval assertEquals(0, session.getMaxInactiveInterval()); // session.getAttributeNames assertEnumeration(new Object[] { }, session.getAttributeNames()); // session.setAttribute/getAttribute session.setAttribute("count", 0); assertEquals(0, session.getAttribute("count")); // session.getAttributeNames assertEnumeration(new Object[] { "count" }, session.getAttributeNames()); // request.getRequestedSessionId assertEquals(null, newRequest.getRequestedSessionId()); // request.isRequestedSessionIdFromCookie assertEquals(false, newRequest.isRequestedSessionIdFromCookie()); // request.isRequestedSessionIdFromURL assertEquals(false, newRequest.isRequestedSessionIdFromURL()); // request.isRequestedSessionIdValid assertEquals(false, newRequest.isRequestedSessionIdValid()); // response.encodeURL/encodeRedirectURL: unchanged for urlEncodeEnabled=false assertEquals("http://localhost/servlet/;JSESSIONID=" + sessionID, newResponse.encodeURL("http://localhost/servlet/")); assertEquals("http://localhost/servlet/;JSESSIONID=" + sessionID, newResponse.encodeRedirectURL("http://localhost/servlet/")); requestContexts.commitRequestContext(requestContext); commitToClient(); assertEquals(null, clientResponse.getNewCookieValue("JSESSIONID")); // new added cookie // ====================== // request 2 Thread.sleep(10); invokeNoopServlet("/servlet/;JSESSIONID=" + sessionID); initRequestContext("session_urlencode"); // session.isNew assertEquals(false, session.isNew()); // session.getId assertEquals(sessionID, session.getId()); // session.getCreationTime assertEquals(lastCreationTime, session.getCreationTime()); lastCreationTime = session.getCreationTime(); // session.getLastAccessedTime assertTrue(session.getLastAccessedTime() != session.getCreationTime()); assertTrue(session.getLastAccessedTime() - currentTime < 1000); // session.getMaxInactiveInterval assertEquals(0, session.getMaxInactiveInterval()); // session.getAttributeNames assertEnumeration(new Object[] { "count" }, session.getAttributeNames()); // session.removeAttribute/getAttribute assertEquals(0, session.getAttribute("count")); session.removeAttribute("count"); // session.getAttributeNames assertEnumeration(new Object[] { }, session.getAttributeNames()); // request.getRequestedSessionId assertEquals(sessionID, newRequest.getRequestedSessionId()); // request.isRequestedSessionIdFromCookie assertEquals(false, newRequest.isRequestedSessionIdFromCookie()); // request.isRequestedSessionIdFromURL assertEquals(true, newRequest.isRequestedSessionIdFromURL()); // request.isRequestedSessionIdValid assertEquals(true, newRequest.isRequestedSessionIdValid()); // response.encodeURL/encodeRedirectURL: unchanged for urlEncodeEnabled=false assertEquals("http://localhost/servlet/;JSESSIONID=" + sessionID, newResponse.encodeURL("http://localhost/servlet/")); assertEquals("http://localhost/servlet/;JSESSIONID=" + sessionID, newResponse.encodeRedirectURL("http://localhost/servlet/")); requestContexts.commitRequestContext(requestContext); commitToClient(); assertEquals(null, clientResponse.getNewCookieValue("JSESSIONID")); // no new cookie } private void assertEnumeration(Object[] expectedValues, Enumeration<?> e) { List<Object> list = createArrayList(); while (e.hasMoreElements()) { list.add(e.nextElement()); } assertArrayEquals(expectedValues, list.toArray(new Object[list.size()])); } @Test public void session_reuseSessionID() throws Exception { // request 1 invokeNoopServlet("/servlet"); CookieSupport cookie = new CookieSupport("JSESSIONID", "1234567890ABCDEFG"); cookie.setPath("/"); cookie.addCookie(response); commitToClient(); assertEquals("1234567890ABCDEFG", clientResponse.getNewCookieValue("JSESSIONID")); // new added cookie // request 2 invokeNoopServlet("/servlet"); initRequestContext(); assertTrue(session.isNew()); String sessionID = session.getId(); assertEquals("1234567890ABCDEFG", sessionID); session.setAttribute("count", 0); assertEquals(0, session.getAttribute("count")); requestContexts.commitRequestContext(requestContext); commitToClient(); assertEquals(null, clientResponse.getNewCookieValue("JSESSIONID")); // no new cookie // request 3 invokeNoopServlet("/servlet"); initRequestContext(); assertEquals(0, session.getAttribute("count")); requestContexts.commitRequestContext(requestContext); commitToClient(); assertEquals(null, clientResponse.getNewCookieValue("JSESSIONID")); // no new cookie } @Test public void session_noKeepInTouch() throws Exception { checkKeepInTouch(null, false); } @Test public void session_keepInTouch() throws Exception { checkKeepInTouch("session_all", true); } private void checkKeepInTouch(String beanName, boolean keepInTouch) throws Exception, InterruptedException { // request 1 invokeNoopServlet("/servlet"); initRequestContext(beanName); session.setAttribute("count", 0); assertEquals(0, session.getAttribute("count")); session.setMaxInactiveInterval(1); requestContexts.commitRequestContext(requestContext); commitToClient(); // request 2 no changes, and not keep in touch Thread.sleep(600); // 等0.6s invokeNoopServlet("/servlet"); initRequestContext(beanName); assertFalse(session.isNew()); requestContexts.commitRequestContext(requestContext); commitToClient(); // request 3 Thread.sleep(600); // 再等0.6s,如果没有keepInTouch,就超过1s过期了。但keepInTouch的话就不会过期。 invokeNoopServlet("/servlet"); initRequestContext(beanName); if (!keepInTouch) { assertTrue(session.isNew()); assertEquals(null, session.getAttribute("count")); } else { assertFalse(session.isNew()); assertEquals(0, session.getAttribute("count")); } requestContexts.commitRequestContext(requestContext); commitToClient(); } @Test public void session_maxInactiveInterval_exceeds() throws Exception { // forceExpirationPeriod=0,sleep=1.1, maxInactiveInterval=1 checkSessionExpired(null, 1, 1100, true); } @Test public void session_forceExpirationPeriod_exceeds() throws Exception { // forceExpirationPeriod=2,sleep=2.1, maxInactiveInterval=10 checkSessionExpired("session-force-expire", 10, 2100, true); } @Test public void session_forceExpirationPeriod_notExceeds() throws Exception { // forceExpirationPeriod=2,sleep=1, maxInactiveInterval=0 checkSessionExpired("session-force-expire", 0, 1000, false); } private void checkSessionExpired(String beanName, int maxInactiveInterval, int sleep, boolean expired) throws Exception, InterruptedException { // request 1 invokeNoopServlet("/servlet"); initRequestContext(beanName); assertTrue(session.isNew()); String sessionID = session.getId(); assertNotNull(sessionID); session.setAttribute("count", 0); assertEquals(0, session.getAttribute("count")); session.setMaxInactiveInterval(maxInactiveInterval); requestContexts.commitRequestContext(requestContext); commitToClient(); Thread.sleep(sleep); assertEquals(sessionID, clientResponse.getNewCookieValue("JSESSIONID")); // new added cookie // request 2 invokeNoopServlet("/servlet"); initRequestContext(beanName); if (expired) { assertTrue(session.isNew()); assertEquals(null, session.getAttribute("count")); requestContexts.commitRequestContext(requestContext); commitToClient(); assertEquals(null, clientResponse.getNewCookieValue("JSESSIONID")); // no new cookie } else { assertFalse(session.isNew()); assertEquals(0, session.getAttribute("count")); requestContexts.commitRequestContext(requestContext); commitToClient(); assertEquals(null, clientResponse.getNewCookieValue("JSESSIONID")); // no new cookie } } @Test public void session_invalidate() throws Exception { // ====================== // request 1 invokeNoopServlet("/servlet"); initRequestContext(); // session.isNew assertEquals(true, session.isNew()); // session.getId sessionID = session.getId(); assertNotNull(sessionID); requestContexts.commitRequestContext(requestContext); commitToClient(); assertEquals(sessionID, clientResponse.getNewCookieValue("JSESSIONID")); // new added cookie // ====================== // request 2 invokeNoopServlet("/servlet"); initRequestContext(); // session.isNew assertEquals(false, session.isNew()); // session.getId assertEquals(sessionID, session.getId()); // session.invalidate assertFalse(((SessionImpl) session).isInvalidated()); session.invalidate(); assertTrue(((SessionImpl) session).isInvalidated()); checkInvalidate(); requestContexts.commitRequestContext(requestContext); commitToClient(); assertEquals("", clientResponse.getNewCookieValue("JSESSIONID")); // got cleared cookie } @Test public void session_invalidate_new() throws Exception { // ====================== // request 1 invokeNoopServlet("/servlet"); initRequestContext(); // session.isNew assertEquals(true, session.isNew()); // session.getId sessionID = session.getId(); assertNotNull(sessionID); // invalidate new session assertFalse(((SessionImpl) session).isInvalidated()); session.invalidate(); assertTrue(((SessionImpl) session).isInvalidated()); checkInvalidate(true); requestContexts.commitRequestContext(requestContext); commitToClient(); assertEquals("", clientResponse.getNewCookieValue("JSESSIONID")); // no new cookie } private void checkInvalidate() throws Exception { checkInvalidate(false); } private void checkInvalidate(boolean invalidateNewSession) throws Exception { // session.getServletContext assertSame(requestContext.getServletContext(), session.getServletContext()); // session.isNew checkInvalidate("isNew"); // session.getId sessionID = session.getId(); assertNotNull(sessionID); // session.getCreationTime checkInvalidate("getCreationTime"); // session.getLastAccessedTime checkInvalidate("getLastAccessedTime"); // session.getMaxInactiveInterval assertEquals(0, session.getMaxInactiveInterval()); // session.getAttributeNames checkInvalidate("getAttributeNames"); // session.setAttribute/getAttribute checkInvalidate("setAttribute", "count", new Object()); checkInvalidate("getAttribute", "count"); // session.getAttributeNames checkInvalidate("getAttributeNames"); // session.invalidate checkInvalidate("invalidate"); // session.clear checkInvalidate("clear"); if (invalidateNewSession) { // request.getRequestedSessionId assertEquals(null, newRequest.getRequestedSessionId()); // request.isRequestedSessionIdFromCookie assertEquals(false, newRequest.isRequestedSessionIdFromCookie()); // request.isRequestedSessionIdFromURL assertEquals(false, newRequest.isRequestedSessionIdFromURL()); // request.isRequestedSessionIdValid assertEquals(false, newRequest.isRequestedSessionIdValid()); } else { // request.getRequestedSessionId assertEquals(sessionID, newRequest.getRequestedSessionId()); // request.isRequestedSessionIdFromCookie assertEquals(true, newRequest.isRequestedSessionIdFromCookie()); // request.isRequestedSessionIdFromURL assertEquals(false, newRequest.isRequestedSessionIdFromURL()); // request.isRequestedSessionIdValid assertEquals(true, newRequest.isRequestedSessionIdValid()); } // response.encodeURL/encodeRedirectURL: unchanged for urlEncodeEnabled=false assertEquals("http://localhost/servlet/", newResponse.encodeURL("http://localhost/servlet/")); assertEquals("http://localhost/servlet/", newResponse.encodeRedirectURL("http://localhost/servlet/")); } private void checkInvalidate(String methodName, Object... params) throws Exception { Class<?>[] paramTypes; if (isEmptyArray(params)) { paramTypes = EMPTY_CLASS_ARRAY; params = EMPTY_OBJECT_ARRAY; } else { paramTypes = new Class<?>[params.length]; for (int i = 0; i < params.length; i++) { paramTypes[i] = params[i].getClass(); } } Method method = session.getClass().getMethod(methodName, paramTypes); try { method.invoke(session, params); fail(methodName); } catch (InvocationTargetException e) { assertThat( e, exception(IllegalStateException.class, "Cannot call method", methodName, "the session has already invalidated")); } } @Test public void session_models() throws Exception { // ====================== // request 1 invokeNoopServlet("/servlet"); initRequestContext("session_models"); SimpleMemoryStoreImpl sms = (SimpleMemoryStoreImpl) requestContext.getSessionConfig().getStores() .getStore("s10"); assertEquals(true, session.isNew()); sessionID = session.getId(); session.setAttribute("myObject", "myValue"); requestContexts.commitRequestContext(requestContext); commitToClient(); assertEquals(sessionID, clientResponse.getNewCookieValue("JSESSIONID")); // new added cookie // 查看session的内容 Map<String, Object> contentMap = sms.getSession(sessionID); assertEquals(2, contentMap.size()); assertEquals("myValue", contentMap.get("myObject")); String model = (String) contentMap.get(MODEL_KEY_DEFAULT); assertNotNull(model); // ====================== // request 2 invokeNoopServlet("/servlet"); initRequestContext("session_models"); assertEquals(false, session.isNew()); assertEquals(sessionID, session.getId()); assertEquals("myValue", session.getAttribute("myObject")); session.setAttribute("myObject", "myValue2"); requestContexts.commitRequestContext(requestContext); commitToClient(); assertEquals(null, clientResponse.getNewCookieValue("JSESSIONID")); // no new cookie // 查看session的内容 assertEquals(2, contentMap.size()); assertEquals("myValue2", contentMap.get("myObject")); assertNotSame(model, contentMap.get(MODEL_KEY_DEFAULT)); model = (String) contentMap.get(MODEL_KEY_DEFAULT); assertTrue(model.contains(session.getId())); // ====================== // request 3 invokeNoopServlet("/servlet"); initRequestContext("session_models"); assertEquals(false, session.isNew()); assertEquals(sessionID, session.getId()); assertEquals("myValue2", session.getAttribute("myObject")); } @Test public void session_id_not_match() throws Exception { // request 1 invokeNoopServlet("/servlet"); initRequestContext("session_cookie"); assertTrue(session.isNew()); String sessionID = session.getId(); assertNotNull(sessionID); session.setAttribute("count", 0); assertEquals(0, session.getAttribute("count")); requestContexts.commitRequestContext(requestContext); commitToClient(); assertEquals(sessionID, clientResponse.getNewCookieValue("JSESSIONID")); // new added cookie String cookieStoreContent = clientResponse.getNewCookieValue("myCookieStore0"); assertNotNull(cookieStoreContent); // request 2 - new session prepareWebClient(); client.putCookie("JSESSIONID", sessionID + "_changed"); // 改变sessionid client.putCookie("myCookieStore0", cookieStoreContent); invokeNoopServlet("/servlet"); initRequestContext("session_cookie"); assertTrue(session.isNew()); assertEquals(sessionID + "_changed", session.getId()); } @Test public void session_id_not_found_in_model() throws Exception { // request 1 invokeNoopServlet("/servlet"); initRequestContext("session_cookie"); assertTrue(session.isNew()); String sessionID = session.getId(); assertNotNull(sessionID); session.setAttribute("count", 0); assertEquals(0, session.getAttribute("count")); Object sessionModel = session.getAttribute("SESSION_MODEL"); getAccessibleField(SessionModelImpl.class, "sessionID").set(sessionModel, null); // 清除sessionModel中的sessionID requestContexts.commitRequestContext(requestContext); commitToClient(); assertEquals(sessionID, clientResponse.getNewCookieValue("JSESSIONID")); // new added cookie String cookieStoreContent = clientResponse.getNewCookieValue("myCookieStore0"); assertNotNull(cookieStoreContent); // request 2 prepareWebClient(); client.putCookie("JSESSIONID", sessionID + "_changed"); // 改变sessionid client.putCookie("myCookieStore0", cookieStoreContent); invokeNoopServlet("/servlet"); initRequestContext("session_cookie"); assertFalse(session.isNew()); assertEquals(sessionID + "_changed", session.getId()); assertEquals(0, session.getAttribute("count")); } public static class MyExactMatchesOnlySessionStore implements ExactMatchesOnlySessionStore { private String[] attrNames; public String[] getAttributeNames() { return attrNames; } public void initAttributeNames(String[] attrNames) { this.attrNames = attrNames; } public void init(String storeName, SessionConfig sessionConfig) { } public Iterable<String> getAttributeNames(String sessionID, StoreContext storeContext) { return null; } public Object loadAttribute(String attrName, String sessionID, StoreContext storeContext) { return null; } public void invalidate(String sessionID, StoreContext storeContext) { } public void commit(Map<String, Object> attrs, String sessionID, StoreContext storeContext) { } } }