mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-22 17:47:04 +03:00
Descriptive error from FileUploadParser when filename not included. (#4340)
* Descriptive error from FileUploadParser when filename not included. * Consistent handling of upload filenames
This commit is contained in:
parent
46a44e52aa
commit
3ef3fee926
|
@ -118,6 +118,10 @@ class FileUploadParser(BaseParser):
|
||||||
Parser for file upload data.
|
Parser for file upload data.
|
||||||
"""
|
"""
|
||||||
media_type = '*/*'
|
media_type = '*/*'
|
||||||
|
errors = {
|
||||||
|
'unhandled': 'FileUpload parse error - none of upload handlers can handle the stream',
|
||||||
|
'no_filename': 'Missing filename. Request should include a Content-Disposition header with a filename parameter.',
|
||||||
|
}
|
||||||
|
|
||||||
def parse(self, stream, media_type=None, parser_context=None):
|
def parse(self, stream, media_type=None, parser_context=None):
|
||||||
"""
|
"""
|
||||||
|
@ -134,6 +138,9 @@ class FileUploadParser(BaseParser):
|
||||||
upload_handlers = request.upload_handlers
|
upload_handlers = request.upload_handlers
|
||||||
filename = self.get_filename(stream, media_type, parser_context)
|
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
|
# Note that this code is extracted from Django's handling of
|
||||||
# file uploads in MultiPartParser.
|
# file uploads in MultiPartParser.
|
||||||
content_type = meta.get('HTTP_CONTENT_TYPE',
|
content_type = meta.get('HTTP_CONTENT_TYPE',
|
||||||
|
@ -146,7 +153,7 @@ class FileUploadParser(BaseParser):
|
||||||
|
|
||||||
# See if the handler will want to take care of the parsing.
|
# See if the handler will want to take care of the parsing.
|
||||||
for handler in upload_handlers:
|
for handler in upload_handlers:
|
||||||
result = handler.handle_raw_input(None,
|
result = handler.handle_raw_input(stream,
|
||||||
meta,
|
meta,
|
||||||
content_length,
|
content_length,
|
||||||
None,
|
None,
|
||||||
|
@ -178,10 +185,10 @@ class FileUploadParser(BaseParser):
|
||||||
|
|
||||||
for index, handler in enumerate(upload_handlers):
|
for index, handler in enumerate(upload_handlers):
|
||||||
file_obj = handler.file_complete(counters[index])
|
file_obj = handler.file_complete(counters[index])
|
||||||
if file_obj:
|
if file_obj is not None:
|
||||||
return DataAndFiles({}, {'file': file_obj})
|
return DataAndFiles({}, {'file': file_obj})
|
||||||
raise ParseError("FileUpload parse error - "
|
|
||||||
"none of upload handlers can handle the stream")
|
raise ParseError(self.errors['unhandled'])
|
||||||
|
|
||||||
def get_filename(self, stream, media_type, parser_context):
|
def get_filename(self, stream, media_type, parser_context):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -2,8 +2,11 @@
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import pytest
|
||||||
from django import forms
|
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.test import TestCase
|
||||||
from django.utils.six.moves import StringIO
|
from django.utils.six.moves import StringIO
|
||||||
|
|
||||||
|
@ -63,8 +66,9 @@ class TestFileUploadParser(TestCase):
|
||||||
parser = FileUploadParser()
|
parser = FileUploadParser()
|
||||||
self.stream.seek(0)
|
self.stream.seek(0)
|
||||||
self.parser_context['request'].META['HTTP_CONTENT_DISPOSITION'] = ''
|
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)
|
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):
|
def test_parse_missing_filename_multiple_upload_handlers(self):
|
||||||
"""
|
"""
|
||||||
|
@ -78,8 +82,23 @@ class TestFileUploadParser(TestCase):
|
||||||
MemoryFileUploadHandler()
|
MemoryFileUploadHandler()
|
||||||
)
|
)
|
||||||
self.parser_context['request'].META['HTTP_CONTENT_DISPOSITION'] = ''
|
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)
|
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):
|
def test_get_filename(self):
|
||||||
parser = FileUploadParser()
|
parser = FileUploadParser()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user