Ticket #13721: content_type_extra.3.diff
File content_type_extra.3.diff, 9.9 KB (added by , 12 years ago) |
---|
-
django/core/files/uploadhandler.py
diff --git a/django/core/files/uploadhandler.py b/django/core/files/uploadhandler.py index f5e95cf..7f8fcf6 100644
a b class FileUploadHandler(object): 84 84 """ 85 85 pass 86 86 87 def new_file(self, field_name, file_name, content_type, content_length, charset=None): 87 def new_file(self, field_name, file_name, content_type, content_length, 88 charset=None, content_type_extra=None): 88 89 """ 89 90 Signal that a new file has been started. 90 91 … … class FileUploadHandler(object): 96 97 self.content_type = content_type 97 98 self.content_length = content_length 98 99 self.charset = charset 100 if content_type_extra is None: 101 content_type_extra = {} 102 self.content_type_extra = content_type_extra 99 103 100 104 def receive_data_chunk(self, raw_data, start): 101 105 """ -
django/http/multipartparser.py
diff --git a/django/http/multipartparser.py b/django/http/multipartparser.py index 070874f..2199c8e 100644
a b class MultiPartParser(object): 176 176 file_name = self.IE_sanitize(unescape_entities(file_name)) 177 177 178 178 content_type = meta_data.get('content-type', ('',))[0].strip() 179 content_type_extra = meta_data.get('content-type', (0, {}))[1] 180 if content_type_extra is None: 181 content_type_extra = {} 179 182 try: 180 charset = meta_data.get('content-type', (0, {}))[1].get('charset', None)183 charset = content_type_extra.get('charset', None) 181 184 except: 182 185 charset = None 183 186 … … class MultiPartParser(object): 192 195 try: 193 196 handler.new_file(field_name, file_name, 194 197 content_type, content_length, 195 charset )198 charset, content_type_extra.copy()) 196 199 except StopFutureHandlers: 197 200 break 198 201 -
django/test/client.py
diff --git a/django/test/client.py b/django/test/client.py index 2506437..f432abc 100644
a b def encode_multipart(boundary, data): 178 178 179 179 def encode_file(boundary, key, file): 180 180 to_bytes = lambda s: force_bytes(s, settings.DEFAULT_CHARSET) 181 content_type = mimetypes.guess_type(file.name)[0] 181 if hasattr(file, 'content_type'): 182 content_type = file.content_type 183 else: 184 content_type = mimetypes.guess_type(file.name)[0] 182 185 if content_type is None: 183 186 content_type = 'application/octet-stream' 184 187 return [ -
docs/topics/http/file-uploads.txt
diff --git a/docs/topics/http/file-uploads.txt b/docs/topics/http/file-uploads.txt index 80bd5f3..142031c 100644
a b In addition to those inherited from :class:`~django.core.files.File`, all 243 243 For :mimetype:`text/*` content-types, the character set (i.e. ``utf8``) 244 244 supplied by the browser. Again, "trust but verify" is the best policy here. 245 245 246 .. attribute:: UploadedFile.content_type_extra 247 248 A dict containing the extra parameters that were passed to the 249 content-type header. 250 246 251 .. attribute:: UploadedFile.temporary_file_path() 247 252 248 253 Only files uploaded onto disk will have this method; it returns the full … … attributes: 402 407 403 408 The default is 64*2\ :sup:`10` bytes, or 64 KB. 404 409 405 ``FileUploadHandler.new_file(self, field_name, file_name, content_type, content_length, charset )``410 ``FileUploadHandler.new_file(self, field_name, file_name, content_type, content_length, charset, content_type_extra)`` 406 411 Callback signaling that a new file upload is starting. This is called 407 412 before any data has been fed to any upload handlers. 408 413 … … attributes: 419 424 ``charset`` is the character set (i.e. ``utf8``) given by the browser. 420 425 Like ``content_length``, this sometimes won't be provided. 421 426 427 ``content_type_extra`` is a dict containing the extra parameters that 428 were passed to the content-type header. 429 422 430 This method may raise a ``StopFutureHandlers`` exception to prevent 423 431 future handlers from handling this file. 424 432 -
tests/regressiontests/file_uploads/tests.py
diff --git a/tests/regressiontests/file_uploads/tests.py b/tests/regressiontests/file_uploads/tests.py index 45e7342..2f5f363 100644
a b class FileUploadTests(TestCase): 249 249 got = json.loads(response.content.decode('utf-8')) 250 250 self.assertTrue('f' not in got) 251 251 252 def test_extra_content_type(self): 253 f = tempfile.NamedTemporaryFile() 254 f.write('a' * (2 ** 21)) 255 f.seek(0) 256 f.content_type = 'text/plain; blob-key=upload blob key; other=test' 257 258 response = self.client.post("/file_uploads/content_type_extra/", {'f': f}) 259 got = json.loads(response.content) 260 self.assertEqual(got['f'], 'upload blob key') 261 252 262 def test_broken_custom_upload_handler(self): 253 263 f = tempfile.NamedTemporaryFile() 254 264 f.write(b'a' * (2 ** 21)) -
tests/regressiontests/file_uploads/uploadhandler.py
diff --git a/tests/regressiontests/file_uploads/uploadhandler.py b/tests/regressiontests/file_uploads/uploadhandler.py index b30ef13..a079aff 100644
a b 2 2 Upload handlers to test the upload API. 3 3 """ 4 4 5 from django.core.files.uploadhandler import FileUploadHandler, StopUpload 5 from django.core.files.uploadedfile import InMemoryUploadedFile 6 from django.core.files.uploadhandler import (FileUploadHandler, StopUpload, 7 StopFutureHandlers) 8 from StringIO import StringIO 6 9 7 10 8 11 class QuotaUploadHandler(FileUploadHandler): … … class ErroringUploadHandler(FileUploadHandler): 33 36 """A handler that raises an exception.""" 34 37 def receive_data_chunk(self, raw_data, start): 35 38 raise CustomUploadError("Oops!") 39 40 class ContentTypeExtraUploadHandler(FileUploadHandler): 41 """ 42 File upload handler that handles content_type_extra 43 """ 44 45 def new_file(self, *args, **kwargs): 46 super(ContentTypeExtraUploadHandler, self).new_file(*args, **kwargs) 47 self.blobkey = self.content_type_extra.get('blob-key', '') 48 self.file = StringIO() 49 self.file.write(self.blobkey) 50 self.active = self.blobkey is not None 51 if self.active: 52 raise StopFutureHandlers() 53 54 def receive_data_chunk(self, raw_data, start): 55 """ 56 Add the data to the StringIO file. 57 """ 58 if not self.active: 59 return raw_data 60 61 def file_complete(self, file_size): 62 if not self.active: 63 return 64 65 self.file.seek(0) 66 return InMemoryUploadedFile( 67 file = self.file, 68 field_name = self.field_name, 69 name = self.file_name, 70 content_type = self.content_type, 71 size = file_size, 72 charset = self.charset 73 ) -
tests/regressiontests/file_uploads/urls.py
diff --git a/tests/regressiontests/file_uploads/urls.py b/tests/regressiontests/file_uploads/urls.py index fc55768..405c727 100644
a b from . import views 6 6 7 7 8 8 urlpatterns = patterns('', 9 (r'^upload/$', views.file_upload_view), 10 (r'^verify/$', views.file_upload_view_verify), 11 (r'^unicode_name/$', views.file_upload_unicode_name), 12 (r'^echo/$', views.file_upload_echo), 13 (r'^echo_content/$', views.file_upload_echo_content), 14 (r'^quota/$', views.file_upload_quota), 15 (r'^quota/broken/$', views.file_upload_quota_broken), 16 (r'^getlist_count/$', views.file_upload_getlist_count), 17 (r'^upload_errors/$', views.file_upload_errors), 18 (r'^filename_case/$', views.file_upload_filename_case_view), 9 (r'^upload/$', views.file_upload_view), 10 (r'^verify/$', views.file_upload_view_verify), 11 (r'^unicode_name/$', views.file_upload_unicode_name), 12 (r'^echo/$', views.file_upload_echo), 13 (r'^echo_content/$', views.file_upload_echo_content), 14 (r'^quota/$', views.file_upload_quota), 15 (r'^quota/broken/$', views.file_upload_quota_broken), 16 (r'^getlist_count/$', views.file_upload_getlist_count), 17 (r'^upload_errors/$', views.file_upload_errors), 18 (r'^content_type_extra/$', views.file_upload_content_type_extra), 19 (r'^filename_case/$', views.file_upload_filename_case_view), 19 20 ) -
tests/regressiontests/file_uploads/views.py
diff --git a/tests/regressiontests/file_uploads/views.py b/tests/regressiontests/file_uploads/views.py index eb7b654..8275365 100644
a b from django.utils.encoding import force_bytes 11 11 12 12 from .models import FileModel 13 13 from .tests import UNICODE_FILENAME, UPLOAD_TO 14 from .uploadhandler import QuotaUploadHandler, ErroringUploadHandler 14 from .uploadhandler import (QuotaUploadHandler, ErroringUploadHandler, 15 ContentTypeExtraUploadHandler) 15 16 16 17 17 18 def file_upload_view(request): … … def file_upload_getlist_count(request): 124 125 file_counts[key] = len(request.FILES.getlist(key)) 125 126 return HttpResponse(json.dumps(file_counts)) 126 127 128 def file_upload_content_type_extra(request): 129 request.upload_handlers.insert(0, ContentTypeExtraUploadHandler()) 130 r = dict([(k, f.read()) for k, f in request.FILES.items()]) 131 return HttpResponse(json.dumps(r)) 132 127 133 def file_upload_errors(request): 128 134 request.upload_handlers.insert(0, ErroringUploadHandler()) 129 135 return file_upload_echo(request)