Skip to content

Descriptive error from FileUploadParser when filename not included. #4340

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions rest_framework/parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,10 @@ class FileUploadParser(BaseParser):
Parser for file upload data.
"""
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):
"""
Expand All @@ -134,6 +138,9 @@ def parse(self, stream, media_type=None, parser_context=None):
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',
Expand All @@ -146,7 +153,7 @@ def parse(self, stream, media_type=None, parser_context=None):

# See if the handler will want to take care of the parsing.
for handler in upload_handlers:
result = handler.handle_raw_input(None,
result = handler.handle_raw_input(stream,
meta,
content_length,
None,
Expand Down Expand Up @@ -178,10 +185,10 @@ def parse(self, stream, media_type=None, parser_context=None):

for index, handler in enumerate(upload_handlers):
file_obj = handler.file_complete(counters[index])
if file_obj:
if file_obj is not None:
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):
"""
Expand Down
25 changes: 22 additions & 3 deletions tests/test_parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -63,8 +66,9 @@ def test_parse_missing_filename(self):
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):
"""
Expand All @@ -78,8 +82,23 @@ def test_parse_missing_filename_multiple_upload_handlers(self):
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()
Expand Down
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy