kb́^dZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl m Z ddlmZmZddlmZddlmZddlmZmZdd lmZmZmZmZmZmZdd lmZdd lm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&dd l'm(Z(dd l)m*Z*m+Z+m,Z,m-Z-ddl.m/Z/dZ0ej1Z2dddZ3d4ej5deddZ6ej7dkrdZ8dZ dZ9dZ:dJdZ;dZd!Z?d"Z@d#ZAd$ZBd%ZCdJd&ZDd'ZEd(ZFd)ZGd*ZHd+ZId,ZJd-ZKd.ZLeMd/ZNd0ZOd1ZPd2ZQd3ZRd4ZSd5ZTej>d6ZUd7ZVdKd8ZWd9ZXdLd:ZYdMd<ZZd=Z[d>Z\d?]d@Z^e^dAzZ_e^dBzZ`dCZadDZbdEZcdFZddGZedHZfdIZgdS)Nz 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)certs __version__)HEADER_VALIDATORSto_native_string)Mapping basestringbytes getproxiesgetproxies_environment integer_types)parse_http_list) proxy_bypassproxy_bypass_environmentquotestrunquoteurlparse urlunparsecookiejar_from_dict)FileModeWarning InvalidHeader InvalidURLUnrewindableBodyError)CaseInsensitiveDict)z.netrc_netrcPi)httphttpsz, z,\s*T)accept_encodingzaccept-encodingwin32cL ddl}n#t$rYdSwxYw ||jd}t ||dd}||dd}n#t tf$rYdSwxYw|r|sdS|d}|D]t}|dkrd|vrd S| dd }| d d }| d d}tj ||tj rd SudS)NrFz;Software\Microsoft\Windows\CurrentVersion\Internet Settings ProxyEnable ProxyOverride;z.Tz\.*z.*?) winreg ImportErrorOpenKeyHKEY_CURRENT_USERint QueryValueExOSError ValueErrorsplitreplacerematchI)hostr.internetSettings proxyEnable proxyOverridetests 0/usr/lib/python3/dist-packages/requests/utils.pyproxy_bypass_registryrAGsv  MMMM   55  %~~(N    f112BMRRSTUVVK"//0@/RRSTUMM$   55  - 5 &++C00 !  Dy  d??44<<U++D<<U++D<<T**DxdBD)) tt us A A::BBcZtrt|St|S)zReturn True, if the host should be bypassed. Checks proxy settings gathered from the environment, if specified, or the registry. )rrrA)r;s r@rrks. " # # /+D11 1(.. .cNt|dr|}|S)z/Returns an internal sequence dictionary update.items)hasattrrE)ds r@dict_to_sequencerHws(q' GGII HrCcd}d}t|drt|}nt|dr|j}n~t|drn |}tj|j}d|jvrtjdtn#tj tf$rYnwxYwt|dr | }t|drW|U |dd | }||pdn'#t$rd}YnwxYwn#t$r||}YnwxYw|d}t!d||z S) Nr__len__lenfilenoba%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.tellseek)rFrKrLosfstatst_sizemodewarningswarnrioUnsupportedOperationAttributeErrorrNrOr4max)o total_lengthcurrent_positionrLs r@ super_lenr^sLq)1vv E  u H   XXZZF8F++3L!&   2$   '8    D  .q&% % vvxx q&!! %l&: %FF1aLLL#$6688LFF+0q1111%%%#$LLL%% 0 0 0 '#/  0* q,!11 2 22s7BB87B8 E3AD55 EEEEFctjd}||f}ndtD} ddlm}m}d}|D]X} tj|}n#t$rYdSwxYwtj |r|}nY|dSt|} d} t|tr| d} | j| d} ||| } | r| drdnd} | | | d fSdS#|t"f$r|rYdSwxYw#t$t&f$rYdSwxYw) z;Returns the Requests tuple auth for a given url from netrc.NETRCNc3 K|] }d|V dS)z~/N).0fs r@ z!get_netrc_auth..s(99888999999rCr)NetrcParseErrornetrc:asciirrP)rQenvironget NETRC_FILESrgrfpath expanduserKeyErrorexistsr isinstancerdecodenetlocr6authenticatorsr4r/rY)url raise_errors netrc_filenetrc_locationsrfrg netrc_pathrdlocrisplitstrr;r!login_is r@get_netrc_authr~s((J%-99[999- 00000000   A g((++      w~~c""      F c]] c3   0w//Hyx((+ U:&&55d;;F 4%ay/!!aw33 4 4 )          (     sZEA'&E' A61E5A66)E!AE=;D;;E E EEE&%E&ct|dd}|rLt|tr9|ddkr/|ddkr%tj|SdSdSdSdS)z0Tries to guess the filename of the given object.nameNr<>)getattrrqr rQrmbasename)objrs r@guess_filenamersw 3 % %D & 4,,&aCDHPSOOw%%%&&&&OOrCctj|r|Stj|\}}|r|tj|s]tj|\}}|sn8d||g}|rtj|]t j|s|St j|}||vr|Stj }tj||dd}tj|sOt|5}| | |dddn #1swxYwY|S)zReplace 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. /rN)rQrmrpr6joinzipfile is_zipfileZipFilenamelisttempfile gettempdir atomic_openwriteread)rmarchivememberprefixzip_filetmpextracted_path file_handlers r@extract_zipped_pathsrs  w~~d gmmD))OGV ,"'..11,'--00  66*++ ,"'..11,  g & & w''H X&&((((     CW\\#v||C'8'8'<==N 7>>. ) )6  ( ( 6L   x}}V44 5 5 5 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 s>)F33F7:F7c#HKtjtj|\}} tj|d5}|Vdddn #1swxYwYtj||dS#t$rtj|wxYw)z-Write a file to the disk in an atomic fashion)dirwbN) rmkstemprQrmdirnamefdopenr7 BaseExceptionremove)filenametmp_descriptortmp_name tmp_handlers r@rr's (/BGOOH4M4MNNNNH Y~t , ,                     8X&&&&&  ( s/BA BA##B&A#'B B!c|dSt|ttttfrt dt |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 N+cannot encode objects that are not 2-tuples)rqrrboolr2r5rvalues r@from_key_val_listr4sG$ }t%#udC011HFGGG u  rCc|dSt|ttttfrt dt|t r|}t|S)aTake 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 Nr) rqrrrr2r5r rElistrs r@to_key_val_listrOsd" }t%#udC011HFGGG%!!  ;;rCcg}t|D]N}|dd|ddcxkrdkrnnt|dd}||O|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 Nrr")_parse_list_headerunquote_header_valueappend)rresultitems r@parse_list_headerrms.F"5)) 8tBCCy ' ' ' 'C ' ' ' ' ''QrT 33D d MrCci}t|D]a}d|vrd||< |dd\}}|dd|ddcxkrdkrnnt|dd}|||<b|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 =Nrrr)rr6r)rrrrs r@parse_dict_headerrs,F"5)) d??F4L jja(( e !9bcc ) ) ) )c ) ) ) ) )(qt55Et MrCc|r`|d|dcxkrdkrGnnD|dd}|r|dddkr*|ddd dS|S) zUnquotes 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 rrrrNrPz\\\z\")r7)r is_filenames r@rrs CqU2Y----#----- ad  CeBQBi611==..66ucBB B LrCc2i}|D]}|j||j<|S)zReturns a key/value dictionary from a CookieJar. :param cj: CookieJar object to extract cookies from. :rtype: dict )rr)cj cookie_dictcookies r@dict_from_cookiejarrs/K00#)< FK  rCc"t||S)zReturns 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)rrs r@add_dict_to_cookiejarrs {B / //rCc`tjdttjdtj}tjdtj}tjd}||||z||zS)zlReturns encodings from given content string. :param content: bytestring to extract encodings from. zIn 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!])flagsz+]z$^<\?xml.*?encoding=["\']*(.+?)["\'>])rUrVDeprecationWarningr8compiler:findall)content charset_re pragma_rexml_res r@get_encodings_from_contentrs  M 1  @MMMJ IQSQUVVVI Z? @ @F 7##   G $ $ % .. ! ! "rCc|d}|d|dd}}i}d}|D]}|}|rs|d}}|d} | dkr=|d| |}|| dzd|}|||<||fS) zReturns content type and parameters from given header :param header: string :return: tuple containing content type and dictionary of parameters r*rrNz"' Trr)r6stripfindlower) headertokens content_typeparams params_dictitems_to_stripparamkeyrindex_of_equalss r@_parse_content_type_headerrs\\#  F!!9??,,fQRRj&LKN--   -C#jjooO"$$,_,-33NCCo1334::>JJ',K $  $$rCc|d}|sdSt|\}}d|vr|ddSd|vrdSd|vrdSdS) z}Returns encodings from given HTTP Header Dict. :param headers: dictionary to extract encoding from. :rtype: str z content-typeNcharsetz'"textz ISO-8859-1zapplication/jsonutf-8)rkrr)headersrrs r@get_encoding_from_headersrs;;~..L t5lCCL&Fi &&u--- |\))w*)rCc#K|j |Ed{VdStj|jd}|D]}||}|r|V|dd}|r|VdSdS)zStream decodes an iterator.Nr7errorsrCT)final)encodingcodecsgetincrementaldecoderrr)iteratorrdecoderchunkrvs r@stream_decode_response_unicoder.s z6f*1:66iHHHG ^^E " "  HHH 4 ( (B rCc#Kd}||dkrt|}|t|kr)||||zV||z }|t|k'dSdS)z Iterate over slices of a string.rN)rK)string slice_lengthposs r@ iter_slicesr?s{ C|q006{{ F  S3--.... | F      rCc:tjdtg}t|j}|r; t |j|S#t$r||YnwxYw t |j|dS#t$r |jcYSwxYw)zReturns 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 zIn 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.)r7r) rUrVrrrrr UnicodeErrorr TypeError)rtried_encodingsrs r@get_unicode_from_responserIs M 1  O)33H- -qy(++ + - - -  " "8 , , , , , -19hy9999 ys#A A+*A+/BBBzBABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~c|d}tdt|D]}||dd}t|dkr|ro t t |d}n!#t $rtd|dwxYw|tvr|||ddz||<d||||<d||||<d |S) zUn-escape any percent-escape sequences in a URI that are unreserved characters. This leaves all reserved, illegal and non-ASCII bytes encoded. :rtype: str %rrrPz"Invalid percent-escape sequence: ''N) r6rangerKisalnumchrr2r5rUNRESERVED_SETr)uripartsihcs r@unquote_unreservedr vs IIcNNE 1c%jj ! ! & & !HQqSM q66Q;;199;;; LAr OO L L L !Ja!J!J!JKKK LN""uQx|+a)uQx>>a%58~~E!HH 775>>s -B  B)cd}d} tt||S#t$rt||cYSwxYw)zRe-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!#$&'()*+,/:;=?@[]~)safe)rr r)rsafe_with_percentsafe_without_percents r@ requote_urirsk/0 5',,3DEEEE 555S3444444 5s$AAc tjdtj|d}|d\}}tjdtjt t |d}tjdtj|d|z}||z||zkS)zThis 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=Lrr)structunpacksocket inet_atonr6dotted_netmaskr2)ipnetipaddrnetaddrbitsnetmasknetworks r@address_in_networkrs]4!1"!5!5 6 6q 9FIIcNNMGTmD&"2>#d))3L3L"M"MNNqQGmD&"27";";<I)r inet_ntoarpack)maskrs r@rrs8 b4i1, ,D  FKd33 4 44rCcT tj|n#t$rYdSwxYwdS)z :rtype: bool FT)rrr4) string_ips r@is_ipv4_addressr$sB#### uu 4s  %%cN|ddkr t|dd}n#t$rYdSwxYw|dks|dkrdS t j|ddn#t $rYdSwxYwdSdS)zV Very simple check of the cidr format in no_proxy variable. :rtype: bool rrFrrT)countr2r6r5rrr4)string_networkr!s r@ is_valid_cidrr(s C  A%% ~++C00344DD   55  !88tbyy5   ^11#66q9 : : : :   55 u 4s#(A AA$-B B B c#K|du}|r.tj|}|tj|< dV|r"|tj|=dS|tj|<dSdS#|r|tj|=n|tj|<wxYw)zSet 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)rQrjrk)env_namer value_changed old_values r@ set_environr-s%M%JNN8,, $ 81   1 Jx((('0 8$$$  1 1= 1 Jx(('0 8$0000s A""#Bcd}|}| |d}t|}|jdS|rd|dddD}t |jr<|D]8}t |rt |j|rdS*|j|krdS9nR|j}|jr |d |jz }|D]4}|j|s||rdS5td|5 t|j}n#ttj f$rd }YnwxYwdddn #1swxYwY|rdSd S) zL Returns whether we should bypass proxies or not. :rtype: bool ctj|p0tj|SN)rQrjrkupper)rs r@ get_proxyz(should_bypass_proxies..get_proxys1z~~c""AbjnnSYY[[&A&AArCNno_proxyTc3K|]}||V dSr0rb)rcr;s r@rez(should_bypass_proxies..s'RRTTRDRRRRRRrC r,:F)rhostnamer7r6r$r(rportendswithr-rrrgaierror) rur3r2 no_proxy_argparsedproxy_iphost_with_portr;bypasss r@should_bypass_proxiesrAs#BBB L9Z(( c]]F t SRX%5%5c2%>%>%D%DS%I%IRRR 6? + + $   ** )&/8DD$#tt$_00 441  $_N{ 4"3fk"3"33   ?++D11 ^5L5LT5R5R  44 Z . . !&/22FF6?+   FFF  t 5s6ED)(E)EEEEEEcDt||riStS)zA Return a dict of environment proxies. :rtype: dict r3)rAr)rur3s r@get_environ_proxiesrD3s( S8444 ||rCc|pi}t|}|j.||j|dS|jdz|jz|jd|jzdg}d}|D]}||vr ||}n|S)zSelect 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 Nallz://zall://)rr8rkscheme)ruproxiesurlparts proxy_keysproxy proxy_keys r@ select_proxyrM?s mG}}H {{8?GKK,>,>??? %("338$$ J E   I&E E  LrCcd||ni}|j}t|j}|d}|}|rct ||sRt ||}|||d}|r||||S)aThis 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 Nr3rCrF)rurrGrkcopyrArD setdefault) requestrH trust_envrurGr3 new_proxiesenviron_proxiesrKs r@resolve_proxiesrUYs!,gg"G +C c]] !F{{:&&H,,..K2.sXFFF2-cHEEE##FO,?,?,F,FGG  2  " "65 1 1 1 rCpython-requestsc|dtS)zO Return a string representing the default user agent. :rtype: str rr)rs r@default_user_agentrXts  " "[ " ""rCcLtttdddS)z9 :rtype: requests.structures.CaseInsensitiveDict z*/*z keep-alive)z User-AgentzAccept-EncodingAccept Connection)r rXDEFAULT_ACCEPT_ENCODINGrbrCr@default_headersr]}s2 ,..6&     rCcg}d}||}|s|Stjd|D]} |dd\}}n#t$r|d}}YnwxYwd|di}|dD]X} |d\}}n#t$rYn0wxYw|||||<Y|||S) zReturn a list of parsed link headers proxies. i.e. Link: ; rel=front; type="image/jpeg",; rel=back;type="image/jpeg" :rtype: list z '"z, * '"r)rr8r6r5r) rlinks replace_charsvalrurlinkrrs r@parse_header_linksrcsA EM KK & &E  x&& "))C++KC " " "rCCC "syy**+\\#&& H HE "[[-- UU    .3[[-G-GD=)) * * T Ls#AA! A!B,, B:9B:rirPc|dd}|tjtjfvrdS|ddtjkrdS|ddtjtjfvrdS|t}|dkrd S|dkr,|dddtkrd S|d ddtkrd S|dkr*|ddtkrd S|d dtkrdSdS)z :rtype: str Nzutf-32rez utf-8-sigrPzutf-16rrz utf-16-berz utf-16-lez utf-32-bez utf-32-le) r BOM_UTF32_LE BOM_UTF32_BEBOM_UTF8 BOM_UTF16_LE BOM_UTF16_BEr&_null_null2_null3)datasample nullcounts r@guess_json_utfrss"1"XF &%v':;;;x bqbzV_$${ bqbzf)6+>???x U##IA~~wA~~ ##A#;& ; !$Q$<6 ! !;A~~ "1":  ; !"":  ; 4rCct|}|\}}}}}}} |j} | s|| }} |rd|| g} ||}|d}t|| |d|| fS)zGiven 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)rrsrr) ru new_schemer=rGauthr;r9rmqueryfragmentrss r@prepend_scheme_if_neededrzs s^^F6<3FD$dE8 ]F $V *4.)) ~ | vvtRA B BBrCct|} t|jt|jf}n#tt f$rd}YnwxYw|S)z{Given a url with authentication components, extract them into a tuple of username,password. :rtype: (str,str) )rr)rrusernamepasswordrYr)rur=rws r@get_auth_from_urlr~sd c]]F(('&/*B*BC I & Ks(:AAc R|\}}|D]@}t|tvr(td|d|d|dt|At|dtt|dt|dtt|dd S) zVerifies that header parts don't contain leading whitespace reserved characters, or return characters. :param header: tuple, in the format (name, value). z Header part (z) from {: z$} must be of type str or bytes, not rrrrN)typer r_validate_header_part)rrrparts r@check_header_validityrs KD% ::. . .:::::5::-1$ZZ::  / $(9$t**(Ea(HIII%*;DKK*H*KLLLLLrCcZ||std|d|dS)NzSInvalid leading whitespace, reserved character(s), or returncharacter(s) in header r)r9r) header_part header_kind validators r@rrsV ??; ' '  E&1 E E5@ E E     rCct|\}}}}}}|s||}}|ddd}t|||||dfS)zW Given a url remove the fragment and the authentication part. :rtype: str rurrr)rrsplitr)rurGrsrmrrxrys r@ urldefragauthrsb 5=SMM1FFD&% $V ]]3 " "2 &F vvtVUB? @ @@rCct|jdd}|Jt|jtr0 ||jdS#t $rt dwxYwt d)zfMove file pointer back to its recorded starting position so it can be read again on redirect. rONz;An error occurred when rewinding request body for redirect.z+Unable to rewind request body for redirect.)rbodyrq_body_positionrr4r)prepared_request body_seeks r@ rewind_bodyr/s(-vt<rsw  ######00000000$$$$$$A@@@@@@@:99999)((((( ,+++++" $c** )) BHWll48889JKLL <7"""H / / /   ?3?3?3D6 6 6 6 r&&&"""J    6<@F2   0002%%%22"$$$PM 0555, 5 5 55550 111*999x    46####   """L  g  @CCC:    MMM&   AAA"SSSSSrC