U ��.e�5�@s�dZddlZddlZddlZddlZddlmZddlmZddl m Z ddl m Z e� e�Ze�d�Zd d �ZGd d �d e�ZdS) z7 The httplib2 algorithms ported for use with requests. �N)� parsedate_tz)�CaseInsensitiveDict�)� DictCache)� Serializerz9^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?cCs0t�|���}|d|d|d|d|dfS)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�G/usr/lib/python3.8/site-packages/pip/_vendor/cachecontrol/controller.py� parse_urisrc@s\eZdZdZddd�Zedd��Zedd ��Zd d �Zd d �Z dd�Z ddd�Z dd�Z dS)�CacheControllerz9An interface to see if request should cached or not. NTcCs,|pt�|_||_|pt�|_|p$d|_dS)N)����i,�-)r�cache� cache_etagsr� serializer�cacheable_status_codes)�selfrrr� status_codesrrr�__init__"s  zCacheController.__init__c Csht|�\}}}}}|r|s&td|��|��}|��}|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) �clsrZschemeZ authority�pathZqueryZfragmentZ request_uriZ defrag_urirrr�_urlnorm*s zCacheController._urlnormcCs |�|�S�N)r$)r"rrrr� cache_url>szCacheController.cache_urlc Cs(tdftdftdfddddddddtdfd� }|�d|�dd��}i}|�d�D]�}|��s^qP|�d d �}|d ��}z||\}} Wn$tk r�t�d |�YqPYnX|r�| s�d||<|rPz||d ���||<WqPtk r�| r�t�d |�YqPtk �r t�d||j �YqPXqP|S)NTF)NF) �max-agez max-stale� min-fresh�no-cache�no-storez no-transformzonly-if-cachedzmust-revalidateZpublicZprivatezproxy-revalidatezs-maxagez cache-controlz Cache-Control��,�=rrz,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�headersZknown_directivesZ cc_headersZretvalZ cc_directive�partsZ directive�typZrequiredrrr�parse_cache_controlBsV�    �� z#CacheController.parse_cache_controlcCs0|�|j�}t�d|�|�|j�}d|kr:t�d�dSd|kr\|ddkr\t�d�dS|j�|�}|dkr~t�d �dS|j� ||�}|s�t� d �dS|j d kr�d }t�|�|St |j�}|r�d |kr�d|kr�t�d�|j� |�t�d�dSt��}t�t|d ��} td|| �} t�d| �|�|�} d} d| k�r^| d} t�d| �nDd|k�r�t|d�} | dk �r�t�| �| }td|�} t�d| �d|k�r�|d} t�d| �d|k�r�|d}| |7} t�d| �| | k�r t�d�t�d| | �|Sd|k�r,t�d�|j� |�dS)ze Return a cached response if it exists in the cache, otherwise return False. zLooking up "%s" in the cacher)z-Request header has "no-cache", cache bypassedFr'rz1Request header has "max_age" as 0, cache bypassedNzNo cache entry availablez1Cache entry deserialization failed, entry ignoredrzVReturning cached "301 Moved Permanently" response (ignoring date and etag information)�date�etagz(Purging cached response: no date or etagz!Ignoring cached response: no datezCurrent 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&�urlr3r4r;r8rr/r�loadsZwarning�statusr�delete�time�calendarZtimegmr�max)r�requestr&�ccZ cache_data�resp�msgr8Znowr<Z current_ageZresp_ccZfreshness_lifetimer>Z expire_timeZ min_freshrrr�cached_requestxs|         �               �       zCacheController.cached_requestcCs`|�|j�}|j�||j�|��}i}|r\t|j�}d|krH|d|d<d|kr\|d|d<|S)Nr=ZETagz If-None-Matchz last-modifiedz Last-ModifiedzIf-Modified-Since)r&r?rr@rr/rr8)rrFr&rHZ new_headersr8rrr�conditional_headers�s    z#CacheController.conditional_headersc Cs�|p|j}|j|kr(t�d|j|�dSt|j�}|dk rfd|krf|d��rft|d�t|�krfdS|� |j�}|� |�}|� |j �} t�d| �d} d|kr�d} t�d�d|kr�d} t�d �| r�|j � | �r�t�d �|j �| �| r�dS|j�r,d |k�r,t�d �|j �| |jj|||d ��n�|jdk�r\t�d�|j �| |j�||��n�d|k�r�d|k�r�|ddk�r�t�d�|j �| |jj|||d ��n:d|k�r�|d�r�t�d�|j �| |jj|||d ��dS)zc Algorithm for caching requests. This assumes a requests Response object. zStatus code %s not in %sN�content-lengthz&Updating cache with response from "%s"Fr*TzResponse header has "no-store"zRequest header has "no-store"z0Purging existing cache entry to honor "no-store"r=zCaching due to etag)�bodyrzCaching permanant redirectr<r'rz'Caching b/c date exists and max-age > 0r>zCaching b/c of expires header)rrAr3r4rr8�isdigitr.�lenr;r&r?rr/rBr�setr�dumps) rrF�responserMrrZresponse_headersZcc_reqrGr&Zno_storerrr�cache_response�sr  � �� ��         �    �   �zCacheController.cache_responsecsv|�|j�}|j�||j�|��}|s*|Sdg�|j�t�fdd�|j� �D���d|_ |j� ||j� ||��|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. rLc3s&|]\}}|���kr||fVqdSr%)r )�.0�k�v�Zexcluded_headersrr� bs �z9CacheController.update_cached_response..r) r&r?rr@rr/r8�update�dict�itemsrArPrQ)rrFrRr&Zcached_responserrWr�update_cached_responseIs   �� z&CacheController.update_cached_response)NTNN)NN) r7� __module__� __qualname__�__doc__r� classmethodr$r&r;rJrKrSr\rrrrrs�   6o Rr)r_Zlogging�rerDrCZ email.utilsrZpip._vendor.requests.structuresrrrZ serializerZ getLoggerr7r3�compiler r�objectrrrrr�s