
0c@_E7                 @   s   d  Z  d d l 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 e  Z e j d  Z d	 d
   Z Gd d   d e  Z d S)z7
The httplib2 algorithms ported for use with requests.
    N)parsedate_tz)CaseInsensitiveDict   )	DictCache)
Serializerz9^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?c             C   s<   t  j |   j   } | d | d | d | d | d f S)zParses a URI using the regex given in Appendix B of RFC 3986.

        (scheme, authority, path, query, fragment) = parse_uri(uri)
    r               )URImatchgroups)urir    r   B/tmp/pip-build-jynh7p1z/pip/pip/_vendor/cachecontrol/controller.py	parse_uri   s    r   c               @   s   e  Z d  Z d Z d d d d d d  Z e d d    Z e d d	    Z d
 d   Z d d   Z	 d d   Z
 d d d d  Z d d   Z d S)CacheControllerz9An interface to see if request should cached or not.
    NTc             C   sL   | d  k r t    n | |  _ | |  _ | p3 t   |  _ | pB d |  _ d  S)N      ,  -  )r   r   r   r   )r   cachecache_etagsr   
serializercacheable_status_codes)selfr   r   r   status_codesr   r   r   __init__"   s    	zCacheController.__init__c       	      C   s   t  |  \ } } } } } | s) | r9 t d |   | j   } | j   } | s] d } | rx d j | | g  p{ | } | d | | } | S)z4Normalize the URL to create a safe key for the cachez(Only absolute URIs are allowed. uri = %s/?z://)r   	Exceptionlowerjoin)	clsr   scheme	authoritypathqueryfragmentrequest_uri
defrag_urir   r   r   _urlnorm*   s    !zCacheController._urlnormc             C   s   |  j  |  S)N)r+   )r#   r   r   r   r   	cache_url>   s    zCacheController.cache_urlc       
      C   s  d t  d f d t  d f d t  d f d d d d d d d	 d d
 d d d d d d d  d t  d f i } | j d | j d d   } i  } x| j d  D]} | j   s q | j d d  } | d j   } y | | \ } }	 Wn% t k
 rt j d |  w Yn X| s|	 r%d  | | <| r y | | d j    | | <Wq t k
 rs|	 rot j d |  Yq t k
 rt j d | | j	  Yq Xq W| S)!Nzmax-ageTz	max-staleFz	min-freshzno-cachezno-storezno-transformzonly-if-cachedzmust-revalidatepublicZprivatezproxy-revalidatezs-maxagezcache-controlzCache-Control ,=r   r   z,Ignoring unknown cache-control directive: %sz-Missing value for cache-control directive: %sz8Invalid value for cache-control directive %s, must be %s)NF)NF)NF)NF)NF)NF)NF)NF)
intgetsplitstripKeyErrorloggerdebug
IndexError
ValueError__name__)
r   headersZknown_directivesZ
cc_headersretvalZcc_directivepartsZ	directivetyprequiredr   r   r   parse_cache_controlB   sP    
z#CacheController.parse_cache_controlc             C   s  |  j  | j  } t j d |  |  j | j  } d | k rQ t j d  d Sd | k r~ | d d k r~ t j d  d S|  j j |  } | d k r t j d	  d S|  j j	 | |  } | s t j
 d
  d S| j d k r d } t j |  | St | j  } | s!d | k r[d | k rJt j d  |  j j |  t j d  d St j   } t j t | d   }	 t d | |	  }
 t j d |
  |  j |  } d } d | k r| d } t j d |  nZ d | k r;t | d  } | d k	 r;t j |  |	 } t d |  } t j d |  d | k ra| d } t j d |  d | k r| d } |
 | 7}
 t j d |
  | |
 k rt j d  t j d | |
  | Sd | k rt j d  |  j j |  d S)ze
        Return a cached response if it exists in the cache, otherwise
        return False.
        zLooking up "%s" in the cachezno-cachez-Request header has "no-cache", cache bypassedFzmax-ager   z1Request header has "max_age" as 0, cache bypassedNzNo cache entry availablez1Cache entry deserialization failed, entry ignoredi-  zVReturning cached "301 Moved Permanently" response (ignoring date and etag information)dateetagz(Purging cached response: no date or etagz!Ignoring cached response: no datezCurrent age based on date: %iz#Freshness lifetime from max-age: %iexpiresz#Freshness lifetime from expires: %iz+Freshness lifetime from request max-age: %iz	min-freshz'Adjusted current age from min-fresh: %iz2The response is "fresh", returning cached responsez%i > %iz4The cached response is "stale" with no etag, purging)r,   urlr6   r7   r@   r;   r   r2   r   loadswarningstatusr   deletetimecalendartimegmr   max)r   requestr,   ccZ
cache_datarespmsgr;   nowrA   current_ageresp_ccfreshness_lifetimerC   expire_time	min_freshr   r   r   cached_requestx   sv    





zCacheController.cached_requestc             C   s   |  j  | j  } |  j j | |  j j |   } i  } | r t | j  } d | k rh | d | d <d | k r | d | d <| S)NrB   ETagzIf-None-Matchzlast-modifiedzLast-ModifiedzIf-Modified-Since)r,   rD   r   rE   r   r2   r   r;   )r   rM   r,   rO   new_headersr;   r   r   r   conditional_headers   s    !z#CacheController.conditional_headersc             C   s  | p |  j  } | j | k r8 t j d | j |  d St | j  } | d k	 r d | k r | d j   r t | d  t |  k r d S|  j	 | j  } |  j	 |  } |  j
 | j  }	 t j d |	  d }
 d | k r d }
 t j d  d | k rd }
 t j d	  |
 rK|  j j |	  rKt j d
  |  j j |	  |
 rUd Sd | j d d  k r~t j d  d S|  j rd | k rt j d  |  j j |	 |  j j | | d |  n | j d k rt j d  |  j j |	 |  j j | |   n d | k rd | k rl| d d k rlt j d  |  j j |	 |  j j | | d |  nK d | k r| d rt j d  |  j j |	 |  j j | | d |  d S)zc
        Algorithm for caching requests.

        This assumes a requests Response object.
        zStatus code %s not in %sNzcontent-lengthz&Updating cache with response from "%s"Fzno-storeTzResponse header has "no-store"zRequest header has "no-store"z0Purging existing cache entry to honor "no-store"*varyr.   zResponse header has "Vary: *"rB   zCaching due to etagbodyi-  zCaching permanant redirectrA   zmax-ager   z'Caching b/c date exists and max-age > 0rC   zCaching b/c of expires header)r   rG   r6   r7   r   r;   isdigitr1   lenr@   r,   rD   r   r2   rH   r   setr   dumps)r   rM   responser]   r   r   response_headerscc_reqrN   r,   no_storer   r   r   cache_response   s^    	"%	"
	zCacheController.cache_responsec                s   |  j  | j  } |  j j | |  j j |   } | s= | Sd g   | j j t   f d d   | j j	   D   d | _
 |  j j | |  j j | |   | S)zOn 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.
        zcontent-lengthc             3   s3   |  ]) \ } } | j      k r | | f Vq d  S)N)r!   ).0kv)excluded_headersr   r   	<genexpr>l  s   	z9CacheController.update_cached_response.<locals>.<genexpr>r   )r,   rD   r   rE   r   r2   r;   updatedictitemsrG   r`   ra   )r   rM   rb   r,   cached_responser   )rj   r   update_cached_responseR  s    !				"z&CacheController.update_cached_response)r:   
__module____qualname____doc__r   classmethodr+   r,   r@   rW   rZ   rf   rp   r   r   r   r   r      s   6o[r   )rs   loggingrerJ   rI   email.utilsr   Zpip._vendor.requests.structuresr   r   r   	serializer   	getLoggerr:   r6   compiler   r   objectr   r   r   r   r   <module>   s   	