Commit 1534ded4 authored by Tres Seaver's avatar Tres Seaver

Merge pull request #19 from zopefoundation/16-fix_leak_w_broken_EndRequestEvent_subscriber-master

Prevent leaked connections when broken 'EndRequestEvent' subscribers raise
parents 3710b7fe a78c15f8
...@@ -11,6 +11,9 @@ http://docs.zope.org/zope2/ ...@@ -11,6 +11,9 @@ http://docs.zope.org/zope2/
Bugs Fixed Bugs Fixed
++++++++++ ++++++++++
- Issue #16: prevent leaked connections when broken ``EndRequestEvent``
subscribers raise exceptions.
- Ensure that the ``WSGIPublisher`` begins and ends an *interaction* - Ensure that the ``WSGIPublisher`` begins and ends an *interaction*
at the request/response barrier. This is required for instance for at the request/response barrier. This is required for instance for
the ``checkPermission`` call to function without an explicit the ``checkPermission`` call to function without an explicit
......
...@@ -215,10 +215,12 @@ class BaseRequest: ...@@ -215,10 +215,12 @@ class BaseRequest:
self._held=None self._held=None
def close(self): def close(self):
notify(EndRequestEvent(None, self)) try:
# subscribers might need the zodb, so `clear` must come afterwards notify(EndRequestEvent(None, self))
# (since `self._held=None` might close the connection, see above) finally:
self.clear() # subscribers might need the zodb, so `clear` must come afterwards
# (since `self._held=None` might close the connection, see above)
self.clear()
def processInputs(self): def processInputs(self):
"""Do any input processing that could raise errors """Do any input processing that could raise errors
......
...@@ -424,6 +424,22 @@ class TestBaseRequest(unittest.TestCase, BaseRequest_factory): ...@@ -424,6 +424,22 @@ class TestBaseRequest(unittest.TestCase, BaseRequest_factory):
r = self._makeOne(root) r = self._makeOne(root)
self.assertRaises(NotFound, r.traverse, 'folder/simpleFrozenSet') self.assertRaises(NotFound, r.traverse, 'folder/simpleFrozenSet')
def test_close_w_broken_subscriber(self):
# See: https://github.com/zopefoundation/Zope/issues/16
from zope.event import subscribers
root, folder = self._makeRootAndFolder()
r = self._makeOne(root)
r.other['foo'] = 'Foo'
BEFORE = subscribers[:]
def _broken(event):
raise ValueError("I'm broken")
subscribers.append(_broken)
try:
self.assertRaises(ValueError, r.close)
finally:
subscribers[:] = BEFORE
self.assertEqual(r.other, {})
def test_hold_after_close(self): def test_hold_after_close(self):
# Request should no longer accept holds after it has been closed # Request should no longer accept holds after it has been closed
root, folder = self._makeRootAndFolder() root, folder = self._makeRootAndFolder()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment