summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Merickel <michael@merickel.org>2019-03-26 00:59:26 -0500
committerMichael Merickel <michael@merickel.org>2019-03-26 00:59:26 -0500
commitef1f87adaa966395a7ea3c7f68bcb7acf1eee694 (patch)
tree9281cd3aa86d42b9b7f22fcc1ddc37715960e0c1
parent29fb97ddc15632f53c8201820f33a1793d63928d (diff)
downloadwaitress-ef1f87adaa966395a7ea3c7f68bcb7acf1eee694.tar.gz
close the buffer if a write fails before the channel takes over handling it
-rw-r--r--waitress/task.py38
1 files changed, 19 insertions, 19 deletions
diff --git a/waitress/task.py b/waitress/task.py
index 8e14b4f..dc283ee 100644
--- a/waitress/task.py
+++ b/waitress/task.py
@@ -451,25 +451,25 @@ class WSGITask(Task):
# Call the application to handle the request and write a response
app_iter = self.channel.server.application(env, start_response)
- if app_iter.__class__ is ReadOnlyFileBasedBuffer:
- # NB: do not put this inside the below try: finally: which closes
- # the app_iter; we need to defer closing the underlying file. It's
- # intention that we don't want to call ``close`` here if the
- # app_iter is a ROFBB; the buffer (and therefore the file) will
- # eventually be closed within channel.py's _flush_some or
- # handle_close instead.
- cl = self.content_length
- size = app_iter.prepare(cl)
- if size:
- if cl != size:
- if cl is not None:
- self.remove_content_length_header()
- self.content_length = size
- self.write(b'') # generate headers
- self.channel.write_soon(app_iter)
- return
-
+ can_close_app_iter = True
try:
+ if app_iter.__class__ is ReadOnlyFileBasedBuffer:
+ cl = self.content_length
+ size = app_iter.prepare(cl)
+ if size:
+ if cl != size:
+ if cl is not None:
+ self.remove_content_length_header()
+ self.content_length = size
+ self.write(b'') # generate headers
+ # if the write_soon below succeeds then the channel will
+ # take over closing the underlying file via the channel's
+ # _flush_some or handle_close so we intentionally avoid
+ # calling close in the finally block
+ self.channel.write_soon(app_iter)
+ can_close_app_iter = False
+ return
+
first_chunk_len = None
for chunk in app_iter:
if first_chunk_len is None:
@@ -503,7 +503,7 @@ class WSGITask(Task):
self.content_bytes_written, cl),
)
finally:
- if hasattr(app_iter, 'close'):
+ if can_close_app_iter and hasattr(app_iter, 'close'):
app_iter.close()
def parse_proxy_headers(