Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagecell
Path: blob/master/timing/test_scripts/MultipartPostHandler.py
447 views
1
#!/usr/bin/python
2
3
####
4
# 02/2006 Will Holcomb <[email protected]>
5
#
6
# This library is free software; you can redistribute it and/or
7
# modify it under the terms of the GNU Lesser General Public
8
# License as published by the Free Software Foundation; either
9
# version 2.1 of the License, or (at your option) any later version.
10
#
11
# This library is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
# Lesser General Public License for more details.
15
#
16
# 7/2/10 refactored by Jason Grout--made two functions instead of a class
17
# 7/26/07 Slightly modified by Brian Schneider
18
# in order to support unicode files ( multipart_encode function )
19
# from http://peerit.blogspot.com/2007/07/multipartposthandler-doesnt-work-for.html
20
21
"""
22
Usage:
23
Enables the use of multipart/form-data for posting forms
24
25
Inspirations:
26
Upload files in python:
27
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/146306
28
urllib2_file:
29
Fabien Seisen: <[email protected]>
30
31
Example:
32
import MultipartPostHandler, urllib2, cookielib
33
34
cookies = cookielib.CookieJar()
35
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookies),
36
MultipartPostHandler.MultipartPostHandler)
37
params = { "username" : "bob", "password" : "riviera",
38
"file" : open("filename", "rb") }
39
opener.open("http://wwww.bobsite.com/upload/", params)
40
41
Further Example:
42
The main function of this file is a sample which downloads a page and
43
then uploads it to the W3C validator.
44
"""
45
46
import urllib
47
import urllib2
48
import mimetools, mimetypes
49
import os, stat
50
from cStringIO import StringIO
51
52
# Controls how sequences are uncoded. If true, elements may be given multiple values by
53
# assigning a sequence.
54
doseq = 1
55
56
57
def encode_request(request):
58
data = request.get_data()
59
if data is not None and type(data) != str:
60
v_files = []
61
v_vars = []
62
if isinstance(data, dict):
63
data=data.items()
64
try:
65
for(key, value) in data:
66
if type(value) == file:
67
v_files.append((key, value))
68
else:
69
v_vars.append((key, value))
70
except TypeError:
71
systype, value, traceback = sys.exc_info()
72
raise TypeError, "not a valid non-string sequence or mapping object", traceback
73
74
if len(v_files) == 0:
75
data = urllib.urlencode(v_vars, doseq)
76
else:
77
boundary, data = multipart_encode(v_vars, v_files)
78
79
contenttype = 'multipart/form-data; boundary=%s' % boundary
80
if(request.has_header('Content-Type')
81
and request.get_header('Content-Type').find('multipart/form-data') != 0):
82
print "Replacing %s with %s" % (request.get_header('content-type'), 'multipart/form-data')
83
request.add_unredirected_header('Content-Type', contenttype)
84
85
request.add_data(data)
86
87
return request
88
89
def multipart_encode(vars, files, boundary = None, buf = None):
90
if boundary is None:
91
boundary = mimetools.choose_boundary()
92
if buf is None:
93
buf = StringIO()
94
for(key, value) in vars:
95
buf.write('--%s\r\n' % boundary)
96
buf.write('Content-Disposition: form-data; name="%s"' % key)
97
buf.write('\r\n\r\n%s\r\n'%value)
98
for(key, fd) in files:
99
file_size = os.fstat(fd.fileno())[stat.ST_SIZE]
100
filename = fd.name.split('/')[-1]
101
contenttype = mimetypes.guess_type(filename)[0] or 'application/octet-stream'
102
buf.write('--%s\r\n' % boundary)
103
buf.write('Content-Disposition: form-data; name="%s"; filename="%s"\r\n' % (key, filename))
104
buf.write('Content-Type: %s\r\n' % contenttype)
105
# buffer += 'Content-Length: %s\r\n' % file_size
106
fd.seek(0)
107
buf.write('\r\n' + fd.read() + '\r\n')
108
buf.write('--' + boundary + '--\r\n\r\n')
109
buf = buf.getvalue()
110
return boundary, buf
111
112
113