o
    VÌhUJ  ã                   @  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 )zƒParses 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   úk/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/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 ||< |r‹z||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 rÒt|d ƒ}|durÒt |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_refú2HTTPResponse | 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 rŒd
}t d¡ d	|
v r—d
}t d¡ |rª| j |¡rªt d¡ | j |¡ |r®dS d| dd¡v r½t d¡ dS | jrþd|v rþd}| d¡ràt	|d ƒ}|duràt
 |dd… ¡|	 }t|dƒ}t d|› d¡ t d¡ |  |||||¡ dS t|jƒtv rt d¡ |  |||d¡ dS d|v r‡t	|d ƒ}|dus'J ‚t
 |dd… ¡}	| d¡}|durQ|dkrQt d¡ |}|  |||||¡ dS d|v r‰|d r‹t	|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 )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.
        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   Úrequests.structuresr   Úcachecontrol.cacher   r	   Úcachecontrol.serializer
   r   Úrequestsr   Úurllib3r   r   Ú	getLoggerrR   rN   Úcompiler   rm   r   r    r   r   r   r   Ú<module>   s,   


