Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 7c59362

Browse filesBrowse files
authored
bpo-29183: Fix double exceptions in wsgiref.handlers.BaseHandler (GH-12914)
1 parent f4e1bab commit 7c59362
Copy full SHA for 7c59362

File tree

Expand file treeCollapse file tree

3 files changed

+38
-1
lines changed
Filter options
Expand file treeCollapse file tree

3 files changed

+38
-1
lines changed

‎Lib/test/test_wsgiref.py

Copy file name to clipboardExpand all lines: Lib/test/test_wsgiref.py
+25Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,31 @@ def write(self, b):
806806

807807
self.assertFalse(stderr.getvalue())
808808

809+
def testDontResetInternalStateOnException(self):
810+
class CustomException(ValueError):
811+
pass
812+
813+
# We are raising CustomException here to trigger an exception
814+
# during the execution of SimpleHandler.finish_response(), so
815+
# we can easily test that the internal state of the handler is
816+
# preserved in case of an exception.
817+
class AbortingWriter:
818+
def write(self, b):
819+
raise CustomException
820+
821+
stderr = StringIO()
822+
environ = {"SERVER_PROTOCOL": "HTTP/1.0"}
823+
h = SimpleHandler(BytesIO(), AbortingWriter(), stderr, environ)
824+
h.run(hello_app)
825+
826+
self.assertIn("CustomException", stderr.getvalue())
827+
828+
# Test that the internal state of the handler is preserved.
829+
self.assertIsNotNone(h.result)
830+
self.assertIsNotNone(h.headers)
831+
self.assertIsNotNone(h.status)
832+
self.assertIsNotNone(h.environ)
833+
809834

810835
if __name__ == "__main__":
811836
unittest.main()

‎Lib/wsgiref/handlers.py

Copy file name to clipboardExpand all lines: Lib/wsgiref/handlers.py
+10-1Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,16 @@ def finish_response(self):
183183
for data in self.result:
184184
self.write(data)
185185
self.finish_content()
186-
finally:
186+
except:
187+
# Call close() on the iterable returned by the WSGI application
188+
# in case of an exception.
189+
if hasattr(self.result, 'close'):
190+
self.result.close()
191+
raise
192+
else:
193+
# We only call close() when no exception is raised, because it
194+
# will set status, result, headers, and environ fields to None.
195+
# See bpo-29183 for more details.
187196
self.close()
188197

189198

+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix double exceptions in :class:`wsgiref.handlers.BaseHandler` by calling
2+
its :meth:`~wsgiref.handlers.BaseHandler.close` method only when no
3+
exception is raised.

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.