1
0
mirror of https://github.com/django/django.git synced 2025-11-07 07:15:35 +00:00

[1.7.x] Fixed #24193 -- Prevented unclosed file warnings in static.serve()

This regression was caused by 818e59a3f0. The patch is a partial
backport of the new FileResponse class available in later Django
versions.
Thanks Raphaël Hertzog for the report, and Tim Graham and Collin
Anderson for the reviews.
This commit is contained in:
Claude Paroz
2015-01-21 20:59:40 +01:00
parent 7b677fe063
commit b1bf8d64fb
5 changed files with 30 additions and 11 deletions

View File

@@ -1,7 +1,8 @@
from django.http.cookie import SimpleCookie, parse_cookie
from django.http.request import (HttpRequest, QueryDict,
RawPostDataException, UnreadablePostError, build_request_repr)
from django.http.response import (HttpResponse, StreamingHttpResponse,
from django.http.response import (
HttpResponse, StreamingHttpResponse, FileResponse,
HttpResponseRedirect, HttpResponsePermanentRedirect,
HttpResponseNotModified, HttpResponseBadRequest, HttpResponseForbidden,
HttpResponseNotFound, HttpResponseNotAllowed, HttpResponseGone,
@@ -16,5 +17,5 @@ __all__ = [
'HttpResponseBadRequest', 'HttpResponseForbidden', 'HttpResponseNotFound',
'HttpResponseNotAllowed', 'HttpResponseGone', 'HttpResponseServerError',
'Http404', 'BadHeaderError', 'fix_location_header', 'JsonResponse',
'conditional_content_removal',
'FileResponse', 'conditional_content_removal',
]

View File

@@ -382,6 +382,9 @@ class StreamingHttpResponse(HttpResponseBase):
@streaming_content.setter
def streaming_content(self, value):
self._set_streaming_content(value)
def _set_streaming_content(self, value):
# Ensure we can never iterate on "value" more than once.
self._iterator = iter(value)
if hasattr(value, 'close'):
@@ -391,6 +394,21 @@ class StreamingHttpResponse(HttpResponseBase):
return self.streaming_content
class FileResponse(StreamingHttpResponse):
"""
A streaming HTTP response class optimized for files.
"""
block_size = 4096
def _set_streaming_content(self, value):
if hasattr(value, 'read'):
self._iterator = iter(lambda: value.read(self.block_size), b'')
if hasattr(value, 'close'):
self._closable_objects.append(value)
else:
super(FileResponse, self)._set_streaming_content(value)
class HttpResponseRedirectBase(HttpResponse):
allowed_schemes = ['http', 'https', 'ftp']