Skip to content

Commit 3ef3fee

Browse files
authored
Descriptive error from FileUploadParser when filename not included. (#4340)
* Descriptive error from FileUploadParser when filename not included. * Consistent handling of upload filenames
1 parent 46a44e5 commit 3ef3fee

File tree

2 files changed

+33
-7
lines changed

2 files changed

+33
-7
lines changed

rest_framework/parsers.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,10 @@ class FileUploadParser(BaseParser):
118118
Parser for file upload data.
119119
"""
120120
media_type = '*/*'
121+
errors = {
122+
'unhandled': 'FileUpload parse error - none of upload handlers can handle the stream',
123+
'no_filename': 'Missing filename. Request should include a Content-Disposition header with a filename parameter.',
124+
}
121125

122126
def parse(self, stream, media_type=None, parser_context=None):
123127
"""
@@ -134,6 +138,9 @@ def parse(self, stream, media_type=None, parser_context=None):
134138
upload_handlers = request.upload_handlers
135139
filename = self.get_filename(stream, media_type, parser_context)
136140

141+
if not filename:
142+
raise ParseError(self.errors['no_filename'])
143+
137144
# Note that this code is extracted from Django's handling of
138145
# file uploads in MultiPartParser.
139146
content_type = meta.get('HTTP_CONTENT_TYPE',
@@ -146,7 +153,7 @@ def parse(self, stream, media_type=None, parser_context=None):
146153

147154
# See if the handler will want to take care of the parsing.
148155
for handler in upload_handlers:
149-
result = handler.handle_raw_input(None,
156+
result = handler.handle_raw_input(stream,
150157
meta,
151158
content_length,
152159
None,
@@ -178,10 +185,10 @@ def parse(self, stream, media_type=None, parser_context=None):
178185

179186
for index, handler in enumerate(upload_handlers):
180187
file_obj = handler.file_complete(counters[index])
181-
if file_obj:
188+
if file_obj is not None:
182189
return DataAndFiles({}, {'file': file_obj})
183-
raise ParseError("FileUpload parse error - "
184-
"none of upload handlers can handle the stream")
190+
191+
raise ParseError(self.errors['unhandled'])
185192

186193
def get_filename(self, stream, media_type, parser_context):
187194
"""

tests/test_parsers.py

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22

33
from __future__ import unicode_literals
44

5+
import pytest
56
from django import forms
6-
from django.core.files.uploadhandler import MemoryFileUploadHandler
7+
from django.core.files.uploadhandler import (
8+
MemoryFileUploadHandler, TemporaryFileUploadHandler
9+
)
710
from django.test import TestCase
811
from django.utils.six.moves import StringIO
912

@@ -63,8 +66,9 @@ def test_parse_missing_filename(self):
6366
parser = FileUploadParser()
6467
self.stream.seek(0)
6568
self.parser_context['request'].META['HTTP_CONTENT_DISPOSITION'] = ''
66-
with self.assertRaises(ParseError):
69+
with pytest.raises(ParseError) as excinfo:
6770
parser.parse(self.stream, None, self.parser_context)
71+
assert str(excinfo.value) == 'Missing filename. Request should include a Content-Disposition header with a filename parameter.'
6872

6973
def test_parse_missing_filename_multiple_upload_handlers(self):
7074
"""
@@ -78,8 +82,23 @@ def test_parse_missing_filename_multiple_upload_handlers(self):
7882
MemoryFileUploadHandler()
7983
)
8084
self.parser_context['request'].META['HTTP_CONTENT_DISPOSITION'] = ''
81-
with self.assertRaises(ParseError):
85+
with pytest.raises(ParseError) as excinfo:
8286
parser.parse(self.stream, None, self.parser_context)
87+
assert str(excinfo.value) == 'Missing filename. Request should include a Content-Disposition header with a filename parameter.'
88+
89+
def test_parse_missing_filename_large_file(self):
90+
"""
91+
Parse raw file upload when filename is missing with TemporaryFileUploadHandler.
92+
"""
93+
parser = FileUploadParser()
94+
self.stream.seek(0)
95+
self.parser_context['request'].upload_handlers = (
96+
TemporaryFileUploadHandler(),
97+
)
98+
self.parser_context['request'].META['HTTP_CONTENT_DISPOSITION'] = ''
99+
with pytest.raises(ParseError) as excinfo:
100+
parser.parse(self.stream, None, self.parser_context)
101+
assert str(excinfo.value) == 'Missing filename. Request should include a Content-Disposition header with a filename parameter.'
83102

84103
def test_get_filename(self):
85104
parser = FileUploadParser()

0 commit comments

Comments
 (0)
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