Commits

Anonymous committed 7cf24e4

Fixed #291

Comments (0)

Files changed (2)

cherrypy/_cphttptools.py

                     # For an HTTPRedirect, we don't go through the regular
                     # mechanism: we return the redirect immediately
                     inst.set_response()
+                    applyFilters('beforeFinalize')
                     finalize()
             finally:
                 applyFilters('onEndResource')
     # in handling errors. That is, it must not raise any errors itself;
     # it cannot be allowed to fail. Therefore, don't add to it!
     # In particular, don't call any other CP functions.
+
     body = "Unrecoverable error in the server."
     if extrabody is not None:
         body += "\n" + extrabody
 
 def applyFilters(methodName):
     """Execute the given method for all registered filters."""
-    if methodName in ('beforeRequestBody', 'beforeMain'):
+    if methodName in ('onStartResource', 'beforeRequestBody', 'beforeMain'):
         filterList = (_cputil._cpDefaultInputFilterList +
                       _cputil.getSpecialAttribute('_cpFilterList'))
-    elif methodName in ('beforeFinalize',):
+    elif methodName in ('beforeFinalize', 'onEndResource',
+                'beforeErrorResponse', 'afterErrorResponse'):
         filterList = (_cputil.getSpecialAttribute('_cpFilterList') +
                       _cputil._cpDefaultOutputFilterList)
+    #else:
+    #    # '', 
+    #    # 'beforeErrorResponse', 'afterErrorResponse'
+    #    filterList = (_cputil._cpDefaultInputFilterList +
+    #                  _cputil.getSpecialAttribute('_cpFilterList') +
+    #                  _cputil._cpDefaultOutputFilterList)
     else:
-        # 'onStartResource', 'onEndResource'
-        # 'beforeErrorResponse', 'afterErrorResponse'
-        filterList = (_cputil._cpDefaultInputFilterList +
-                      _cputil.getSpecialAttribute('_cpFilterList') +
-                      _cputil._cpDefaultOutputFilterList)
+        assert False # Wrong methodName for the filter
     for filter in filterList:
         method = getattr(filter, methodName, None)
         if method:

cherrypy/lib/filter/sessionfilter.py

 
     def beforeFinalize(self):
         def returnBodyAndSaveData(body, sess):
-            # If the body is a generator, we have to save the data
-            #   *after* the generator has been consumed
-            if isinstance(body, types.GeneratorType):
-                for line in body:
-                    yield line
+            try:
+                # If the body is a generator, we have to save the data
+                #   *after* the generator has been consumed
+                if isinstance(body, types.GeneratorType):
+                    for line in body:
+                        yield line
 
-            # Save session data
-            expirationTime = datetime.datetime.now() + \
-                    datetime.timedelta(seconds = sess.sessionTimeout * 60)
-            sess.sessionStorage.save(
-                    sess.sessionID, sess.sessionData, expirationTime)
-            if sess.locked:
-                # Always release the lock if the user didn't release it
-                sess.sessionStorage.releaseLock()
+                # Save session data
+                expirationTime = datetime.datetime.now() + \
+                        datetime.timedelta(seconds = sess.sessionTimeout * 60)
+                sess.sessionStorage.save(
+                        sess.sessionID, sess.sessionData, expirationTime)
+                if sess.locked:
+                    # Always release the lock if the user didn't release it
+                    sess.sessionStorage.releaseLock()
 
-            # If the body is not a generator, we save the data
-            #   before the body is returned
-            if not isinstance(body, types.GeneratorType):
-                for line in body:
-                    yield line
+                # If the body is not a generator, we save the data
+                #   before the body is returned
+                if not isinstance(body, types.GeneratorType):
+                    for line in body:
+                        yield line
+            except:
+                # Can't use try/finally because of yield
+                self._clean(sess)
+                raise
+            self._clean(sess)
 
         sess = cherrypy.threadData._session
         if not sess.sessionStorage:
         cherrypy.response.body = \
             returnBodyAndSaveData(cherrypy.response.body, sess)
 
-
-    def onEndResource(self):
-        sess = cherrypy.threadData._session
+    def _clean(self, sess):
         if getattr(sess, 'locked', None):
             # If the session is still locked there probably was an
             #   error while processing the request.
         if getattr(sess, 'sessionStorage', None):
             del sess.sessionStorage
 
+
 class RamStorage:
     """ Implementation of the RAM backend for sessions """
     def load(self, id):
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.