Ticket #1484: 1484.m-r.diff

File 1484.m-r.diff, 5.8 KB (added by Maniac <Maniac@…>, 9 years ago)

Patch for magic-removal branch

  • django/http/__init__.py

     
    22from pprint import pformat
    33from urllib import urlencode
    44from django.utils.datastructures import MultiValueDict
     5import cgi
     6from StringIO import StringIO
    57
    68try:
    79    # The mod_python version is more efficient, so try importing it first.
     
    3537    def get_full_path(self):
    3638        return ''
    3739
    38 def parse_file_upload(header_dict, post_data):
     40class FileDict(dict):
     41    "Keeps uploaded file as file-like object and reads its content on demand"
     42    def __getitem__(self, name):
     43        if name=='content' and not 'content' in self:
     44            self['file'].seek(0, 2)
     45            size = self['file'].tell()
     46            self['file'].seek(0, 0)
     47            self['content']=self['file'].read(size)
     48        return dict.__getitem__(self, name)
     49
     50class FieldStorage(cgi.FieldStorage):
     51    "cgi.FieldStorage with ability to store files on disk or in memory"
     52    def make_file(self, binary=None):
     53        from django.conf.settings import STORE_UPLOAD_ON_DISK
     54        if STORE_UPLOAD_ON_DISK:
     55            return cgi.FieldStorage.make_file(self, binary)
     56        else:
     57            return StringIO()
     58
     59def parse_file_upload(post_stream, environ):
    3960    "Returns a tuple of (POST MultiValueDict, FILES MultiValueDict)"
    40     import email, email.Message
    41     from cgi import parse_header
    42     raw_message = '\r\n'.join(['%s:%s' % pair for pair in header_dict.items()])
    43     raw_message += '\r\n\r\n' + post_data
    44     msg = email.message_from_string(raw_message)
     61    fs = FieldStorage(post_stream, environ=environ)
    4562    POST = MultiValueDict()
    4663    FILES = MultiValueDict()
    47     for submessage in msg.get_payload():
    48         if isinstance(submessage, email.Message.Message):
    49             name_dict = parse_header(submessage['Content-Disposition'])[1]
    50             # name_dict is something like {'name': 'file', 'filename': 'test.txt'} for file uploads
    51             # or {'name': 'blah'} for POST fields
    52             # We assume all uploaded files have a 'filename' set.
    53             if name_dict.has_key('filename'):
    54                 assert type([]) != type(submessage.get_payload()), "Nested MIME messages are not supported"
    55                 if not name_dict['filename'].strip():
     64    for key in fs.keys():
     65        for value in fs.getlist(key):
     66            if hasattr(fs[key], 'filename'):
     67                if not fs[key].filename.strip():
    5668                    continue
    5769                # IE submits the full path, so trim everything but the basename.
    5870                # (We can't use os.path.basename because it expects Linux paths.)
    59                 filename = name_dict['filename'][name_dict['filename'].rfind("\\")+1:]
    60                 FILES.appendlist(name_dict['name'], {
     71                filename = fs[key].filename[fs[key].filename.rfind("\\")+1:]
     72                FILES.appendlist(fs[key].name, FileDict({
    6173                    'filename': filename,
    62                     'content-type': (submessage.has_key('Content-Type') and submessage['Content-Type'] or None),
    63                     'content': submessage.get_payload(),
    64                 })
     74                    'content-type': fs[key].type,
     75                    'file': fs[key].file,
     76                }))
    6577            else:
    66                 POST.appendlist(name_dict['name'], submessage.get_payload())
     78                POST.appendlist(fs[key].name, value)
    6779    return POST, FILES
    6880
    6981class QueryDict(MultiValueDict):
  • django/conf/global_settings.py

     
    198198# Hint: you really don't!
    199199TRANSACTIONS_MANAGED = False
    200200
     201# Whether to store uploaded files in temp files rather than in memory.
     202# Storing files on disk may be necessary for accepting large files.
     203STORE_UPLOAD_ON_DISK = False
     204
    201205##############
    202206# MIDDLEWARE #
    203207##############
  • django/core/handlers/wsgi.py

     
    6969        # Populates self._post and self._files
    7070        if self.environ['REQUEST_METHOD'] == 'POST':
    7171            if self.environ.get('CONTENT_TYPE', '').startswith('multipart'):
    72                 header_dict = dict([(k, v) for k, v in self.environ.items() if k.startswith('HTTP_')])
    73                 header_dict['Content-Type'] = self.environ.get('CONTENT_TYPE', '')
    74                 self._post, self._files = http.parse_file_upload(header_dict, self.raw_post_data)
     72                self._post, self._files = http.parse_file_upload(self.environ['wsgi.input'], self.environ)
    7573            else:
    7674                self._post, self._files = http.QueryDict(self.raw_post_data), datastructures.MultiValueDict()
    7775        else:
  • django/core/handlers/modpython.py

     
    2626    def _load_post_and_files(self):
    2727        "Populates self._post and self._files"
    2828        if self._req.headers_in.has_key('content-type') and self._req.headers_in['content-type'].startswith('multipart'):
    29             self._post, self._files = http.parse_file_upload(self._req.headers_in, self.raw_post_data)
     29            environ = dict(self.META)
     30            environ['CONTENT_LENGTH'] = environ['HTTP_CONTENT_LENGTH']
     31            environ['CONTENT_TYPE'] = environ['HTTP_CONTENT_TYPE']
     32            self._post, self._files = http.parse_file_upload(self._req, environ)
    3033        else:
    3134            self._post, self._files = http.QueryDict(self.raw_post_data), datastructures.MultiValueDict()
    3235
Back to Top