o
    th                     @   sJ  d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dlm	Z	m
Z
mZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ d dlmZmZmZmZmZmZmZmZmZ d d	l m!Z!m"Z"m#Z#m$Z$ d dl%Z%d d
l%m&Z& d dl'm(Z(m)Z)m*Z* e+e,Z-dZ.eedge/f  Z0dd Z1dd Z2de3fddZ4d[de5de6de7ddfddZ8de5ddfddZ9ded  fd!d"Z:G d#d$ d$Z;G d%d de;Z<G d&d de;Z=G d'd( d(Z>G d)d de?Z@d*d+ ZAd,e5de6fd-d.ZBdd/d0e@d1e0dee6 fd2d3ZCddd d4ddddd5d5ddd6d5d7d6d8d1e0d9e/de>fd:d;ZD	d\d<ed=ef d>e5de3d?ejEd@ee6 defdAdBZF	C	Dd]d<ed=ef dEee5 dFe6de3deee5 ee> f f
dGdHZGG dIdJ dJeZHe6dKde-jIdddddd7d5dCdLdMe6dee6 dNedOee dPee6 d1e0dQeeee6ge6f  dRe5dSe/dTe6fdUdVZJG dWdX dXZK	d\dYdZZLdS )^    N)ThreadPoolExecutorTimeoutErroras_completed)	parsedate)partial)	NOT_FOUND)count)create_default_context)	AnyCallableIteratorListMapping
NamedTupleOptionalTupleUnion)quoteurlparseurlsplit
urlunparse)
exceptions)performanceutilversionREDACTEDUrlErrorc                 C   s<   t t| dd}|d s|d r|d |d< d|d< t|S )Nhttp)scheme       )listr   r   )url
parsed_url r%   6/usr/lib/python3/dist-packages/cloudinit/url_helper.py	_cleanurl1   s
   r'   c                 G   s$   dd }| }|D ]}|||}q|S )Nc                 S   sN   t t| }|d }|r|ds|d7 }|tt|dd7 }||d< t|S )Nr    /z/:)safe)r"   r   endswithr   strr   )r#   add_on
url_parsedpathr%   r%   r&   combine_single<   s   z#combine_url.<locals>.combine_singler%   )baseadd_onsr/   r#   r,   r%   r%   r&   combine_url;   s
   	r2   returnc              
   C   s^   t jdt jdt jdt jdtdi}|t| }|s-t| t	r&| j
r&| j
}|S td d}|S )z4helper for read_ftps to map return codes to a number,      iX  i  z9Unexpected exception type while connecting to ftp server.i)ftpliberror_reply
error_temp
error_permerror_protoEOFErrorgettype
isinstanceOSErrorerrnoLOGwarning)excftp_error_codescoder%   r%   r&   "ftp_get_return_code_from_exceptionK   s    rG         @r#   timeoutkwargsFtpResponsec                 K   s  t | }|jstdtd| dt _}|jpd}|jpd}d|jkrzt	j
t d}td| | |j|j||p;d	d
 W n! t	jy` } zt|}	td|  d|	 d|	d| d|d}~ww td| z|j||jpodd td |  W n t	jy } ztd tddd| d|d}~ww zNz,td|j |jd|j |jd t| | W W td |  W  d   S  t	jy } zt|}	td|  d|	 d|	d| d|d}~ww td |  w zwzTt	 }
td| | |
j|j||pd	d
 td| |
j||jpdd td|j |
jd|j |jd t| | W W td |
  W  d   S  t	jyh } zt|}	td|  d|	 d|	d| d|d}~ww td |
  w 1 sww   Y  dS )az  connect to URL using ftp over TLS and read a file

    when using strict mode (ftps://), raise exception in event of failure
    when not using strict mode (ftp://), fall back to using unencrypted ftp

    url: string containing the desination to read a file from. The url is
        parsed with urllib.urlsplit to identify username, password, host,
        path, and port in the following format:
            ftps://[username:password@]host[:port]/[path]
        host is the only required component
    timeout: maximum time for the connection to take
    kwargs: unused, for compatibility with read_url
    returns: UrlResponse
    zInvalid url providedNcauserF   headersr#      	anonymousftps)contextz3Attempting to connect to %s via port [%s] over tls.rH   )hostportrI   z1Reading file from server over tls failed for url z []z"Attempting to login with user [%s]r!   )userpasswdzCreating a secure connectionzAttempted to connect to an insecure ftp server but used a scheme of ftps://, which is not allowed. Use ftp:// to allow connecting to insecure ftp servers.r6   zReading file: %szRETR )callbackzClosing connectionz,Reading file from ftp server failed for url z(Attempting to connect to %s via port %s.)r   hostnamer   r   ioBytesIOrT   usernamer   r7   FTP_TLSr	   rB   debugconnect
all_errorsrG   loginpasswordprot_pr:   rC   r.   
retrbinarywriterK   getvaluecloseFTP)r#   rI   rJ   	url_partsbufferrT   rV   ftp_tlserF   ftpr%   r%   r&   	read_ftpsb   s   




	
<



]

rn   r.   FileResponsec              
   K   s   | drtd|  zt| }t|| W S  ty+ } z	t|td| d|d}~w t	y@ } z
t||j
d| d|d}~ww )zmread a binary file and return a FileResponse

    matches function signature with read_ftps and read_url
    dataz'Unable to post data to file resource %sNrL   )r=   rB   rC   r   load_binary_filero   FileNotFoundErrorr   r   IOErrorrA   )r.   rJ   contentsrl   r%   r%   r&   
_read_file   s   

ru   )ro   UrlResponserK   c              
   K   s   |   } zt| }W n ty } zt|| d|d}~ww |j}|dks-| r6d| d kr6t|jfi |S |dv rBt| fi |S |dv rNt| fi |S t	
d| t| fi |S )	a0  Wrapper function around readurl to allow passing a file path as url.

    When url is not a local file path, passthrough any kwargs to readurl.

    In the case of parameter passthrough to readurl, default values for some
    parameters. See: call-signature of readurl in this module for param docs.
    )rM   r#   Nfiler(   r   )rm   rQ   )r   httpszAttempting unknown protocol %s)lstripr   
ValueErrorr   r   ru   r.   rn   readurlrB   rC   )r#   rJ   parsedrl   r   r%   r%   r&   read_file_or_url   s    
r}   c                   @   s&   e Zd Zd	ddZdd Zdd ZdS )
StringResponse   c                 C   s   || _ i | _|| _|| _d S N)rF   rN   rt   r#   selfrt   r#   rF   r%   r%   r&   __init__  s   
zStringResponse.__init__c                 O   s
   | j dkS )Nr   rF   r   argsrJ   r%   r%   r&   ok     
zStringResponse.okc                 C   s   | j dS )Nzutf-8)rt   decoder   r%   r%   r&   __str__  s   zStringResponse.__str__Nr   )__name__
__module____qualname__r   r   r   r%   r%   r%   r&   r~     s    
r~   c                       s(   e Zd Zddedef fddZ  ZS )ro   r   rt   r#   c                    s   t  j|||d d S )Nr   superr   r   	__class__r%   r&   r   !  s   zFileResponse.__init__r   r   r   r   bytesr+   r   __classcell__r%   r%   r   r&   ro      s     c                       s&   e Zd Zdedef fddZ  ZS )rK   rt   r#   c                    s   t  || d S r   r   )r   rt   r#   r   r%   r&   r   &  s   zFtpResponse.__init__r   r%   r%   r   r&   rK   %  s    c                   @   s   e Zd ZdejfddZedefddZede	fddZ
ddefd
dZedd ZedefddZdd Z		ddee dedee fddZdS )rv   responsec                 C   s
   || _ d S r   )	_response)r   r   r%   r%   r&   r   +  r   zUrlResponse.__init__r3   c                 C   s   | j jd u rdS | j jS )N    )r   contentr   r%   r%   r&   rt   .  s   zUrlResponse.contentsc                 C      | j jS r   )r   r#   r   r%   r%   r&   r#   4     zUrlResponse.urlFc                 C   s.   d}|rd}d| j   kr|k rdS  dS dS )Nr4   r5   r   TFr   )r   redirects_okupperr%   r%   r&   r   8  s   zUrlResponse.okc                 C   r   r   )r   rN   r   r%   r%   r&   rN   A  r   zUrlResponse.headersc                 C   r   r   )r   status_coder   r%   r%   r&   rF   E  r   zUrlResponse.codec                 C   r   r   )r   textr   r%   r%   r&   r   I  s   zUrlResponse.__str__r   
chunk_sizedecode_unicodec                 c   s    | j ||E dH  dS )at  Iterates over the response data.

        When stream=True is set on the request, this avoids reading the content
        at once into memory for large responses.

        :param chunk_size: Number of bytes it should read into memory.
        :param decode_unicode: If True, content will be decoded using the best
        available encoding based on the response.
        N)r   iter_content)r   r   r   r%   r%   r&   r   L  s   zUrlResponse.iter_contentN)F)r   F)r   r   r   requestsResponser   propertyr   rt   r+   r#   boolr   rN   intrF   r   r   r   r   r%   r%   r%   r&   rv   *  s(    	
rv   c                
   @   s:   e Zd Z			ddedee dee dee fddZdS )	r   NrM   rF   rN   r#   c                 C   s8   t | t| || _|| _|d u ri n|| _|| _d S r   )rs   r   r+   rM   rF   rN   r#   )r   rM   rF   rN   r#   r%   r%   r&   r   \  s
   
zUrlError.__init__)NNN)	r   r   r   r
   r   r   r   r+   r   r%   r%   r%   r&   r   [  s    c                 C   s   i }t | j}|dkr@|r@d|v r|d r|d |d< nd|d< d|v r4d|v r4|d |d g|d< |S d|v r@t|d |d< |S )Nrx   ca_certsverifyT	cert_filekey_filecert)r   r   r+   )r#   ssl_detailsssl_argsr   r%   r%   r&   _get_ssl_argsj  s   
r   retry_afterc                 C   s   zt | }W |S  tyV } zCzt| }|std|t t|t  }W n ty8   td|  d}Y nw |dk rKtd d}W Y d}~|S W Y d}~|S d}~ww )a<  Parse a Retry-After header value into an integer.

    : param retry_after: The value of the Retry-After header.
        https://www.rfc-editor.org/rfc/rfc9110.html#section-10.2.3
        https://www.rfc-editor.org/rfc/rfc2616#section-3.3
    : return: The number of seconds to wait before retrying the request.
    z(Failed to parse Retry-After header valuezGFailed to parse Retry-After header value: %s. Waiting 1 second instead.r   r   zBRetry-After header value is in the past. Waiting 1 second instead.N)floatrz   r   timemktimerB   info)r   to_waitrD   
time_tupler%   r%   r&   _get_retry_after|  s<   

r   exception_cberrorr   c                C   s`   |r|| rdS | j r*| j dkr*td| j | jr#t| jddS td dS |s.dS | )a  Handle exceptions raised during request processing.

    If we have no exception callback or the callback handled the error or we
    got a 503, return with an optional timeout so the request can be retried.
    Otherwise, raise the error.

    :param error: The exception raised during the request.
    :param response: The response object.
    :param exception_cb: Callable to handle the exception.

    :return: Optional time to wait before retrying the request.
    Ni  zNEndpoint returned a 503 error. HTTP endpoint is overloaded. Retrying URL (%s).zRetry-After1z7Unable to introspect response header. Waiting 1 second.r   )rF   rB   rC   r#   rN   r   r=   r   )r   r   r%   r%   r&   _handle_error  s   
r   r   TFr!   )rp   rI   retriessec_betweenrN   
headers_cbheaders_redactr   check_statusallow_redirectsr   sessioninfinitelog_req_resprequest_methodstreamr   c                    s  t | } | |d}|t| | |
|d< |s|rdnd}||d< |dur8t|tr/||d< n	tt|d|d< |du r>g }d	}|rKtt|d	 d	}d
t	  }|durZ|
 }ni }|rb||d< |du rhd}|du rpt }t D ]}|r||| }d|vr||d< ||d< i }| D ]1\} |dkrq|dkr|r fdd|D }|rt
 ||< |D ]}t|| |< qq ||< qz3|rtd||rdn|| | |jdi |}|	r|  td| |jt|j|d	  t|W   S  tjy } zt|| d|d}~w tjy) } zt||jj|jj| d}|}W Y d}~n"d}~w tjyF } zt|| d}|}d}W Y d}~nd}~ww t ||d}|s_|pX|d	 |k }|s_|||pc|}|dkrw|rrtd| t!"| qst#d)a`  Wrapper around requests.Session to read the url and retry if necessary

    :param url: Mandatory url to request.
    :param data: Optional form data to post the URL. Will set request_method
        to 'POST' if present.
    :param timeout: Timeout in seconds to wait for a response. May be a tuple
        if specifying (connection timeout, read timeout).
    :param retries: Number of times to retry on exception if exception_cb is
        None or exception_cb returns True for the exception caught. Default is
        to fail with 0 retries on exception.
    :param sec_between: Default 1: amount of seconds passed to time.sleep
        between retries. None or -1 means don't sleep.
    :param headers: Optional dict of headers to send during request
    :param headers_cb: Optional callable returning a dict of values to send as
        headers during request
    :param headers_redact: Optional list of header names to redact from the log
    :param ssl_details: Optional dict providing key_file, ca_certs, and
        cert_file keys for use on in ssl connections.
    :param check_status: Optional boolean set True to raise when HTTPError
        occurs. Default: True.
    :param allow_redirects: Optional boolean passed straight to Session.request
        as 'allow_redirects'. Default: True.
    :param exception_cb: Optional callable to handle exception and returns
        True if retries are permitted.
    :param session: Optional exiting requests.Session instance to reuse.
    :param infinite: Bool, set True to retry indefinitely. Default: False.
    :param log_req_resp: Set False to turn off verbose debug messages.
    :param request_method: String passed as 'method' to Session.request.
        Typically GET, or POST. Default: POST if data is provided, GET
        otherwise.
    :param stream: if False, the response content will be immediately
    downloaded.
    )r#   r   r   POSTGETmethodNrI   r   r   zCloud-Init/%srp   z
User-AgentrN   c                    s   g | ]	}  |r|qS r%   )r=   ).0kvr%   r&   
<listcomp>*  s    zreadurl.<locals>.<listcomp>z'[%s/%s] open '%s' with %s configurationr   z(Read from %s (%s, %sb) after %s attemptsr#   rF   rN   r#   r   1Please wait %s seconds while we wait to try againz"This path should be unreachable...r%   )$r'   updater   r?   tuplemaxr   r   r   version_stringcopyr   Sessionr   itemsdeepcopyr   rB   r^   requestraise_for_statusr   lenr   rv   r   SSLErrorr   	HTTPErrorr   rN   RequestExceptionr   r   sleepRuntimeError) r#   rp   rI   r   r   rN   r   r   r   r   r   r   r   r   r   r   r   req_argsmanual_tries
user_agentifiltered_req_argsr   matched_headerskeyr   rl   	url_errorraised_exceptionresponse_sleep_time
will_retry
sleep_timer%   r   r&   r{     s   5








r{   func.addreventdelayc                 C   s   |r
|j |dr
dS | ||S )z Execute func with optional delayrI   Nwaitr   r   rI   r   r   r%   r%   r&   _run_func_with_delays  s   
r   333333?
   	addressesstagger_delayc                    s.  d}d}d}g }t  tt|d z|zW fddt|D }t|dD ],}	||	 }|	 }
|
r>|
}|| q*|	 }|rV	  ||f  W W  j
dd S q*|rbtd|| |td	| td
 ty   tdd|dtt| Y nw W  j
dd ||fS  j
dd w )a  execute multiple callbacks in parallel

    Run blocking func against two different addresses staggered with a
    delay. The first call to return successfully is returned from this
    function and remaining unfinished calls are cancelled if they have not
    yet started
    N)max_workersc              
      s,   i | ]\}} j t|| d |qS )r   )submitr   )r   r   r   executorr   is_doner   rI   r%   r&   
<dictcomp>  s    	zdual_stack.<locals>.<dictcomp>r   Fr   z<Exception(s) %s during request to %s, raising last exceptionzEmpty result for address %szNo result returnedzJTimed out waiting for addresses: %s, exception(s) raised while waiting: %s )	threadingEventr   r   	enumerater   	exceptionappendresultsetshutdownrB   r^   r   rz   r   joinmapr+   )r   r   r   rI   return_resultreturned_addresslast_exceptionr   futuresfuturereturn_exceptionr%   r   r&   
dual_stack  sT   		r  c                   @   s2   e Zd ZU ee ed< ee ed< ee ed< dS )HandledResponser#   r   	wait_timeN)r   r   r   r   r+   __annotations__rv   r   r%   r%   r%   r&   r    s   
 r  inf)max_waitrI   	status_cbr   r   r   r   sleep_time_cbr   connect_synchronouslyasync_delayr  r  r   r   r  r   r  r  c                   s  dt dtf
fdd}d#dtdtdtfd	d
dtt dtt dttt tf fdddttgttt tt f f dt	tt
t f dt dtdtdtffdddtdt dtf	fdddtffdd}dtf fdd}t }
r|rtd|
r|n|}|p|}dd}	 |||||}d|jr|j|jjfS |jrt|j d  dq||}||r	 d"S d  td!| t| t }|r|| | kr||  }|dkr	 d"S q)$a  Wait for a response from one of the urls provided.

    :param urls: List of urls to try
    :param max_wait: Roughly the maximum time to wait before giving up
        The max time is *actually* len(urls)*timeout as each url will
        be tried once and given the timeout provided.
        a number <= 0 will always result in only one try
    :param timeout: Timeout provided to urlopen
    :param status_cb: Callable with string message when a url is not available
    :param headers_cb: Callable with single argument of url to get headers
        for request.
    :param headers_redact: List of header names to redact from the log
    :param sleep_time: Amount of time to sleep between retries. If this and
        sleep_time_cb are None, the default sleep time defaults to 1 second
        and increases by 1 seconds every 5 tries. Cannot be specified along
        with `sleep_time_cb`.
    :param exception_cb: Callable to handle exception and returns True if
        retries are permitted.
    :param sleep_time_cb: Callable with 2 arguments (response, loop_n) that
        generates the next sleep time. Cannot be specified
        along with 'sleep_time`.
    :param request_method: Indicates the type of HTTP request:
        GET, PUT, or POST
    :param connect_synchronously: If false, enables executing requests
        in parallel
    :param async_delay: Delay before parallel metadata requests, see RFC 6555

    :return: tuple of (url, response contents), on failure, (False, None)

    :raises: UrlError on unrecoverable error
    loop_numberr3   c                    s    d ur S |d d S )N   r   r%   )_r  )r   r%   r&   default_sleep_time  s   z(wait_for_url.<locals>.default_sleep_timer   r  
start_timer   c                 S   s0   | t ddfv r
dS | dkpt | | | kS )z4Check if time is up based on start time and max waitr  NFr   )r   r   	monotonic)r  r#  r   r%   r%   r&   timeup  s
   zwait_for_url.<locals>.timeupr   r#   c              
   S   s   d}d}| r|sd}t t|}||fS z| j  W n& tjjyA } zt ||jj|jj	|d}|t
|fW  Y d}~S d}~ww | jsZd| j }t t|| j| j	|d}||fS |  sod| j }t t|| j| j	|d}||fS )z?Map requests response code/contents to internal "UrlError" typer!   NzRequest timed outr   zempty response [%s]zbad status code [%s])r   rz   r   r   r   r   r   r   r   rN   r+   rt   rF   r   )r   r#   reasonurl_excrl   r%   r%   r&   handle_url_response  sH   

z)wait_for_url.<locals>.handle_url_responseurl_reader_cburlsexc_cblog_cbc              
      s  d}d}z| |\}} ||\}}|st ||ddW S W n/ ty5 }	 zd|	 }|	}W Y d}	~	nd}	~	w tyL }	 zd|	 }|	}W Y d}	~	nd}	~	ww tt | }
r[d nd}d|pet|d	d	|
||f }|| t ddt|trt||d
dS ddS )z:Execute request, handle response, optionally log exceptionr!   N)r  zrequest error [%s]zunexpected error [%s]z%ss	unlimitedzCalling '%s' failed [%s/%s]: %sr#   r   r#   r   r  )	r  r   	Exceptionr   r   r$  getattrr?   r   )r)  r*  r#  r+  r,  r&  r#   r   r'  rl   
time_takenmax_wait_str
status_msg)r(  r  r%   r&   read_url_handle_exceptionsD  sD   
z0wait_for_url.<locals>.read_url_handle_exceptionsrI   c                    s$   t |  d u ri n | |ddS )NF)rN   r   rI   r   r   )r{   )r#   rI   )r   r   r   r%   r&   read_url_cbp  s   z!wait_for_url.<locals>.read_url_cbc           
         s   dt f fdd}g }D ]H}t }dkr>s>| r(tdddd  S dur> r>|  |  kr>t|  |  ||| ||}|jrM|  S |jrV||j q|r]t|nd}	tdd|	dS )z|iterate over list of urls, request each one and handle responses
        and thrown exceptions individually per url
        r#   c                    s   |  | fS r   r%   r   )r5  rI   r%   r&   url_reader_serial     z@wait_for_url.<locals>.read_url_serial.<locals>.url_reader_serialr   Nr.  )	r+   r   r$  r  r   r   r  r	  r   )
r#  rI   r+  r,  r6  
wait_timesr#   nowoutr  )loop_nr  must_try_againr5  r4  r%  r*  r   r&   read_url_serialz  s0   


z%wait_for_url.<locals>.read_url_serialc                    s    t t |d}|| ||S )zpass list of urls to dual_stack which sends requests in parallel
        handle response and exceptions of the first endpoint to respond
        )r   rI   )r   r  )r#  rI   r+  r,  url_reader_parallel)r  r5  r4  r*  r%   r&   read_url_parallel  s   
z'wait_for_url.<locals>.read_url_parallelz3sleep_time and sleep_time_cb are mutually exclusiveNTFr   r   )FN)r   )r   r   r   rv   r+   r   r   r   r
   r   r   ExceptionCallbackr  r   r$  rz   r   r#   rt   r  r   rB   r^   )r*  r  rI   r  r   r   r   r   r  r   r  r  r"  r=  r?  r#  do_read_urlcalculate_sleep_timer   respcurrent_sleep_timecurrent_timer%   )r  r(  r   r   r;  r  r<  r5  r4  r   r   r%  r*  r&   wait_for_url  s   /
),
$


rF  c                   @   sh   e Zd Z					dddZdd Zdd Zd	d
 Zdd Zdd Zdd Z	dd Z
dd Zdd ZdS )OauthUrlHelperN/run/oauth_skew.jsonc                 C   st   || _ |pd| _|| _|| _|| _d| _d| _| j| j| j f}t|s'd| _nt|s/t	d| 
 }|p6i | _d S )Nr!   Tr   FzBall or none of token_key, token_secret, or consumer_key can be set)consumer_keyconsumer_secret	token_keytoken_secretskew_data_file	_do_oauthskew_change_limitanyallrz   read_skew_file	skew_data)r   rI  rK  rL  rJ  rM  requiredoldr%   r%   r&   r     s    
zOauthUrlHelper.__init__c              	   C   s   | j rGtj| j rGtd| j  , t| j dd}t|W  d    W  d    S 1 s2w   Y  W d    d S 1 sBw   Y  d S )NzReading rmode)	rM  osr.   isfiler   Timedopenjsonload)r   fpr%   r%   r&   rR    s   :zOauthUrlHelper.read_skew_filec              	   C   s   | j sd S |  }|d u ri }|||< td| j  0 t| j dd}|t| W d    n1 s7w   Y  W d    d S W d    d S 1 sOw   Y  d S )NzWriting wrW  )rM  rR  r   r[  r\  re   r]  dumps)r   rS   valuecurr_  r%   r%   r&   update_skew_file  s   PzOauthUrlHelper.update_skew_filec              
   C   s   t |tr|jdks|jdksd S d|jvrtd|j d S |jd }z	tt|}W n t	yG } ztd|| W Y d }~d S d }~ww t
|t  }t|jj}| j|d}t|| | jkrs| || td|| || j|< d S )Ni  i  datez$Missing header 'date' in %s responsez#Failed to convert datetime '%s': %sr   z$Setting oauth clockskew for %s to %d)r?   r   rF   rN   rB   rC   r   r   r   r/  r   r   r#   netlocrS  r=   absrO  rd  )r   r  re  remote_timerl   skewrS   old_skewr%   r%   r&   r     s.   


zOauthUrlHelper.exception_cbc                 C   sZ   | j si S d }t|j}| jr|| jv rtt | j|  }t|| j| j| j	| j
|dS )N)r#   rI  rK  rL  rJ  	timestamp)rN  r   rf  rS  r   r   oauth_headersrI  rK  rL  rJ  )r   r#   rk  rS   r%   r%   r&   r   -  s   
zOauthUrlHelper.headers_cbc                 C   s:   t | j|d|d< t | j|d|d< ||i |S )Nr   r   )r   _headers_cbr=   _exception_cb)r   wrapped_funcr   rJ   r%   r%   r&   _wrapped?  s   zOauthUrlHelper._wrappedc                 O      |  t||S r   )rp  rF  r   r%   r%   r&   rF  H  r7  zOauthUrlHelper.wait_for_urlc                 O   rq  r   )rp  r{   r   r%   r%   r&   r{   K  r7  zOauthUrlHelper.readurlc              	   C   s>   d}z|r||}W |  | |S W |  | |S |  | w )NTr   )r   extra_exception_cbr  retr%   r%   r&   rn  N  s   


zOauthUrlHelper._exception_cbc                 C   s$   i }|r||}| | | |S r   )r   r   )r   extra_headers_cbr#   rN   r%   r%   r&   rm  W  s
   zOauthUrlHelper._headers_cb)NNNNrH  )r   r   r   r   rR  rd  r   r   rp  rF  r{   rn  rm  r%   r%   r%   r&   rG    s     
		rG  c              
   C   sr   zdd l m} W n ty } ztd|d }~ww |r!t|}nd }|j|||||j|d}|| \}	}
}|
S )Nr   zoauth support is not available)client_secretresource_owner_keyresource_owner_secretsignature_methodrk  )oauthlib.oauth1oauth1ImportErrorNotImplementedErrorr+   ClientSIGNATURE_PLAINTEXTsign)r#   rI  rK  rL  rJ  rk  rz  rl   client_urisigned_headers_bodyr%   r%   r&   rl  _  s&   

rl  )rH   r   )r   r   )Mr   r7   rZ   r]  loggingrY  r  r   concurrent.futuresr   r   r   email.utilsr   	functoolsr   http.clientr   	itertoolsr   sslr	   typingr
   r   r   r   r   r   r   r   r   urllib.parser   r   r   r   r   r   	cloudinitr   r   r   	getLoggerr   rB   r   r   r@  r'   r2   r   rG   r+   r   dictrn   ru   r}   r~   ro   rK   rv   rs   r   r   r   r   r{   r  r   r  r  r^   rF  rG  rl  r%   r%   r%   r&   <module>   s  
,

 
1'
&
 6



S	

   