WW-3895 Uses session id for synchronisation

This commit is contained in:
Lukasz Lenart
2014-08-22 17:25:45 +02:00
parent c6b7aaf816
commit eecd907638
4 changed files with 21 additions and 8 deletions
@@ -21,6 +21,8 @@
package org.apache.struts2.dispatcher;
import org.apache.struts2.components.Submit;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.Serializable;
@@ -68,7 +70,7 @@ public class SessionMap<K, V> extends AbstractMap<K, V> implements Serializable
return;
}
synchronized (session) {
synchronized (session.getId().intern()) {
session.invalidate();
session = null;
entries = null;
@@ -79,12 +81,13 @@ public class SessionMap<K, V> extends AbstractMap<K, V> implements Serializable
* Removes all attributes from the session as well as clears entries in this
* map.
*/
@SuppressWarnings("unchecked")
public void clear() {
if (session == null) {
return;
}
synchronized (session) {
synchronized (session.getId().intern()) {
entries = null;
Enumeration<String> attributeNamesEnum = session.getAttributeNames();
while (attributeNamesEnum.hasMoreElements()) {
@@ -99,12 +102,13 @@ public class SessionMap<K, V> extends AbstractMap<K, V> implements Serializable
*
* @return a Set of attributes from the http session.
*/
@SuppressWarnings("unchecked")
public Set<java.util.Map.Entry<K, V>> entrySet() {
if (session == null) {
return Collections.emptySet();
}
synchronized (session) {
synchronized (session.getId().intern()) {
if (entries == null) {
entries = new HashSet<Map.Entry<K, V>>();
@@ -154,12 +158,13 @@ public class SessionMap<K, V> extends AbstractMap<K, V> implements Serializable
* @param key the name of the session attribute.
* @return the session attribute or <tt>null</tt> if it doesn't exist.
*/
@SuppressWarnings("unchecked")
public V get(Object key) {
if (session == null) {
return null;
}
synchronized (session) {
synchronized (session.getId().intern()) {
return (V) session.getAttribute(key.toString());
}
}
@@ -177,7 +182,7 @@ public class SessionMap<K, V> extends AbstractMap<K, V> implements Serializable
session = request.getSession(true);
}
}
synchronized (session) {
synchronized (session.getId().intern()) {
V oldValue = get(key);
entries = null;
session.setAttribute(key.toString(), value);
@@ -196,7 +201,7 @@ public class SessionMap<K, V> extends AbstractMap<K, V> implements Serializable
return null;
}
synchronized (session) {
synchronized (session.getId().intern()) {
entries = null;
V value = get(key);
@@ -218,7 +223,7 @@ public class SessionMap<K, V> extends AbstractMap<K, V> implements Serializable
return false;
}
synchronized (session) {
synchronized (session.getId().intern()) {
return (session.getAttribute(key.toString()) != null);
}
}
@@ -109,7 +109,7 @@ public class TokenSessionStoreInterceptor extends TokenInterceptor {
//see WW-2902: we need to use the real HttpSession here, as opposed to the map
//that wraps the session, because a new wrap is created on every request
HttpSession session = ServletActionContext.getRequest().getSession(true);
synchronized (session) {
synchronized (session.getId().intern()) {
if (!TokenHelper.validToken()) {
return handleInvalidToken(invocation);
}
@@ -207,6 +207,7 @@ public class SessionMapTest extends TestCase {
protected void setUp() throws Exception {
sessionMock = new Mock(HttpSession.class);
sessionMock.matchAndReturn("getId", "1");
requestMock = new Mock(HttpServletRequest.class);
requestMock.matchAndReturn("getSession", new Constraint[]{new IsEqual(Boolean.FALSE)}, sessionMock.proxy());
}
@@ -23,6 +23,7 @@ package org.apache.struts2.views.jsp;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.UUID;
import com.mockobjects.servlet.MockHttpSession;
@@ -67,4 +68,10 @@ public class StrutsMockHttpSession extends MockHttpSession {
public void setupGetAttributeNames(Enumeration enumeration) {
throw new UnsupportedOperationException();
}
@Override
public String getId() {
return UUID.randomUUID().toString();
}
}