diff options
Diffstat (limited to 'django')
| -rw-r--r-- | django/core/files/storage.py | 2 | ||||
| -rw-r--r-- | django/core/files/uploadedfile.py | 3 | ||||
| -rw-r--r-- | django/core/handlers/base.py | 2 | ||||
| -rw-r--r-- | django/http/multipartparser.py | 10 | ||||
| -rw-r--r-- | django/http/request.py | 6 |
5 files changed, 18 insertions, 5 deletions
diff --git a/django/core/files/storage.py b/django/core/files/storage.py index 98864f7f22..58c623b883 100644 --- a/django/core/files/storage.py +++ b/django/core/files/storage.py @@ -209,7 +209,6 @@ class FileSystemStorage(Storage): # This file has a file path that we can move. if hasattr(content, 'temporary_file_path'): file_move_safe(content.temporary_file_path(), full_path) - content.close() # This is a normal uploadedfile that we can stream. else: @@ -228,7 +227,6 @@ class FileSystemStorage(Storage): _file = os.fdopen(fd, mode) _file.write(chunk) finally: - content.close() locks.unlock(fd) if _file is not None: _file.close() diff --git a/django/core/files/uploadedfile.py b/django/core/files/uploadedfile.py index 75f25405b9..9a94894424 100644 --- a/django/core/files/uploadedfile.py +++ b/django/core/files/uploadedfile.py @@ -96,9 +96,6 @@ class InMemoryUploadedFile(UploadedFile): def open(self, mode=None): self.file.seek(0) - def close(self): - pass - def chunks(self, chunk_size=None): self.file.seek(0) yield self.read() diff --git a/django/core/handlers/base.py b/django/core/handlers/base.py index ffc48a076a..887898a33c 100644 --- a/django/core/handlers/base.py +++ b/django/core/handlers/base.py @@ -207,6 +207,8 @@ class BaseHandler(object): signals.got_request_exception.send(sender=self.__class__, request=request) response = self.handle_uncaught_exception(request, resolver, sys.exc_info()) + response._closable_objects.append(request) + return response def handle_uncaught_exception(self, request, resolver, exc_info): diff --git a/django/http/multipartparser.py b/django/http/multipartparser.py index 20232cb7c6..1bcace94cd 100644 --- a/django/http/multipartparser.py +++ b/django/http/multipartparser.py @@ -228,6 +228,7 @@ class MultiPartParser(object): break except SkipFile: + self._close_files() # Just use up the rest of this file... exhaust(field_stream) else: @@ -237,6 +238,7 @@ class MultiPartParser(object): # If this is neither a FIELD or a FILE, just exhaust the stream. exhaust(stream) except StopUpload as e: + self._close_files() if not e.connection_reset: exhaust(self._input_data) else: @@ -268,6 +270,14 @@ class MultiPartParser(object): """Cleanup filename from Internet Explorer full paths.""" return filename and filename[filename.rfind("\\") + 1:].strip() + def _close_files(self): + # Free up all file handles. + # FIXME: this currently assumes that upload handlers store the file as 'file' + # We should document that... (Maybe add handler.free_file to complement new_file) + for handler in self._upload_handlers: + if hasattr(handler, 'file'): + handler.file.close() + class LazyStream(six.Iterator): """ diff --git a/django/http/request.py b/django/http/request.py index ded4744a87..ecad639c82 100644 --- a/django/http/request.py +++ b/django/http/request.py @@ -5,6 +5,7 @@ import os import re import sys from io import BytesIO +from itertools import chain from pprint import pformat from django.conf import settings @@ -245,6 +246,11 @@ class HttpRequest(object): else: self._post, self._files = QueryDict('', encoding=self._encoding), MultiValueDict() + def close(self): + if hasattr(self, '_files'): + for f in chain.from_iterable(l[1] for l in self._files.lists()): + f.close() + # File-like and iterator interface. # # Expects self._stream to be set to an appropriate source of bytes by |
