e8b30bddf2e631e3d349854a44434e45ebf0a2a7
[sdc/sdc-distribution-client.git] /
1 # urllib3/filepost.py
2 # Copyright 2008-2013 Andrey Petrov and contributors (see CONTRIBUTORS.txt)
3 #
4 # This module is part of urllib3 and is released under
5 # the MIT License: http://www.opensource.org/licenses/mit-license.php
6
7 import codecs
8 import mimetypes
9
10 from uuid import uuid4
11 from io import BytesIO
12
13 from .packages import six
14 from .packages.six import b
15 from .fields import RequestField
16
17 writer = codecs.lookup('utf-8')[3]
18
19
20 def choose_boundary():
21     """
22     Our embarassingly-simple replacement for mimetools.choose_boundary.
23     """
24     return uuid4().hex
25
26
27 def iter_field_objects(fields):
28     """
29     Iterate over fields.
30
31     Supports list of (k, v) tuples and dicts, and lists of
32     :class:`~urllib3.fields.RequestField`.
33
34     """
35     if isinstance(fields, dict):
36         i = six.iteritems(fields)
37     else:
38         i = iter(fields)
39
40     for field in i:
41       if isinstance(field, RequestField):
42         yield field
43       else:
44         yield RequestField.from_tuples(*field)
45
46
47 def iter_fields(fields):
48     """
49     .. deprecated:: 1.6
50
51     Iterate over fields.
52
53     The addition of :class:`~urllib3.fields.RequestField` makes this function
54     obsolete. Instead, use :func:`iter_field_objects`, which returns
55     :class:`~urllib3.fields.RequestField` objects.
56
57     Supports list of (k, v) tuples and dicts.
58     """
59     if isinstance(fields, dict):
60         return ((k, v) for k, v in six.iteritems(fields))
61
62     return ((k, v) for k, v in fields)
63
64
65 def encode_multipart_formdata(fields, boundary=None):
66     """
67     Encode a dictionary of ``fields`` using the multipart/form-data MIME format.
68
69     :param fields:
70         Dictionary of fields or list of (key, :class:`~urllib3.fields.RequestField`).
71
72     :param boundary:
73         If not specified, then a random boundary will be generated using
74         :func:`mimetools.choose_boundary`.
75     """
76     body = BytesIO()
77     if boundary is None:
78         boundary = choose_boundary()
79
80     for field in iter_field_objects(fields):
81         body.write(b('--%s\r\n' % (boundary)))
82
83         writer(body).write(field.render_headers())
84         data = field.data
85
86         if isinstance(data, int):
87             data = str(data)  # Backwards compatibility
88
89         if isinstance(data, six.text_type):
90             writer(body).write(data)
91         else:
92             body.write(data)
93
94         body.write(b'\r\n')
95
96     body.write(b('--%s--\r\n' % (boundary)))
97
98     content_type = str('multipart/form-data; boundary=%s' % boundary)
99
100     return body.getvalue(), content_type