[java-opensaml COMMIT] in /trunk: opensaml-storage-api/src/main/java/org/opensaml/storage/RequestScopedStorageService...

noreply at shibboleth.net noreply at shibboleth.net
Tue Oct 29 16:19:46 EDT 2013


Author: scantor
Date: Tue Oct 29 16:19:46 2013
New Revision: 3491

URL: http://svn.shibboleth.net/view/java-opensaml?rev=3491&view=rev
Log:
Fix bugs and race conditions in load/save flow.

Modified:
    trunk/opensaml-storage-api/src/main/java/org/opensaml/storage/RequestScopedStorageService.java
    trunk/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/JSONRequestScopedStorageService.java
    trunk/opensaml-storage-impl/src/test/java/org/opensaml/storage/impl/JSONRequestScopedStorageServiceTest.java

Modified: trunk/opensaml-storage-api/src/main/java/org/opensaml/storage/RequestScopedStorageService.java
URL: http://svn.shibboleth.net/view/java-opensaml/trunk/opensaml-storage-api/src/main/java/org/opensaml/storage/RequestScopedStorageService.java?rev=3491&r1=3490&r2=3491&view=diff
==============================================================================
--- trunk/opensaml-storage-api/src/main/java/org/opensaml/storage/RequestScopedStorageService.java (original)
+++ trunk/opensaml-storage-api/src/main/java/org/opensaml/storage/RequestScopedStorageService.java Tue Oct 29 16:19:46 2013
@@ -38,6 +38,8 @@
     /**
      * Reconstitute stored data.
      * 
+     * <p>This method must be idempotent with respect to existing state when called more than once.</p> 
+     * 
      * @throws IOException  if an error occurs reconstituting the data
      */
     public void load() throws IOException;

Modified: trunk/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/JSONRequestScopedStorageService.java
URL: http://svn.shibboleth.net/view/java-opensaml/trunk/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/JSONRequestScopedStorageService.java?rev=3491&r1=3490&r2=3491&view=diff
==============================================================================
--- trunk/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/JSONRequestScopedStorageService.java (original)
+++ trunk/opensaml-storage-impl/src/main/java/org/opensaml/storage/impl/JSONRequestScopedStorageService.java Tue Oct 29 16:19:46 2013
@@ -18,6 +18,7 @@
 package org.opensaml.storage.impl;
 
 import java.io.IOException;
+import java.io.PrintWriter;
 import java.io.StringReader;
 import java.io.StringWriter;
 import java.util.Arrays;
@@ -41,11 +42,13 @@
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
 import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
 
 import net.shibboleth.utilities.java.support.annotation.constraint.Live;
 import net.shibboleth.utilities.java.support.annotation.constraint.NonnullAfterInit;
@@ -82,11 +85,11 @@
     implements RequestScopedStorageService, Filter {
 
     /** Name of request attribute for context map. */
-    @Nonnull private static final String CONTEXT_MAP_ATTRIBUTE = 
+    @Nonnull protected static final String CONTEXT_MAP_ATTRIBUTE = 
             "org.opensaml.storage.impl.JSONRequestScopedStorageService.contextMap";
 
     /** Name of request attribute used as a dirty bit. */
-    @Nonnull private static final String DIRTY_BIT_ATTRIBUTE =
+    @Nonnull protected static final String DIRTY_BIT_ATTRIBUTE =
             "org.opensaml.storage.impl.JSONRequestScopedStorageService.dirty";
 
     /** Default cookie name for storage tracking. */
@@ -228,9 +231,18 @@
 
     /** {@inheritDoc} */
     public void load() throws IOException {
+        
+        Map<String,Map<String,MutableStorageRecord>> contextMap = getContextMap();
+        
+        // Check for recursion. If load() is called directly, the above getter will
+        // call us, which means we need to short-circuit the "outer" load call by
+        // detecting that data has been loaded already.
+        if (!contextMap.isEmpty()) {
+            return;
+        }
+        
         log.trace("Loading storage state from cookie in current request");
         
-        getContextMap().clear();
         setDirty(false);
         
         // Search for our cookie.
@@ -263,7 +275,7 @@
             
             for (Map.Entry<String,JsonValue> context : obj.entrySet()) {
                 if (context.getValue().getValueType() != JsonValue.ValueType.OBJECT) {
-                    getContextMap().clear();
+                    contextMap.clear();
                     throw new IOException("Found invalid data structure while parsing context map");
                 }
                 
@@ -281,7 +293,7 @@
             }
             setDirty(false);
         } catch (NullPointerException | ClassCastException | ArithmeticException | JsonException e) {
-            getContextMap().clear();
+            contextMap.clear();
             setDirty(false);
             log.error("Exception while parsing context map", e);
             throw new IOException("Found invalid data structure while parsing context map", e);
@@ -375,10 +387,12 @@

[... 127 lines stripped ...]


More information about the commits mailing list