o
    ~Āg	=                     @   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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)
Serializerz9^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?)-  4  c                 C   s0   t |  }|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   W/var/www/html/myenv/lib/python3.10/site-packages/pip/_vendor/cachecontrol/controller.py	parse_uri   s   "r   c                   @   s^   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 ZdS )CacheControllerz9An interface to see if request should cached or not.
    NTc                 C   s4   |d u rt  n|| _|| _|pt | _|pd| _d S )N)      i,  r   r   )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}|r(d||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   _urlnorm0   s   zCacheController._urlnormc                 C   s
   |  |S N)r+   )r#   r   r   r   r   	cache_urlD   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 }|dD ]c}| s/q(|d	d
}|d  }z|| \}}	W n tyR   td| Y q(w |rW|	s[d ||< |rz||d
  ||< W q( tyz   |	rxtd| Y q( ty   td||j	 Y q(w q(|S )NTF)NF)max-agez	max-stale	min-freshno-cache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_controlH   s^   z#CacheController.parse_cache_controlc                 C   s*  |  |j}td| | |j}d|v rtd dS d|v r.|d dkr.td dS | j|}|du r?td	 dS | j	||}|sOt
d
 dS t|jtv r_d}t| |S t|j}|rjd|vrd|vrytd | j| td dS t }tt|d }	td||	 }
td|
 | |}d}d|v r|d }td| n d|v rt|d }|durt||	 }td|}td| d|v r|d }td| d|v r|d }|
|7 }
td|
 ||
krtd td||
 |S d|vrtd | j| dS )ze
        Return a cached response if it exists in the cache, otherwise
        return False.
        zLooking up "%s" in the cacher0   z-Request header has "no-cache", cache bypassedFr.   r   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: %ir/   z'Adjusted current age from min-fresh: %iz2The response is "fresh", returning cached responsez%i > %iz4The cached response is "stale" with no etag, purging)r-   urlr<   r=   rJ   rA   r   r8   r   loadswarningr7   statusPERMANENT_REDIRECT_STATUSESr   deletetimecalendartimegmr   max)r   requestr-   cc
cache_datarespmsgrA   nowrK   current_ageresp_ccfreshness_lifetimerM   expire_time	min_freshr   r   r   cached_request~   sz   













zCacheController.cached_requestc                 C   s`   |  |j}| j|| j|}i }|r.t|j}d|v r$|d |d< d|v r.|d |d< |S )NrL   ETagzIf-None-Matchzlast-modifiedzLast-ModifiedzIf-Modified-Since)r-   rN   r   rO   r   r8   r   rA   )r   rX   r-   r[   new_headersrA   r   r   r   conditional_headers   s   
z#CacheController.conditional_headersc                 C   s  |p| j }|j|vrtd|j| dS t|j}d|v r'tt|d }nd}|durCd|v rC|d 	 rCt
|d t|krCdS | |j}| |}	| |j}
td|
 d}d|	v rgd	}td
 d|v rrd	}td |r| j|
rtd | j|
 |rdS d|ddv rtd dS | jrd|v rd}|drt|d }|durt|| }t|d}td| td | jj|
| j||||d dS t
|jtv rtd | j|
| j||d dS d|v rbtt|d }d|	v r)|	d dkr)td |	d }| jj|
| j||||d dS d|v rd|d rft|d }|durFt|| }nd}td| | jj|
| jj|||d|d dS dS dS dS )zc
        Algorithm for caching requests.

        This assumes a requests Response object.
        zStatus code %s not in %sNrK   r   content-lengthz&Updating cache with response from "%s"Fr1   TzResponse header has "no-store"zRequest header has "no-store"z0Purging existing cache entry to honor "no-store"*varyr4   zResponse header has "Vary: *"rL   rM   i u z"etag object cached for {0} secondszCaching due to etag)rM   zCaching permanent redirect    r.   z'Caching b/c date exists and max-age > 0z5Caching b/c of expires header. expires in {0} seconds)body)r   rQ   r<   r=   r   rA   rU   rV   r   isdigitr7   lenrJ   r-   rN   r   r8   rS   r   rW   formatsetr   dumpsrR   )r   rX   responserk   r   r   response_headersrK   cc_reqrY   r-   no_storeexpires_timerM   r   r   r   cache_response   s   




















zCacheController.cache_responsec                    sv   |  |j}| j|| j|}|s|S dg |jt fdd|j	 D  d|_
| 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.
        rg   c                 3   s(    | ]\}}|   vr||fV  qd S r,   )r!   ).0kvexcluded_headersr   r   	<genexpr>  s    z9CacheController.update_cached_response.<locals>.<genexpr>r   )r-   rN   r   rO   r   r8   rA   updatedictitemsrQ   ro   rp   )r   rX   rq   r-   cached_responser   rz   r   update_cached_responsey  s   		z&CacheController.update_cached_response)NTNN)NN)r@   
__module____qualname____doc__r   classmethodr+   r-   rJ   rc   rf   rv   r   r   r   r   r   r   $   s    


6p
{r   )r   loggingrerU   rT   email.utilsr   pip._vendor.requests.structuresr   r   r   	serializer   	getLoggerr@   r<   compiler   rR   r   objectr   r   r   r   r   <module>   s   

	