diff options
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) |
commit | ce5fe83878c56ac17007e88148714ee523e64c94 (patch) | |
tree | d93797d6393b3836dc31f40a21f568889eb58de0 /Lib/packaging/util.py | |
parent | f8bebf8566bc31e4fe90c5c5f10bfa72f3b90c91 (diff) | |
download | cpython-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.py | 47 |
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 |