U
    +5øi2  ã                   @   sÎ   d dl 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m	Z	m
Z
 d dlmZmZ d dlmZ dZe d¡Ze e¡ZG dd	„ d	ƒZG d
d„ de jƒZdd„ Zdd„ Zdd„ Zdd„ ZG dd„ dƒZdS )é    N)ÚTOKEN_RE)ÚConfigurationProblemÚInvalidHeaderÚInvalidHeaderName)ÚSERVER_SOFTWAREÚSERVER)Úutiliÿÿÿ?z[ \t\x21-\x7e\x80-\xff]*c                   @   s   e Zd Zddd„Zdd„ ZdS )ÚFileWrapperé    c                 C   s"   || _ || _t|dƒr|j| _d S )NÚclose)ÚfilelikeÚblksizeÚhasattrr   )Úselfr   r   © r   ú6/tmp/pip-unpacked-wheel-pa3uujlc/gunicorn/http/wsgi.pyÚ__init__   s    
zFileWrapper.__init__c                 C   s   | j  | j¡}|r|S t‚d S ©N)r   Úreadr   Ú
IndexError)r   ÚkeyÚdatar   r   r   Ú__getitem__#   s    zFileWrapper.__getitem__N)r
   )Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r   r	      s   
r	   c                   @   s   e Zd Zdd„ Zdd„ ZdS )ÚWSGIErrorsWrapperc                 C   s`   t  d¡}|j}g | _|jdkr:| j tj¡ |dd … }|D ]}t|dƒr>| j |j	¡ q>d S )Nzgunicorn.errorú-é   Ústream)
ÚloggingÚ	getLoggerÚhandlersÚstreamsÚerrorlogÚappendÚsysÚstderrr   r   )r   Úcfgr$   r"   Úhr   r   r   r   ,   s    


zWSGIErrorsWrapper.__init__c              	   C   sL   | j D ]@}z| |¡ W n$ tk
r<   | | d¡¡ Y nX | ¡  qd S )NzUTF-8)r#   ÚwriteÚUnicodeErrorÚencodeÚflush)r   r   r   r   r   r   r*   <   s    
zWSGIErrorsWrapper.writeN)r   r   r   r   r*   r   r   r   r   r   *   s   r   c              	   C   s    t | ƒdd| jdkdtdtdœS )N©r   r   Fr   T)zwsgi.errorszwsgi.versionzwsgi.multithreadzwsgi.multiprocesszwsgi.run_oncezwsgi.file_wrapperzwsgi.input_terminatedr   )r   Úworkersr	   r   )r(   r   r   r   Úbase_environE   s    ør0   c                 C   sB   t |ƒ}| | j|| j| j| jdd dd„ | jD ƒ¡ dœ¡ |S )NzHTTP/%sÚ.c                 S   s   g | ]}t |ƒ‘qS r   )Ústr)Ú.0Úvr   r   r   Ú
<listcomp>Z   s     z#default_environ.<locals>.<listcomp>)z
wsgi.inputzgunicorn.socketÚREQUEST_METHODÚQUERY_STRINGZRAW_URIZSERVER_PROTOCOL)r0   ÚupdateÚbodyÚmethodÚqueryÚuriÚjoinÚversion)ÚreqÚsockr(   Úenvr   r   r   Údefault_environR   s    úrB   c                 C   s:   | j }|si S |d |d t|d ƒ|d t|d ƒdœS )NZproxy_protocolÚclient_addrZclient_portZ
proxy_addrZ
proxy_port)ZPROXY_PROTOCOLÚREMOTE_ADDRÚREMOTE_PORTZ
PROXY_ADDRZ
PROXY_PORT)Zproxy_protocol_infor2   )r?   Úinfor   r   r   Úproxy_environ_   s    

ûrG   c                 C   s(  t | ||ƒ}t| ||ƒ}d }tj dd¡}| jD ]š\}	}
|	dkrX|
 ¡ dkrš| d¡ nB|	dkrf|
}n4|	dkrt|
}n&|	dkrˆ|
|d< q0n|	d	krš|
|d
< q0d|	 dd¡ }||krÂd|| |
f }
|
||< q0| j	|d< t
|tƒrê||d< n6t
|tƒ�r| ¡ |d< n|d |d< t|d ƒ|d< t
|tƒ�r¨| d¡}t|ƒdk�r¨|�rž| d¡}t|ƒdk�r¨| j	dk�rz| d¡ n"| j	dk�r’| d¡ n
| d¡ n
| d¡ |d |d< t|d ƒ|d< | j}|�rü| |¡�sìtd||f ƒ‚|t|ƒd … }t |¡|d< ||d< | t| ƒ¡ ||fS )NZSCRIPT_NAMEÚ ZEXPECTz100-continues   HTTP/1.1 100 Continue

ZHOSTzCONTENT-TYPEÚCONTENT_TYPEzCONTENT-LENGTHÚCONTENT_LENGTHZHTTP_r   Ú_z%s,%szwsgi.url_schemerD   r   r   rE   ú:ÚhttpéP   Úhttpsi»  ZSERVER_NAMEZSERVER_PORTz2Request path %r does not start with SCRIPT_NAME %rZ	PATH_INFO)ÚResponserB   ÚosÚenvironÚgetÚheadersÚlowerÚsendÚreplaceÚschemeÚ
isinstancer2   ÚbytesÚdecodeÚsplitÚlenr%   ÚpathÚ
startswithr   r   Zunquote_to_wsgi_strr8   rG   )r?   r@   ÚclientÚserverr(   ÚresprR   ÚhostÚscript_nameZhdr_nameZ	hdr_valuer   Z	path_infor   r   r   Úcreaten   sp    






ÿÿre   c                   @   sv   e Zd Zdd„ Zdd„ Zdd„ Zddd	„Zd
d„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ ZdS )rP   c                 C   sL   || _ || _t| _d | _d| _d| _g | _d| _d | _	d| _
d| _|| _d S )NFr   )r?   r@   r   r>   ÚstatusÚchunkedÚ
must_closerT   Úheaders_sentÚresponse_lengthÚsentÚupgrader(   )r   r?   r@   r(   r   r   r   r   Ê   s    zResponse.__init__c                 C   s
   d| _ d S )NT)rh   ©r   r   r   r   Úforce_closeØ   s    zResponse.force_closec                 C   sT   | j s| j ¡ rdS | jd k	s$| jr(dS | jjdkr8dS | jdk sL| jdkrPdS dS )NTFÚHEADéÈ   ©éÌ   i0  )rh   r?   Úshould_closerj   rg   r:   Ústatus_coderm   r   r   r   rs   Û   s    zResponse.should_closeNc                 C   sž   |r8z*| j r,| jr,t |d |d |d ¡ W 5 d }X n| j d k	rJtdƒ‚|| _ zt| j  ¡ d ƒ| _W n tk
r‚   d | _Y nX |  	|¡ |  
¡ | _| jS )Nr   r   é   zResponse headers already set!)rf   ri   r   ÚreraiseÚAssertionErrorÚintr\   rt   Ú
ValueErrorÚprocess_headersÚ
is_chunkedrg   r*   )r   rf   rT   Úexc_infor   r   r   Ústart_responseæ   s    


zResponse.start_responsec                 C   sì   |D ]â\}}t |tƒs"td| ƒ‚t |¡s8td| ƒ‚t |tƒsNtd| ƒ‚t |¡sdtd| ƒ‚| d¡}| 	¡ }|dkrŠt
|ƒ| _nLt |¡rÖ|dkr°| 	¡ dkrÔd| _q|dkr| 	¡ dkr| j ||f¡ q| j ||f¡ qd S )	Nz%r is not a stringz%rz 	zcontent-lengthÚ
connectionrl   TZ	websocket)rY   r2   Ú	TypeErrorr   Ú	fullmatchr   ÚHEADER_VALUE_REr   ÚstriprU   rx   rj   r   Z
is_hoppishrl   rT   r%   )r   rT   ÚnameÚvalueÚlnamer   r   r   rz   þ   s,    





zResponse.process_headersc                 C   s@   | j d k	rdS | jjdkrdS | jjdkr.dS | jdkr<dS dS )NFr.   ro   rq   T)rj   r?   r>   r:   rt   rm   r   r   r   r{     s    

zResponse.is_chunkedc                 C   sl   | j rd}n|  ¡ rd}nd}d| jjd | jjd | jf d| j dt ¡  d	| g}| jrh| d
¡ |S )Nrl   r   z
keep-alivezHTTP/%s.%s %s
r   r   zServer: %s
z
Date: %s
zConnection: %s
zTransfer-Encoding: chunked
)	rl   rs   r?   r>   rf   r   Z	http_daterg   r%   )r   r~   rT   r   r   r   Údefault_headers/  s     
 ÿ
û
zResponse.default_headersc                 C   sV   | j r
d S |  ¡ }| dd„ | jD ƒ¡ dd |¡ }t | jt |d¡¡ d| _ d S )Nc                 S   s   g | ]\}}d ||f ‘qS )z%s: %s
r   )r3   Úkr4   r   r   r   r5   G  s     z)Response.send_headers.<locals>.<listcomp>z%s
rH   zlatin-1T)	ri   r†   ÚextendrT   r=   r   r*   r@   Zto_bytestring)r   ÚtosendÚ
header_strr   r   r   Úsend_headersC  s    zResponse.send_headersc                 C   s    |   ¡  t|tƒstd| ƒ‚t|ƒ}|}| jd k	rj| j| jkrDd S t| j| j |ƒ}||k rj|d |… }| jr||dkr|d S |  j|7  _t	 
| j|| j¡ d S )Nz%r is not a byter   )r‹   rY   rZ   r   r]   rj   rk   Úminrg   r   r*   r@   )r   ÚargZarglenr‰   r   r   r   r*   M  s    

zResponse.writec                 C   s   | j jdk	S )NF)r(   Úsendfilerm   r   r   r   Úcan_sendfiled  s    zResponse.can_sendfilec              	   C   sô   | j js|  ¡ sdS t |j¡s$dS |j ¡ }z:t |dtj	¡}| j
d kr`t |¡j}|| }n| j
}W n ttjfk
r„   Y dS X |  ¡  |  ¡ r°d| }| j | d¡¡ |dkrÌ| jj|j||d� |  ¡ rà| j d¡ t ||tj¡ dS )NFr   z%X
zutf-8)ÚoffsetÚcounts   
T)r(   Zis_sslr�   r   Z
has_filenor   ÚfilenorQ   ÚlseekÚSEEK_CURrj   ÚfstatÚst_sizeÚOSErrorÚioÚUnsupportedOperationr‹   r{   r@   Úsendallr,   rŽ   ÚSEEK_SET)r   Úrespiterr’   r�   ÚfilesizeÚnbytesÚ
chunk_sizer   r   r   rŽ   g  s.    



zResponse.sendfilec                 C   s"   |   |¡s|D ]}|  |¡ qd S r   )rŽ   r*   )r   rœ   Úitemr   r   r   Ú
write_fileˆ  s    
zResponse.write_filec                 C   s&   | j s|  ¡  | jr"t | jd¡ d S )Nó    )ri   r‹   rg   r   Zwrite_chunkr@   rm   r   r   r   r   �  s    zResponse.close)N)r   r   r   r   rn   rs   r}   rz   r{   r†   r‹   r*   r�   rŽ   r¡   r   r   r   r   r   rP   È   s   
 
!rP   )r˜   r    rQ   Úrer&   Zgunicorn.http.messager   Zgunicorn.http.errorsr   r   r   Zgunicornr   r   r   ZBLKSIZEÚcompiler�   r!   r   Úlogr	   Ú	RawIOBaser   r0   rB   rG   re   rP   r   r   r   r   Ú<module>   s$   

Z