1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- from __future__ import absolute_import
- import binascii
- import codecs
- import os
- from io import BytesIO
- from .fields import RequestField
- from .packages import six
- from .packages.six import b
- writer = codecs.lookup("utf-8")[3]
- def choose_boundary():
- """
- Our embarrassingly-simple replacement for mimetools.choose_boundary.
- """
- boundary = binascii.hexlify(os.urandom(16))
- if not six.PY2:
- boundary = boundary.decode("ascii")
- return boundary
- 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:`urllib3.filepost.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
|