summaryrefslogtreecommitdiffstats
path: root/Lib/packaging/util.py
diff options
context:
space:
mode:
authorÉric Araujo <merwok@netwok.org>2011-07-08 14:27:12 (GMT)
committerÉric Araujo <merwok@netwok.org>2011-07-08 14:27:12 (GMT)
commitce5fe83878c56ac17007e88148714ee523e64c94 (patch)
treed93797d6393b3836dc31f40a21f568889eb58de0 /Lib/packaging/util.py
parentf8bebf8566bc31e4fe90c5c5f10bfa72f3b90c91 (diff)
downloadcpython-ce5fe83878c56ac17007e88148714ee523e64c94.zip
cpython-ce5fe83878c56ac17007e88148714ee523e64c94.tar.gz
cpython-ce5fe83878c56ac17007e88148714ee523e64c94.tar.bz2
Factor out code used by packaging commands for HTTP requests (#12169).
We now have one function to prepare multipart POST requests, and we use CRLF, as recommended by the HTTP spec (#10150). Initial patch by John Edmonds.
Diffstat (limited to 'Lib/packaging/util.py')
-rw-r--r--Lib/packaging/util.py47
1 files changed, 47 insertions, 0 deletions
diff --git a/Lib/packaging/util.py b/Lib/packaging/util.py
index 76db89a..5637e80 100644
--- a/Lib/packaging/util.py
+++ b/Lib/packaging/util.py
@@ -1487,3 +1487,50 @@ def _mkpath(name, mode=0o777, verbose=True, dry_run=False):
_path_created.add(abs_head)
return created_dirs
+
+
+def encode_multipart(fields, files, boundary=None):
+ """Prepare a multipart HTTP request.
+
+ *fields* is a sequence of (name: str, value: str) elements for regular
+ form fields, *files* is a sequence of (name: str, filename: str, value:
+ bytes) elements for data to be uploaded as files.
+
+ Returns (content_type: bytes, body: bytes) ready for http.client.HTTP.
+ """
+ # Taken from
+ # http://code.activestate.com/recipes/146306-http-client-to-post-using-multipartform-data/
+
+ if boundary is None:
+ boundary = b'--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'
+ elif not isinstance(boundary, bytes):
+ raise TypeError('boundary must be bytes, not %r' % type(boundary))
+
+ l = []
+ for key, values in fields:
+ # handle multiple entries for the same name
+ if not isinstance(values, (tuple, list)):
+ values=[values]
+
+ for value in values:
+ l.extend((
+ b'--' + boundary,
+ ('Content-Disposition: form-data; name="%s"' %
+ key).encode('utf-8'),
+ b'',
+ value.encode('utf-8')))
+
+ for key, filename, value in files:
+ l.extend((
+ b'--' + boundary,
+ ('Content-Disposition: form-data; name="%s"; filename="%s"' %
+ (key, filename)).encode('utf-8'),
+ b'',
+ value))
+
+ l.append(b'--' + boundary + b'--')
+ l.append(b'')
+
+ body = b'\r\n'.join(l)
+ content_type = b'multipart/form-data; boundary=' + boundary
+ return content_type, body