o
    :ήc3!                     @   s   d dl Zd dlZd dlZd dlZd dlmZ d dlZd dlm	Z	m
Z
 d dlmZ d dlmZmZmZ d dlmZmZmZ ejedf ZG dd	 d	eZG d
d dZdS )    N)	parsedate)URLHeaders)HTTPException)FileResponseRedirectResponseResponse)ReceiveScopeSendzos.PathLike[str]c                       s&   e Zd ZdZdef fddZ  ZS )NotModifiedResponse)zcache-controlzcontent-locationdateetagexpiresvaryheadersc                    s&   t  jd fdd| D d d S )Ni0  c                    s    i | ]\}}| j v r||qS  )NOT_MODIFIED_HEADERS).0namevalueselfr   </tmp/pip-target-vg8gfxp4/lib/python/starlette/staticfiles.py
<dictcomp>   s    z0NotModifiedResponse.__init__.<locals>.<dictcomp>)status_coder   )super__init__items)r   r   	__class__r   r   r      s   

zNotModifiedResponse.__init__)__name__
__module____qualname__r   r   r   __classcell__r   r   r   r   r      s    	r   c                   @   sN  e Zd Zddddddeje dejejejeej	eef f   de
de
d	df
d
dZ		d&deje dejejejeej	eef f   d	eje fddZdededed	dfddZded	efddZdeded	efddZded	ej	eejej f fddZ	d'dedejdeded	ef
ddZd(d d!Zd"ed#ed	e
fd$d%ZdS ))StaticFilesNFT)	directorypackageshtml	check_dirr&   r'   r(   r)   returnc                C   sZ   || _ || _| ||| _|| _d| _|r'|d ur)tj|s+t	d| dd S d S d S )NFDirectory 'z' does not exist)
r&   r'   get_directoriesall_directoriesr(   config_checkedospathisdirRuntimeError)r   r&   r'   r(   r)   r   r   r   r   '   s   
zStaticFiles.__init__c                 C   s   g }|dur| | |pg D ]P}t|tr|\}}nd}tj|}|dus/J d|d|jdus<J d|dtj	tj
|jd|}tj|sZJ d|d|d| | q|S )z
        Given `directory` and `packages` arguments, return a list of all the
        directories that should be used for serving static files from.
        NstaticszPackage z could not be found.z..r+   z' in package )append
isinstancetuple	importlibutil	find_specoriginr/   r0   normpathjoinr1   )r   r&   r'   directoriespackagestatics_dirspecpackage_directoryr   r   r   r,   9   s(   


zStaticFiles.get_directoriesscopereceivesendc                    s^   |d dks	J | j s|  I dH  d| _ | |}| ||I dH }||||I dH  dS )z'
        The ASGI entry point.
        typehttpNT)r.   check_configget_pathget_response)r   rB   rC   rD   r0   responser   r   r   __call__Z   s   
zStaticFiles.__call__c                 C   s   t jt jj|d d S )z
        Given the ASGI scope, return the `path` string to serve up,
        with OS specific path separators, and any '..', '.' components removed.
        r0   /)r/   r0   r;   r<   split)r   rB   r   r   r   rH   h   s   zStaticFiles.get_pathr0   c                    s^  |d dvrt ddztj| j|I dH \}}W n ty'   t dd ty.    w |r>t|j	r>| 
|||S |rt|j	r| jrtj|d}tj| j|I dH \}}|durt|j	r|d d	st|d
}|j|jd	 d}t|dS | 
|||S | jrtj| jdI dH \}}|rt|j	rt|||d ddS t dd)z`
        Returns an HTTP response, given the incoming path, method and request headers.
        method)GETHEADi  )r   Ni  z
index.htmlr0   rL   rB   )r0   )urlz404.htmli  )stat_resultrN   r   )r   anyio	to_threadrun_synclookup_pathPermissionErrorOSErrorstatS_ISREGst_modefile_responseS_ISDIRr(   r/   r0   r<   endswithr   replacer   r   )r   r0   rB   	full_pathrS   
index_pathrR   r   r   r   rI   o   sJ   




zStaticFiles.get_responsec              
   C   sr   | j D ]3}tjtj||}tj|}tj||g|kr!qz
|t|fW   S  ttfy6   Y qw dS )N) N)	r-   r/   r0   realpathr<   commonprefixrZ   FileNotFoundErrorNotADirectoryError)r   r0   r&   ra   r   r   r   rW      s   
zStaticFiles.lookup_path   ra   rS   r   c                 C   s>   |d }t |d}t||||d}| |j|rt|jS |S )NrN   rQ   )r   rS   rN   )r   r   is_not_modifiedr   r   )r   ra   rS   rB   r   rN   request_headersrJ   r   r   r   r]      s   

zStaticFiles.file_responsec                    s   | j du rdS ztjtj| j I dH }W n ty&   td| j  dw t|j	s<t
|j	s>td| j  ddS dS )z
        Perform a one-off configuration check that StaticFiles is actually
        pointed at a directory, so that we can raise loud errors rather than
        just returning 404 responses.
        NzStaticFiles directory 'z' does not exist.zStaticFiles path 'z' is not a directory.)r&   rT   rU   rV   r/   rZ   rf   r2   r^   r\   S_ISLNK)r   rS   r   r   r   rG      s   
zStaticFiles.check_configresponse_headersrj   c                 C   s   z|d }|d }||krW dS W n	 t y   Y nw z$t|d }t|d }|dur7|dur:||kr=W dS W dS W dS W dS  t yI   Y dS w )z
        Given the request and response headers, return `True` if an HTTP
        "Not Modified" response could be returned instead.
        zif-none-matchr   Tzif-modified-sincezlast-modifiedNF)KeyErrorr   )r   rl   rj   if_none_matchr   if_modified_sincelast_modifiedr   r   r   ri      s:   			zStaticFiles.is_not_modified)NN)rh   )r*   N)r!   r"   r#   typingOptionalPathLikeListUnionstrTupleboolr   r,   r
   r	   r   rK   rH   r   rI   r/   rS   rW   intr]   rG   r   ri   r   r   r   r   r%   &   sr    	

!1


r%   )importlib.utilr7   r/   rZ   rq   email.utilsr   rT   starlette.datastructuresr   r   starlette.exceptionsr   starlette.responsesr   r   r   starlette.typesr	   r
   r   ru   rv   rs   r   r%   r   r   r   r   <module>   s    