B
    '\i                 @   s8  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 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" ddl#m$Z$m%Z%m&Z&m'Z' ddl(m)Z) ee*Z+dZ,G dd deZ-G dd de.Z/e"e/G dd de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)
FTPAdapter)LocalFSAdapter)	S3Adapter   )read_binstar_tokens   )dals)CONDA_HOMEPAGE_URL)context)	iteritemswith_metaclass)add_username_and_passwordget_proxy_username_and_passsplit_anaconda_tokenurlparse)
ProxyErrorc               @   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.7/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   superr1   __new__)ZmcsnamebasesZdct)	__class__r)   r*   r4   .   s    
zCondaSessionType.__new__c                s8   y| j jS  tk
r2   tt|   }| j _|S X d S )N)r2   sessionAttributeErrorr3   r1   __call__)clsr8   )r7   r)   r*   r:   2   s
    zCondaSessionType.__call__)r.   r/   r0   __doc__r4   r:   __classcell__r)   r)   )r7   r*   r1   (   s   r1   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| n@ttj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rtj| _d S )Nzhttp://zhttps://zftp://zs3://)Zmax_retrieszfile://z
User-Agent)r3   r>   __init__CondaHttpAuthauthproxiesupdater   Zproxy_serversZoffliner!   Zmountr   Zremote_max_retriesr   r   r   Z
user_agentheadersZ
ssl_verifyZverifyZclient_ssl_cert_keyZclient_ssl_certZcert)r$   Zunused_adapterZhttp_adapter)r7   r)   r*   r?   =   s*    zCondaSession.__init__)r.   r/   r0   r?   r=   r)   r)   )r7   r*   r>   :   s   r>   c               @   s8   e Zd Zdd Zedd Zedd Zedd Zd	S )
r@   c             C   s*   t |j|_| | |d| j |S )Nresponse)r@   add_binstar_tokenr"   _apply_basic_authZregister_hook
handle_407)r$   r%   r)   r)   r*   r:   b   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   rD   )r%   Zurl_authrA   r)   r)   r*   rG   h   s    

zCondaHttpAuth._apply_basic_authc             C   sn   t | \}}|sjtjrjxRtt D ]D\}}||r"td| ddlm	} ||}||_
|jddS q"W | S )Nz"Adding anaconda token for url <%s>r   )ChannelT)Zwith_credentials)r   r   Zadd_anaconda_tokenr   r   
startswithlogdebugZmodels.channelrM   tokenr"   )r"   Z	clean_urlrQ   Zbinstar_urlrM   Zchannelr)   r)   r*   rF   w   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  rB   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_cookiesrD   Z
connectionr+   historyappend)
rE   r'   rB   Zproxy_schemeZ	proxy_urlZusernameZpasswordZproxy_authorization_headerZprepZ	_responser)   r)   r*   rH      s.    




zCondaHttpAuth.handle_407N)r.   r/   r0   r:   staticmethodrG   rF   rH   r)   r)   r)   r*   r@   _   s   r@   N)2Z
__future__r   r   r   r   Zloggingr   Z	threadingr    r	   r
   r   r   r   r   r   r   Zadapters.ftpr   Zadapters.localfsr   Zadapters.s3r   Zanaconda_clientr   Z_vendor.auxlib.ishr   Zbase.constantsr   Zbase.contextr   Zcommon.compatr   r   Z
common.urlr   r   r   r   
exceptionsr    r.   rO   ZRETRIESr!   typer1   r>   r@   r)   r)   r)   r*   <module>   s(   ($