mirror of
				https://github.com/encode/django-rest-framework.git
				synced 2025-11-04 09:57:55 +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