aboutsummaryrefslogtreecommitdiff
path: root/.venv/lib/python3.12/site-packages/urllib3/filepost.py
diff options
context:
space:
mode:
Diffstat (limited to '.venv/lib/python3.12/site-packages/urllib3/filepost.py')
-rw-r--r--.venv/lib/python3.12/site-packages/urllib3/filepost.py89
1 files changed, 89 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/urllib3/filepost.py b/.venv/lib/python3.12/site-packages/urllib3/filepost.py
new file mode 100644
index 00000000..14f70b05
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/urllib3/filepost.py
@@ -0,0 +1,89 @@
+from __future__ import annotations
+
+import binascii
+import codecs
+import os
+import typing
+from io import BytesIO
+
+from .fields import _TYPE_FIELD_VALUE_TUPLE, RequestField
+
+writer = codecs.lookup("utf-8")[3]
+
+_TYPE_FIELDS_SEQUENCE = typing.Sequence[
+ typing.Union[tuple[str, _TYPE_FIELD_VALUE_TUPLE], RequestField]
+]
+_TYPE_FIELDS = typing.Union[
+ _TYPE_FIELDS_SEQUENCE,
+ typing.Mapping[str, _TYPE_FIELD_VALUE_TUPLE],
+]
+
+
+def choose_boundary() -> str:
+ """
+ Our embarrassingly-simple replacement for mimetools.choose_boundary.
+ """
+ return binascii.hexlify(os.urandom(16)).decode()
+
+
+def iter_field_objects(fields: _TYPE_FIELDS) -> typing.Iterable[RequestField]:
+ """
+ Iterate over fields.
+
+ Supports list of (k, v) tuples and dicts, and lists of
+ :class:`~urllib3.fields.RequestField`.
+
+ """
+ iterable: typing.Iterable[RequestField | tuple[str, _TYPE_FIELD_VALUE_TUPLE]]
+
+ if isinstance(fields, typing.Mapping):
+ iterable = fields.items()
+ else:
+ iterable = fields
+
+ for field in iterable:
+ if isinstance(field, RequestField):
+ yield field
+ else:
+ yield RequestField.from_tuples(*field)
+
+
+def encode_multipart_formdata(
+ fields: _TYPE_FIELDS, boundary: str | None = None
+) -> tuple[bytes, str]:
+ """
+ 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`).
+ Values are processed by :func:`urllib3.fields.RequestField.from_tuples`.
+
+ :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(f"--{boundary}\r\n".encode("latin-1"))
+
+ writer(body).write(field.render_headers())
+ data = field.data
+
+ if isinstance(data, int):
+ data = str(data) # Backwards compatibility
+
+ if isinstance(data, str):
+ writer(body).write(data)
+ else:
+ body.write(data)
+
+ body.write(b"\r\n")
+
+ body.write(f"--{boundary}--\r\n".encode("latin-1"))
+
+ content_type = f"multipart/form-data; boundary={boundary}"
+
+ return body.getvalue(), content_type