o nnh-@sdZddlmZddlZddlZddlZddlZddlZddl Zddl Zddl Z ddl Z ddlZddlZddlZddlZddlZddlZddlZddlZddlZddlZddlmZddl mZddlmZmZmZddlm Z z ddl!Z!dZ"dZ#Wne$yd Z"e%Z#e&Z'Ynwe!j'Z'dd l(m)Z)dd l*m+Z+m,Z,dd l-m.Z.m/Z/m0Z0zddl1Z1dZ2Wn e3yd Z2YnwdZ4zdd l5m6Z6ddl7m8Z8ddl9m:Z:ddl;mWn e$yd Z>YnwdZ?zddl@Z@Gddde ZAWne$ye%Z?dZAYnwejBdejCejDBdZEGddde3ZFGdddeFZGGdddeFZHGdddeHZIGddde3ZJdZKdZLe2rledd ZMGd!d"d"e jNjOZLGd#d$d$ejPjQZKGd%d&d&e jNjRZSGd'd(d(ejPjTZUGd)d*d*eVZWd+d,ZXd-d.ZYd/d0ZZd1d2Z[Gd3d4d4e'Z\Gd5d6d6ejPj]Z]  d]d7d8Z^d^d9d:Z_d_d;d<Z`d=d>Zad`d@dAZbdBdCZcGdDdEdEZd    G   dadHdIZedJdKZfdLdMZgdNdOZh  F  dbdPdQZidRdSZjdcdWdXZk  F dddYdZZld[d\ZmdS)ea The **urls** utils module offers a replacement for the urllib python library. urllib is the python stdlib way to retrieve files from the Internet but it lacks some security features (around verifying SSL certificates) that users should care about in most situations. Using the functions in this module corrects deficiencies in the urllib module wherever possible. There are also third-party libraries (for instance, requests) which can be used to replace urllib with a more secure library. However, all third party libraries require that the library be installed on the managed machine. That is an extra step for users making use of a module. If possible, avoid third party libraries by using this code instead. ) annotationsN)contextmanager) cookiejar)unquoteurlparse urlunparse) BaseHandlerTFmissing_required_lib)Mapping is_sequence)to_bytes to_nativeto_text)x509)default_backend)hashes)UnsupportedAlgorithmc@s<eZdZdZedejZdZd ddZ ddZ d d Z dS) HTTPGSSAPIAuthHandlerz@ Handles Negotiate/Kerberos support through the gssapi library. z)(?:.*)\s*(Negotiate|Kerberos)\s*([^,]*),?iNcCs||_||_d|_dSN)usernamepassword_context)selfrrrD/usr/local/lib/python3.10/dist-packages/ansible/module_utils/urls.py__init__gs zHTTPGSSAPIAuthHandler.__init__cCs6|j|dd}|r|dt|dfSdS)Nzwww-authenticate)AUTH_HEADER_PATTERNsearchgetgroupbase64 b64decode)rheaders auth_matchrrrget_auth_valuelsz$HTTPGSSAPIAuthHandler.get_auth_valuecCs~|jrdSt|}||}|sdS|\}} d} |jr'tj|jtjjd} | rH|j rHt tj ds6t dt |j dd} tj j| | ddj} ntj| dd} d} t|d }|rmtd krmt|}|rmtj jd |d } td |jtjj}tjd|| | d|_d}|jjs|j| }|s |Sd|tt|f}|d||j |}||j!}|s |S|d} |jjr|S)N) name_typeacquire_cred_with_passwordzPlatform GSSAPI library does not support gss_acquire_cred_with_password, cannot acquire GSSAPI credential with explicit username and password.surrogate_or_stricterrorsinitiate)usage)namer/TDarwinstls-server-end-point:)application_datazHTTP@%s)r/r0credschannel_bindingsz%s %s Authorizationr)"rr get_full_urlr(rgssapiNameNameTypeuserrhasattrrawNotImplementedErrorr r*r3 Credentials getpeercertplatformsystemget_channel_binding_cert_hashChannelBindingshostnamehostbased_serviceSecurityContextcompletesteprr$ b64encodeadd_unredirected_headerparentopenr&)rreqfpcodemsgr&parsed auth_header auth_protocolin_tokenr b_passwordcredcbtcert cert_hashtargetresp out_tokenrrrhttp_error_401qsP          z$HTTPGSSAPIAuthHandler.http_error_401NN) __name__ __module__ __qualname____doc__recompileIr handler_orderrr(r]rrrrras  rz;^-----BEGIN CERTIFICATE-----\n.+?-----END CERTIFICATE-----$)flagsc@eZdZdZdS)ConnectionErrorzFailed to connect to the serverNr_r`rarbrrrrriric@rh) ProxyErrorz%Failure to connect because of a proxyNrjrrrrrlrkrlc@rh)SSLValidationErrorzoFailure to connect due to SSL validation failing No longer used, but kept for backwards compatibility Nrjrrrrrmrmc@rh) NoSSLErrorzNeeded to connect to an HTTPS url but no ssl library available to verify the certificate No longer used, but kept for backwards compatibility Nrjrrrrrornrocs"eZdZdZdfdd ZZS)MissingModuleErrorz8Failed to import 3rd party module required by the callerNcst|||_||_dSr)superrimport_tracebackmodule)rmessagerrrs __class__rrrs  zMissingModuleError.__init__r)r_r`rarbr __classcell__rrrurrpsrpccs,tjjj}tjtjj_dV|tjj_dS)zMonkey patch ``http.client.HTTPConnection.connect`` to be ``UnixHTTPConnection.connect`` so that when calling ``super(UnixHTTPSConnection, self).connect()`` we get the correct behavior of creating self.sock for the unix socket N)httpclientHTTPConnectionconnectUnixHTTPConnection)_connectrrr(unix_socket_patch_httpconnection_connects   r~cs0eZdZddZfddZfddZZS)UnixHTTPSConnectioncC ||_dSr _unix_socketr unix_socketrrrr zUnixHTTPSConnection.__init__cs6ttWddS1swYdSr)r~rqr{rrurrr{s "zUnixHTTPSConnection.connectctj|i||Srrqrrargskwargsrurr__call__zUnixHTTPSConnection.__call__)r_r`rarr{rrwrrrurrs  rcs$eZdZfddZddZZS)UnixHTTPSHandlerc tjdi|||_dSNrrqrrrrrrurrr zUnixHTTPSHandler.__init__cCsFi}z|j|d<Wn tyYnw|jt|j|fd|ji|S)Ncheck_hostnamecontext)_check_hostnameAttributeErrordo_openrrr)rrMrrrr https_opens zUnixHTTPSHandler.https_open)r_r`rarrrwrrrurrs rcs0eZdZdZddZddZfddZZS)r|z+Handles http requests to a unix socket filecCrrrrrrrrrzUnixHTTPConnection.__init__c Csrttjtj|_z |j|jWnty'}z td|j|fd}~ww|jtjur7|j |jdSdS)NzInvalid Socket File (%s): %s) socketAF_UNIX SOCK_STREAMsockr{rOSErrortimeout_GLOBAL_DEFAULT_TIMEOUT settimeout)rerrrr{s zUnixHTTPConnection.connectcrrrrrurrrrzUnixHTTPConnection.__call__)r_r`rarbrr{rrwrrrurr|s  r|c(eZdZdZfddZddZZS)UnixHTTPHandlerzHandler for Unix urlsc rrrrrurrr'rzUnixHTTPHandler.__init__cCs|t|j|Sr)rr|r)rrMrrr http_open+szUnixHTTPHandler.http_open)r_r`rarbrrrwrrrurr$s rcr)ParseResultDottedDictzO A dict that acts similarly to the ParseResult named tuple from urllib cstj|i|||_dSr)rqr__dict__rrurrr3rzParseResultDottedDict.__init__csfdddDS)z] Generate a list from this dict, that looks like the ParseResult named tuple csg|]}|dqSr)r").0krrr ;sz1ParseResultDottedDict.as_list..)schemenetlocpathparamsqueryfragmentrrrrras_list7szParseResultDottedDict.as_list)r_r`rarbrrrwrrrurr/s rcCs,t|}||j|j|j|jd|S)a Returns a dictionary of url parts as parsed by urlparse, but accounts for the fact that older versions of that library do not support named attributes (ie. .netloc) This method isn't of much use any longer, but is kept in a minimal state for backwards compat. )rrrDport)r_asdictupdaterrrDr)partsresultrrrgeneric_urlparse>s rccs"t|D]}|dVqdS)Nr) PEM_CERT_REfinditerr#)datamatchrrrextract_pem_certsQsrcCsJ|}t|d}tj|dpd}|rt|}|jjdddp$|S)Nr/filenamezcontent-dispositionheader) geturlrosrbasenamerstriprr& get_param)responseurlrrrrrget_response_filenameVs  rcCsT|jj}|jj}|p ddd}|d\}}|dpddd}||||fS)Napplication/octet-stream,rrcharsetzutf-8)r&get_content_typersplit)rget_typer content_type main_typesub_typerrrrparse_content_type`s  rcs4eZdZdZfddZddZeddZZS)GzipDecodedReaderzA file-like object to decode a response encoded with the gzip method, as described in RFC 1952. Largely copied from ``xmlrpclib``/``xmlrpc.client`` cs0ts t|td||_tjd|jddS)Nrrrb)modefileobj)HAS_GZIPrpmissing_gzip_error GZIP_IMP_ERR_iorqr)rrNrurrroszGzipDecodedReader.__init__cCs*ztj|W|jdS|jwr)gzipGzipFilecloserrrrrrvszGzipDecodedReader.closecCs tdddS)Nrzito decompress gzip encoded responses. Set "decompress" to False, to prevent attempting auto decompression)reasonr rrrrr|sz$GzipDecodedReader.missing_gzip_error) r_r`rarbrr staticmethodrrwrrrurris  rcs^eZdZdZd ddZfddZzejjj Wne y&ejjj Z YnwddZ Z S) HTTPRedirectHandlerzThis is an implementation of a RedirectHandler to match the functionality provided by httplib2. It will utilize the value of ``follow_redirects`` to determine how redirects should be handled in urllib. NcCrr)follow_redirects)rrrrrrrzHTTPRedirectHandler.__init__crrrrrurrrrzHTTPRedirectHandler.__call__c Csh|j}|dvrtjj|||||||S|dvr"tj||||||}|dvr?|dks2|dkr>tj|||||n)|dkr\|dksO|dksO|dvr[tj|||||n tj||||||j } |j } | dd }|d vr||j } n*d} d d |j D} |d kr|dkrd}|dkr|dkrd}|dkr|dkrd}tjj|| | | d|dS)N)urllib2urllib)nononeF)allyesTi,safe)GETHEAD z%20)i3i4cSs"i|] \}}|dvr||qS))zcontent-length content-typeztransfer-encodinglowerrrvrrr s z8HTTPRedirectHandler.redirect_request..i/rri.i-POSTT)rr&origin_req_host unverifiablemethod)rrrequestrredirect_requesterror HTTPError get_methodr6rrreplacer&itemsRequestupper) rrMrNrOrPr&newurlrrrr req_headersrrrrsH z$HTTPRedirectHandler.redirect_requestr)r_r`rarbrrrrrhttp_error_308rhttp_error_302rrwrrrurrs   rcCs|durg}t|std|jjtj|d}|s)|jtjO_d|_tj |_ |rD|sD|s2t }| t |dd|rD|j|d|rQ|dtt||rbt|dr[d |_|j||d |S) NzCiphers must be a list. Got %s.)cafileF)capathr)cadata:post_handshake_authT)keyfile)r TypeErrorrvr_sslcreate_default_contextoptions OP_NO_SSLv3r CERT_NONE verify_mode bytearrayextend get_ca_certsload_verify_locations set_ciphersjoinmaprr;r load_cert_chain)rrrciphersvalidate_certs client_cert client_keyrrrr make_contexts,   rc Csni}|r<|g}tt|ddddd}t|D] }t|}d||<qWdn1s/wYt||fSt}|j }|pG|j h}|rP| |t t dd} | dkrl| d| d| dn@| d krv| d n6| d kr| d n,| d kr| dn"| dkr| dn| dkr| d| dn | dkr| d| d|D]y} | r| |kstj| sqt| D]d}tj| |} tj| r+tj|ddvr+z.cer.crt.pem)rLr rreadr PEM_cert_to_DER_certrrget_default_verify_pathsrraddrr@rArrisdirlistdirisfilesplitext ExceptionrIOErrorlist)rrr paths_checkedfpemb_derdefault_verify_pathsdefault_capathrAr full_path cert_filerXrrrrsv               $    rcCs,|jjj}z||WStyYdSw)zC Attempt to get the peer certificate of the response from urlopen. N)rNr<_sockr?r)r binary_formrrrrr?Js   r?cCsntsdSt|t}d}z|j}Wn tyYnw|r#|jdvr't}t |t}| || S)zM Gets the channel binding app data for a TLS connection using the peer cert. N)md5sha1) HAS_CRYPTOGRAPHYrload_der_x509_certificatersignature_hash_algorithmrr0rSHA256Hashrfinalize)certificate_derrXhash_algorithmdigestrrrrBTs   rB-0000c CsHdgd|d|dgd|dd|d|d|d |d |fS) zAccepts a timetuple and optional zone which defaults to ``-0000`` and returns a date string as specified by RFC 2822, e.g.: Fri, 09 Nov 2001 01:08:47 -0000 Copied from email.utils.formatdate and modified for separate use z"%s, %02d %s %04d %02d:%02d:%02d %s)MonTueWedThuFriSatSunr) JanFebMarAprMayJunJulAugSepOctNovDecrrr) timetuplezonerrrrfc2822_date_stringks rdcCsi}g}t|}|jdkr|||fS|} |} | r|j} n/d|jvrK|jdd\} } d| vr7| dd\} } n| } d} t| } t| } t|j| d}|retrX|t| | nrt ddd d } t | t d | r|st j }|d| | | t j |}t j |}||||n=| r|rt| | |d <n1|rzttjd }||j}Wn tyd}Ynw|r|\} }} | r| rt| | |d <|||fS)Nftp@rrr)rr7zfor use_gssapi=Truez https://pypi.org/project/gssapi/)rrrr5NETRC)rrrrrr_replacerappendr rpGSSAPI_IMP_ERRrrHTTPPasswordMgrWithDefaultRealm add_passwordHTTPBasicAuthHandlerHTTPDigestAuthHandlerbasic_auth_headernetrcrenvironr"authenticatorsrDr3)r url_username url_password use_gssapiforce_basic_auth use_netrcr&handlersrQrrr credentials imp_err_msgpassman authhandlerdigest_authhandlerrclogindummyrrr_configure_auth|s\            rc@s~eZdZ     dddZdd Z       dd d Zd d ZddZddZdddZ dddZ dddZ ddZ dS)rNTF rcCs|pi|_t|jtstd|j||_||_||_||_||_||_ ||_ | |_ | |_ | |_ | |_||_||_||_||_||_||_||_t| tjrS| |_dSt|_dS)a<This class works somewhat similarly to the ``Session`` class of from requests by defining a cookiejar that can be used across requests as well as cascaded defaults that can apply to repeated requests For documentation of params, see ``Request.open`` >>> from ansible.module_utils.urls import Request >>> r = Request() >>> r.open('GET', 'http://httpbin.org/cookies/set?k1=v1').read() '{ "cookies": { "k1": "v1" } } ' >>> r = Request(url_username='user', url_password='passwd') >>> r.open('GET', 'http://httpbin.org/basic-auth/user/passwd').read() '{ "authenticated": true, "user": "user" } ' >>> r = Request(headers=dict(foo='bar')) >>> r.open('GET', 'http://httpbin.org/get', headers=dict(baz='qux')).read() zheaders must be a dict: %rN)r& isinstancedict ValueError use_proxyforcerrrsrt http_agentrvrrrrca_pathunredirected_headers decompressrrwrr CookieJarcookies)rr&rrrrrsrtrrvrrrrrrrrrrwrrrrrs0    zRequest.__init__cCs|dur|S|Srr)rvaluefallbackrrr _fallbackszRequest._fallbackc%Cs|duri}n t|tstdt|jfi|}|||j}|||j}|||j}|| |j} || |j } || |j } || |j } || |j } |||j }|||j}|||j}|||j}|||j}|||j}|||j}|||j}|||j}|||j}|||j}g}|r|t|t|| | || |\}}}|||||stji}|||st ||| ||d}|rt!||d}ntjj"|d}|||t#||dur|tj$|tjj%|}tj&|t'|dd}tjj(|||)d} | r'| *d | |r1| *d d n|rAt+|,d }!| *d |!dd|pHgD}|D]}"|"-|vr`| .|"||"qM| *|"||"qMtj/| d|}#|r|#j0dd-dkrt1|#j2}$|$|#_2d|#_3|#S)a Sends a request via HTTP(S) or FTP using urllib (Python3) Does not require the module environment Returns :class:`HTTPResponse` object. :arg method: method for the request :arg url: URL to request :kwarg data: (optional) bytes, or file-like object to send in the body of the request :kwarg headers: (optional) Dictionary of HTTP Headers to send with the request :kwarg use_proxy: (optional) Boolean of whether or not to use proxy :kwarg force: (optional) Boolean of whether or not to set `cache-control: no-cache` header :kwarg last_mod_time: (optional) Datetime object to use when setting If-Modified-Since header :kwarg timeout: (optional) How long to wait for the server to send data before giving up, as a float :kwarg validate_certs: (optional) Booleani that controls whether we verify the server's TLS certificate :kwarg url_username: (optional) String of the user to use when authenticating :kwarg url_password: (optional) String of the password to use when authenticating :kwarg http_agent: (optional) String of the User-Agent to use in the request :kwarg force_basic_auth: (optional) Boolean determining if auth header should be sent in the initial request :kwarg follow_redirects: (optional) String of urllib2, all/yes, safe, none to determine how redirects are followed, see HTTPRedirectHandler for more information :kwarg client_cert: (optional) PEM formatted certificate chain file to be used for SSL client authentication. This file can also include the key as well, and if the key is included, client_key is not required :kwarg client_key: (optional) PEM formatted file that contains your private key to be used for SSL client authentication. If client_cert contains both the certificate and key, this option is not required :kwarg cookies: (optional) CookieJar object to send with the request :kwarg use_gssapi: (optional) Use GSSAPI handler of requests. :kwarg unix_socket: (optional) String of file system path to unix socket file to use when establishing connection to the provided url :kwarg ca_path: (optional) String of file system path to CA cert bundle to use :kwarg unredirected_headers: (optional) A list of headers to not attach on a redirected request :kwarg decompress: (optional) Whether to attempt to decompress gzip content-encoded responses :kwarg ciphers: (optional) List of ciphers to use :kwarg use_netrc: (optional) Boolean determining whether to use credentials from ~/.netrc file :kwarg context: (optional) ssl.Context object for SSL validation. When provided, all other SSL related arguments are ignored. See make_context. :returns: HTTPResponse. Added in Ansible 2.9 Nzheaders must be a dict)rrrrr)rr)rpassthru) nonstring)rrz User-agentz cache-controlzno-cacheGMTzIf-Modified-SincecSsg|]}|qSrr)rhrrrr|z Request.open..zcontent-encodingrr)4rrrr&rrrrrrsrtrrvrrrrrrrrrrwrrirrrrrr ProxyHandlerrr HTTPSHandlerrHTTPCookieProcessor build_openerinstall_openerr rr add_headerrdrbrrJurlopenr"rrNlength)%rrrrr&rr last_mod_timerrrsrtrrvrrrrrurrrrrrwrrx auth_headers auth_handlers proxyhandler ssl_handleropenerrtstamprrrNrrrrLs5             z Request.opencK|jd|fi|S)zSends a GET request. Returns :class:`HTTPResponse` object. :arg url: URL to request :kwarg \*\*kwargs: Optional arguments that ``open`` takes. :returns: HTTPResponse rrLrrrrrrr"z Request.getcKr)zSends a OPTIONS request. Returns :class:`HTTPResponse` object. :arg url: URL to request :kwarg \*\*kwargs: Optional arguments that ``open`` takes. :returns: HTTPResponse OPTIONSrrrrrrrzRequest.optionscKr)zSends a HEAD request. Returns :class:`HTTPResponse` object. :arg url: URL to request :kwarg \*\*kwargs: Optional arguments that ``open`` takes. :returns: HTTPResponse rrrrrrheadrz Request.headcK|jd|fd|i|S)a(Sends a POST request. Returns :class:`HTTPResponse` object. :arg url: URL to request. :kwarg data: (optional) bytes, or file-like object to send in the body of the request. :kwarg \*\*kwargs: Optional arguments that ``open`` takes. :returns: HTTPResponse rrrrrrrrrrpost z Request.postcKr)a'Sends a PUT request. Returns :class:`HTTPResponse` object. :arg url: URL to request. :kwarg data: (optional) bytes, or file-like object to send in the body of the request. :kwarg \*\*kwargs: Optional arguments that ``open`` takes. :returns: HTTPResponse PUTrrrrrrputrz Request.putcKr)a)Sends a PATCH request. Returns :class:`HTTPResponse` object. :arg url: URL to request. :kwarg data: (optional) bytes, or file-like object to send in the body of the request. :kwarg \*\*kwargs: Optional arguments that ``open`` takes. :returns: HTTPResponse PATCHrrrrrrpatchrz Request.patchcKr)zSends a DELETE request. Returns :class:`HTTPResponse` object. :arg url: URL to request :kwargs \*\*kwargs: Optional arguments that ``open`` takes. :returns: HTTPResponse DELETErrrrrdeleterzRequest.delete)NTFrTNNNFrNNNNNNTNTN)NNNNNNNNNNNNNNNFNNNNNNNr) r_r`rarrrLr"rrrrrrrrrrrs0 1   rrrcCs|p|rdnd}tj||fid|d|d|d|d|d|d |d | d | d | d | d| d|d|d|d|d|d|d|d|d|d|S)zp Sends a request via HTTP(S) or FTP using urllib (Python3) Does not require the module environment rrrr&rrrrrrsrtrrvrrrrrurrrrrrw)rrL)rrr&rrrrrrrsrtrrvrrrrrurrrrrrwrrropen_urlsP "rc Cst|ts td|jjtjjd}t | D]\}}t|t r,d}d}|}d}nLt|trp| d}| d}t ||fsEtd| d }|sgztj|pRd d d d pYd}Wn tyfd}Ynw|d\}} }ntd|jj|s|rtt|ddd} tjj| } | d=| dd||fWdn1swYntjj||} | t|| dd| d=| jd|dd|r| jdttj |dd|!| q|j"tj#j$d} ~| d\} } }~ tj%&j'}|| d|fS)aATakes a mapping, and prepares a multipart/form-data body :arg fields: Mapping :returns: tuple of (content_type, body) where ``content_type`` is the ``multipart/form-data`` ``Content-Type`` header including ``boundary`` and ``body`` is the prepared bytestring body Payload content from a file will be base64 encoded and will include the appropriate ``Content-Transfer-Encoding`` and ``Content-Type`` headers. Example: { "file1": { "filename": "/bin/true", "mime_type": "application/octet-stream" }, "file2": { "content": "text based file content", "filename": "fake.txt", "mime_type": "text/plain", }, "text_form_field": "value" } z&Mapping is required, cannot be type %sz form-datatextplainNrcontentz4at least one of filename or content must be provided mime_typerF)strictrrrz5value must be a string, or mapping, cannot be type %sr+r,rz Content-Typez%s/%szContent-Dispositionz MIME-Versionr0r)policys r)(rr r rvr_emailmime multipart MIMEMultipartsortedrstrr"anyr mimetypes guess_typer2 partitionrLr applicationMIMEApplicationr*r nonmultipartMIMENonMultipart set_payload set_paramrrrrattachas_bytesrHTTPparserBytesHeaderParser parsebytes)fieldsmfieldrrrrrrsepr6partb_datar& b_contentrrrrprepare_multipartst              rcCs*|durd}dttd||fddS)zTakes a username and password and returns a byte string suitable for using as value of an Authorization header to do basic auth. NrsBasic %sz%s:%sr+r,)r$rIr )rrrrrroSsrocCsnttddtdddtdddtdddtdddtddtdddtdddtd dtd dtdddd S) zz Creates an argument spec that can be used with any module that will be requesting content via urllib/urllib2 r)typeboolF)rdefaultansible-httpgetT)rno_logr) rrrrrrsrtrvrrru)rrrrrurl_argument_spec\s       rc% Cs8ts |jtdtj}|jt_|jdd}|dur#|jdd}|jdd}|jdd}|jd t }|jd d}|jd d }|jd }|jd}|jd| } t | t j sdt } d}t |dd}z*zt|fid|d|d|d|d|d|d|d|d|d|d |d |d |d |d|d| d| d| d| d| d|d|d|}|dd |Di}|jD]\}}|}||vrd!|||f||<q|||<q||g}i} | D]}!|!j| |!j<||!j|!jfqd"d#d$|D|d%<| |d<|t d&|jd'd(||jd)Wn(ttfyQ}"z|jd5d*t|"i|WYd}"~"nd}"~"wtym}"z|jt|"|"jd+WYd}"~"nd}"~"wt j!j"y}"zN|"}z|"j#durt$|"%}#Wn t$yd}#Ynw|"&z|d,d |"DWn t'yYnw|t|"|#|"jd-WYd}"~"nd}"~"wt j!j(y}"zt)t*|"d.d}$|t d/t|"|$d0WYd}"~"nd}"~"wt+j!y}"z|t d1t|"dd0WYd}"~"nrd}"~"wt,j-j.y4}"z|t d2t|"j/dd0WYd}"~"nXd}"~"wt'yW}"z|jt d3t|"dd0t01d4WYd}"~"n=d}"~"wwW|t_||fSW|t_||fSW|t_||fSW|t_||fSW|t_||fSW|t_||fSW|t_||fSW|t_||fS|t_w)6aSends a request via HTTP(S) or FTP (needs the module as parameter) :arg module: The AnsibleModule (used to get username, password etc. (s.b.). :arg url: The url to use. :kwarg data: The data to be sent (in case of POST/PUT). :kwarg headers: A dict with the request headers. :kwarg method: "POST", "PUT", etc. :kwarg use_proxy: (optional) whether or not to use proxy (Default: True) :kwarg boolean force: If True: Do not get a cached copy (Default: False) :kwarg last_mod_time: Default: None :kwarg int timeout: Default: 10 :kwarg boolean use_gssapi: Default: False :kwarg unix_socket: (optional) String of file system path to unix socket file to use when establishing connection to the provided url :kwarg ca_path: (optional) String of file system path to CA cert bundle to use :kwarg cookies: (optional) CookieJar object to send with the request :kwarg unredirected_headers: (optional) A list of headers to not attach on a redirected request :kwarg decompress: (optional) Whether to attempt to decompress gzip content-encoded responses :kwarg cipher: (optional) List of ciphers to use :kwarg boolean use_netrc: (optional) If False: Ignores login and password in ~/.netrc file (Default: True) :returns: A tuple of (**response**, **info**). Use ``response.read()`` to read the data. The **info** contains the 'status' and other meta data. When a HttpError (status >= 400) occurred then ``info['body']`` contains the error response data:: Example:: data={...} resp, info = fetch_url(module, "http://example.com", data=module.jsonify(data), headers={'Content-type': 'application/json'}, method="POST") status_code = info["status"] body = resp.read() if status_code >= 400 : body = info['body'] rPrTNrrsrrtrrvrrrrru)rstatusrr&rrrrrrrrrrrwcSi|] \}}||qSrrrrrrrzfetch_url..z, z; css|]}d|VqdS)z%s=%sNr)rcrrr szfetch_url..cookies_stringz OK (%s bytes)zContent-Lengthunknown)rPrrrP)rP exceptioncSrrrrrrrrr)rPbodyrrOzRequest failed: %s)rPrzConnection failure: %szRConnection failure: connection was closed before a valid response was received: %szAn unknown error occurred: %s)rr)2r fail_jsonrrtempfiletempdirtmpdirrr"get_user_agentrrrrrrinforr&rrrr0rirrOrirrrprrrrrrrNrr*rr2URLErrorintgetattrrrxry BadStatusLineline traceback format_exc)%rsrrr&rrrrrrurrrrrrrw old_tempdirrrrrrvrrrrr temp_headersr0r cookie_list cookie_dictcookierrrOrrr fetch_urlps,        .&    $&&('%#  rcCs4|drgS|d}dd|dddDS)z1A list of the final component's suffixes, if any..cSsg|]}d|qS)rr)rsrrrrrz_suffixes..rN)endswithlstripr)r0rrr _suffixes s  rr_r`rcCstd}ttt|D]+\}}||kr||fS|t|kr#|kr1nn d||f}||}q ||fS||fS)aSplit a multi-part extension from a file name. Returns '([name minus extension], extension)'. Define the valid extension length (including the '.') with 'min' and 'max', 'count' sets the number of extensions, counting from the end, to evaluate. Evaluation stops on the first file extension that is outside the min and max range. If no valid extensions are found, the original ``name`` is returned and ``extension`` is empty. :arg name: File name or path. :kwarg min: Minimum length of a valid file extension. :kwarg max: Maximum length of a valid file extension. :kwarg count: Number of suffixes from the end to evaluate. rz%s%s) enumeratereversedrlenr)r0minmaxcount extensionisfxrrr_split_multiexts   r c Csd} t|} ttj| jdd\}}tj|j||dd}||j zCt |||||||||| | | d \}}|r@|j rL|j dkrL|j d||d fd | | }|r_||| | }|sS|W|j Sty}z|j d|t|fd WYd }~|j Sd }~ww) aDownload and save a file via HTTP(S) or FTP (needs the module as parameter). This is basically a wrapper around fetch_url(). :arg module: The AnsibleModule (used to get username, password etc. (s.b.). :arg url: The url to use. :kwarg data: The data to be sent (in case of POST/PUT). :kwarg headers: A dict with the request headers. :kwarg method: "POST", "PUT", etc. :kwarg boolean use_proxy: Default: True :kwarg boolean force: If True: Do not get a cached copy (Default: False) :kwarg last_mod_time: Default: None :kwarg int timeout: Default: 10 :kwarg unredirected_headers: (optional) A list of headers to not attach on a redirected request :kwarg decompress: (optional) Whether to attempt to decompress gzip content-encoded responses :kwarg ciphers: (optional) List of ciphers to use :returns: A string, the path to the downloaded file. ir)rF)dirprefixsuffixr)rrrrzFailure downloading %s, %srPrN)rr rrrrNamedTemporaryFileradd_cleanup_filer0rrOrr*writerr2r)rsrrr&rrrrrrrrbufsizer file_prefixfile_extfetch_temp_filersprrrrr fetch_file2s.      "rcCsdS)z%Returns a user agent used by open_urlrrrrrrr]sr)NNNNTNNr^)F)rJ)NNNTFNrTNNNFrNNNFNNNTNT)NNNNFNrFNNNNTNT)r_r`r) NNNTFNrNTN)nrb __future__rr$email.mime.applicationremail.mime.multipartemail.mime.nonmultipart email.parser email.policy email.utils http.clientrxrrprr@rcrrrtypes urllib.errorrurllib.request contextlibrr urllib.parserrrrrrr ImportErrorrobjectransible.module_utils.basicr 'ansible.module_utils.common.collectionsr r +ansible.module_utils.common.text.convertersr rrr HAS_SSLr2rA cryptographyrcryptography.hazmat.backendsrcryptography.hazmat.primitivesrcryptography.exceptionsr urllib_gssapi HAS_GSSAPIrjr7rrdMSrrirlrmrorprrr~ryHTTPSConnectionrrrzr| HTTPHandlerrrrrrrrrrrrr?rBrdrrrrrorrrr rrrrrrs            K       R ' L D g   ! +