U
    J~Hjš&  ã                   @  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   ú9/tmp/pip-unpacked-wheel-dkq0z1h6/whitenoise/responders.pyÚ__init__   s    zResponse.__init__N)Ú__name__Ú
__module__Ú__qualname__Ú	__slots__r   r   r   r   r   r
      s   r
   )ZAllowz	GET, HEADr   )zCache-ControlzContent-LocationÚDateÚETagZ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krt S |  |¡r| jS |  |¡\}}|dkr>t|dƒ}nd }| d¡}|rvz|  |||¡W S  tk
rt   Y nX tt	j
||ƒS )N)ÚGETÚHEADr;   ÚrbZ
HTTP_RANGE)ÚNOT_ALLOWED_RESPONSEÚis_not_modifiedr3   Úget_path_and_headersÚopenÚgetÚget_range_responseÚ
ValueErrorr
   r   ÚOK)r   ÚmethodÚrequest_headersr6   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rV|  ||¡S |d k	rjt|||ƒ}| 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   rH   Úbase_headersrG   r   Úitemr(   r!   r"   r   r   r   rB   d   s     zStaticFile.get_range_responsec                 C  sL   |   |¡\}}|dk r$t|| dƒ}|d kr6|d }nt||d ƒ}||fS )Nr   r   )Úparse_byte_rangeÚmaxr%   )r   rH   r(   r!   r"   r   r   r   rP   t   s    
zStaticFile.get_byte_rangec           	      C  st   |   ¡  d¡\}}}|dkr"tƒ ‚|  ¡  d¡\}}}|s@tƒ ‚|sTt|ƒ }d }nt|ƒ}|rht|ƒnd }||fS )Nú=ÚbytesrL   )ÚstripÚ	partitionrC   rN   )	rH   ZunitsÚ_Z
range_specZ	start_strÚsepZend_strr!   r"   r   r   r   rV   ~   s    
zStaticFile.parse_byte_rangec                 C  s*   | d k	r|   ¡  ttjdd|› �fgd ƒS )NrK   zbytes */)r*   r
   r   ÚREQUESTED_RANGE_NOT_SATISFIABLE)rG   r(   r   r   r   rQ   �   s    ýz-StaticFile.get_range_not_satisfiable_responsec              	   C  sT   d t | |ƒi}|rP| ¡ D ]4\}}zt ||ƒ||< W q tk
rL   Y qY qX q|S r   )Ú	FileEntryÚitemsÚMissingFileError)r6   r7   r8   r9   ÚencodingZalt_pathr   r   r   r.   š   s    zStaticFile.get_file_statsc                 C  sŠ   t |ƒ}|d  }t|ƒdkr$d|d< d|krF|j}|rFt|dd�|d< d|kr†t|d ƒ}|r†tt|ƒƒ}d|d	›d
|jd	›d�|d< |S )Nr   zAccept-Encodingr   r-   T)Úusegmtr   ú"ÚxrL   )r	   r'   Úmtimer   r   rN   r   r(   )r   Zheaders_listr9   r   Z	main_filerf   r0   Ú	timestampr   r   r   r/   ¦   s    zStaticFile.get_headersc                 C  s8   g }t D ]}|| kr| || | f¡ qttj|d d�S )Nr   )ÚNOT_MODIFIED_HEADERSrO   r
   r   ÚNOT_MODIFIED)r   Znot_modified_headersÚkeyr   r   r   r2   ¸   s      ÿz$StaticFile.get_not_modified_responsec                 C  s€   g }t | ¡ dd„ d�}|D ]^\}}t|  ¡ ƒ}t|jƒ|d< |rZ||d< t d| ¡}n
t d¡}| ||j| ¡ f¡ q|S )Nc                 S  s
   | d j S r   )r(   )Úir   r   r   Ú<lambda>Æ   r$   z-StaticFile.get_alternatives.<locals>.<lambda>)rj   rJ   zContent-Encodingz\b%s\bÚ )	Úsortedr`   r	   rR   r(   ÚreÚcompilerO   r6   )rT   r9   r5   Zfiles_by_sizerb   Z
file_entryr   Úencoding_rer   r   r   r4   Â   s    
zStaticFile.get_alternativesc                 C  sl   |  d¡}|d k	r|| jkS | jd kr*dS z|d }W n tk
rL   Y dS X t|ƒ}|d k	rh|| jkS dS )NZHTTP_IF_NONE_MATCHFZHTTP_IF_MODIFIED_SINCE)rA   r1   r0   ÚKeyErrorr   )r   rF   Zprevious_etagZlast_requestedZlast_requested_tsr   r   r   r>   Ò   s    



zStaticFile.is_not_modifiedc                 C  sD   |  dd¡}|dkrd}| jD ] \}}}| |¡r||f  S qd S )NZHTTP_ACCEPT_ENCODINGrm   Ú*)rA   r5   Úsearch)r   rF   Úaccept_encodingrq   r6   r   r   r   r   r?   á   s    
zStaticFile.get_path_and_headers)NN)r   r   r   r   rI   rB   rP   ÚstaticmethodrV   rQ   r.   r/   r2   r4   r>   r?   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 )NZLocationÚutf8)	Úlistr`   rO   r   Úencoder
   r   ÚFOUNDÚresponse)r   Úlocationr   r   r   r   r   ì   s    zRedirect.__init__c                 C  s   | j S r   )r|   )r   rE   rF   r   r   r   rI   ñ   s    zRedirect.get_response)N)r   r   r   r   rI   r   r   r   r   rw   ë   s   
rw   c                   @  s   e Zd ZdS )ÚNotARegularFileErrorN©r   r   r   r   r   r   r   r~   õ   s   r~   c                   @  s   e Zd ZdS )ra   Nr   r   r   r   r   ra   ù   s   ra   c                   @  s   e Zd ZdS )ÚIsDirectoryErrorNr   r   r   r   r   r€   ý   s   r€   c                   @  s&   e Zd ZdZddd„Zedd„ ƒZdS )r_   )r6   r(   rf   Nc                 C  s:   || _ |d krtjn|j}|  ||¡}|j| _|j| _d S r   )	r6   ÚosÚstatÚ__getitem__Ústat_regular_fileÚst_sizer(   Úst_mtimerf   )r   r6   r8   Ústat_functionr‚   r   r   r   r     s
    zFileEntry.__init__c              
   C  s¢   z|| ƒ}W nZ t k
r(   t| ƒ‚Y n@ tk
rf } z"|jtjtjfkrTt| ƒ‚n‚ W 5 d}~X Y nX t |j¡sžt 	|j¡r�t
d| › �ƒ‚n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: )rr   ra   ÚOSErrorÚerrnoÚENOENTZENAMETOOLONGr‚   ÚS_ISREGÚst_modeÚS_ISDIRr€   r~   )r6   r‡   Ústat_resultÚer   r   r   r„     s    
zFileEntry.stat_regular_file)N)r   r   r   r   r   rv   r„   r   r   r   r   r_     s   
r_   )Ú
__future__r   r‰   r�   ro   r‚   Úemail.utilsr   r   Úhttpr   Úior   Útimer   Úurllib.parser   Zwsgiref.headersr	   r
   ÚMETHOD_NOT_ALLOWEDr=   rh   r   r,   rw   Ú	Exceptionr~   ra   r€   r_   r   r   r   r   Ú<module>   s4   	ý
 &
