def parse_file_upload(header_dict, post_data): "Returns a tuple of (POST URLQuery, FILES URLQuery)" raw_message = '\r\n'.join(['%s:%s' % pair for pair in header_dict.items()]) raw_message += '\r\n\r\n' + post_data msg = email.message_from_string(raw_message) POST = urlparse.URLQuery() FILES = urlparse.URLQuery() for submessage in msg.get_payload(): if isinstance(submessage, email.Message.Message): cd = httputils.get_header(submessage['Content-Disposition']) if cd.parameters.has_key('filename'): assert type(submessage.get_payload()) is not list, \ "Nested MIME messages are not supported" if not cd.parameters['filename'].strip(): continue # IE submits the full path, so trim everything but the basename. # (We can't use os.path.basename because it expects Linux paths.) filename = cd.parameters['filename'][cd.parameters['filename']. rfind("\\") + 1:] FILES.appendlist( cd.parameters['name'], { 'filename': filename, 'content-type': (submessage.has_key('Content-Type') and submessage['Content-Type'] or None), 'content': submessage.get_payload(), }) else: POST.appendlist(cd.parameters['name'], submessage.get_payload()) return POST, FILES
def parse_formdata(contenttype, post_data): post = urlparse.URLQuery() files = urlparse.URLQuery() boundary = b"--" + contenttype.parameters[b"boundary"] for part in post_data.split(boundary): if not part: continue if part.startswith(b"--"): continue headers, body = httputils.get_headers_and_body(part) cd = headers[0] if "filename" in cd.parameters: files[cd.parameters['name']] = body else: post[cd.parameters['name']] = body.strip() return post, files
def _load_post_and_files(self): # Populates self._post and self._files if self.method == 'POST': if self.environ.get('CONTENT_TYPE', '').startswith('multipart'): header_dict = dict([(k, v) for k, v in self.environ.items() if k.startswith('HTTP_')]) header_dict['Content-Type'] = self.environ.get( 'CONTENT_TYPE', '') self._post, self._files = parse_file_upload( header_dict, self.raw_post_data) else: self._post = urlparse.queryparse(self.raw_post_data) self._files = urlparse.URLQuery() else: self._post = urlparse.URLQuery() self._post = urlparse.URLQuery()
def _parse_post_content(self): if self.method == b'POST': content_type = httputils.ContentType( self.environ.get(b'CONTENT_TYPE', '')) ctvalue = content_type.value.lower() if ctvalue == b'multipart/form-data': self._post, self._files = parse_formdata( content_type, self._get_raw_post_data()) elif ctvalue == b"application/x-www-form-urlencoded": self._post = urlparse.queryparse(self._get_raw_post_data()) self._files = None else: # some buggy clients don't set proper content-type, so # just preserve the raw data as a file. self.log_error("Bad content-type: {!s}".format(content_type)) data = self._get_raw_post_data() self._post = urlparse.queryparse(data) self._files = {} self._files["body"] = { b'content-type': content_type, b'content': data, } else: self._post = urlparse.URLQuery() self._files = None