| # urllib3/filepost.py |
| # Copyright 2008-2013 Andrey Petrov and contributors (see CONTRIBUTORS.txt) |
| # |
| # This module is part of urllib3 and is released under |
| # the MIT License: http://www.opensource.org/licenses/mit-license.php |
| |
| import codecs |
| import mimetypes |
| |
| from uuid import uuid4 |
| from io import BytesIO |
| |
| from .packages import six |
| from .packages.six import b |
| from .fields import RequestField |
| |
| writer = codecs.lookup('utf-8')[3] |
| |
| |
| def choose_boundary(): |
| """ |
| Our embarassingly-simple replacement for mimetools.choose_boundary. |
| """ |
| return uuid4().hex |
| |
| |
| def iter_field_objects(fields): |
| """ |
| Iterate over fields. |
| |
| Supports list of (k, v) tuples and dicts, and lists of |
| :class:`~urllib3.fields.RequestField`. |
| |
| """ |
| if isinstance(fields, dict): |
| i = six.iteritems(fields) |
| else: |
| i = iter(fields) |
| |
| for field in i: |
| if isinstance(field, RequestField): |
| yield field |
| else: |
| yield RequestField.from_tuples(*field) |
| |
| |
| def iter_fields(fields): |
| """ |
| .. deprecated:: 1.6 |
| |
| Iterate over fields. |
| |
| The addition of :class:`~urllib3.fields.RequestField` makes this function |
| obsolete. Instead, use :func:`iter_field_objects`, which returns |
| :class:`~urllib3.fields.RequestField` objects. |
| |
| Supports list of (k, v) tuples and dicts. |
| """ |
| if isinstance(fields, dict): |
| return ((k, v) for k, v in six.iteritems(fields)) |
| |
| return ((k, v) for k, v in fields) |
| |
| |
| def encode_multipart_formdata(fields, boundary=None): |
| """ |
| Encode a dictionary of ``fields`` using the multipart/form-data MIME format. |
| |
| :param fields: |
| Dictionary of fields or list of (key, :class:`~urllib3.fields.RequestField`). |
| |
| :param boundary: |
| If not specified, then a random boundary will be generated using |
| :func:`mimetools.choose_boundary`. |
| """ |
| body = BytesIO() |
| if boundary is None: |
| boundary = choose_boundary() |
| |
| for field in iter_field_objects(fields): |
| body.write(b('--%s\r\n' % (boundary))) |
| |
| writer(body).write(field.render_headers()) |
| data = field.data |
| |
| if isinstance(data, int): |
| data = str(data) # Backwards compatibility |
| |
| if isinstance(data, six.text_type): |
| writer(body).write(data) |
| else: |
| body.write(data) |
| |
| body.write(b'\r\n') |
| |
| body.write(b('--%s--\r\n' % (boundary))) |
| |
| content_type = str('multipart/form-data; boundary=%s' % boundary) |
| |
| return body.getvalue(), content_type |