Ticket #1484: 1484.trunk.5.diff
File 1484.trunk.5.diff, 6.5 KB (added by , 19 years ago) |
---|
-
django/utils/httpwrappers.py
2 2 from pprint import pformat 3 3 from urllib import urlencode 4 4 from django.utils.datastructures import MultiValueDict 5 import cgi 6 from StringIO import StringIO 5 7 6 8 try: 7 9 # The mod_python version is more efficient, so try importing it first. … … 32 34 def get_full_path(self): 33 35 return '' 34 36 35 def parse_file_upload(header_dict, post_data): 37 class FileDict(dict): 38 "Keeps uploaded file as a file-like object and reads its content on demand" 39 def __getitem__(self, name): 40 if name=='content' and not 'content' in self: 41 self['file'].seek(0, 2) 42 size = self['file'].tell() 43 self['file'].seek(0, 0) 44 self['content']=self['file'].read(size) 45 return dict.__getitem__(self, name) 46 47 def __deepcopy__(self, memo={}): 48 self['content'] # make sure file content is loaded 49 import copy 50 result = self.__class__() 51 memo[id(self)] = result 52 for key, value in dict.items(self): 53 dict.__setitem__(result, copy.deepcopy(key, memo), copy.deepcopy(value, memo)) 54 return result 55 56 class FieldStorage(cgi.FieldStorage): 57 "cgi.FieldStorage with ability to store files on disk or in memory" 58 def make_file(self, binary=None): 59 from django.conf.settings import STORE_UPLOAD_ON_DISK 60 if STORE_UPLOAD_ON_DISK: 61 return cgi.FieldStorage.make_file(self, binary) 62 else: 63 return StringIO() 64 65 def parse_file_upload(post_stream, environ): 36 66 "Returns a tuple of (POST MultiValueDict, FILES MultiValueDict)" 37 import email, email.Message 38 from cgi import parse_header 39 raw_message = '\r\n'.join(['%s:%s' % pair for pair in header_dict.items()]) 40 raw_message += '\r\n\r\n' + post_data 41 msg = email.message_from_string(raw_message) 67 fs = FieldStorage(post_stream, environ=environ) 42 68 POST = MultiValueDict() 43 69 FILES = MultiValueDict() 44 for submessage in msg.get_payload(): 45 if isinstance(submessage, email.Message.Message): 46 name_dict = parse_header(submessage['Content-Disposition'])[1] 47 # name_dict is something like {'name': 'file', 'filename': 'test.txt'} for file uploads 48 # or {'name': 'blah'} for POST fields 49 # We assume all uploaded files have a 'filename' set. 50 if name_dict.has_key('filename'): 51 assert type([]) != type(submessage.get_payload()), "Nested MIME messages are not supported" 52 if not name_dict['filename'].strip(): 70 for key in fs.keys(): 71 # We can't use FieldStorage.getlist to get contents of a 72 # field as a list because for file fields it returns only filenames 73 if type(fs[key]) == type([]): 74 field_list = fs[key] 75 else: 76 field_list = [fs[key]] 77 for field in field_list: 78 if hasattr(field, 'filename') and field.filename is not None: 79 if not field.filename.strip(): 53 80 continue 54 81 # IE submits the full path, so trim everything but the basename. 55 82 # (We can't use os.path.basename because it expects Linux paths.) 56 filename = name_dict['filename'][name_dict['filename'].rfind("\\")+1:]57 FILES.appendlist( name_dict['name'],{83 filename = field.filename[field.filename.rfind("\\") + 1:] 84 FILES.appendlist(key, FileDict({ 58 85 'filename': filename, 59 'content-type': (submessage.has_key('Content-Type') and submessage['Content-Type'] or None),60 ' content': submessage.get_payload(),61 }) 86 'content-type': field.type, 87 'file': field.file, 88 })) 62 89 else: 63 POST.appendlist( name_dict['name'], submessage.get_payload())90 POST.appendlist(key, field.value) 64 91 return POST, FILES 65 92 66 93 class QueryDict(MultiValueDict): -
django/conf/global_settings.py
202 202 # http://psyco.sourceforge.net/ 203 203 ENABLE_PSYCO = False 204 204 205 # Whether to store uploaded files in temp files rather than in memory. 206 # Storing files on disk may be necessary for accepting large files. 207 STORE_UPLOAD_ON_DISK = False 208 205 209 ############## 206 210 # MIDDLEWARE # 207 211 ############## -
django/core/handlers/wsgi.py
66 66 # Populates self._post and self._files 67 67 if self.environ['REQUEST_METHOD'] == 'POST': 68 68 if self.environ.get('CONTENT_TYPE', '').startswith('multipart'): 69 header_dict = dict([(k, v) for k, v in self.environ.items() if k.startswith('HTTP_')]) 70 header_dict['Content-Type'] = self.environ.get('CONTENT_TYPE', '') 71 self._post, self._files = httpwrappers.parse_file_upload(header_dict, self.raw_post_data) 69 self._post, self._files = httpwrappers.parse_file_upload(self.environ['wsgi.input'], self.environ) 72 70 else: 73 71 self._post, self._files = httpwrappers.QueryDict(self.raw_post_data), datastructures.MultiValueDict() 74 72 else: -
django/core/handlers/modpython.py
23 23 def _load_post_and_files(self): 24 24 "Populates self._post and self._files" 25 25 if self._req.headers_in.has_key('content-type') and self._req.headers_in['content-type'].startswith('multipart'): 26 self._post, self._files = httpwrappers.parse_file_upload(self._req.headers_in, self.raw_post_data) 26 environ = dict(self.META) 27 environ['CONTENT_LENGTH'] = environ['HTTP_CONTENT_LENGTH'] 28 environ['CONTENT_TYPE'] = environ['HTTP_CONTENT_TYPE'] 29 self._post, self._files = httpwrappers.parse_file_upload(self._req, environ) 27 30 else: 28 31 self._post, self._files = httpwrappers.QueryDict(self.raw_post_data), datastructures.MultiValueDict() 29 32