Ticket #13721: content_type_extra.2.diff

File content_type_extra.2.diff, 9.3 KB (added by wkornewald, 4 years ago)

patch against trunk

  • django/core/files/uploadhandler.py

    diff -r 6f0361df1c82 django/core/files/uploadhandler.py
    a b  
    8484        """
    8585        pass
    8686
    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):
    8889        """
    8990        Signal that a new file has been started.
    9091
     
    9697        self.content_type = content_type
    9798        self.content_length = content_length
    9899        self.charset = charset
     100        if content_type_extra is None:
     101            content_type_extra = {}
     102        self.content_type_extra = content_type_extra
    99103
    100104    def receive_data_chunk(self, raw_data, start):
    101105        """
  • django/http/multipartparser.py

    diff -r 6f0361df1c82 django/http/multipartparser.py
    a b  
    171171                    file_name = self.IE_sanitize(unescape_entities(file_name))
    172172
    173173                    content_type = meta_data.get('content-type', ('',))[0].strip()
     174                    content_type_extra = meta_data.get('content-type', (0,{}))[1]
     175                    if content_type_extra is None:
     176                        content_type_extra = {}
    174177                    try:
    175                         charset = meta_data.get('content-type', (0,{}))[1].get('charset', None)
     178                        charset = content_type_extra.get('charset', None)
    176179                    except:
    177180                        charset = None
    178181
     
    187190                            try:
    188191                                handler.new_file(field_name, file_name,
    189192                                                 content_type, content_length,
    190                                                  charset)
     193                                                 charset, content_type_extra.copy())
    191194                            except StopFutureHandlers:
    192195                                break
    193196
  • django/test/client.py

    diff -r 6f0361df1c82 django/test/client.py
    a b  
    146146
    147147def encode_file(boundary, key, file):
    148148    to_str = lambda s: smart_str(s, settings.DEFAULT_CHARSET)
    149     content_type = mimetypes.guess_type(file.name)[0]
     149    if hasattr(file, 'content_type'):
     150        content_type = file.content_type
     151    else:
     152        content_type = mimetypes.guess_type(file.name)[0]
    150153    if content_type is None:
    151154        content_type = 'application/octet-stream'
    152155    return [
  • docs/topics/http/file-uploads.txt

    diff -r 6f0361df1c82 docs/topics/http/file-uploads.txt
    a b  
    200200    For ``text/*`` content-types, the character set (i.e. ``utf8``) supplied
    201201    by the browser. Again, "trust but verify" is the best policy here.
    202202
     203.. attribute:: UploadedFile.content_type_extra
     204
     205    A dict containing the extra parameters that were passed to the
     206    content-type header.
     207
    203208.. attribute:: UploadedFile.temporary_file_path()
    204209
    205210    Only files uploaded onto disk will have this method; it returns the full
     
    357362
    358363        The default is 64*2\ :sup:`10` bytes, or 64 KB.
    359364
    360     ``FileUploadHandler.new_file(self, field_name, file_name, content_type, content_length, charset)``
     365    ``FileUploadHandler.new_file(self, field_name, file_name, content_type, content_length, charset, content_type_extra)``
    361366        Callback signaling that a new file upload is starting. This is called
    362367        before any data has been fed to any upload handlers.
    363368
     
    374379        ``charset`` is the character set (i.e. ``utf8``) given by the browser.
    375380        Like ``content_length``, this sometimes won't be provided.
    376381
     382        ``content_type_extra`` is a dict containing the extra parameters that
     383        were passed to the content-type header.
     384
    377385        This method may raise a ``StopFutureHandlers`` exception to prevent
    378386        future handlers from handling this file.
    379387
  • tests/regressiontests/file_uploads/tests.py

    diff -r 6f0361df1c82 tests/regressiontests/file_uploads/tests.py
    a b  
    197197        got = simplejson.loads(response.content)
    198198        self.assertTrue('f' not in got)
    199199
     200    def test_extra_content_type(self):
     201        f = tempfile.NamedTemporaryFile()
     202        f.write('a' * (2 ** 21))
     203        f.seek(0)
     204        f.content_type = 'text/plain; blob-key=upload blob key; other=test'
     205
     206        response = self.client.post("/file_uploads/content_type_extra/", {'f': f})
     207        got = simplejson.loads(response.content)
     208        self.assertEqual(got['f'], 'upload blob key')
     209
    200210    def test_broken_custom_upload_handler(self):
    201211        f = tempfile.NamedTemporaryFile()
    202212        f.write('a' * (2 ** 21))
  • tests/regressiontests/file_uploads/uploadhandler.py

    diff -r 6f0361df1c82 tests/regressiontests/file_uploads/uploadhandler.py
    a b  
    22Upload handlers to test the upload API.
    33"""
    44
    5 from django.core.files.uploadhandler import FileUploadHandler, StopUpload
     5from django.core.files.uploadedfile import InMemoryUploadedFile
     6from django.core.files.uploadhandler import (FileUploadHandler, StopUpload,
     7    StopFutureHandlers)
     8from StringIO import StringIO
    69
    710class QuotaUploadHandler(FileUploadHandler):
    811    """
     
    3235    """A handler that raises an exception."""
    3336    def receive_data_chunk(self, raw_data, start):
    3437        raise CustomUploadError("Oops!")
     38
     39class ContentTypeExtraUploadHandler(FileUploadHandler):
     40    """
     41    File upload handler that handles content_type_extra
     42    """
     43
     44    def new_file(self, *args, **kwargs):
     45        super(ContentTypeExtraUploadHandler, self).new_file(*args, **kwargs)
     46        self.blobkey = self.content_type_extra.get('blob-key', '')
     47        self.file = StringIO()
     48        self.file.write(self.blobkey)
     49        self.active = self.blobkey is not None
     50        if self.active:
     51            raise StopFutureHandlers()
     52
     53    def receive_data_chunk(self, raw_data, start):
     54        """
     55        Add the data to the StringIO file.
     56        """
     57        if not self.active:
     58            return raw_data
     59
     60    def file_complete(self, file_size):
     61        if not self.active:
     62            return
     63
     64        self.file.seek(0)
     65        return InMemoryUploadedFile(
     66            file = self.file,
     67            field_name = self.field_name,
     68            name = self.file_name,
     69            content_type = self.content_type,
     70            size = file_size,
     71            charset = self.charset
     72        )
  • tests/regressiontests/file_uploads/urls.py

    diff -r 6f0361df1c82 tests/regressiontests/file_uploads/urls.py
    a b  
    22import views
    33
    44urlpatterns = patterns('',
    5     (r'^upload/$',          views.file_upload_view),
    6     (r'^verify/$',          views.file_upload_view_verify),
    7     (r'^unicode_name/$',    views.file_upload_unicode_name),
    8     (r'^echo/$',            views.file_upload_echo),
    9     (r'^echo_content/$',    views.file_upload_echo_content),
    10     (r'^quota/$',           views.file_upload_quota),
    11     (r'^quota/broken/$',    views.file_upload_quota_broken),
    12     (r'^getlist_count/$',   views.file_upload_getlist_count),
    13     (r'^upload_errors/$',   views.file_upload_errors),
     5    (r'^upload/$',              views.file_upload_view),
     6    (r'^verify/$',              views.file_upload_view_verify),
     7    (r'^unicode_name/$',        views.file_upload_unicode_name),
     8    (r'^echo/$',                views.file_upload_echo),
     9    (r'^echo_content/$',        views.file_upload_echo_content),
     10    (r'^quota/$',               views.file_upload_quota),
     11    (r'^quota/broken/$',        views.file_upload_quota_broken),
     12    (r'^getlist_count/$',       views.file_upload_getlist_count),
     13    (r'^upload_errors/$',       views.file_upload_errors),
     14    (r'^content_type_extra/$',  views.file_upload_content_type_extra),
    1415)
  • tests/regressiontests/file_uploads/views.py

    diff -r 6f0361df1c82 tests/regressiontests/file_uploads/views.py
    a b  
    44from django.http import HttpResponse, HttpResponseServerError
    55from django.utils import simplejson
    66from models import FileModel, UPLOAD_TO
    7 from uploadhandler import QuotaUploadHandler, ErroringUploadHandler
     7from uploadhandler import (QuotaUploadHandler, ErroringUploadHandler,
     8    ContentTypeExtraUploadHandler)
    89from tests import UNICODE_FILENAME
    910
    1011def file_upload_view(request):
     
    120121def file_upload_errors(request):
    121122    request.upload_handlers.insert(0, ErroringUploadHandler())
    122123    return file_upload_echo(request)
     124
     125def file_upload_content_type_extra(request):
     126    request.upload_handlers.insert(0, ContentTypeExtraUploadHandler())
     127    r = dict([(k, f.read()) for k, f in request.FILES.items()])
     128    return HttpResponse(simplejson.dumps(r))
Back to Top