From 148313eddd94237b79d3bfe74335c4c940ac563b Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Mon, 1 Aug 2016 18:34:44 +0100 Subject: [PATCH] Consistent handling of upload filenames --- rest_framework/parsers.py | 5 +++-- tests/test_parsers.py | 25 ++++++++++++++++++++++--- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/rest_framework/parsers.py b/rest_framework/parsers.py index 360ca1bed..238382364 100644 --- a/rest_framework/parsers.py +++ b/rest_framework/parsers.py @@ -138,6 +138,9 @@ class FileUploadParser(BaseParser): upload_handlers = request.upload_handlers filename = self.get_filename(stream, media_type, parser_context) + if not filename: + raise ParseError(self.errors['no_filename']) + # Note that this code is extracted from Django's handling of # file uploads in MultiPartParser. content_type = meta.get('HTTP_CONTENT_TYPE', @@ -183,8 +186,6 @@ class FileUploadParser(BaseParser): for index, handler in enumerate(upload_handlers): file_obj = handler.file_complete(counters[index]) if file_obj is not None: - if not file_obj.name: - raise ParseError(self.errors['no_filename']) return DataAndFiles({}, {'file': file_obj}) raise ParseError(self.errors['unhandled']) diff --git a/tests/test_parsers.py b/tests/test_parsers.py index 1e0f2e17f..f3af6817f 100644 --- a/tests/test_parsers.py +++ b/tests/test_parsers.py @@ -2,8 +2,11 @@ from __future__ import unicode_literals +import pytest from django import forms -from django.core.files.uploadhandler import MemoryFileUploadHandler +from django.core.files.uploadhandler import ( + MemoryFileUploadHandler, TemporaryFileUploadHandler +) from django.test import TestCase from django.utils.six.moves import StringIO @@ -63,8 +66,9 @@ class TestFileUploadParser(TestCase): parser = FileUploadParser() self.stream.seek(0) self.parser_context['request'].META['HTTP_CONTENT_DISPOSITION'] = '' - with self.assertRaises(ParseError): + with pytest.raises(ParseError) as excinfo: parser.parse(self.stream, None, self.parser_context) + assert str(excinfo.value) == 'Missing filename. Request should include a Content-Disposition header with a filename parameter.' def test_parse_missing_filename_multiple_upload_handlers(self): """ @@ -78,8 +82,23 @@ class TestFileUploadParser(TestCase): MemoryFileUploadHandler() ) self.parser_context['request'].META['HTTP_CONTENT_DISPOSITION'] = '' - with self.assertRaises(ParseError): + with pytest.raises(ParseError) as excinfo: parser.parse(self.stream, None, self.parser_context) + assert str(excinfo.value) == 'Missing filename. Request should include a Content-Disposition header with a filename parameter.' + + def test_parse_missing_filename_large_file(self): + """ + Parse raw file upload when filename is missing with TemporaryFileUploadHandler. + """ + parser = FileUploadParser() + self.stream.seek(0) + self.parser_context['request'].upload_handlers = ( + TemporaryFileUploadHandler(), + ) + self.parser_context['request'].META['HTTP_CONTENT_DISPOSITION'] = '' + with pytest.raises(ParseError) as excinfo: + parser.parse(self.stream, None, self.parser_context) + assert str(excinfo.value) == 'Missing filename. Request should include a Content-Disposition header with a filename parameter.' def test_get_filename(self): parser = FileUploadParser()