ia64/xen-unstable

view tools/python/xen/xend/encode.py @ 12725:36fe7ca48e54

Tidy up the creation of directories that Xend needs. This avoids potential
races in this creation.

Signed-off-by: Ewan Mellor <ewan@xensource.com>
author Ewan Mellor <ewan@xensource.com>
date Fri Dec 01 11:32:32 2006 +0000 (2006-12-01)
parents 06d84bf87159
children
line source
1 #============================================================================
2 # This library is free software; you can redistribute it and/or
3 # modify it under the terms of version 2.1 of the GNU Lesser General Public
4 # License as published by the Free Software Foundation.
5 #
6 # This library is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9 # Lesser General Public License for more details.
10 #
11 # You should have received a copy of the GNU Lesser General Public
12 # License along with this library; if not, write to the Free Software
13 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14 #============================================================================
15 # Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
16 #============================================================================
18 """Encoding for arguments to HTTP calls.
19 Uses the url-encoding with MIME type 'application/x-www-form-urlencoded'
20 if the data does not include files. Otherwise it uses the encoding with
21 MIME type 'multipart/form-data'. See the HTML4 spec for details.
23 """
24 import sys
25 import types
26 from StringIO import StringIO
28 import urllib
29 import random
30 import md5
32 # Extract from HTML4 spec.
33 ## The following example illustrates "multipart/form-data"
34 ## encoding. Suppose we have the following form:
36 ## <FORM action="http://server.com/cgi/handle"
37 ## enctype="multipart/form-data"
38 ## method="post">
39 ## <P>
40 ## What is your name? <INPUT type="text" name="submit-name"><BR>
41 ## What files are you sending? <INPUT type="file" name="files"><BR>
42 ## <INPUT type="submit" value="Send"> <INPUT type="reset">
43 ## </FORM>
45 ## If the user enters "Larry" in the text input, and selects the text
46 ## file "file1.txt", the user agent might send back the following data:
48 ## Content-Type: multipart/form-data; boundary=AaB03x
50 ## --AaB03x
51 ## Content-Disposition: form-data; name="submit-name"
53 ## Larry
54 ## --AaB03x
55 ## Content-Disposition: form-data; name="files"; filename="file1.txt"
56 ## Content-Type: text/plain
58 ## ... contents of file1.txt ...
59 ## --AaB03x--
61 ## If the user selected a second (image) file "file2.gif", the user agent
62 ## might construct the parts as follows:
64 ## Content-Type: multipart/form-data; boundary=AaB03x
66 ## --AaB03x
67 ## Content-Disposition: form-data; name="submit-name"
69 ## Larry
70 ## --AaB03x
71 ## Content-Disposition: form-data; name="files"
72 ## Content-Type: multipart/mixed; boundary=BbC04y
74 ## --BbC04y
75 ## Content-Disposition: file; filename="file1.txt"
76 ## Content-Type: text/plain
78 ## ... contents of file1.txt ...
79 ## --BbC04y
80 ## Content-Disposition: file; filename="file2.gif"
81 ## Content-Type: image/gif
82 ## Content-Transfer-Encoding: binary
84 ## ...contents of file2.gif...
85 ## --BbC04y--
86 ## --AaB03x--
88 __all__ = ['encode_data', 'encode_multipart', 'encode_form', 'mime_boundary' ]
90 def data_values(d):
91 if isinstance(d, types.DictType):
92 return d.items()
93 else:
94 return d
96 def encode_data(d):
97 """Encode some data for HTTP transport.
98 The encoding used is stored in 'Content-Type' in the headers.
100 d data - sequence of tuples or dictionary
101 returns a 2-tuple of the headers and the encoded data
102 """
103 val = ({}, None)
104 if d is None: return val
105 multipart = 0
106 for (_, v) in data_values(d):
107 if encode_isfile(v):
108 multipart = 1
109 break
110 if multipart:
111 val = encode_multipart(d)
112 else:
113 val = encode_form(d)
114 return val
116 def encode_isfile(v):
117 if isinstance(v, types.FileType):
118 return 1
119 if hasattr(v, 'readlines'):
120 return 1
121 return 0
123 def encode_multipart(d):
124 boundary = mime_boundary()
125 hdr = { 'Content-Type': 'multipart/form-data; boundary=' + boundary }
126 out = StringIO()
127 for (k,v) in data_values(d):
128 out.write('--')
129 out.write(boundary)
130 out.write('\r\n')
131 if encode_isfile(v):
132 out.write('Content-Disposition: form-data; name="')
133 out.write(k)
134 if hasattr(v, 'name'):
135 out.write('"; filename="')
136 out.write(v.name)
137 out.write('"\r\n')
138 out.write('Content-Type: application/octet-stream\r\n')
139 out.write('\r\n')
140 for l in v.readlines():
141 out.write(l)
142 else:
143 out.write('Content-Disposition: form-data; name="')
144 out.write(k)
145 out.write('"\r\n')
146 out.write('\r\n')
147 out.write(str(v))
148 out.write('\r\n')
149 out.write('--')
150 out.write(boundary)
151 out.write('--')
152 out.write('\r\n')
153 return (hdr, out.getvalue())
155 def mime_boundary():
156 random.seed()
157 m = md5.new()
158 for _ in range(0, 10):
159 c = chr(random.randint(1, 255))
160 m.update(c)
161 b = m.hexdigest()
162 return b[0:16]
164 def encode_form(d):
165 hdr = { 'Content-Type': 'application/x-www-form-urlencoded' }
166 val = urllib.urlencode(d)
167 return (hdr, val)
169 def main():
170 #d = {'a': 1, 'b': 'x y', 'c': file('conf.sxp') }
171 #d = {'a': 1, 'b': 'x y' }
172 d = [ ('a', 1), ('b', 'x y'), ('c', file('conf.sxp')) ]
173 #d = [ ('a', 1), ('b', 'x y')]
174 v = encode_data(d)
175 print v[0]
176 sys.stdout.write(v[1])
177 print
179 if __name__ == "__main__":
180 main()