This commit is contained in:
Vladislav Vlastovskiy 2014-08-19 02:31:45 +00:00
commit e93a1d1f56
2 changed files with 35 additions and 2 deletions

View File

@ -10,7 +10,7 @@ from django.core.files.uploadhandler import StopFutureHandlers
from django.http import QueryDict
from django.http.multipartparser import MultiPartParser as DjangoMultiPartParser
from django.http.multipartparser import MultiPartParserError, parse_header, ChunkIter
from rest_framework.compat import etree, six, yaml, force_text
from rest_framework.compat import etree, six, yaml, force_text, urlparse
from rest_framework.exceptions import ParseError
from rest_framework import renderers
import json
@ -289,6 +289,17 @@ class FileUploadParser(BaseParser):
try:
meta = parser_context['request'].META
disposition = parse_header(meta['HTTP_CONTENT_DISPOSITION'].encode('utf-8'))
return force_text(disposition[1]['filename'])
if 'filename*' in disposition[1]:
filename_encoded = force_text(disposition[1]['filename*'])
try:
charset, filename_encoded = filename_encoded.split('\'\'', 1)
filename = urlparse.unquote(filename_encoded)
except (ValueError, LookupError):
filename = force_text(disposition[1]['filename'])
else:
filename = force_text(disposition[1]['filename'])
return filename
except (AttributeError, KeyError):
pass

View File

@ -1,3 +1,5 @@
#-*- coding: utf-8 -*-
from __future__ import unicode_literals
from rest_framework.compat import StringIO
from django import forms
@ -113,3 +115,23 @@ class TestFileUploadParser(TestCase):
parser = FileUploadParser()
filename = parser.get_filename(self.stream, None, self.parser_context)
self.assertEqual(filename, 'file.txt')
def test_get_encoded_filename(self):
parser = FileUploadParser()
self.__replace_content_disposition('inline; filename*=utf-8\'\'ÀĥƦ.txt')
filename = parser.get_filename(self.stream, None, self.parser_context)
self.assertEqual(filename, 'ÀĥƦ.txt')
self.__replace_content_disposition('inline; filename=fallback.txt; filename*=utf-8\'\'ÀĥƦ.txt')
filename = parser.get_filename(self.stream, None, self.parser_context)
self.assertEqual(filename, 'ÀĥƦ.txt')
self.__replace_content_disposition('inline; filename=fallback.txt; filename*=utf-8--ÀĥƦ.txt')
filename = parser.get_filename(self.stream, None, self.parser_context)
self.assertEqual(filename, 'fallback.txt')
def __replace_content_disposition(self, disposition):
self.parser_context['request'].META['HTTP_CONTENT_DISPOSITION'] = disposition