import httplib #, mimetypes import sysinfo # Modified from # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/146306 def post_multipart(host, selector, fields, files): """ Post fields and files to an http host as multipart/form-data. fields is a sequence of (name, value) elements for regular form fields. files is a sequence of (name, filename, value) elements for data to be uploaded as files Return the server's response page. """ content_type, body = encode_multipart_formdata(fields, files) h = httplib.HTTPConnection(host) headers = { 'User-Agent': sysinfo.sw_version(), 'Content-Type': content_type } h.request('POST', selector, body, headers) res = h.getresponse() return res.status, res.reason, res.read() def encode_multipart_formdata(fields, files): """ fields is a sequence of (name, value) elements for regular form fields. files is a sequence of (name, filename, value) elements for data to be uploaded as files Return (content_type, body) ready for httplib.HTTP instance """ BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$' CRLF = '\r\n' L = [] # No need to URL encode as this is form text data. for (key, value) in fields: L.append('--' + BOUNDARY) L.append('Content-Disposition: form-data; name="%s"' % key) L.append('') L.append(value) for (key, filename, value) in files: L.append('--' + BOUNDARY) L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename)) L.append('Content-Type: %s' % get_content_type(filename)) L.append('') L.append(value) L.append('--' + BOUNDARY + '--') L.append('') # ''.join() won't work here (PyS60 doesn't like it), so we do it # with a virtual file. from cStringIO import StringIO file_str = StringIO() for i in range(len(L)): file_str.write(L[i]) file_str.write(CRLF) body = file_str.getvalue() content_type = 'multipart/form-data; boundary=%s' % BOUNDARY return content_type, body def get_content_type(filename): # we should guess the type, but since its not in our PyS60 # distribution, we will just say octet. # return mimetypes.guess_type(filename)[0] or 'application/octet-stream' return 'application/octet-stream'