3

V'ícýã@södZddlZddlZddlZddlZddlZddlZddlZddlZddl	Z	ddl
Z
ddlZddlm
Z
ddlmZddlmZddlmZddlmZdd	lmZdd
lmZddlmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&ddl'm(Z(dd
l)m*Z*ddl+m,Z,m-Z-m.Z.m/Z/dvZ0ej1ƒZ2dddœZ3dj4ej5dedddƒƒZ6ej7dkrndd„Z8dd„Zdd„Z9d d!„Z:dwd#d$„Z;d%d&„Z<d'd(„Z=ej>d)d*„ƒZ?d+d,„Z@d-d.„ZAd/d0„ZBd1d2„ZCdxd3d4„ZDd5d6„ZEd7d8„ZFd9d:„ZGd;d<„ZHd=d>„ZId?d@„ZJdAdB„ZKdCdD„ZLeMdyƒZNdGdH„ZOdIdJ„ZPdKdL„ZQdMdN„ZRdOdP„ZSdQdR„ZTej>dSdT„ƒZUdUdV„ZVdzdWdX„ZWdYdZ„ZXd{d[d\„ZYd|d^d_„ZZd`da„Z[dbdc„Z\ddj]deƒZ^e^dfZ_e^dgZ`dhdi„Zadjdk„Zbdldm„ZcejddnƒZeejddoƒZfdpdq„Zgdrds„Zhdtdu„ZidS)}z”
requests.utils
~~~~~~~~~~~~~~

This module provides utility functions that are used within Requests
that are also useful for external consumption.
éN)ÚOrderedDict)Úmake_headers)Ú	parse_urlé)Ú__version__)Úcerts)Úto_native_string)Úparse_http_list)ÚquoteÚurlparseÚbytesÚstrÚunquoteÚ
getproxiesÚproxy_bypassÚ
urlunparseÚ
basestringÚ
integer_typesÚis_py3Úproxy_bypass_environmentÚgetproxies_environmentÚMapping)Úcookiejar_from_dict)ÚCaseInsensitiveDict)Ú
InvalidURLÚ
InvalidHeaderÚFileModeWarningÚUnrewindableBodyErrorú.netrcÚ_netrcéPi»)ÚhttpÚhttpsz, z,\s*T)Úaccept_encodingzaccept-encodingÚwin32cCsôytrddl}nddl}Wntk
r.dSXy6|j|jdƒ}t|j|dƒdƒ}|j|dƒd}Wntk
rzdSX|sˆ|rŒdS|j	dƒ}xX|D]P}|dkr´d|kr´d	S|j
dd
ƒ}|j
ddƒ}|j
d
dƒ}tj||tj
ƒrœd	SqœWdS)NrFz;Software\Microsoft\Windows\CurrentVersion\Internet SettingsZProxyEnableZ
ProxyOverrideú;z<local>Ú.Tz\.Ú*z.*ú?)rÚwinregÚ_winregÚImportErrorÚOpenKeyÚHKEY_CURRENT_USERÚintÚQueryValueExÚOSErrorÚsplitÚreplaceÚreÚmatchÚI)Úhostr)ZinternetSettingsZproxyEnableZ
proxyOverrideÚtest©r8ú2/tmp/pip-build-gk9425m9/requests/requests/utils.pyÚproxy_bypass_registry7s8


r:cCstƒrt|ƒSt|ƒSdS)zšReturn True, if the host should be bypassed.

        Checks proxy settings gathered from the environment, if specified,
        or the registry.
        N)rrr:)r6r8r8r9r^srcCst|dƒr|jƒ}|S)z/Returns an internal sequence dictionary update.Úitems)Úhasattrr;)Údr8r8r9Údict_to_sequencejs
r>cCs6d}d}t|dƒrt|ƒ}nft|dƒr.|j}nTt|dƒr‚y|jƒ}Wntjtfk
r^Yn$Xtj|ƒj}d|j	kr‚t
jdtƒt|dƒry|j
ƒ}Wn$ttfk
r¾|dk	rº|}Yn\Xt|dƒoÐ|dkry&|jdd	ƒ|j
ƒ}|j|pôdƒWnttfk
rd}YnX|dkr(d}td||ƒS)
NrÚ__len__ÚlenÚfilenoÚba%Requests has determined the content-length for this request using the binary size of the file: however, the file has been opened in text mode (i.e. without the 'b' flag in the mode). This may lead to an incorrect content-length. In Requests 3.0, support will be removed for files in text mode.ÚtellÚseeké)r<r@rAÚioÚUnsupportedOperationÚAttributeErrorÚosÚfstatÚst_sizeÚmodeÚwarningsÚwarnrrCr0ÚIOErrorrDÚmax)ÚoÚtotal_lengthÚcurrent_positionrAr8r8r9Ú	super_lenss@







rTFcCs>tjjdƒ}|dk	r|f}ndd„tDƒ}yôddlm}m}d}xD|D]<}ytjj|ƒ}Wntk
rndSXtjj	|ƒrF|}PqFW|dkr’dSt
|ƒ}	d}
t|tƒr²|
j
dƒ}
|	jj|
ƒd}y6||ƒj|ƒ}|rö|drâdnd	}
||
|d
fSWn"|tfk
r|r‚YnXWnttfk
r8YnXdS)z;Returns the Requests tuple auth for a given url from netrc.ZNETRCNcss|]}dj|ƒVqdS)z~/{}N)Úformat)Ú.0Úfr8r8r9ú	<genexpr>ºsz!get_netrc_auth.<locals>.<genexpr>r)ÚnetrcÚNetrcParseErroró:ÚasciirrE)rIÚenvironÚgetÚNETRC_FILESrYrZÚpathÚ
expanduserÚKeyErrorÚexistsrÚ
isinstancer
ÚdecodeÚnetlocr1ÚauthenticatorsrOr+rH)ÚurlÚraise_errorsZ
netrc_fileZnetrc_locationsrYrZÚ
netrc_pathrWÚlocÚriÚsplitstrr6rÚlogin_ir8r8r9Úget_netrc_auth³s@


rocCsBt|ddƒ}|r>t|tƒr>|ddkr>|ddkr>tjj|ƒSdS)z0Tries to guess the filename of the given object.ÚnameNrú<rú>éÿÿÿÿ)ÚgetattrrdrrIr`Úbasename)Úobjrpr8r8r9Úguess_filenameìsrwc
CsØtjj|ƒr|Stjj|ƒ\}}x:|rZtjj|ƒrZtjj|ƒ\}}|sJPdj||gƒ}q"Wtj|ƒsj|Stj|ƒ}||jƒkr„|St	j
ƒ}tjj||jdƒdƒ}tjj|ƒsÔt|ƒ}|j|j
|ƒƒWdQRX|S)zÄReplace nonexistent paths that look like they refer to a member of a zip
    archive with the location of an extracted copy of the target, or else
    just return the provided path unchanged.
    ú/rNrs)rIr`rcr1ÚjoinÚzipfileÚ
is_zipfileÚZipFileÚnamelistÚtempfileÚ
gettempdirÚatomic_openÚwriteÚread)r`ÚarchiveÚmemberÚprefixZzip_fileÚtmpZextracted_pathZfile_handlerr8r8r9Úextract_zipped_pathsôs&


r‡ccs„tjddkrtjntj}tjtjj|ƒd\}}y,tj	|dƒ}|VWdQRX|||ƒWn t
k
r~tj|ƒ‚YnXdS)z-Write a file to the disk in an atomic fashionrrE)ÚdirÚwbN)ÚsysÚversion_inforIÚrenamer2r~Úmkstempr`ÚdirnameÚfdopenÚ
BaseExceptionÚremove)ÚfilenameZreplacerZtmp_descriptorZtmp_nameZtmp_handlerr8r8r9r€s
r€cCs.|dkrdSt|ttttfƒr&tdƒ‚t|ƒS)aTake an object and test to see if it can be represented as a
    dictionary. Unless it can not be represented as such, return an
    OrderedDict, e.g.,

    ::

        >>> from_key_val_list([('key', 'val')])
        OrderedDict([('key', 'val')])
        >>> from_key_val_list('string')
        Traceback (most recent call last):
        ...
        ValueError: cannot encode objects that are not 2-tuples
        >>> from_key_val_list({'key': 'val'})
        OrderedDict([('key', 'val')])

    :rtype: OrderedDict
    Nz+cannot encode objects that are not 2-tuples)rdr
rÚboolr.Ú
ValueErrorr)Úvaluer8r8r9Úfrom_key_val_list's
r–cCs@|dkrdSt|ttttfƒr&tdƒ‚t|tƒr8|jƒ}t|ƒS)aÂTake an object and test to see if it can be represented as a
    dictionary. If it can be, return a list of tuples, e.g.,

    ::

        >>> to_key_val_list([('key', 'val')])
        [('key', 'val')]
        >>> to_key_val_list({'key': 'val'})
        [('key', 'val')]
        >>> to_key_val_list('string')
        Traceback (most recent call last):
        ...
        ValueError: cannot encode objects that are not 2-tuples

    :rtype: list
    Nz+cannot encode objects that are not 2-tuples)	rdr
rr“r.r”rr;Úlist)r•r8r8r9Úto_key_val_listBs
r˜cCs\g}xRt|ƒD]F}|dd…|dd…ko4dknrJt|dd…ƒ}|j|ƒqW|S)aParse lists as described by RFC 2068 Section 2.

    In particular, parse comma-separated lists where the elements of
    the list may include quoted-strings.  A quoted-string could
    contain a comma.  A non-quoted string could have quotes in the
    middle.  Quotes are removed automatically after parsing.

    It basically works like :func:`parse_set_header` just that items
    may appear multiple times and case sensitivity is preserved.

    The return value is a standard :class:`list`:

    >>> parse_list_header('token, "quoted value"')
    ['token', 'quoted value']

    To create a header from the :class:`list` again, use the
    :func:`dump_header` function.

    :param value: a string with a list header.
    :return: :class:`list`
    :rtype: list
    Nrú"rsrs)Ú_parse_list_headerÚunquote_header_valueÚappend)r•ÚresultÚitemr8r8r9Úparse_list_header`s(rŸcCs|i}xrt|ƒD]f}d|kr$d||<q|jddƒ\}}|dd…|dd…koVdknrlt|dd…ƒ}|||<qW|S)a^Parse lists of key, value pairs as described by RFC 2068 Section 2 and
    convert them into a python dict:

    >>> d = parse_dict_header('foo="is a fish", bar="as well"')
    >>> type(d) is dict
    True
    >>> sorted(d.items())
    [('bar', 'as well'), ('foo', 'is a fish')]

    If there is no value for a key it will be `None`:

    >>> parse_dict_header('key_without_value')
    {'key_without_value': None}

    To create a header from the :class:`dict` again, use the
    :func:`dump_header` function.

    :param value: a string with a dict header.
    :return: :class:`dict`
    :rtype: dict
    ú=Nrr™rsrs)ršr1r›)r•rržrpr8r8r9Úparse_dict_header€s(r¡cCs^|rZ|d|d	kodknrZ|dd
…}|sF|dd…dkrZ|jddƒjddƒS|S)zçUnquotes a header value.  (Reversal of :func:`quote_header_value`).
    This does not use the real unquoting but what browsers are actually
    using for quoting.

    :param value: the header value to unquote.
    :rtype: str
    rrr™NrEz\\ú\z\"rsrs)r2)r•Úis_filenamer8r8r9r›£s
$r›cCs"i}x|D]}|j||j<q
W|S)z€Returns a key/value dictionary from a CookieJar.

    :param cj: CookieJar object to extract cookies from.
    :rtype: dict
    )r•rp)ÚcjÚcookie_dictÚcookier8r8r9Údict_from_cookiejar¼s
r§cCs
t||ƒS)zÂReturns a CookieJar from a key/value dictionary.

    :param cj: CookieJar to insert cookies into.
    :param cookie_dict: Dict of key/values to insert into CookieJar.
    :rtype: CookieJar
    )r)r¤r¥r8r8r9Úadd_dict_to_cookiejarËsr¨cCsTtjdtƒtjdtjd}tjdtjd}tjdƒ}|j|ƒ|j|ƒ|j|ƒS)zlReturns encodings from given content string.

    :param content: bytestring to extract encodings from.
    z¤In requests 3.0, get_encodings_from_content will be removed. For more information, please see the discussion on issue #2266. (This warning should only appear once.)z!<meta.*?charset=["\']*(.+?)["\'>])Úflagsz+<meta.*?content=["\']*;?charset=(.+?)["\'>]z$^<\?xml.*?encoding=["\']*(.+?)["\'>])rMrNÚDeprecationWarningr3Úcompiler5Úfindall)ÚcontentÚ
charset_reÚ	pragma_reÚxml_rer8r8r9Úget_encodings_from_contentÖs
r±c
Csž|jdƒ}|djƒ|dd…}}i}d}xh|D]`}|jƒ}|r2|d}}|jdƒ}	|	dkr†|d|	…j|ƒ}||	dd…j|ƒ}|||jƒ<q2W||fS)	z¦Returns content type and parameters from given header

    :param header: string
    :return: tuple containing content type and dictionary of
         parameters
    r%rrNz"' Tr rs)r1ÚstripÚfindÚlower)
ÚheaderÚtokensÚcontent_typeÚparamsZparams_dictZitems_to_stripÚparamÚkeyr•Zindex_of_equalsr8r8r9Ú_parse_content_type_headerês



r»cCsP|jdƒ}|sdSt|ƒ\}}d|kr4|djdƒSd|kr@dSd|krLdSdS)	z}Returns encodings from given HTTP Header Dict.

    :param headers: dictionary to extract encoding from.
    :rtype: str
    zcontent-typeNÚcharsetz'"Útextz
ISO-8859-1zapplication/jsonzutf-8)r^r»r²)Úheadersr·r¸r8r8r9Úget_encoding_from_headerss
r¿ccsr|jdkr"x|D]
}|VqWdStj|jƒdd}x |D]}|j|ƒ}|r:|Vq:W|jddd}|rn|VdS)zStream decodes a iterator.Nr2)ÚerrorsóT)Úfinal)ÚencodingÚcodecsÚgetincrementaldecoderre)ÚiteratorÚrržÚdecoderÚchunkÚrvr8r8r9Ústream_decode_response_unicodes





rËccsLd}|dks|dkrt|ƒ}x*|t|ƒkrF||||…V||7}qWdS)z Iterate over slices of a string.rN)r@)ÚstringÚslice_lengthÚposr8r8r9Úiter_slices.srÏcCsvtjdtƒg}t|jƒ}|rJyt|j|ƒStk
rH|j|ƒYnXyt|j|ddSt	k
rp|jSXdS)zâReturns the requested content back in unicode.

    :param r: Response object to get unicode content from.

    Tried:

    1. charset from content-type
    2. fall back and replace all unicode characters

    :rtype: str
    z£In requests 3.0, get_unicode_from_response will be removed. For more information, please see the discussion on issue #2266. (This warning should only appear once.)r2)rÀN)
rMrNrªr¿r¾r
r­ÚUnicodeErrorrœÚ	TypeError)rÇÚtried_encodingsrÃr8r8r9Úget_unicode_from_response8s
rÓZ4ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzz0123456789-._~c
CsÈ|jdƒ}x²tdt|ƒƒD] }||dd…}t|ƒdkrª|jƒrªytt|dƒƒ}Wn tk
rttd|ƒ‚YnX|tkr˜|||dd…||<qºd||||<qd||||<qWdj	|ƒS)	z¨Un-escape any percent-escape sequences in a URI that are unreserved
    characters. This leaves all reserved, illegal and non-ASCII bytes encoded.

    :rtype: str
    ú%rrrEéz%Invalid percent-escape sequence: '%s'NÚ)
r1Úranger@ÚisalnumÚchrr.r”rÚUNRESERVED_SETry)ÚuriÚpartsÚiÚhÚcr8r8r9Úunquote_unreservedas
ràcCs:d}d}ytt|ƒ|dStk
r4t||dSXdS)z¬Re-quote the given URI.

    This function passes the given URI through an unquote/quote cycle to
    ensure that it is fully and consistently quoted.

    :rtype: str
    z!#$%&'()*+,/:;=?@[]~z!#$&'()*+,/:;=?@[]~)ÚsafeN)r
ràr)rÛÚsafe_with_percentÚsafe_without_percentr8r8r9Úrequote_uriysräcCsltjdtj|ƒƒd}|jdƒ\}}tjdtjtt|ƒƒƒƒd}tjdtj|ƒƒd|@}||@||@kS)zïThis function allows you to check if an IP belongs to a network subnet

    Example: returns True if ip = 192.168.1.1 and net = 192.168.1.0/24
             returns False if ip = 192.168.1.1 and net = 192.168.100.0/24

    :rtype: bool
    z=Lrrx)ÚstructÚunpackÚsocketÚ	inet_atonr1Údotted_netmaskr.)ÚipÚnetÚipaddrÚnetaddrÚbitsÚnetmaskÚnetworkr8r8r9Úaddress_in_networks
rñcCs&ddd|>dA}tjtjd|ƒƒS)zConverts mask from /xx format to xxx.xxx.xxx.xxx

    Example: if mask is 24 function returns 255.255.255.0

    :rtype: str
    lÿÿré z>I)rçÚ	inet_ntoaråÚpack)Úmaskrîr8r8r9réžsrécCs*ytj|ƒWntjk
r$dSXdS)z
    :rtype: bool
    FT)rçrèÚerror)Ú	string_ipr8r8r9Úis_ipv4_address©s
røcCsˆ|jdƒdkr€yt|jdƒdƒ}Wntk
r8dSX|dksJ|dkrNdSytj|jdƒdƒWq„tjk
r|dSXndSdS)zV
    Very simple check of the cidr format in no_proxy variable.

    :rtype: bool
    rxrFròrT)Úcountr.r1r”rçrèrö)Ústring_networkrõr8r8r9Ú
is_valid_cidr´srûccsT|dk	}|r"tjj|ƒ}|tj|<z
dVWd|rN|dkrDtj|=n
|tj|<XdS)zÎSet the environment variable 'env_name' to 'value'

    Save previous value, yield, and then restore the previous value stored in
    the environment variable 'env_name'.

    If 'value' is None, do nothingN)rIr]r^)Úenv_namer•Ú
value_changedÚ	old_valuer8r8r9Úset_environÌs


rÿc	Cs,dd„}|}|dkr|dƒ}t|ƒ}|jdkr2dS|rØdd„|jdd	ƒjd
ƒDƒ}t|jƒr”xz|D],}t|ƒr€t|j|ƒrŽdSqb|j|krbdSqbWnD|j}|jr°|dj|jƒ7}x&|D]}|jj	|ƒsÐ|j	|ƒr¶dSq¶Wt
d|ƒ6yt|jƒ}Wn tt
jfk
rd}YnXWdQRX|r(dSdS)
zL
    Returns whether we should bypass proxies or not.

    :rtype: bool
    cSstjj|ƒptjj|jƒƒS)N)rIr]r^Úupper)Úkr8r8r9Ú<lambda>êsz'should_bypass_proxies.<locals>.<lambda>NÚno_proxyTcss|]}|r|VqdS)Nr8)rVr6r8r8r9rXûsz(should_bypass_proxies.<locals>.<genexpr>ú rÖú,z:{}F)rÚhostnamer2r1rørûrñÚportrUÚendswithrÿrrÑrçÚgaierror)	rhrÚ	get_proxyÚno_proxy_argÚparsedÚproxy_ipZhost_with_portr6Úbypassr8r8r9Úshould_bypass_proxiesâs<





rcCst||driStƒSdS)zA
    Return a dict of environment proxies.

    :rtype: dict
    )rN)rr)rhrr8r8r9Úget_environ_proxiessrcCsv|pi}t|ƒ}|jdkr.|j|j|jdƒƒS|jd|j|jd|jdg}d}x|D]}||krX||}PqXW|S)z­Select a proxy for the url, if applicable.

    :param url: The url being for the request
    :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs
    NÚallz://zall://)rrr^Úscheme)rhÚproxiesÚurlpartsÚ
proxy_keysÚproxyÚ	proxy_keyr8r8r9Úselect_proxy+s

rc	Csv|dk	r|ni}|j}t|ƒj}|jdƒ}|jƒ}|rrt||drrt||d}|j||jdƒƒ}|rr|j||ƒ|S)a¨This method takes proxy information from a request and configuration
    input to resolve a mapping of target proxies. This will consider settings
    such a NO_PROXY to strip proxy configurations.

    :param request: Request or PreparedRequest
    :param proxies: A dictionary of schemes or schemes and hosts to proxy URLs
    :param trust_env: Boolean declaring whether to trust environment configs

    :rtype: dict
    Nr)rr)rhrrr^ÚcopyrrÚ
setdefault)	ÚrequestrÚ	trust_envrhrrÚnew_proxiesÚenviron_proxiesrr8r8r9Úresolve_proxiesEs

rúpython-requestscCsd|tfS)zO
    Return a string representing the default user agent.

    :rtype: str
    z%s/%s)r)rpr8r8r9Údefault_user_agent`sr!cCsttƒtdddœƒS)z9
    :rtype: requests.structures.CaseInsensitiveDict
    z*/*z
keep-alive)z
User-AgentzAccept-EncodingÚAcceptÚ
Connection)rr!ÚDEFAULT_ACCEPT_ENCODINGr8r8r8r9Údefault_headersis
r%c	CsÒg}d}|j|ƒ}|s|Sx²tjd|ƒD]¢}y|jddƒ\}}Wntk
r^|d}}YnXd|jdƒi}xP|jdƒD]B}y|jdƒ\}}Wntk
r¦PYnX|j|ƒ||j|ƒ<qzW|j|ƒq(W|S)	z¼Return a list of parsed link headers proxies.

    i.e. Link: <http:/.../front.jpeg>; rel=front; type="image/jpeg",<http://.../back.jpeg>; rel=back;type="image/jpeg"

    :rtype: list
    z '"z, *<r%rrÖrhz<> '"r )r²r3r1r”rœ)	r•ÚlinksÚ
replace_charsÚvalrhr¸Úlinkr¹rºr8r8r9Úparse_header_linksus&
r*úr\rEécCsÐ|dd…}|tjtjfkr dS|dd…tjkr6dS|dd…tjtjfkrRdS|jtƒ}|dkrhd	S|dkrœ|ddd…tkr†d
S|ddd…tkrœdS|dkrÌ|dd…t	kr¸d
S|dd…t	krÌdSdS)z
    :rtype: str
    Nézutf-32r,z	utf-8-sigrEzutf-16rzutf-8z	utf-16-berz	utf-16-lez	utf-32-bez	utf-32-le)
rÄÚBOM_UTF32_LEÚBOM_UTF32_BEÚBOM_UTF8ÚBOM_UTF16_LEÚBOM_UTF16_BErùÚ_nullÚ_null2Ú_null3)ÚdataÚsampleÚ	nullcountr8r8r9Úguess_json_utf s*
r9cCslt|ƒ}|\}}}}}}}	|j}
|
s.||
}
}|r@dj||
gƒ}
|dkrL|}|dkrXd}t||
|d||	fƒS)zªGiven a URL that may or may not have a scheme, prepend the given scheme.
    Does not replace a present scheme with the one provided as an argument.

    :rtype: str
    ú@NrÖ)rrfryr)rhÚ
new_schemerrÚauthr6rr`ÚqueryÚfragmentrfr8r8r9Úprepend_scheme_if_neededÀs
r?cCsBt|ƒ}yt|jƒt|jƒf}Wnttfk
r<d}YnX|S)z{Given a url with authentication components, extract them into a tuple of
    username,password.

    :rtype: (str,str)
    rÖ)rÖrÖ)rrÚusernameÚpasswordrHrÑ)rhrr<r8r8r9Úget_auth_from_urlÝs
rBs^\S[^\r\n]*$|^$z^\S[^\r\n]*$|^$cCsf|\}}t|tƒrt}nt}y|j|ƒs4td|ƒ‚Wn*tk
r`td||t|ƒfƒ‚YnXdS)zÕVerifies that header value is a string which doesn't contain
    leading whitespace or return characters. This prevents unintended
    header injection.

    :param header: tuple, in the format (name, value).
    z7Invalid return character or leading space in header: %sz>Value for header {%s: %s} must be of type str or bytes, not %sN)rdrÚ_CLEAN_HEADER_REGEX_BYTEÚ_CLEAN_HEADER_REGEX_STRr4rrÑÚtype)rµrpr•Úpatr8r8r9Úcheck_header_validityòs

rGcCsFt|ƒ\}}}}}}|s"||}}|jddƒd}t|||||dfƒS)zW
    Given a url remove the fragment and the authentication part.

    :rtype: str
    r:rrÖrs)rÚrsplitr)rhrrfr`r¸r=r>r8r8r9Ú
urldefragauths

rIcCs`t|jddƒ}|dk	rTt|jtƒrTy||jƒWq\ttfk
rPtdƒ‚Yq\Xntdƒ‚dS)zfMove file pointer back to its recorded starting position
    so it can be read again on redirect.
    rDNz;An error occurred when rewinding request body for redirect.z+Unable to rewind request body for redirect.)rtÚbodyrdÚ_body_positionrrOr0r)Úprepared_requestÚ	body_seekr8r8r9Úrewind_bodysrN)rr)F)FzBABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~)N)T)r )jÚ__doc__rÄÚ
contextlibrFrIr3rçrårŠr~rMrzÚcollectionsrZurllib3.utilrrrrÖrÚ_internal_utilsrÚcompatr	ršr
rrr
rrrrrrrrrrÚcookiesrÚ
structuresrÚ
exceptionsrrrrr_ÚwhereÚDEFAULT_CA_BUNDLE_PATHZ
DEFAULT_PORTSryr1r$Úplatformr:r>rTrorwr‡Úcontextmanagerr€r–r˜rŸr¡r›r§r¨r±r»r¿rËrÏrÓÚ	frozensetrÚràrärñrérørûrÿrrrrr!r%r*Úencoder3r4r5r9r?rBr«rCrDrGrIrNr8r8r8r9Ú<module>	s˜@
'	@
9% #

%=


	&