ó
¨9Vc           @   sœ   d  Z  d d l Z d d l Z d d l Z d d l m Z d d l m Z d d l m	 Z	 d d l
 m Z e j d ƒ Z d	 „  Z d
 e f d „  ƒ  YZ d S(   s7   
The httplib2 algorithms ported for use with requests.
iÿÿÿÿN(   t   parsedate_tz(   t   CaseInsensitiveDicti   (   t	   DictCache(   t
   Serializers9   ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?c         C   s<   t  j |  ƒ j ƒ  } | d | d | d | d | d f S(   s‡   Parses a URI using the regex given in Appendix B of RFC 3986.

        (scheme, authority, path, query, fragment) = parse_uri(uri)
    i   i   i   i   i   (   t   URIt   matcht   groups(   t   uriR   (    (    s@   /tmp/pip-build-5Z5nTX/pip/pip/_vendor/cachecontrol/controller.pyt	   parse_uri   s    t   CacheControllerc           B   sn   e  Z d  Z d	 e d	 d „ Z e d „  ƒ Z e d „  ƒ Z d „  Z	 d „  Z
 d „  Z d	 d „ Z d „  Z RS(
   s9   An interface to see if request should cached or not.
    c         C   s1   | p t  ƒ  |  _ | |  _ | p' t ƒ  |  _ d  S(   N(   R   t   cachet   cache_etagsR   t
   serializer(   t   selfR
   R   R   (    (    s@   /tmp/pip-build-5Z5nTX/pip/pip/_vendor/cachecontrol/controller.pyt   __init__   s    	c   	      C   sš   t  | ƒ \ } } } } } | s) | r< t d | ƒ ‚ n  | j ƒ  } | j ƒ  } | sc d } n  | r~ d j | | g ƒ p | } | d | | } | S(   s4   Normalize the URL to create a safe key for the caches(   Only absolute URIs are allowed. uri = %st   /t   ?s   ://(   R   t	   Exceptiont   lowert   join(	   t   clsR   t   schemet	   authorityt   patht   queryt   fragmentt   request_urit
   defrag_uri(    (    s@   /tmp/pip-build-5Z5nTX/pip/pip/_vendor/cachecontrol/controller.pyt   _urlnorm#   s    	!c         C   s   |  j  | ƒ S(   N(   R   (   R   R   (    (    s@   /tmp/pip-build-5Z5nTX/pip/pip/_vendor/cachecontrol/controller.pyt	   cache_url7   s    c   
      C   sö   i  } d } d | k r! d } n  | | k rò | | j  d ƒ } g  | D]R } d | j d ƒ k rG t g  | j  d d ƒ D] } | j ƒ  j ƒ  ^ qx ƒ ^ qG } g  | D]3 } d | j d ƒ k r¦ | j ƒ  j ƒ  d f ^ q¦ }	 t | |	 ƒ } n  | S(   sz   
        Parse the cache control headers returning a dictionary with values
        for the different directives.
        s   cache-controls   Cache-Controlt   ,iÿÿÿÿt   =i   (   t   splitt   findt   tuplet   stripR   t   dict(
   R   t   headerst   retvalt	   cc_headert   partst   partt   xt   parts_with_argst   namet   parts_wo_args(    (    s@   /tmp/pip-build-5Z5nTX/pip/pip/_vendor/cachecontrol/controller.pyt   parse_cache_control;   s    	\=c         C   sw  |  j  | j ƒ } |  j | j ƒ } d | k r6 t n t } d | k ra | d d k ra t } n  | rk t S|  j j | |  j j	 | ƒ ƒ } | s– t S| j
 d k r© | St | j ƒ } | sË d | k rî d | k rê |  j j | ƒ n  t St j ƒ  } t j t | d ƒ ƒ } t d | | ƒ }	 |  j | ƒ }
 d } d |
 k rj|
 d j ƒ  rjt |
 d ƒ } nP d | k rºt | d ƒ } | d	 k	 rºt j | ƒ | } t d | ƒ } qºn  d | k r÷y t | d ƒ } Wq÷t k
 ród } q÷Xn  d | k r>y t | d ƒ } Wn t k
 r0d } n X|	 | 7}	 n  | |	 k } | rT| Sd | k rs|  j j | ƒ n  t S(
   se   
        Return a cached response if it exists in the cache, otherwise
        return False.
        s   no-caches   max-agei    i-  t   datet   etagt   expiress	   min-freshN(   R   t   urlR.   R%   t   Truet   FalseR   t   loadsR
   t   gett   statusR   t   deletet   timet   calendart   timegmR    t   maxt   isdigitt   intt   Nonet
   ValueError(   R   t   requestR   t   cct   no_cachet   respR%   t   nowR/   t   current_aget   resp_cct   freshness_lifetimeR1   t   expire_timet	   min_fresht   fresh(    (    s@   /tmp/pip-build-5Z5nTX/pip/pip/_vendor/cachecontrol/controller.pyt   cached_requestS   s^    	!

c         C   s   |  j  | j ƒ } |  j j | |  j j | ƒ ƒ } i  } | r‹ t | j ƒ } d | k rk | d | d <n  d | k r‹ | d | d <q‹ n  | S(   NR0   t   ETags   If-None-Matchs   last-modifieds   Last-Modifieds   If-Modified-Since(   R   R2   R   R5   R
   R6   R   R%   (   R   RA   R   RD   t   new_headersR%   (    (    s@   /tmp/pip-build-5Z5nTX/pip/pip/_vendor/cachecontrol/controller.pyt   conditional_headersµ   s    !c   	      C   sÂ  | j  d k r d St | j ƒ } |  j | j ƒ } |  j | ƒ } |  j | j ƒ } | j d ƒ pp | j d ƒ } | rž |  j j | ƒ rž |  j j | ƒ n  |  j	 rÞ d | k rÞ |  j j
 | |  j j | | d | ƒƒ nà | j  d k r|  j j
 | |  j j | | ƒ ƒ n¬ d	 | k r¾| rw| j d
 ƒ rwt | d
 ƒ d k r»|  j j
 | |  j j | | d | ƒƒ q»q¾d | k r¾| d r»|  j j
 | |  j j | | d | ƒƒ q»q¾n  d S(   sc   
        Algorithm for caching requests.

        This assumes a requests Response object.
        iÈ   iË   i,  i-  Ns   no-storeR0   t   bodyR/   s   max-agei    R1   (   iÈ   iË   i,  i-  (   R7   R   R%   R.   R   R2   R6   R
   R8   R   t   setR   t   dumpsR>   (	   R   RA   t   responseRP   t   response_headerst   cc_reqRB   R   t   no_store(    (    s@   /tmp/pip-build-5Z5nTX/pip/pip/_vendor/cachecontrol/controller.pyt   cache_responseÅ   s8    			"
	c            s¤   |  j  | j ƒ } |  j j | |  j j | ƒ ƒ } | s= | Sd g ‰  | j j t ‡  f d †  | j j	 ƒ  Dƒ ƒ ƒ d | _
 |  j j | |  j j | | ƒ ƒ | S(   sé   On a 304 we will get a new set of headers that we want to
        update our cached value with, assuming we have one.

        This should only ever be called when we've sent an ETag and
        gotten a 304 as the response.
        s   content-lengthc         3   s3   |  ]) \ } } | j  ƒ  ˆ  k r | | f Vq d  S(   N(   R   (   t   .0t   kt   v(   t   excluded_headers(    s@   /tmp/pip-build-5Z5nTX/pip/pip/_vendor/cachecontrol/controller.pys	   <genexpr>  s    	iÈ   (   R   R2   R   R5   R
   R6   R%   t   updateR$   t   itemsR7   RQ   RR   (   R   RA   RS   R   t   cached_response(    (   R[   s@   /tmp/pip-build-5Z5nTX/pip/pip/_vendor/cachecontrol/controller.pyt   update_cached_response   s    	
		&		N(   t   __name__t
   __module__t   __doc__R?   R3   R   t   classmethodR   R   R.   RL   RO   RW   R_   (    (    (    s@   /tmp/pip-build-5Z5nTX/pip/pip/_vendor/cachecontrol/controller.pyR	      s   		b	;(   Rb   t   reR:   R9   t   email.utilsR    t   pip._vendor.requests.structuresR   R
   R   t	   serializeR   t   compileR   R   t   objectR	   (    (    (    s@   /tmp/pip-build-5Z5nTX/pip/pip/_vendor/cachecontrol/controller.pyt   <module>   s   		