Commit b0953dc9 authored by Benjamin Kagia's avatar Benjamin Kagia Committed by Tim Graham
Browse files

Fixed #13721 -- Added UploadedFile.content_type_extra.

Thanks Waldemar Kornewald and mvschaik for work on the patch.
parent ecd74619
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -23,11 +23,12 @@ class UploadedFile(File):
    """
    DEFAULT_CHUNK_SIZE = 64 * 2**10

    def __init__(self, file=None, name=None, content_type=None, size=None, charset=None):
    def __init__(self, file=None, name=None, content_type=None, size=None, charset=None, content_type_extra=None):
        super(UploadedFile, self).__init__(file, name)
        self.size = size
        self.content_type = content_type
        self.charset = charset
        self.content_type_extra = content_type_extra

    def __repr__(self):
        return force_str("<%s: %s (%s)>" % (
@@ -55,13 +56,13 @@ class TemporaryUploadedFile(UploadedFile):
    """
    A file uploaded to a temporary location (i.e. stream-to-disk).
    """
    def __init__(self, name, content_type, size, charset):
    def __init__(self, name, content_type, size, charset, content_type_extra):
        if settings.FILE_UPLOAD_TEMP_DIR:
            file = tempfile.NamedTemporaryFile(suffix='.upload',
                dir=settings.FILE_UPLOAD_TEMP_DIR)
        else:
            file = tempfile.NamedTemporaryFile(suffix='.upload')
        super(TemporaryUploadedFile, self).__init__(file, name, content_type, size, charset)
        super(TemporaryUploadedFile, self).__init__(file, name, content_type, size, charset, content_type_extra)

    def temporary_file_path(self):
        """
@@ -83,8 +84,8 @@ class InMemoryUploadedFile(UploadedFile):
    """
    A file uploaded into memory (i.e. stream-to-memory).
    """
    def __init__(self, file, field_name, name, content_type, size, charset):
        super(InMemoryUploadedFile, self).__init__(file, name, content_type, size, charset)
    def __init__(self, file, field_name, name, content_type, size, charset, content_type_extra):
        super(InMemoryUploadedFile, self).__init__(file, name, content_type, size, charset, content_type_extra)
        self.field_name = field_name

    def open(self, mode=None):
@@ -109,7 +110,7 @@ class SimpleUploadedFile(InMemoryUploadedFile):
    def __init__(self, name, content, content_type='text/plain'):
        content = content or b''
        super(SimpleUploadedFile, self).__init__(BytesIO(content), None, name,
                                                 content_type, len(content), None)
                                                 content_type, len(content), None, None)

    def from_dict(cls, file_dict):
        """
+6 −3
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ class FileUploadHandler(object):
        self.content_type = None
        self.content_length = None
        self.charset = None
        self.content_type_extra = None
        self.request = request

    def handle_raw_input(self, input_data, META, content_length, boundary, encoding=None):
@@ -84,7 +85,7 @@ class FileUploadHandler(object):
        """
        pass

    def new_file(self, field_name, file_name, content_type, content_length, charset=None):
    def new_file(self, field_name, file_name, content_type, content_length, charset=None, content_type_extra=None):
        """
        Signal that a new file has been started.

@@ -96,6 +97,7 @@ class FileUploadHandler(object):
        self.content_type = content_type
        self.content_length = content_length
        self.charset = charset
        self.content_type_extra = content_type_extra

    def receive_data_chunk(self, raw_data, start):
        """
@@ -132,7 +134,7 @@ class TemporaryFileUploadHandler(FileUploadHandler):
        Create the file object to append to as data is coming in.
        """
        super(TemporaryFileUploadHandler, self).new_file(file_name, *args, **kwargs)
        self.file = TemporaryUploadedFile(self.file_name, self.content_type, 0, self.charset)
        self.file = TemporaryUploadedFile(self.file_name, self.content_type, 0, self.charset, self.content_type_extra)

    def receive_data_chunk(self, raw_data, start):
        self.file.write(raw_data)
@@ -187,7 +189,8 @@ class MemoryFileUploadHandler(FileUploadHandler):
            name = self.file_name,
            content_type = self.content_type,
            size = file_size,
            charset = self.charset
            charset = self.charset,
            content_type_extra = self.content_type_extra
        )


+5 −7
Original line number Diff line number Diff line
@@ -177,11 +177,9 @@ class MultiPartParser(object):
                    file_name = force_text(file_name, encoding, errors='replace')
                    file_name = self.IE_sanitize(unescape_entities(file_name))

                    content_type = meta_data.get('content-type', ('',))[0].strip()
                    try:
                        charset = meta_data.get('content-type', (0, {}))[1].get('charset', None)
                    except:
                        charset = None
                    content_type, content_type_extra = meta_data.get('content-type', ('', {}))
                    content_type = content_type.strip()
                    charset = content_type_extra.get('charset')

                    try:
                        content_length = int(meta_data.get('content-length')[0])
@@ -194,7 +192,7 @@ class MultiPartParser(object):
                            try:
                                handler.new_file(field_name, file_name,
                                                 content_type, content_length,
                                                 charset)
                                                 charset, content_type_extra)
                            except StopFutureHandlers:
                                break

+5 −1
Original line number Diff line number Diff line
@@ -180,7 +180,11 @@ def encode_multipart(boundary, data):

def encode_file(boundary, key, file):
    to_bytes = lambda s: force_bytes(s, settings.DEFAULT_CHARSET)
    if hasattr(file, 'content_type'):
        content_type = file.content_type
    else:
        content_type = mimetypes.guess_type(file.name)[0]

    if content_type is None:
        content_type = 'application/octet-stream'
    return [
+16 −0
Original line number Diff line number Diff line
@@ -30,6 +30,14 @@ In addition, the widgets now display a help message when the browser and
server time zone are different, to clarify how the value inserted in the field
will be interpreted.

Minor features
~~~~~~~~~~~~~~

* The new :attr:`UploadedFile.content_type_extra
  <django.core.files.uploadedfile.UploadedFile.content_type_extra>` attribute
  contains extra parameters passed to the ``content-type`` header on a file
  upload.

Backwards incompatible changes in 1.7
=====================================

@@ -41,6 +49,14 @@ Backwards incompatible changes in 1.7
    deprecation timeline for a given feature, its removal may appear as a
    backwards incompatible change.

Miscellaneous
~~~~~~~~~~~~~

* The :meth:`django.core.files.uploadhandler.FileUploadHandler.new_file()`
  method is now passed an additional ``content_type_extra`` parameter. If you
  have a custom :class:`~django.core.files.uploadhandler.FileUploadHandler`
  that implements ``new_file()``, be sure it accepts this new parameter.

Features deprecated in 1.7
==========================

Loading