a „oe¨‚ã@sòdZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl Z ddl m Z ddlmZmZddlmZddlmZddlmZmZmZmZdd lmZmZmZmZmZmZdd lm Z!dd 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/ddl0m1Z1dZ2e 3¡Z4dddœZ5d 6e 7dedd�d¡¡Z8ej9dk�rvdd„Z:dd„Z"dd„Z;dd „Zd&d'„Z?ej@d(d)„ƒZAd*d+„ZBd,d-„ZCd.d/„ZDd0d1„ZEdud2d3„ZFd4d5„ZGd6d7„ZHd8d9„ZId:d;„ZJdd?„ZLd@dA„ZMdBdC„ZNeOdDƒZPdEdF„ZQdGdH„ZRdIdJ„ZSdKdL„ZTdMdN„ZUdOdP„ZVej@dQdR„ƒZWdSdT„ZXdvdUdV„ZYdWdX„ZZdwdYdZ„Z[dxd\d]„Z\d^d_„Z]d`da„Z^db _dc¡Z`e`ddZae`deZbdfdg„Zcdhdi„Zddjdk„Zedldm„Zfdndo„Zgdpdq„Zhdrds„ZidS)yz” 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_VALIDATORS_BYTEÚ_HEADER_VALIDATORS_STRÚHEADER_VALIDATORSÚto_native_string)ÚMappingÚ basestringÚbytesÚ getproxiesÚgetproxies_environmentÚ integer_types)Úparse_http_list)Ú proxy_bypassÚproxy_bypass_environmentÚquoteÚstrÚunquoteÚurlparseÚ urlunparse©Úcookiejar_from_dict)ÚFileModeWarningÚ InvalidHeaderÚ InvalidURLÚUnrewindableBodyError)ÚCaseInsensitiveDict)z.netrcÚ_netrcéPi»)ÚhttpÚhttpsz, z,\s*T)Zaccept_encodingzaccept-encodingÚwin32c Csæz ddl}Wnty YdS0z6| |jd¡}t| |d¡dƒ}| |d¡d}WnttfypYdS0|rz|s~dS| d¡}|D]T}|dkr¦d|vr¦d S|  dd ¡}|  d d ¡}|  d d¡}t   ||t j ¡rŒd SqŒdS)NrFz;Software\Microsoft\Windows\CurrentVersion\Internet SettingsZ ProxyEnableZ ProxyOverrideú;zÚ.Tz\.Ú*z.*ú?) ÚwinregÚ ImportErrorÚOpenKeyÚHKEY_CURRENT_USERÚintÚ QueryValueExÚOSErrorÚ ValueErrorÚsplitÚreplaceÚreÚmatchÚI)Úhostr+ZinternetSettingsZ proxyEnableZ proxyOverrideÚtest©r:ú/C:\Program Files\Certbot\pkgs\requests\utils.pyÚproxy_bypass_registryLs4  þ    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<)r8r:r:r;rpsrcCst|dƒr| ¡}|S)z/Returns an internal sequence dictionary update.Úitems)Úhasattrr=)Údr:r:r;Údict_to_sequence|s r@c Cs*d}d}t|dƒrt|ƒ}ndt|dƒr.|j}nRt|dƒr€z | ¡}Wntjtfy\Yn$0t |¡j}d|j vr€t   dt ¡t|dƒ�rz |  ¡}Wnty¶|dur²|}YnX0t|dƒ�r|du�rz&| dd ¡|  ¡}| |pîd¡Wnt�y d}Yn0|du�rd}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>rBrCÚioÚUnsupportedOperationÚAttributeErrorÚosÚfstatÚst_sizeÚmodeÚwarningsÚwarnrrEr1rFÚmax)ÚoZ total_lengthZcurrent_positionrCr:r:r;Ú super_len…sB       ÷       rSFc CsFtj d¡}|dur|f}ndd„tDƒ}�züddlm}m}d}|D]B}ztj |¡}WntyrYWdS0tj  |¡rF|}qŠqF|dur˜WdSt |ƒ} d} t |t ƒr¸|   d¡} | j | ¡d} z<||ƒ | ¡} | �r| drêdnd } | | | d fWWSWn |tf�y$|�r ‚Yn0Wnttf�y@Yn0dS) z;Returns the Requests tuple auth for a given url from netrc.ZNETRCNcss|]}d|›�VqdS)z~/Nr:)Ú.0Úfr:r:r;Ú Îóz!get_netrc_auth..r)ÚNetrcParseErrorÚnetrcó:ÚasciirrG)rKÚenvironÚgetÚ NETRC_FILESrYrXÚpathÚ expanduserÚKeyErrorÚexistsrÚ isinstancerÚdecodeÚnetlocr3Zauthenticatorsr1r,rJ)ÚurlZ raise_errorsZ netrc_fileZnetrc_locationsrXrYZ netrc_pathrUÚlocZriZsplitstrr8r"Zlogin_ir:r:r;Úget_netrc_authÇs@       rhcCsBt|ddƒ}|r>t|tƒr>|ddkr>|ddkr>tj |¡SdS)z0Tries to guess the filename of the given object.ÚnameNrú<éÿÿÿÿú>)ÚgetattrrcrrKr_Úbasename)Úobjrir:r:r;Úguess_filenames &rpcCsætj |¡r|Stj |¡\}}|rVtj |¡sVtj |¡\}}|sFqVd ||g¡}q t |¡sd|St |¡}|| ¡vr~|St   ¡}tj || d¡d¡}tj |¡sât |ƒ� }|  |  |¡¡Wdƒn1sØ0Y|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. ú/rkN)rKr_rbr3ÚjoinÚzipfileÚ is_zipfileÚZipFileZnamelistÚtempfileZ gettempdirÚ atomic_openÚwriteÚread)r_ÚarchiveÚmemberÚprefixZzip_fileÚtmpZextracted_pathZ file_handlerr:r:r;Úextract_zipped_pathss&      .r~ccs~tjtj |¡d�\}}zBt |d¡�}|VWdƒn1sB0Yt ||¡Wntyxt |¡‚Yn0dS)z-Write a file to the disk in an atomic fashion)ÚdirÚwbN) rvZmkstemprKr_ÚdirnameÚfdopenr4Ú BaseExceptionÚremove)ÚfilenameZtmp_descriptorZtmp_nameZ tmp_handlerr:r:r;rw,s$  rwcCs.|dur 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 Nú+cannot encode objects that are not 2-tuples)rcrrÚboolr/r2r©Úvaluer:r:r;Úfrom_key_val_list9s rŠcCs@|dur dSt|ttttfƒr&tdƒ‚t|tƒr8| ¡}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 Nr†) rcrrr‡r/r2r r=Úlistrˆr:r:r;Úto_key_val_listTs rŒcCsXg}t|ƒD]F}|dd…|dd…kr4dkrHnnt|dd…ƒ}| |¡q |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 Nrrkú")Ú_parse_list_headerÚunquote_header_valueÚappend)r‰ÚresultÚitemr:r:r;Úparse_list_headerrs  ( r“cCsxi}t|ƒD]f}d|vr"d||<q | dd¡\}}|dd…|dd…krVdkrjnnt|dd…ƒ}|||<q |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 ú=Nrrkr�)rŽr3r�)r‰r‘r’rir:r:r;Úparse_dict_header’s ( r•cCs\|rX|d|dkr dkrXnn4|dd…}|rD|dd…dkrX| dd¡ d d¡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 rrkr�rNrGz\\ú\z\")r4)r‰Z is_filenamer:r:r;r�µs $ r�cCsi}|D]}|j||j<q|S)z€Returns a key/value dictionary from a CookieJar. :param cj: CookieJar object to extract cookies from. :rtype: dict )r‰ri)ÚcjÚ cookie_dictÚcookier:r:r;Údict_from_cookiejarÎsrš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˜r:r:r;Úadd_dict_to_cookiejarÝsr›cCsTt dt¡tjdtjd�}tjdtjd�}t d¡}| |¡| |¡| |¡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!])Úflagsz+]z$^<\?xml.*?encoding=["\']*(.+?)["\'>])rOrPÚDeprecationWarningr5Úcompiler7Úfindall)ÚcontentZ charset_reZ pragma_reZxml_rer:r:r;Úget_encodings_from_contentèsú  ÿþÿr¡c Csš| d¡}|d ¡|dd…}}i}d}|D]`}| ¡}|r0|d}}| d¡} | dkr„|d| … |¡}|| dd… |¡}||| ¡<q0||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”rk)r3ÚstripÚfindÚlower) ÚheaderÚtokensÚ content_typeÚparamsZ params_dictZitems_to_stripÚparamÚkeyr‰Zindex_of_equalsr:r:r;Ú_parse_content_type_headers   r«cCsP| d¡}|sdSt|ƒ\}}d|vr4|d d¡Sd|vr@dSd|vrLdSdS) 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/jsonúutf-8)r]r«r¢)Úheadersr§r¨r:r:r;Úget_encoding_from_headerss  r°ccsd|jdur|EdHdSt |j¡dd�}|D]}| |¡}|r.|Vq.|jddd�}|r`|VdS)zStream decodes an iterator.Nr4©ÚerrorsrWT)Úfinal)ÚencodingÚcodecsÚgetincrementaldecoderrd)ÚiteratorÚrÚdecoderÚchunkÚrvr:r:r;Ústream_decode_response_unicode3s   r¼ccsHd}|dus|dkrt|ƒ}|t|ƒkrD||||…V||7}qdS)z Iterate over slices of a string.rN)rB)ÚstringZ slice_lengthÚposr:r:r;Ú iter_slicesDs  r¿cCszt dt¡g}t|jƒ}|rJzt|j|ƒWStyH| |¡Yn0zt|j|dd�WSt yt|jYS0dS)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.)r4r±N) rOrPr�r°r¯rr Ú UnicodeErrorr�Ú TypeError)r¸Ztried_encodingsr´r:r:r;Úget_unicode_from_responseNs ú    rÂzBABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~c CsÊ| d¡}tdt|ƒƒD]¦}||dd…}t|ƒdkr¬| ¡r¬ztt|dƒƒ}Wn"tyttd|›d�ƒ‚Yn0|tvr˜|||dd…||<q¾d||›�||<qd||›�||<qd   |¡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 ú%rrrGéz"Invalid percent-escape sequence: 'ú'NÚ) r3ÚrangerBÚisalnumÚchrr/r2rÚUNRESERVED_SETrr)ÚuriÚpartsÚiÚhÚcr:r:r;Úunquote_unreserved{s  rÐcCs>d}d}ztt|ƒ|d�WSty8t||d�YS0dS)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)rrÐr)rËZsafe_with_percentZsafe_without_percentr:r:r;Ú requote_uri“s  rÒcCslt dt |¡¡d}| d¡\}}t dt tt|ƒƒ¡¡d}t dt |¡¡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=Lrrq)ÚstructÚunpackÚsocketÚ inet_atonr3Údotted_netmaskr/)ZipZnetZipaddrZnetaddrÚbitsZnetmaskZnetworkr:r:r;Úaddress_in_network©s rÙcCs&ddd|>dA}t t d|¡¡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ÕZ inet_ntoarÓÚpack)ÚmaskrØr:r:r;r׸sr×cCs(zt |¡Wnty"YdS0dS)z :rtype: bool FT)rÕrÖr1)Z string_ipr:r:r;Úis_ipv4_addressÃs  rÝcCs†| d¡dkr~zt| d¡dƒ}Wnty8YdS0|dksJ|dkrNdSzt | d¡d¡Wq‚tyzYdS0ndSdS)zV Very simple check of the cidr format in no_proxy variable. :rtype: bool rqrFrÚrT)Úcountr/r3r2rÕrÖr1)Zstring_networkrÜr:r:r;Ú is_valid_cidrÎs   rßc cst|du}|r"tj |¡}|tj|<z*dVW|rp|durBtj|=qp|tj|<n"|rn|durdtj|=n |tj|<0dS)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)rKr\r])Zenv_namer‰Z value_changedÚ old_valuer:r:r;Ú set_environæs    ü rác Cs>dd„}|}|dur|dƒ}t|ƒ}|jdur2dS|rÖdd„| dd ¡ d ¡Dƒ}t|jƒr”|D]0}t|ƒr€t|j|ƒr�dSq`|j|kr`dSq`nB|j}|jr°|d |j›�7}|D] }|j |¡sÎ| |¡r´dSq´t d|ƒ�>zt |jƒ}Wnt t j f�yd }Yn0Wdƒn1�s&0Y|�r:dSd S) zL Returns whether we should bypass proxies or not. :rtype: bool cSstj |¡ptj | ¡¡S©N)rKr\r]Úupper)rªr:r:r;Ú get_proxysz(should_bypass_proxies..get_proxyNÚno_proxyTcss|]}|r|VqdSrâr:)rTr8r:r:r;rVrWz(should_bypass_proxies..ú rÆú,ú:F)rÚhostnamer4r3rÝrßrÙÚportÚendswithrárrÁrÕZgaierror) rfråräZ no_proxy_argÚparsedZproxy_ipZhost_with_portr8Zbypassr:r:r;Úshould_bypass_proxiesüs<      *rícCst||d�riStƒSdS)zA Return a dict of environment proxies. :rtype: dict ©råN)rír)rfrår:r:r;Úget_environ_proxies8s rïcCst|pi}t|ƒ}|jdur.| |j| d¡¡S|jd|j|jd|jdg}d}|D]}||vrV||}qpqV|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://)rrér]Úscheme)rfÚproxiesZurlpartsZ proxy_keysÚproxyZ proxy_keyr:r:r;Ú select_proxyDs ürôc Cst|dur |ni}|j}t|ƒj}| d¡}| ¡}|rpt||d�spt||d�}| || d¡¡}|rp| ||¡|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årîrð)rfrrñr]ÚcopyrírïÚ setdefault) ZrequestròZ trust_envrfrñråZ new_proxiesZenviron_proxiesrór:r:r;Úresolve_proxies^s     r÷úpython-requestscCs|›dt›�S)zO Return a string representing the default user agent. :rtype: str rqr)rir:r:r;Údefault_user_agentysrùcCsttƒtdddœƒS)z9 :rtype: requests.structures.CaseInsensitiveDict z*/*z keep-alive)z User-AgentzAccept-EncodingZAcceptZ Connection)r!rùÚDEFAULT_ACCEPT_ENCODINGr:r:r:r;Údefault_headers‚süÿrûc CsÊg}d}| |¡}|s|St d|¡D]ž}z| dd¡\}}WntyZ|d}}Yn0d| d¡i}| d¡D]D}z| d¡\}}Wnty¢YqºYn0| |¡|| |¡<qt| |¡q&|S) z¼Return 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”)r¢r5r3r2r�) r‰ZlinksZ replace_charsÚvalrfr¨Úlinkr©rªr:r:r;Úparse_header_links�s&     rþúr[rGécCsÐ|dd…}|tjtjfvr dS|dd…tjkr6dS|dd…tjtjfvrRdS| t¡}|dkrhd S|dkrœ|ddd…tkr†d S|d dd…tkrœd S|dkrÌ|dd…t kr¸d S|d d…t krÌdSdS)z :rtype: str Nézutf-32rz utf-8-sigrGzutf-16rr®z 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)ÚdataZsampleZ nullcountr:r:r;Úguess_json_utf»s*  r c Cslt|ƒ}|\}}}}}}} |j} | s.|| } }|r@d || g¡} |durL|}|durXd}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Æ)rrerrr) rfZ new_schemerìrñÚauthr8rêr_ÚqueryÚfragmentrer:r:r;Úprepend_scheme_if_neededÛs rc Cs@t|ƒ}zt|jƒt|jƒf}Wnttfy:d}Yn0|S)z{Given a url with authentication components, extract them into a tuple of username,password. :rtype: (str,str) )rÆrÆ)rrÚusernameÚpasswordrJrÁ)rfrìr r:r:r;Úget_auth_from_urløs  rcCs$|\}}t||dƒt||dƒdS)z§Verifies that header parts don't contain leading whitespace reserved characters, or return characters. :param header: tuple, in the format (name, value). rrN)Ú_validate_header_part)r¥rir‰r:r:r;Úcheck_header_validitys rcCsxt|tƒrt|}n2t|tƒr(t|}ntd|›d|›dt|ƒ›�ƒ‚| |¡st|dkr\dnd}td|›d|›�ƒ‚dS) Nz Header part (z) from z# must be of type str or bytes, not rrir‰zSInvalid leading whitespace, reserved character(s), or returncharacter(s) in header z: )rcrr rr rÚtyper6)r¥Z header_partZheader_validator_indexZ validatorZ header_kindr:r:r;rs$    ÿÿ ÿÿÿrcCsFt|ƒ\}}}}}}|s"||}}| dd¡d}t|||||dfƒS)zW Given a url remove the fragment and the authentication part. :rtype: str r rrkrÆ)rÚrsplitr)rfrñrer_r¨rrr:r:r;Ú urldefragauth&s  rcCsZt|jddƒ}|durNt|jtƒrNz||jƒWqVtyJtdƒ‚YqV0ntdƒ‚dS)zfMove file pointer back to its recorded starting position so it can be read again on redirect. rFNz;An error occurred when rewinding request body for redirect.z+Unable to rewind request body for redirect.)rmÚbodyrcZ_body_positionrr1r )Zprepared_requestZ body_seekr:r:r;Ú rewind_body7s ÿ ÿ r)F)F)N)T)rø)jÚ__doc__rµÚ contextlibrHrKr5rÕrÓÚsysrvrOrsÚ collectionsrZ urllib3.utilrrrÆrrZ_internal_utilsr r r r Úcompatr rrrrrrrŽrrrrrrrZcookiesrÚ exceptionsrrrr Z structuresr!r^ÚwhereZDEFAULT_CA_BUNDLE_PATHZ DEFAULT_PORTSrrr3rúÚplatformr<r@rSrhrpr~ÚcontextmanagerrwrŠrŒr“r•r�ršr›r¡r«r°r¼r¿rÂÚ frozensetrÊrÐrÒrÙr×rÝrßrárírïrôr÷rùrûrþÚencoderrr r rrrrrrr:r:r:r;Úsž     $   ÿ $  B 9%  #   (ÿ   <   &