B
    žHe @  ã               @   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
mZ ddlmZ e e¡Ze d¡Zd	Zd
d„ ZG dd„ deƒZdS )z7
The httplib2 algorithms ported for use with requests.
é    N)Úparsedate_tz)ÚCaseInsensitiveDicté   )Ú	DictCacheÚSeparateBodyBaseCache)Ú
Serializerz9^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?)i-  i4  c             C   s0   t  | ¡ ¡ }|d |d |d |d |d fS )zƒParses 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   úw/var/www/downstreamdata.science/rtclock/rtclock-venv/lib/python3.7/site-packages/pip/_vendor/cachecontrol/controller.pyÚ	parse_uri   s    r   c               @   sf   e Zd ZdZddd„Zedd„ ƒZedd	„ ƒZd
d„ Zdd„ Z	dd„ Z
ddd„Zddd„Zdd„ ZdS )ÚCacheControllerz4An interface to see if request should cached or not.NTc             C   s4   |d krt ƒ n|| _|| _|p"tƒ | _|p,d| _d S )N)éÈ   éË   i,  i-  i4  )r   ÚcacheÚcache_etagsr   Ú
serializerÚcacheable_status_codes)Úselfr   r   r   Ústatus_codesr   r   r   Ú__init__'   s    zCacheController.__init__c       	      C   sh   t |ƒ\}}}}}|r|s&td| ƒ‚| ¡ }| ¡ }|s>d}|rPd ||g¡pR|}|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
   |   |¡S )N)r*   )r"   r   r   r   r   Ú	cache_urlC   s    zCacheController.cache_urlc       
      C   s*  t dft dft dfddddddddt dfdœ}| d| dd¡¡}i }xÞ| d¡D ]Ð}| ¡ s`qR| d	d
¡}|d  ¡ }y|| \}}	W n" tk
rª   t d|¡ wRY nX |r´|	s¼d ||< |rRy||d
  ¡ ƒ||< W qR tk
rü   |	røt d|¡ Y qR tk
r    t d||j	¡ Y qRX qRW |S )NTF)NF)zmax-agez	max-stalez	min-freshzno-cachezno-storezno-transformzonly-if-cachedzmust-revalidateÚpublicÚ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)
ÚintÚgetÚsplitÚstripÚKeyErrorÚloggerÚdebugÚ
IndexErrorÚ
ValueErrorÚ__name__)
r   ÚheadersÚknown_directivesÚ
cc_headersÚretvalÚcc_directiveÚpartsÚ	directiveÚtypÚrequiredr   r   r   Úparse_cache_controlG   sP    
z#CacheController.parse_cache_controlc             C   sX  |   |j¡}t d|¡ |  |j¡}d|kr:t d¡ dS d|kr\|d dkr\t d¡ dS | j |¡}|dkr~t d	¡ dS t| jt	ƒr˜| j 
|¡}nd}| j |||¡}|s¾t d
¡ dS t|jƒtkrÞd}t |¡ |S t|jƒ}|röd|kr$d|krt d¡ | j |¡ t d¡ dS t ¡ }	t t|d ƒ¡}
td|	|
 ƒ}t d|¡ |  |¡}d}d|kr†|d }t d|¡ nDd|krÊt|d ƒ}|dk	rÊt |¡|
 }td|ƒ}t d|¡ d|krè|d }t d|¡ d|kr|d }||7 }t d|¡ ||kr4t d¡ t d||¡ |S d|krTt d¡ | 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 ignoredzQReturning cached permanent redirect 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   rD   r;   r   r2   Ú
isinstancer   Úget_bodyr   ÚloadsÚwarningr1   ÚstatusÚPERMANENT_REDIRECT_STATUSESr   ÚdeleteÚtimeÚcalendarÚtimegmr   Úmax)r   Úrequestr+   ÚccÚ
cache_dataÚ	body_fileÚrespÚmsgr;   ÚnowrE   Úcurrent_ageÚresp_ccÚfreshness_lifetimerG   Úexpire_timeÚ	min_freshr   r   r   Úcached_request}   s|    



















zCacheController.cached_requestc             C   s`   |   |j¡}| j || j |¡¡}i }|r\t|jƒ}d|krH|d |d< d|kr\|d |d< |S )NrF   ÚETagzIf-None-Matchzlast-modifiedzLast-ModifiedzIf-Modified-Since)r+   rH   r   rK   r   r2   r   r;   )r   rT   r+   rX   Únew_headersr;   r   r   r   Úconditional_headersò   s    
z#CacheController.conditional_headersc             C   s\   t | jtƒr:| jj|| j ||d¡|d | j ||¡ n| jj|| j |||¡|d dS )z.
        Store the data in the cache.
        ó    )rG   N)rI   r   r   Úsetr   ÚdumpsÚset_body)r   r+   rT   ÚresponseÚbodyÚexpires_timer   r   r   Ú
_cache_set  s    zCacheController._cache_setc             C   s   |p| j }|j|kr(t d|j|¡ dS t|jƒ}d|krNt t|d ƒ¡}nd}|dk	r†d|kr†|d  	¡ r†t
|d ƒt|ƒkr†dS |  |j¡}|  |¡}	|  |j¡}
t d|
¡ d}d|	krÎd	}t d
¡ d|kräd	}t d¡ |r| j |
¡rt d¡ | j |
¡ |rdS d| dd¡kr8t d¡ dS | jr¶d|kr¶d}| d¡r~t|d ƒ}|dk	r~t |¡| }t|dƒ}t d |¡¡ t d¡ |  |
||||¡ næt
|jƒtkrât d¡ |  |
||d¡ nºd|krœt t|d ƒ¡}d|	kr<|	d dkr<t d¡ |	d }|  |
||||¡ n`d|krœ|d rœt|d ƒ}|dk	rvt |¡| }nd}t d |¡¡ |  |
||||¡ dS )zc
        Algorithm for caching requests.

        This assumes a requests Response object.
        zStatus code %s not in %sNrE   r   z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: *"rF   rG   i u z"etag object cached for {0} secondszCaching due to etagzCaching permanent redirectrd   zmax-agez'Caching b/c date exists and max-age > 0z5Caching b/c of expires header. expires in {0} seconds)r   rM   r6   r7   r   r;   rQ   rR   r   Úisdigitr1   ÚlenrD   r+   rH   r   r2   rO   r   rS   Úformatrk   rN   )r   rT   rh   ri   r   r   Úresponse_headersrE   Úcc_reqrU   r+   Úno_storerj   rG   r   r   r   Úcache_response  s    
















zCacheController.cache_responsec                sl   |   |j¡}| j || j |¡¡}|s*|S dg‰ |j t‡ fdd„|j 	¡ D ƒƒ¡ d|_
|  |||¡ |S )zé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.
        zcontent-lengthc             3   s&   | ]\}}|  ¡ ˆ kr||fV  qd S )N)r    )Ú.0ÚkÚv)Úexcluded_headersr   r   ú	<genexpr>«  s   z9CacheController.update_cached_response.<locals>.<genexpr>r   )r+   rH   r   rK   r   r2   r;   ÚupdateÚdictÚitemsrM   rk   )r   rT   rh   r+   Úcached_responser   )rx   r   Úupdate_cached_response‘  s    	
z&CacheController.update_cached_response)NTNN)NN)NN)r:   Ú
__module__Ú__qualname__Ú__doc__r   Úclassmethodr*   r+   rD   r`   rc   rk   rt   r~   r   r   r   r   r   $   s   
6u

{r   )r   ÚloggingÚrerQ   rP   Úemail.utilsr   Zpip._vendor.requests.structuresr   r   r   r   Ú	serializer   Ú	getLoggerr:   r6   Úcompiler   rN   r   Úobjectr   r   r   r   r   Ú<module>   s   

	