Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
from ..util.retry import Retry
from ..util.ssl_ import (
create_urllib3_context,
merge_context_settings,
resolve_ssl_version,
resolve_cert_reqs,
BaseSSLError,
)
from ..util.timeout import Timeout
from ..util.url import get_host, Url
try:
import ssl
except ImportError:
ssl = None
if six.PY2:
# Queue is imported for side effects on MS Windows
import Queue as _unused_module_Queue # noqa: F401
xrange = six.moves.xrange
log = logging.getLogger(__name__)
_Default = object()
def _add_transport_headers(headers):
"""
Adds the transport framing headers, if needed. Naturally, this method
cannot add a content-length header, so if there is no content-length header
then it will add Transfer-Encoding: chunked instead. Should only be called
if there is a body to upload.
This should be a bit smarter: in particular, it should allow for bad or
unexpected versions of these headers, particularly transfer-encoding.
def wrap_socket(
self,
sock,
server_side=False,
do_handshake_on_connect=True,
suppress_ragged_eofs=True,
server_hostname=None,
):
cnx = OpenSSL.SSL.Connection(self._ctx, sock)
if isinstance(
server_hostname, six.text_type
): # Platform-specific: Python 3
server_hostname = server_hostname.encode('utf-8')
if server_hostname is not None:
cnx.set_tlsext_host_name(server_hostname)
cnx.set_connect_state()
while True:
try:
cnx.do_handshake()
except OpenSSL.SSL.WantReadError:
rd = util.wait_for_read(sock, sock.gettimeout())
if not rd:
raise timeout('select timed out')
continue
except OpenSSL.SSL.Error as e:
extra_kw = {'headers': {}}
if fields:
if 'body' in urlopen_kw:
raise TypeError(
"request got values for both 'fields' and 'body', can only specify one."
)
if encode_multipart:
body, content_type = encode_multipart_formdata(
fields, boundary=multipart_boundary
)
else:
body, content_type = urlencode(
fields
), 'application/x-www-form-urlencoded'
if isinstance(body, six.text_type):
body = body.encode('utf-8')
extra_kw['body'] = body
extra_kw['headers'] = {'Content-Type': content_type}
extra_kw['headers'].update(headers)
extra_kw.update(urlopen_kw)
return self.urlopen(method, url, **extra_kw)
def _stringify_headers(headers):
"""
A generator that transforms headers so they're suitable for sending by h11.
"""
# TODO: revisit
for name, value in headers:
if isinstance(name, six.text_type):
name = name.encode('ascii')
if isinstance(value, six.text_type):
value = value.encode('latin-1')
elif isinstance(value, int):
value = str(value).encode('ascii')
yield (name, value)
The basic logic here is:
- byte strings are turned into single-element lists
- readables are wrapped in an iterable that repeatedly calls read until
nothing is returned anymore
- other iterables are used directly
- anything else is not acceptable
In particular, note that we do not support *text* data of any kind. This
is deliberate: users must make choices about the encoding of the data they
use.
"""
if body is None:
return []
elif isinstance(body, six.binary_type):
return [body]
elif hasattr(body, "read"):
return _read_readable(body)
elif isinstance(body, collections.Iterable) and not isinstance(
body, six.text_type
):
return body
else:
raise InvalidBodyError("Unacceptable body type: %s" % type(body))
def _stringify_headers(headers):
"""
A generator that transforms headers so they're suitable for sending by h11.
"""
# TODO: revisit
for name, value in headers:
if isinstance(name, six.text_type):
name = name.encode('ascii')
if isinstance(value, six.text_type):
value = value.encode('latin-1')
elif isinstance(value, int):
value = str(value).encode('ascii')
yield (name, value)
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)
The basic logic here is:
- byte strings are turned into single-element lists
- readables are wrapped in an iterable that repeatedly calls read until
nothing is returned anymore
- other iterables are used directly
- anything else is not acceptable
In particular, note that we do not support *text* data of any kind. This
is deliberate: users must make choices about the encoding of the data they
use.
"""
if body is None:
return []
elif isinstance(body, six.binary_type):
return [body]
elif hasattr(body, "read"):
return _read_readable(body)
elif isinstance(body, collections.Iterable) and not isinstance(
body, six.text_type
):
return body
else:
raise InvalidBodyError("Unacceptable body type: %s" % type(body))
def _stringify_headers(headers):
"""
A generator that transforms headers so they're suitable for sending by h11.
"""
# TODO: revisit
for name, value in headers:
if isinstance(name, six.text_type):
name = name.encode('ascii')
if isinstance(value, six.text_type):
value = value.encode('latin-1')
elif isinstance(value, int):
value = str(value).encode('ascii')
yield (name, value)