mirror of
				https://github.com/encode/django-rest-framework.git
				synced 2025-10-31 07:57:55 +03:00 
			
		
		
		
	FileUploadParser. Raising StopFutureHandlers removes any handlers not yet run for the active set. Closes #2109.
This commit is contained in:
		
							parent
							
								
									e30e3f6dfc
								
							
						
					
					
						commit
						0359e9250d
					
				|  | @ -256,23 +256,24 @@ class FileUploadParser(BaseParser): | ||||||
|         chunks = ChunkIter(stream, chunk_size) |         chunks = ChunkIter(stream, chunk_size) | ||||||
|         counters = [0] * len(upload_handlers) |         counters = [0] * len(upload_handlers) | ||||||
| 
 | 
 | ||||||
|         for handler in upload_handlers: |         for index, handler in enumerate(upload_handlers): | ||||||
|             try: |             try: | ||||||
|                 handler.new_file(None, filename, content_type, |                 handler.new_file(None, filename, content_type, | ||||||
|                                  content_length, encoding) |                                  content_length, encoding) | ||||||
|             except StopFutureHandlers: |             except StopFutureHandlers: | ||||||
|  |                 upload_handlers = upload_handlers[:index + 1] | ||||||
|                 break |                 break | ||||||
| 
 | 
 | ||||||
|         for chunk in chunks: |         for chunk in chunks: | ||||||
|             for i, handler in enumerate(upload_handlers): |             for index, handler in enumerate(upload_handlers): | ||||||
|                 chunk_length = len(chunk) |                 chunk_length = len(chunk) | ||||||
|                 chunk = handler.receive_data_chunk(chunk, counters[i]) |                 chunk = handler.receive_data_chunk(chunk, counters[index]) | ||||||
|                 counters[i] += chunk_length |                 counters[index] += chunk_length | ||||||
|                 if chunk is None: |                 if chunk is None: | ||||||
|                     break |                     break | ||||||
| 
 | 
 | ||||||
|         for i, handler in enumerate(upload_handlers): |         for index, handler in enumerate(upload_handlers): | ||||||
|             file_obj = handler.file_complete(counters[i]) |             file_obj = handler.file_complete(counters[index]) | ||||||
|             if file_obj: |             if file_obj: | ||||||
|                 return DataAndFiles(None, {'file': file_obj}) |                 return DataAndFiles(None, {'file': file_obj}) | ||||||
|         raise ParseError("FileUpload parse error - " |         raise ParseError("FileUpload parse error - " | ||||||
|  |  | ||||||
|  | @ -1,12 +1,13 @@ | ||||||
| # -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||||
| 
 | 
 | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| from rest_framework.compat import StringIO |  | ||||||
| from django import forms | from django import forms | ||||||
| from django.core.files.uploadhandler import MemoryFileUploadHandler | from django.core.files.uploadhandler import MemoryFileUploadHandler | ||||||
| from django.test import TestCase | from django.test import TestCase | ||||||
| from django.utils import unittest | from django.utils import unittest | ||||||
| from rest_framework.compat import etree | from rest_framework.compat import etree | ||||||
|  | from rest_framework.compat import StringIO | ||||||
|  | from rest_framework.exceptions import ParseError | ||||||
| from rest_framework.parsers import FormParser, FileUploadParser | from rest_framework.parsers import FormParser, FileUploadParser | ||||||
| from rest_framework.parsers import XMLParser | from rest_framework.parsers import XMLParser | ||||||
| import datetime | import datetime | ||||||
|  | @ -104,13 +105,40 @@ class TestFileUploadParser(TestCase): | ||||||
|         self.parser_context = {'request': request, 'kwargs': {}} |         self.parser_context = {'request': request, 'kwargs': {}} | ||||||
| 
 | 
 | ||||||
|     def test_parse(self): |     def test_parse(self): | ||||||
|         """ Make sure the `QueryDict` works OK """ |         """ | ||||||
|  |         Parse raw file upload. | ||||||
|  |         """ | ||||||
|         parser = FileUploadParser() |         parser = FileUploadParser() | ||||||
|         self.stream.seek(0) |         self.stream.seek(0) | ||||||
|         data_and_files = parser.parse(self.stream, None, self.parser_context) |         data_and_files = parser.parse(self.stream, None, self.parser_context) | ||||||
|         file_obj = data_and_files.files['file'] |         file_obj = data_and_files.files['file'] | ||||||
|         self.assertEqual(file_obj._size, 14) |         self.assertEqual(file_obj._size, 14) | ||||||
| 
 | 
 | ||||||
|  |     def test_parse_missing_filename(self): | ||||||
|  |         """ | ||||||
|  |         Parse raw file upload when filename is missing. | ||||||
|  |         """ | ||||||
|  |         parser = FileUploadParser() | ||||||
|  |         self.stream.seek(0) | ||||||
|  |         self.parser_context['request'].META['HTTP_CONTENT_DISPOSITION'] = '' | ||||||
|  |         with self.assertRaises(ParseError): | ||||||
|  |             parser.parse(self.stream, None, self.parser_context) | ||||||
|  | 
 | ||||||
|  |     def test_parse_missing_filename_multiple_upload_handlers(self): | ||||||
|  |         """ | ||||||
|  |         Parse raw file upload with multiple handlers when filename is missing. | ||||||
|  |         Regression test for #2109. | ||||||
|  |         """ | ||||||
|  |         parser = FileUploadParser() | ||||||
|  |         self.stream.seek(0) | ||||||
|  |         self.parser_context['request'].upload_handlers = ( | ||||||
|  |             MemoryFileUploadHandler(), | ||||||
|  |             MemoryFileUploadHandler() | ||||||
|  |         ) | ||||||
|  |         self.parser_context['request'].META['HTTP_CONTENT_DISPOSITION'] = '' | ||||||
|  |         with self.assertRaises(ParseError): | ||||||
|  |             parser.parse(self.stream, None, self.parser_context) | ||||||
|  | 
 | ||||||
|     def test_get_filename(self): |     def test_get_filename(self): | ||||||
|         parser = FileUploadParser() |         parser = FileUploadParser() | ||||||
|         filename = parser.get_filename(self.stream, None, self.parser_context) |         filename = parser.get_filename(self.stream, None, self.parser_context) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user