mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-01-24 00:04:16 +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