U
    bk                     @   s0  d dl mZmZmZ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 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  ddl!m"Z"m#Z#m$Z$m%Z% ddl&m'Z' ee(Z)dZ*e+dZ,G dd deZ-G dd de.Z/G dd dee/dZ0G dd de
Z1dS )    )absolute_importdivisionprint_functionunicode_literals)	getLogger)local   )	AuthBaseBaseAdapterHTTPAdapterSession_basic_auth_strextract_cookies_to_jarget_auth_from_urlget_netrc_authRetry)
FTPAdapter)LocalFSAdapter)	S3Adapter   )read_binstar_tokens   )dals)CONDA_HOMEPAGE_URL)context)add_username_and_passwordget_proxy_username_and_passsplit_anaconda_tokenurlparse)
ProxyError)ZhttpZhttpsZftpZs3filec                   @   s   e Zd Zdd Zdd ZdS )EnforceUnusedAdapterc                 O   s   t d|j }t|d S )Nz|
        EnforceUnusedAdapter called with url %s
        This command is using a remote connection in offline mode.
        )r   urlRuntimeError)selfrequestargskwargsmessage r)   @lib/python3.8/site-packages/conda/gateways/connection/session.pysend$   s    zEnforceUnusedAdapter.sendc                 C   s
   t  d S N)NotImplementedError)r$   r)   r)   r*   close+   s    zEnforceUnusedAdapter.closeN)__name__
__module____qualname__r+   r.   r)   r)   r)   r*   r!   "   s   r!   c                       s,   e Zd ZdZ fddZ fddZ  ZS )CondaSessionTypez
    Takes advice from https://github.com/requests/requests/issues/1871#issuecomment-33327847
    and creates one Session instance per thread.
    c                    s    t  |d< tt| | |||S )N_thread_local)r   superr2   __new__)ZmcsnamebasesZdct	__class__r)   r*   r5   5   s    
zCondaSessionType.__new__c                    s>   z
| j jW S  tk
r8   tt|   }| j _| Y S X d S r,   )r3   sessionAttributeErrorr4   r2   __call__)clsr:   r8   r)   r*   r<   9   s
    
zCondaSessionType.__call__)r/   r0   r1   __doc__r5   r<   __classcell__r)   r)   r8   r*   r2   /   s   r2   c                       s   e Zd Z fddZ  ZS )CondaSessionc                    s  t t|   t | _| jtj tj	rbt
 }| d| | d| | d| | d| nZttjtjddddgd	d
}t|d}| d| | d| | dt  | dt  | dt  tj| jd< tj| _tjrtjtjf| _ntjrtj| _d S )Nzhttp://zhttps://zftp://zs3://i  i  i  i  F)ZtotalZbackoff_factorZstatus_forcelistZraise_on_status)Zmax_retrieszfile://z
User-Agent)r4   r@   __init__CondaHttpAuthauthproxiesupdater   Zproxy_serversZoffliner!   Zmountr   Zremote_max_retriesZremote_backoff_factorr   r   r   r   Z
user_agentheadersZ
ssl_verifyZverifyZclient_ssl_cert_keyZclient_ssl_certZcert)r$   Zunused_adapterZretryZhttp_adapterr8   r)   r*   rA   C   s4    

zCondaSession.__init__)r/   r0   r1   rA   r?   r)   r)   r8   r*   r@   A   s   r@   )	metaclassc                   @   s8   e Zd Zdd Zedd Zedd Zedd Zd	S )
rB   c                 C   s*   t |j|_| | |d| j |S )Nresponse)rB   add_binstar_tokenr"   _apply_basic_authZregister_hook
handle_407)r$   r%   r)   r)   r*   r<   l   s    
zCondaHttpAuth.__call__c                 C   sT   t | j}t|r|nd }|d kr,t| j}t|trPt|dkrPt| | jd< | S )Nr   ZAuthorization)	r   r"   anyr   
isinstancetuplelenr   rF   )r%   Zurl_authrC   r)   r)   r*   rJ   r   s    

zCondaHttpAuth._apply_basic_authc                 C   sn   t | \}}|sjtjrjt  D ]H\}}||r td| ddlm	} ||}||_
|jdd  S q | S )Nz"Adding anaconda token for url <%s>r   )ChannelT)Zwith_credentials)r   r   Zadd_anaconda_tokenr   items
startswithlogdebugZmodels.channelrP   tokenr"   )r"   Z	clean_urlrU   Zbinstar_urlrP   Zchannelr)   r)   r*   rI      s    

zCondaHttpAuth.add_binstar_tokenc           
      K   s   | j dkr| S | j |   |d}t| jj}||krNttd|t	f || }t
|\}}t|||}t||}|||< ||d< | j }t|j| j| j ||j ||jd< | jj|f|}	|	j|  ||	_|	S )a  
        Prompts the user for the proxy username and password and modifies the
        proxy in the session object to include it.

        This method is modeled after
          * requests.auth.HTTPDigestAuth.handle_401()
          * requests.auth.HTTPProxyAuth
          * the previous conda.fetch.handle_proxy_407()

        It both adds 'username:password' to the proxy URL, as well as adding a
        'Proxy-Authorization' header.  If any of this is incorrect, please file an issue.

        i  rD   z
            Could not find a proxy for %r. See
            %s/docs/html#configure-conda-for-use-behind-a-proxy-server
            for more information on how to configure proxies.
            zProxy-Authorization)Zstatus_codeZcontentr.   popr   r"   Zschemer   r   r   r   r   r   r%   copyr   Z_cookiesrawZprepare_cookiesrF   Z
connectionr+   historyappend)
rH   r'   rD   Zproxy_schemeZ	proxy_urlZusernameZpasswordZproxy_authorization_headerZprepZ	_responser)   r)   r*   rK      s0    




zCondaHttpAuth.handle_407N)r/   r0   r1   r<   staticmethodrJ   rI   rK   r)   r)   r)   r*   rB   i   s   

rB   N)2Z
__future__r   r   r   r   Zloggingr   Z	threadingr    r	   r
   r   r   r   r   r   r   r   Zadapters.ftpr   Zadapters.localfsr   Zadapters.s3r   Zanaconda_clientr   Z
auxlib.ishr   Zbase.constantsr   Zbase.contextr   Z
common.urlr   r   r   r   
exceptionsr   r/   rS   ZRETRIES	frozensetZCONDA_SESSION_SCHEMESr!   typer2   r@   rB   r)   r)   r)   r*   <module>   s&   ,(