o
    eB(                     @  s   d dl m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	m
Z
 d dlmZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZ d dlmZ G dd dZdd ZdS )    )annotationsN)normpath)Callable)Headers)FileWrapper)
MediaTypes)IsDirectoryError)MissingFileError)Redirect)
StaticFile)decode_path_info)ensure_leading_trailing_slashc                
   @  s   e Zd ZdZ		d7dddddddddd8ddZdd Zedd Zd9ddZdd  Z	d9d!d"Z
d#d$ Zd%d& Zd'd( Zed)d* Zed9d+d,Zd9d-d.Zd/d0 Zd1d2 Zd3d4 Zd5d6 ZdS ):
WhiteNoisei NF<   Tzutf-8)autorefreshmax_ageallow_all_originscharset	mimetypesadd_headers_function
index_fileimmutable_file_testr   boolr   
int | Noner   r   strr   dict[str, str] | Noner   *Callable[[Headers, str, str], None] | Noner   str | bool | Noner   Callable | str | Nonec                  s   || _ || _|| _|| _|	| _|
du rd| _nt|
tr |
| _nd | _|d ur;t|s8t	
|  fdd| _n|| _t|d| _|| _i | _g | _|d urV| || d S d S )NTz
index.htmlc                   s   t  |S N)r   search)pathurlregex B/var/www/html/venv/lib/python3.10/site-packages/whitenoise/base.py<lambda>?   s    z%WhiteNoise.__init__.<locals>.<lambda>)extra_types)r   r   r   r   r   r   
isinstancer   callablerecompiler   r   media_typesapplicationfilesdirectories	add_files)selfr.   rootprefixr   r   r   r   r   r   r   r   r%   r#   r&   __init__   s,   

zWhiteNoise.__init__c                 C  sP   t |dd}| jr| |}n| j|}|d u r!| ||S | |||S )N	PATH_INFO )r   getr   	find_filer/   r.   serve)r2   environstart_responser!   static_filer%   r%   r&   __call__J   s   zWhiteNoise.__call__c                 C  sX   |  |d |}|j d|jj }||t|j |jd ur*|dt}||jS g S )NREQUEST_METHOD zwsgi.file_wrapper)get_responsestatusphraselistheadersfiler8   r   )r=   r;   r<   responsestatus_linefile_wrapperr%   r%   r&   r:   U   s   

zWhiteNoise.servec                 C  sz   t j|}|t jjt jj }t|}| jr#| jd||f d S t j	|r1| 
|| d S tjd| dd d S )Nr   zNo directory at:    )
stacklevel)osr!   abspathrstripsepr   r   r0   insertisdirupdate_files_dictionarywarningswarn)r2   r3   r4   r%   r%   r&   r1   `   s   zWhiteNoise.add_filesc                 C  sR   t t|}| D ]}|t|d  }|dd}|| }| j|||d q
d S )N\/
stat_cache)dictscantreekeyslenreplaceadd_file_to_dictionary)r2   r3   r4   rX   r!   relative_pathrelative_urlr"   r%   r%   r&   rR   o   s   z"WhiteNoise.update_files_dictionaryc                 C  s   | j ||dr	d S | jd ur9|d| j r9|d t| j  }|d}| ||| j|< | ||| j|< |}| j|||d}|| j|< d S )NrW   rV   )is_compressed_variantr   endswithr\   rN   redirectr/   get_static_file)r2   r"   r!   rX   	index_urlindex_no_slashr=   r%   r%   r&   r^   y   s   
z!WhiteNoise.add_file_to_dictionaryc              	   C  s^   | j d u r|drd S | |sd S | |D ]}z	| ||W   S  ty,   Y qw d S NrV   )r   rb   url_is_canonicalcandidate_paths_for_urlfind_file_at_pathr	   )r2   r"   r!   r%   r%   r&   r9      s   
zWhiteNoise.find_filec                 c  sT    | j D ]#\}}||r'tj||t|d  }tj||f|kr'|V  qd S r   )r0   
startswithrL   r!   joinr\   commonprefix)r2   r"   r3   r4   r!   r%   r%   r&   ri      s   
z"WhiteNoise.candidate_paths_for_urlc              	   C  s   |  |r	t|| jd urk|dr!tj|| j}| ||S |d| j rAtj|r=| 	||d t
| j  S t|z| ||W S  tyj   tjtj|| jre| 	||d  Y S Y t|w | ||S rg   )ra   r	   r   rb   rL   r!   rl   rd   isfilerc   r\   r   r2   r!   r"   r%   r%   r&   rj      s&   


zWhiteNoise.find_file_at_pathc                 C  s6   d| v rdS t | }| dr| dkr|d7 }|| kS )z
        Check that the URL path is in canonical format i.e. has normalised
        slashes and no path traversal elements
        rU   FrV   )r   rb   )r"   
normalisedr%   r%   r&   rh      s   zWhiteNoise.url_is_canonicalc                 C  s<   | dd  dv r| d d }|d u rt j|S ||v S dS )N).gz.brF)rL   r!   rn   )r!   rX   uncompressed_pathr%   r%   r&   ra      s   z WhiteNoise.is_compressed_variantc                 C  s   |d u rt j|st|tg }| ||| | ||| | jr'd|d< | jd ur3| ||| t	||
 ||d |d ddS )N*zAccess-Control-Allow-Originrr   rs   )gzipbr)rX   	encodings)rL   r!   existsr	   r   add_mime_headersadd_cache_headersr   r   r   items)r2   r!   r"   rX   rE   r%   r%   r&   rd      s   
zWhiteNoise.get_static_filec                 C  sF   | j |}|drdt| ji}ni }|jdt|fi | d S )Nztext/r   zContent-Type)r-   get_typerk   r   r   
add_header)r2   rE   r!   r"   
media_typeparamsr%   r%   r&   rz      s
   
zWhiteNoise.add_mime_headersc                 C  sD   |  ||rd| j|d< d S | jd ur d| j d|d< d S d S )Nzmax-age={}, public, immutableCache-Controlmax-age=, public)r   formatFOREVERr   )r2   rE   r!   r"   r%   r%   r&   r{      s   
zWhiteNoise.add_cache_headersc                 C  s   dS )z
        This should be implemented by sub-classes (see e.g. WhiteNoiseMiddleware)
        or by setting the `immutable_file_test` config option
        Fr%   ro   r%   r%   r&   r      s   zWhiteNoise.immutable_file_testc                 C  sv   ||d kr| dd d }n||| j krd}n
td| d| | jdur3dd| j d	i}ni }t||d
S )z
        Return a relative 302 redirect

        We use relative redirects as we don't know the absolute URL the app is
        being hosted under
        rV   z./zCannot handle redirect: z > Nr   r   r   )rE   )splitr   
ValueErrorr   r
   )r2   from_urlto_urlr`   rE   r%   r%   r&   rc      s   
zWhiteNoise.redirect)NN)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )__name__
__module____qualname__r   r5   r>   staticmethodr:   r1   rR   r^   r9   ri   rj   rh   ra   rd   rz   r{   r   rc   r%   r%   r%   r&   r      s@    	1






	r   c                 c  s@    t | D ]}| rt|jE dH  q|j| fV  qdS )zR
    Recurse the given directory yielding (pathname, os.stat(pathname)) pairs
    N)rL   scandiris_dirrZ   r!   stat)r3   entryr%   r%   r&   rZ     s   rZ   )
__future__r   rL   r+   rS   	posixpathr   typingr   wsgiref.headersr   wsgiref.utilr   whitenoise.media_typesr   whitenoise.respondersr   r	   r
   r   whitenoise.string_utilsr   r   r   rZ   r%   r%   r%   r&   <module>   s$     n