U
    d(0                     @   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	 d dl
mZmZ d dlmZ dZedZeeZG dd deZG d	d
 d
e jZdd Zdd Zdd Zdd ZG dd deZdS )    N)	HEADER_RE)InvalidHeaderInvalidHeaderName)SERVER_SOFTWARESERVERi?z[\x00-\x1F\x7F]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-1tw_qy24/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_environD   s    r.   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>Y   s     z#default_environ.<locals>.<listcomp>)z
wsgi.inputzgunicorn.socketREQUEST_METHODQUERY_STRINGZRAW_URIZSERVER_PROTOCOL)r.   updatebodymethodqueryurijoinversion)reqsockr&   envr   r   r   default_environQ   s    r@   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_infor0   )r=   infor   r   r   proxy_environ^   s    

rE   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rd|| |
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||d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_schemerB   r   r   rC   :httpP   httpsi  ZSERVER_NAMEZSERVER_PORTZ	PATH_INFO)Responser@   osenvirongetheaderslowersendreplacescheme
isinstancer0   bytesdecodesplitlenr#   pathutilZunquote_to_wsgi_strr6   rE   )r=   r>   clientserverr&   resprP   hostscript_nameZhdr_nameZ	hdr_valuer   Z	path_infor   r   r   createm   sd    






rc   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 )rN   c                 C   sL   || _ || _t| _d | _d| _d| _g | _d| _d | _	d| _
d| _|| _d S )NFr   )r=   r>   r   r<   statuschunked
must_closerR   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)rf   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  )rf   r=   should_closerh   re   r8   status_coderk   r   r   r   rq      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!)rd   rg   r]   reraiseAssertionErrorintrZ   rr   
ValueErrorprocess_headers
is_chunkedre   r(   )r   rd   rR   exc_infor   r   r   start_response   s    


zResponse.start_responsec                 C   s   |D ]\}}t |ts"td| t|r8td| t |tsNtd| t|rdtd| | }|	  }|dkrt
|| _nXt|r|dkr|	  dkrd| _q|dkr|	  dkr| j| |f q| j| |f qd S )Nz%r is not a stringz%rzcontent-length
connectionrj   TZ	websocket)rW   r0   	TypeErrorr   searchr   HEADER_VALUE_REr   striprS   rv   rh   r]   Z
is_hoppishrj   rR   r#   )r   rR   namevaluelnamer   r   r   rx      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,   rm   ro   T)rh   r=   r<   r8   rr   rk   r   r   r   ry     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 )Nrj   r	   z
keep-alivezHTTP/%s.%s %s
r   r   zServer: %s
z
Date: %s
zConnection: %s
zTransfer-Encoding: chunked
)	rj   rq   r=   r<   rd   r]   Z	http_datere   r#   )r   r|   rR   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   )r1   kr2   r   r   r   r3   ?  s     z)Response.send_headers.<locals>.<listcomp>z%s
rF   zlatin-1T)	rg   r   extendrR   r;   r]   r(   r>   Zto_bytestring)r   tosend
header_strr   r   r   send_headers;  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   rW   rX   r}   r[   rh   ri   minre   r]   r(   r>   )r   argZarglenr   r   r   r   r(   E  s    

zResponse.writec                 C   s   | j jdk	S )NF)r&   sendfilerk   r   r   r   can_sendfile\  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 |   |  rd| }| j|d | jj|j|d |  r| jd t||tj dS )NFr   z%X
zutf-8)counts   
T)r&   Zis_sslr   r]   Z
has_filenor
   filenorO   lseekSEEK_CURrh   fstatst_sizeOSErrorioUnsupportedOperationr   ry   r>   sendallr*   r   SEEK_SET)r   respiterr   offsetfilesizenbytes
chunk_sizer   r   r   r   _  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    )rg   r   re   r]   Zwrite_chunkr>   rk   r   r   r   r	     s    zResponse.close)N)r   r   r   r   rl   rq   r{   rx   ry   r   r   r(   r   r   r   r	   r   r   r   r   rN      s   

!rN   )r   r   rO   rer$   Zgunicorn.http.messager   Zgunicorn.http.errorsr   r   Zgunicornr   r   Zgunicorn.utilr]   ZBLKSIZEcompiler   r   r   logobjectr   	RawIOBaser   r.   r@   rE   rc   rN   r   r   r   r   <module>   s$   

T