o
    ҷhJ                     @  s   d Z ddlmZ ddl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mZmZ ddlmZ ddlmZmZ ddlmZ erZd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dZ!G dd dZ"dS )z7
The httplib2 algorithms ported for use with requests.
    )annotationsN)parsedate_tz)TYPE_CHECKING
CollectionMapping)CaseInsensitiveDict)	DictCacheSeparateBodyBaseCache)
Serializer)Literal)PreparedRequest)HTTPResponse)	BaseCachez9^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?)-  4  uristrreturntuple[str, str, str, str, str]c                 C  s@   t | }|dus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)
    N               )URImatchgroups)r   r   r    r   V/var/www/html/venv/lib/python3.10/site-packages/pip/_vendor/cachecontrol/controller.py	parse_uri'   s   
"r   c                   @  s   e Zd ZdZ				d5d6ddZed7ddZed7ddZd8ddZd9ddZ	d:d d!Z
d;d#d$Z		d<d=d-d.Z		d<d>d1d2Zd?d3d4ZdS )@CacheControllerz4An interface to see if request should cached or not.NTcacheBaseCache | Nonecache_etagsbool
serializerSerializer | Nonestatus_codesCollection[int] | Nonec                 C  s4   |d u rt  n|| _|| _|pt | _|pd| _d S )N)      i,  r   r   )r   r!   r#   r
   r%   cacheable_status_codes)selfr!   r#   r%   r'   r   r   r   __init__5   s   zCacheController.__init__r   r   r   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   _urlnormA   s   zCacheController._urlnormc                 C  s
   |  |S )N)r;   )r3   r   r   r   r   	cache_urlU   s   
zCacheController.cache_urlheadersMapping[str, str]dict[str, int | None]c           
      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,   r=   known_directives
cc_headersretvalcc_directiveparts	directivetyprequiredr   r   r   parse_cache_controlY   s^   z#CacheController.parse_cache_controlrequestr   HTTPResponse | Nonec                 C  s   d|j v rdS |j}|dusJ | j|}|du r!td dS t| jtr.| j|}nd}| j	
|||}|du rAtd |S )zO
        Load a cached response, or return None if it's not available.
        RangeNzNo cache entry availablez1Cache entry deserialization failed, entry ignored)r=   urlr!   rJ   rN   rO   
isinstancer	   get_bodyr%   loadswarning)r,   r\   r<   
cache_data	body_fileresultr   r   r   _load_from_cache   s   


z CacheController._load_from_cacheHTTPResponse | Literal[False]c                 C  s6  |j dusJ | |j }td| | |j}d|v r$td dS d|v r5|d dkr5td dS | |}|s>dS t|jt	v rNd	}t| |S t
|j}|rYd
|vrod|vrhtd | j| td dS t }t|d
 }|dusJ t|dd }	td||	 }
td|
 | |}d}|d}|dur|}td| n$d|v rt|d }|durt|dd |	 }td|}td| |d}|dur|}td| |d}|dur|
|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.
        NzLooking up "%s" in the cacherB   z-Request header has "no-cache", cache bypassedFr@   r   z1Request header has "max_age" as 0, cache bypassedzQReturning cached permanent redirect response (ignoring date and etag information)dateetagz(Purging cached response: no date or etagz!Ignoring cached response: no dater   zCurrent age based on date: %iz#Freshness lifetime from max-age: %iexpiresz#Freshness lifetime from expires: %iz+Freshness lifetime from request max-age: %irA   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_   r<   rN   rO   r[   r=   rg   rI   statusPERMANENT_REDIRECT_STATUSESr   r!   deletetimer   calendartimegmmaxrJ   )r,   r\   r<   ccrespmsgr=   now
time_tupleri   current_ageresp_ccfreshness_lifetimemax_agerk   expire_time	min_freshr   r   r   cached_request   sz   















zCacheController.cached_requestdict[str, str]c                 C  sH   |  |}i }|r"t|j}d|v r|d |d< d|v r"|d |d< |S )Nrj   ETagzIf-None-Matchzlast-modifiedzLast-ModifiedzIf-Modified-Since)rg   r   r=   )r,   r\   rt   new_headersr=   r   r   r   conditional_headers  s   

z#CacheController.conditional_headersr<   responser   bodybytes | Noneexpires_time
int | NoneNonec                 C  sj   t | jtr$| jj|| j||d|d |dur"| j|| dS dS | jj|| j||||d dS )z.
        Store the data in the cache.
            )rk   N)r`   r!   r	   setr%   dumpsset_body)r,   r<   r\   r   r   r   r   r   r   
_cache_set&  s   
zCacheController._cache_setresponse_or_ref2HTTPResponse | weakref.ReferenceType[HTTPResponse]c                 C  s  t |tjr| }|du rdS n|}|p| j}|j|vr&td|j| dS t|j}d|v rEt	|d }|dus;J t
|dd }	nd}	|durad|v ra|d  rat|d t|kradS | |j}
| |}|jdussJ | |j}td| d}d	|v rd
}td d	|
v rd
}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
|dd |	 }t|d}td| d td | ||||| dS t|jtv rtd | |||d dS d|v rt	|d }|dus'J t
|dd }	|d}|durQ|dkrQtd |}| ||||| dS d|v r|d rt	|d }|durrt
|dd |	 }nd}td| | ||||| dS dS dS dS )zc
        Algorithm for caching requests.

        This assumes a requests Response object.
        NzStatus code %s not in %sri   r   r   content-lengthz&Updating cache with response from "%s"FrC   TzResponse header has "no-store"zRequest header has "no-store"z0Purging existing cache entry to honor "no-store"*varyrF   zResponse header has "Vary: *"rj   rk   i u zetag object cached for z secondszCaching due to etagzCaching permanent redirectr   r@   z'Caching b/c date exists and max-age > 0z4Caching b/c of expires header. expires in {} seconds)r`   weakrefReferenceTyper+   rl   rN   rO   r   r=   r   rp   rq   isdigitrI   lenr[   r_   r<   r!   rJ   rn   r#   rr   r   rm   format)r,   r\   r   r   r'   r   r+   response_headersrw   ri   cc_reqrs   r<   no_storer   rk   r{   r   r   r   cache_responseD  s   


















zCacheController.cache_responsec                   sj   |j dusJ | |j }| |}|s|S dg |j fdd|j D  d|_| ||| |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.
        Nr   c                   s"   i | ]\}}|   vr||qS r   )r1   ).0kvexcluded_headersr   r   
<dictcomp>  s
    z:CacheController.update_cached_response.<locals>.<dictcomp>r)   )r_   r<   rg   r=   updateitemsrl   r   )r,   r\   r   r<   cached_responser   r   r   update_cached_response  s   	
	
	z&CacheController.update_cached_response)NTNN)r!   r"   r#   r$   r%   r&   r'   r(   )r   r   r   r   )r=   r>   r   r?   )r\   r   r   r]   )r\   r   r   rh   )r\   r   r   r   )NN)r<   r   r\   r   r   r   r   r   r   r   r   r   )
r\   r   r   r   r   r   r'   r(   r   r   )r\   r   r   r   r   r   )rR   
__module____qualname____doc__r-   classmethodr;   r<   r[   rg   r~   r   r   r   r   r   r   r   r   r    2   s.    

6

n" r    )r   r   r   r   )#r   
__future__r   rp   loggingrero   r   email.utilsr   typingr   r   r   pip._vendor.requests.structuresr   pip._vendor.cachecontrol.cacher   r	   "pip._vendor.cachecontrol.serializer
   r   pip._vendor.requestsr   pip._vendor.urllib3r   r   	getLoggerrR   rN   compiler   rm   r   r    r   r   r   r   <module>   s,   


