o
    e&                     @  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	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ee
jdgddZdZG dd deZG dd dZG dd dZG dd deZG dd deZG dd deZG dd dZdS )    )annotationsN)
formatdate)	parsedate)
HTTPStatus)BufferedIOBase)mktime)quote)Headersc                   @  s   e Zd ZdZdd ZdS )Responsestatusheadersfilec                 C  s   || _ || _|| _d S Nr   )selfr   r   r    r   H/var/www/html/venv/lib/python3.10/site-packages/whitenoise/responders.py__init__   s   
zResponse.__init__N)__name__
__module____qualname__	__slots__r   r   r   r   r   r
      s    r
   )Allowz	GET, HEADr   )zCache-ControlzContent-LocationDateETagExpiresVaryc                   @  s*   e Zd ZdZdd Zd
ddZdd Zd	S )
SlicedFilez
    A file like wrapper to handle seeking to the start byte of a range request
    and to return no further output once the end byte of a range request has
    been reached.
    c                 C  s"   | | || _|| d | _d S N   )seekfileobj	remaining)r   r!   startendr   r   r   r   2   s   
zSlicedFile.__init__c                 C  sL   | j dkrdS |dk r| j }nt|| j }| j|}|  j t|8  _ |S )Nr       )r"   minr!   readlen)r   sizedatar   r   r   r(   7   s   
zSlicedFile.readc                 C  s   | j   d S r   )r!   close)r   r   r   r   r,   B   s   zSlicedFile.closeN)r%   )r   r   r   __doc__r   r(   r,   r   r   r   r   r   +   s
    
r   c                   @  s   e Zd ZdddZdd Zdd Zdd	 Zed
d Zedd Z	edd Z
dd Zedd Zedd Zdd Zdd ZdS )
StaticFileNc                 C  sP   |  |||}| ||}t|d | _|d | _| || _| ||| _d S )NLast-Modifiedr   )	get_file_statsget_headersr   last_modifiedetagget_not_modified_responsenot_modified_responseget_alternativesalternatives)r   pathr   	encodings
stat_cachefilesr   r   r   r   G   s   
zStaticFile.__init__c                 C  s   |dvrt S | |r| jS | |\}}|dkrt|d}nd }|d}|r:z| |||W S  ty9   Y nw tt	j
||S )N)GETHEADr=   rb
HTTP_RANGE)NOT_ALLOWED_RESPONSEis_not_modifiedr5   get_path_and_headersopengetget_range_response
ValueErrorr
   r   OK)r   methodrequest_headersr8   r   file_handlerange_headerr   r   r   get_responseO   s    

zStaticFile.get_responsec           	   	   C  s   g }|D ]}|d dkrt |d }q|| q| ||\}}||kr+| ||S |d ur5t|||}|dd| d| d| f |dt|| d f ttj||S )Nr   Content-Lengthr   Content-Rangezbytes -/)	intappendget_byte_range"get_range_not_satisfiable_responser   strr
   r   PARTIAL_CONTENT)	r   rK   base_headersrJ   r   itemr*   r#   r$   r   r   r   rE   d   s    zStaticFile.get_range_responsec                 C  sR   |  |\}}|dk rt|| d}|d u r|d }||fS t||d }||fS )Nr   r   )parse_byte_rangemaxr'   )r   rK   r*   r#   r$   r   r   r   rS   t   s   zStaticFile.get_byte_rangec           	      C  sz   |   d\}}}|dkrt |  d\}}}|s t |s-t| }d }||fS t|}|r7t|nd }||fS )N=bytesrO   )strip	partitionrF   rQ   )	rK   units_
range_spec	start_strsepend_strr#   r$   r   r   r   rY   ~   s   
zStaticFile.parse_byte_rangec                 C  s*   | d ur|    ttjdd| fgd S )NrN   zbytes */)r,   r
   r   REQUESTED_RANGE_NOT_SATISFIABLE)rJ   r*   r   r   r   rT      s   z-StaticFile.get_range_not_satisfiable_responsec              	   C  sL   d t | |i}|r$| D ]\}}z	t ||||< W q ty#   Y qw |S r   )	FileEntryitemsMissingFileError)r8   r9   r:   r;   encodingalt_pathr   r   r   r0      s   zStaticFile.get_file_statsc                 C  s   t |}|d  }t|dkrd|d< d|vr#|j}|r#t|dd|d< d|vrCt|d }|rCtt|}d|d	d
|jd	d|d< |S )Nr   zAccept-Encodingr   r/   T)usegmtr   "xrO   )r	   r)   mtimer   r   rQ   r   r*   )r   headers_listr;   r   	main_filern   r2   	timestampr   r   r   r1      s   zStaticFile.get_headersc                 C  s8   g }t D ]}|| v r||| | f qttj|d dS )Nr   )NOT_MODIFIED_HEADERSrR   r
   r   NOT_MODIFIED)r   not_modified_headerskeyr   r   r   r4      s   z$StaticFile.get_not_modified_responsec                 C  s   g }t | dd d}|D ]/\}}t|  }t|j|d< |r-||d< td| }ntd}|||j| f q|S )Nc                 S  s
   | d j S r   )r*   )ir   r   r   <lambda>   s   
 z-StaticFile.get_alternatives.<locals>.<lambda>)ru   rM   zContent-Encodingz\b%s\b )	sortedrg   r	   rU   r*   recompilerR   r8   )rW   r;   r7   files_by_sizeri   
file_entryr   encoding_rer   r   r   r6      s   
zStaticFile.get_alternativesc                 C  sj   | d}|d ur|| jkS | jd u rdS z|d }W n
 ty%   Y dS w t|}|d ur3|| jkS dS )NHTTP_IF_NONE_MATCHFHTTP_IF_MODIFIED_SINCE)rD   r3   r2   KeyErrorr   )r   rI   previous_etaglast_requestedlast_requested_tsr   r   r   rA      s   



zStaticFile.is_not_modifiedc                 C  sD   | dd}|dkrd}| jD ]\}}}||r||f  S qd S )NHTTP_ACCEPT_ENCODINGrx   *)rD   r7   search)r   rI   accept_encodingr~   r8   r   r   r   r   rB      s   
zStaticFile.get_path_and_headers)NN)r   r   r   r   rL   rE   rS   staticmethodrY   rT   r0   r1   r4   r6   rA   rB   r   r   r   r   r.   F   s$    



	

	
r.   c                   @  s   e Zd ZdddZdd ZdS )RedirectNc                 C  s@   |rt | ng }|dt|df ttj|d | _d S )NLocationutf8)	listrg   rR   r   encoder
   r   FOUNDresponse)r   locationr   r   r   r   r      s   zRedirect.__init__c                 C  s   | j S r   )r   )r   rH   rI   r   r   r   rL      s   zRedirect.get_responser   )r   r   r   r   rL   r   r   r   r   r      s    
r   c                   @     e Zd ZdS )NotARegularFileErrorNr   r   r   r   r   r   r   r          r   c                   @  r   )rh   Nr   r   r   r   r   rh      r   rh   c                   @  r   )IsDirectoryErrorNr   r   r   r   r   r      r   r   c                   @  s&   e Zd ZdZdddZedd ZdS )rf   )r8   r*   rn   Nc                 C  s:   || _ |d u r
tjn|j}| ||}|j| _|j| _d S r   )	r8   osstat__getitem__stat_regular_filest_sizer*   st_mtimern   )r   r8   r:   stat_functionr   r   r   r   r     s
   zFileEntry.__init__c              
   C  s   z|| }W n$ t y   t|  ty* } z|jtjtjfv r%t|  d}~ww t|jsEt	|jr>t
d|  td|  |S )zj
        Wrap `stat_function` to raise appropriate errors if `path` is not a
        regular file
        NzPath is a directory: zNot a regular file: )r   rh   OSErrorerrnoENOENTENAMETOOLONGr   S_ISREGst_modeS_ISDIRr   r   )r8   r   stat_resulter   r   r   r     s   zFileEntry.stat_regular_filer   )r   r   r   r   r   r   r   r   r   r   r   rf     s
    
rf   )
__future__r   r   r   rz   r   email.utilsr   r   httpr   ior   timer   urllib.parser   wsgiref.headersr	   r
   METHOD_NOT_ALLOWEDr@   rr   r   r.   r   	Exceptionr   rh   r   rf   r   r   r   r   <module>   s6    	
 &
