Opened 6 years ago
Last modified 5 years ago
#30565 closed Bug
Close StreamingHttpResponse content immediately after iterating it — at Version 1
Description (last modified by ) ¶
This ticket is to suggest doing for StreamingHttpResponse
what #25725 did for HttpReponse
, namely to close the underlying content iterator after it has been iterated over.
Currently, if creating a StreamingHttpResponse
from a file-like object, it doesn't seem like there's an obvious way to close the underlying file after the file has been streamed. And as one of the comments in #25725 pointed out, trying to do this in StreamingHttpResponse.close()
isn't a good solution because WSGI servers can't be relied upon to call close()
.
I believe an alternative, more reliable solution may be to call close()
immediately after the iterator has been exhausted (if hasattr(value, 'close')
is true, as #25725 does). This is essentially what #25725 did for non-streaming HttpResponse
objects. Here is that code:
def content(self, value): # Consume iterators upon assignment to allow repeated iteration. if hasattr(value, '__iter__') and not isinstance(value, (bytes, str)): content = b''.join(self.make_bytes(chunk) for chunk in value) if hasattr(value, 'close'): try: value.close() except Exception: pass else: content = self.make_bytes(value)
In the streaming case, the content value
argument could be wrapped something like so (inside StreamingHttpResponse._set_streaming_content(value)
):
def iter_content(): yield from value if hasattr(value, 'close'): try: value.close() except Exception: pass new_value = iter_content()
Here is the current code for StreamingHttpResponse._set_streaming_content()
:
def _set_streaming_content(self, value): # Ensure we can never iterate on "value" more than once. self._iterator = iter(value) if hasattr(value, 'close'): self._closable_objects.append(value)
Change History (1)
comment:1 by , 6 years ago
Description: | modified (diff) |
---|---|
Type: | Uncategorized → Cleanup/optimization |
Version: | 2.2 → master |