o
    ùT·jo#  ã                   @  sÞ   d dl m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Zd dlZd dlm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 d d
lmZ e
edf ZG dd„ deƒZ G dd„ dƒZ!dS )é    )ÚannotationsN)Ú	parsedate)ÚUnion)Úget_route_path)ÚURLÚHeaders)ÚHTTPException)ÚFileResponseÚRedirectResponseÚResponse)ÚReceiveÚScopeÚSend)ÚWebSocketClosezos.PathLike[str]c                      s"   e Zd ZdZd‡ fdd„Z‡  ZS )ÚNotModifiedResponse)zcache-controlzcontent-locationÚdateÚetagÚexpiresÚvaryÚheadersr   c                   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   úX/home/dinkstrade/pdmp-scanner/venv/lib/python3.10/site-packages/starlette/staticfiles.pyÚ
<dictcomp>$   s     z0NotModifiedResponse.__init__.<locals>.<dictcomp>)Ústatus_coder   )ÚsuperÚ__init__Úitems)r   r   ©Ú	__class__r   r   r!   !   s   
þzNotModifiedResponse.__init__)r   r   )Ú__name__Ú
__module__Ú__qualname__r   r!   Ú__classcell__r   r   r#   r   r      s    	r   c                   @  s~   e Zd Zddddddœd6dd„Z		d7d8dd„Zd9dd„Zd:dd„Zd;d!d"„Zd<d$d%„Z	&d=d>d-d.„Z	d?d/d0„Z
d@d4d5„ZdS )AÚStaticFilesNFT)Ú	directoryÚpackagesÚhtmlÚ	check_dirÚfollow_symlinkr*   úPathLike | Noner+   ú"list[str | tuple[str, str]] | Noner,   Úboolr-   r.   ÚreturnÚNonec                C  s`   || _ || _|  ||¡| _|| _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_checkedr.   ÚosÚpathÚisdirÚRuntimeError)r   r*   r+   r,   r-   r.   r   r   r   r!   )   s   	ÿzStaticFiles.__init__úlist[PathLike]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..r4   z' in package )ÚappendÚ
isinstanceÚtupleÚ	importlibÚutilÚ	find_specÚoriginr8   r9   ÚnormpathÚjoinr:   )r   r*   r+   ÚdirectoriesÚpackageÚstatics_dirÚspecÚpackage_directoryr   r   r   r5   ;   s    	


ÿzStaticFiles.get_directoriesÚscoper   Úreceiver   Úsendr   c                 Ã  s†   �|d dkrt ƒ }||||ƒI dH  d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Ú	websocketNÚhttpT)r   r7   Úcheck_configÚget_pathÚget_response)r   rL   rM   rN   Úwebsocket_closer9   Úresponser   r   r   Ú__call__X   s   €
zStaticFiles.__call__Ústrc                 C  s"   t |ƒ}tj tjj| d¡Ž ¡S )z�
        Given the ASGI scope, return the `path` string to serve up,
        with OS specific path separators, and any '..', '.' components removed.
        ú/)r   r8   r9   rE   rF   Úsplit)r   rL   Ú
route_pathr   r   r   rS   k   s   zStaticFiles.get_pathr9   r   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? } z|jtjkr9t dd�‚|‚d}~w t	yJ   t dd�‚w |rZt
 |j¡rZ|  |||¡S |r¤t
 |j¡r¤| jr¤tj |d¡}tj | j|¡I dH \}}|dur¤t
 |j¡r¤|d	  d
¡s�t|d�}|j|jd
 d�}t|d�S |  |||¡S | jrÃtj | jd¡I dH \}}|rÃt
 |j¡rÃt||dd�S t dd�‚)z`
        Returns an HTTP response, given the incoming path, method and request headers.
        Úmethod)ÚGETÚHEADi•  )r   Ni‘  i”  z
index.htmlr9   rY   ©rL   )r9   )Úurlz404.html)Ústat_resultr   )r   ÚanyioÚ	to_threadÚrun_syncÚlookup_pathÚPermissionErrorÚOSErrorÚerrnoÚENAMETOOLONGÚ
ValueErrorÚstatÚS_ISREGÚst_modeÚfile_responseÚS_ISDIRr,   r8   r9   rF   Úendswithr   Úreplacer
   r	   )r   r9   rL   Ú	full_pathra   ÚexcÚ
index_pathr`   r   r   r   rT   s   s>   €


€
þ


zStaticFiles.get_responseú!tuple[str, os.stat_result | None]c              
   C  s¨   |  d¡rdS | jD ]G}tj ||¡}| jr#tj |¡}tj |¡}ntj |¡}tj |¡}tj ||g¡t	|ƒkr<q
z
|t 
|¡fW   S  ttfyQ   Y q
w dS )N)rY   ú\)Ú N)Ú
startswithr6   r8   r9   rF   r.   ÚabspathÚrealpathÚ
commonpathrX   rk   ÚFileNotFoundErrorÚNotADirectoryError)r   r9   r*   Újoined_pathrr   r   r   r   re       s"   

ÿzStaticFiles.lookup_pathéÈ   rr   ÚPathLikera   úos.stat_resultr   Úintc                 C  s4   t |d�}t|||d�}|  |j|¡rt|jƒS |S )Nr_   )r   ra   )r   r	   Úis_not_modifiedr   r   )r   rr   ra   rL   r   Úrequest_headersrV   r   r   r   rn   µ   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*   rb   rc   rd   r8   rk   r|   r;   ro   rm   ÚS_ISLNK)r   ra   r   r   r   rR   Ã   s   €
ÿÿzStaticFiles.check_configÚresponse_headersr   r„   c                 C  sœ   |  d¡ }r| ¡ dkrdS |d }|dd„ | d¡D ƒv S z$t|d ƒ}t|d	 ƒ}|d
ur;|d
ur>||krAW dS W dS W dS W dS  tyM   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-matchÚ*Tr   c                 S  s   g | ]	}|  ¡  d ¡‘qS )zW/)ÚstripÚremoveprefix)r   Útagr   r   r   Ú
<listcomp>Ý   s    z/StaticFiles.is_not_modified.<locals>.<listcomp>ú,zif-modified-sincezlast-modifiedNF)Úgetrˆ   rZ   r   ÚKeyError)r   r†   r„   Úif_none_matchr   Úif_modified_sinceÚlast_modifiedr   r   r   rƒ   Ó   s(   ÿûûýýzStaticFiles.is_not_modified)r*   r/   r+   r0   r,   r1   r-   r1   r.   r1   r2   r3   )NN)r*   r/   r+   r0   r2   r<   )rL   r   rM   r   rN   r   r2   r3   )rL   r   r2   rX   )r9   rX   rL   r   r2   r   )r9   rX   r2   ru   )r   )
rr   r€   ra   r�   rL   r   r   r‚   r2   r   )r2   r3   )r†   r   r„   r   r2   r1   )r%   r&   r'   r!   r5   rW   rS   rT   re   rn   rR   rƒ   r   r   r   r   r)   (   s$    ùý



-û
r)   )"Ú
__future__r   rh   Úimportlib.utilrA   r8   rk   Úemail.utilsr   Útypingr   rb   Úanyio.to_threadÚstarlette._utilsr   Ústarlette.datastructuresr   r   Ústarlette.exceptionsr   Ústarlette.responsesr	   r
   r   Ústarlette.typesr   r   r   Ústarlette.websocketsr   rX   r€   r   r)   r   r   r   r   Ú<module>   s$    