ó
Ý²k^c           @` s?  d  d l  m Z m Z m Z m Z d  d l m Z d  d l Z d  d l Z d  d l	 m
 Z
 d  d l m 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 e e ƒ Z e j j Z d „  Z e e j _ d e f d „  ƒ  YZ d „  Z d „  Z  d „  Z! d „  Z" d „  Z# d „  Z$ d S(   i    (   t   absolute_importt   divisiont   print_functiont   unicode_literals(   t	   b64decodeN(   t   BytesIO(   t	   getLoggeri   (   t   BaseAdaptert   Responset   dispatch_hooki   (   t   StringIO(   t   urlparse(   t   AuthenticationErrorc         C` s/   t  |  ƒ \ } } |  j j ƒ  d } | | f S(   Ni    (   t   _old_makepasvt   sockt   getpeername(   t   selft   hostt   port(    (    sE   lib/python2.7/site-packages/conda/gateways/connection/adapters/ftp.pyt   _new_makepasv(   s    t
   FTPAdapterc           B` s_   e  Z d  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z	 d „  Z
 d	 „  Z RS(
   u3   A Requests Transport Adapter that handles FTP urls.c         C` sR   t  t |  ƒ j ƒ  i |  j d 6|  j d 6|  j d 6|  j d 6|  j d 6|  _ d  S(   Nu   LISTu   RETRu   STORu   NLSTu   GET(   t   superR   t   __init__t   listt   retrt   stort   nlstt
   func_table(   R   (    (    sE   lib/python2.7/site-packages/conda/gateways/connection/adapters/ftp.pyR   3   s    


c   	      K` sÊ   |  j  | ƒ } |  j | ƒ \ } } } | j d d ƒ } t | t ƒ sQ d } n  t j ƒ  |  _ |  j j	 | | | ƒ | d k	 r  |  j j
 | d | d ƒ n |  j j
 ƒ  |  j | j | | ƒ } | S(   uC   Sends a PreparedRequest object over FTP. Returns a response object.u   timeouti
   i    i   N(   t!   get_username_password_from_headert   get_host_and_path_from_urlt   gett   Nonet
   isinstancet   intt   ftplibt   FTPt   connt   connectt   loginR   t   method(	   R   t   requestt   kwargst   authR   R   t   patht   timeoutt   resp(    (    sE   lib/python2.7/site-packages/conda/gateways/connection/adapters/ftp.pyt   send?   s    	c         C` s   d S(   u   Dispose of any internal state.N(    (   R   (    (    sE   lib/python2.7/site-packages/conda/gateways/connection/adapters/ftp.pyt   close\   s    c         C` sc   t  ƒ  } | j | _ |  j j | ƒ |  j j d t | ƒ ƒ } t | | | ƒ } |  j j ƒ  | S(   u0   Executes the FTP LIST command on the given path.u   LIST(   R
   R/   t   release_connR$   t   cwdt
   retrbinaryt   data_callback_factoryt   build_text_response(   R   R+   R(   t   datat   codet   response(    (    sE   lib/python2.7/site-packages/conda/gateways/connection/adapters/ftp.pyR   a   s    	c         C` sW   t  ƒ  } | j | _ |  j j d | t | ƒ ƒ } t | | | ƒ } |  j j ƒ  | S(   u0   Executes the FTP RETR command on the given path.u   RETR (   R   R/   R0   R$   R2   R3   t   build_binary_response(   R   R+   R(   R5   R6   R7   (    (    sE   lib/python2.7/site-packages/conda/gateways/connection/adapters/ftp.pyR   u   s    	c         C` ss   t  | ƒ } t j j | ƒ \ } } |  j j | ƒ |  j j d | | ƒ } |  j j ƒ  t | t	 ƒ  | ƒ } | S(   u0   Executes the FTP STOR command on the given path.u   STOR (
   t   parse_multipart_filest   osR+   t   splitR$   R1   t
   storbinaryR/   R8   R   (   R   R+   R(   R5   t   filenameR6   R7   (    (    sE   lib/python2.7/site-packages/conda/gateways/connection/adapters/ftp.pyR   †   s    c         C` sc   t  ƒ  } | j | _ |  j j | ƒ |  j j d t | ƒ ƒ } t | | | ƒ } |  j j ƒ  | S(   u0   Executes the FTP NLST command on the given path.u   NLST(   R
   R/   R0   R$   R1   R2   R3   R4   (   R   R+   R(   R5   R6   R7   (    (    sE   lib/python2.7/site-packages/conda/gateways/connection/adapters/ftp.pyR   ž   s    	c   	      C` s’   | j  j d ƒ } | rŠ | j ƒ  d  } | d d k rG t d ƒ ‚ n
 | d } t | ƒ } | j d ƒ } | d } | d } | | f Sd Sd S(	   uì   Given a PreparedRequest object, reverse the process of adding HTTP
        Basic auth to obtain the username and password. Allows the FTP adapter
        to piggyback on the basic auth notation without changing the control
        flow.u   Authorizationi   i    u   Basicu$   Invalid form of Authentication used.i   u   :N(   t   headersR   R;   R   R   R   (	   R   R(   t   auth_headert   encoded_componentst   encodedt   decodedt
   componentst   usernamet   password(    (    sE   lib/python2.7/site-packages/conda/gateways/connection/adapters/ftp.pyR   °   s    



c         C` s`   | j  } t | ƒ } | j } | d d k r; | d } n  | j } | j pP d } | | | f S(   uµ   Given a PreparedRequest object, split the URL in such a manner as to
        determine the host and the path. This is a separate method to wrap some
        of urlparse's craziness.i    u   /i   (   t   urlR   R+   t   hostnameR   (   R   R(   RF   t   parsedR+   R   R   (    (    sE   lib/python2.7/site-packages/conda/gateways/connection/adapters/ftp.pyR   Í   s    			(   t   __name__t
   __module__t   __doc__R   R.   R/   R   R   R   R   R   R   (    (    (    sE   lib/python2.7/site-packages/conda/gateways/connection/adapters/ftp.pyR   1   s   								c         ` s   ‡  f d †  } | S(   uÃ   Returns a callback suitable for use by the FTP library. This callback
    will repeatedly save data into the variable provided to this function. This
    variable should be a file-like structure.c         ` s   ˆ  j  |  ƒ d  S(   N(   t   write(   R5   (   t   variable(    sE   lib/python2.7/site-packages/conda/gateways/connection/adapters/ftp.pyt   callbackã   s    (    (   RM   RN   (    (   RM   sE   lib/python2.7/site-packages/conda/gateways/connection/adapters/ftp.pyR3   ß   s    c         C` s   t  |  | | d ƒ S(   u"   Build a response for textual data.u   ascii(   t   build_response(   R(   R5   R6   (    (    sE   lib/python2.7/site-packages/conda/gateways/connection/adapters/ftp.pyR4   ê   s    c         C` s   t  |  | | d ƒ S(   u4   Build a response for data whose encoding is unknown.N(   RO   R   (   R(   R5   R6   (    (    sE   lib/python2.7/site-packages/conda/gateways/connection/adapters/ftp.pyR8   ï   s    c         C` sh   t  ƒ  } | | _ | | _ |  j | _ |  | _ t | ƒ | _ | j j d ƒ t d |  j	 | ƒ } | S(   u\   Builds a response object from the data returned by ftplib, using the
    specified encoding.i    u   response(
   R   t   encodingt   rawRF   R(   t"   get_status_code_from_code_responset   status_codet   seekR	   t   hooks(   R(   R5   R6   RP   R7   (    (    sE   lib/python2.7/site-packages/conda/gateways/connection/adapters/ftp.pyRO   ô   s    				c         C` s    t  j |  j d ƒ \ } } t ƒ  } | j |  j ƒ | j d ƒ t  j | | ƒ } | j ƒ  \ } } | j	 ƒ  t ƒ  } | j d j
 | ƒ ƒ | j d ƒ | S(   uj   Given a prepared reqest, return a file-like object containing the
    original data. This is pretty hacky.u   Content-Typei    u    (   t   cgit   parse_headerR>   R   RL   t   bodyRT   t   parse_multipartt   popitemR/   t   join(   R(   t   _t   pdictt   bufR5   t   filedata(    (    sE   lib/python2.7/site-packages/conda/gateways/connection/adapters/ftp.pyR9   	  s    	
	c         C` s{   g  |  j  d ƒ D] } | r | ^ q d } t | j  ƒ  d ƒ } t |  d  ƒ } | | k rw t j d |  | | ƒ n  | S(   u×  
    The idea is to handle complicated code response (even multi lines).
    We get the status code in two ways:
    - extracting the code from the last valid line in the response
    - getting it from the 3 first digits in the code
    After a comparison between the two values,
    we can safely set the code or raise a warning.
    Examples:
        - get_status_code_from_code_response('200 Welcome') == 200
        - multi_line_code = '226-File successfully transferred
226 0.000 seconds'
          get_status_code_from_code_response(multi_line_code) == 226
        - multi_line_with_code_conflicts = '200-File successfully transferred
226 0.000 seconds'
          get_status_code_from_code_response(multi_line_with_code_conflicts) == 226
    For more detail see RFC 959, page 36, on multi-line responses:
        https://www.ietf.org/rfc/rfc959.txt
        "Thus the format for multi-line replies is that the first line
         will begin with the exact required reply code, followed
         immediately by a Hyphen, "-" (also known as Minus), followed by
         text.  The last line will begin with the same code, followed
         immediately by Space <SP>, optionally some text, and the Telnet
         end-of-line code."
    u   
iÿÿÿÿi    i   uZ   FTP response status code seems to be inconsistent.
Code received: %s, extracted: %s and %s(   R;   R!   t   logt   warning(   R6   t   linet   last_valid_line_from_codet   status_code_from_last_linet   status_code_from_first_digits(    (    sE   lib/python2.7/site-packages/conda/gateways/connection/adapters/ftp.pyRR   !  s    ,
(%   t
   __future__R    R   R   R   t   base64R   RV   R"   t   ioR   t   loggingR   R:   t    R   R   R	   t   common.compatR
   t
   common.urlR   t
   exceptionsR   RI   R`   R#   t   makepasvR   R   R   R3   R4   R8   RO   R9   RR   (    (    (    sE   lib/python2.7/site-packages/conda/gateways/connection/adapters/ftp.pyt   <module>   s*   "	®					