U
    hU                     @   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	m
Z
mZ dddZed	ZG d
d dZG dd dZG dd deZG dd deZdS )    )dequeN   )ReadOnlyFileBasedBuffer)build_http_dateloggerqueue_loggerCONTENT_LENGTHCONTENT_TYPE)r   r	   )
connection
keep-alivezproxy-authenticatezproxy-authorizationteZtrailersztransfer-encodingupgradec                   @   sR   e Zd ZdZdZdZeZeZdd Zdd Z	dd Z
d	d
 Zdd ZdddZdS )ThreadedTaskDispatcherz6A Task Dispatcher that creates a thread for each task.r   c                 C   s:   t  | _t | _t | _t| j| _t| j| _	d S N)
setthreadsr   queue	threadingLocklock	Conditionqueue_cvthread_exit_cvself r   ?/var/www/html/venv/lib/python3.8/site-packages/waitress/task.py__init__3   s
    
zThreadedTaskDispatcher.__init__c                 C   s*   t j|d| |fd}d|_|  d S )Nz	waitress-)targetnameargsT)r   Threaddaemonstart)r   r   	thread_notr   r   r   start_new_thread:   s      z'ThreadedTaskDispatcher.start_new_threadc              	   C   s   | j  | js@| jdkr@|  jd8  _| j  |  jd7  _q| jdkr|  jd8  _|  jd8  _| j| | j	  W 5 Q R  q| j
 }W 5 Q R X z|  W q  tk
r   | jd| Y q X q d S )Nr   r   zException when servicing %r)r   r   
stop_countactive_countr   waitr   discardr   notifypopleftserviceBaseExceptionr   	exception)r   r$   taskr   r   r   handler_threadA   s     


z%ThreadedTaskDispatcher.handler_threadc              	   C   s   | j  | j}d}t|| j }||k rr||kr:|d }q(|| |d7 }| | j| |  jd7  _|d }q ||kr|  j|| 7  _| j	  W 5 Q R X d S )Nr   r   )
r   r   lenr'   addr&   r1   r(   r   
notify_all)r   countr   r$   runningr   r   r   set_thread_countX   s    


z'ThreadedTaskDispatcher.set_thread_countc              	   C   sf   | j V | j| | j  t| j}t| j| j | j }||krX| j	
d||  W 5 Q R X d S )NzTask queue depth is %d)r   r   appendr   r+   r2   r   r'   r(   r   warning)r   r0   Z
queue_sizeZidle_threadsr   r   r   add_taskk   s    

 zThreadedTaskDispatcher.add_taskT   c              	   C   s   |  d | j}t | }| j |rVt |krH| jdt| qV| jd q$|r| j	}t|dkr~| jdt| |r|
 }|  q~| j  W 5 Q R  dS W 5 Q R X dS )Nr   z%d thread(s) still runningg?zCanceling %d pending task(s)TF)r7   r   timer   r   r9   r2   r   r)   r   r,   cancelr   r4   )r   Zcancel_pendingtimeoutr   Z
expirationr   r0   r   r   r   shutdownv   s&    


zThreadedTaskDispatcher.shutdownN)Tr;   )__name__
__module____qualname____doc__r'   r(   r   r   r   r&   r1   r7   r:   r?   r   r   r   r   r   +   s   r   c                   @   s   e Zd ZdZdZdZdZdZdZdZ	dZ
dZdZeZdd Zdd Zed	d
 ZddddZdd Zdd Zdd Zdd Zdd ZdS )TaskFz200 OKr   Nc                 C   s.   || _ || _g | _|j}|dkr$d}|| _d S )N)1.01.1rE   )channelrequestresponse_headersversion)r   rG   rH   rJ   r   r   r   r      s    zTask.__init__c                 C   sH   z|    |   |   W n& tk
rB   d| _| jjjr> Y nX d S )NT)r#   executefinishOSErrorclose_on_finishrG   adjZlog_socket_errorsr   r   r   r   r-      s    
zTask.servicec                 C   s&   | j dp"| j dp"| j d S )N1Z204Z304)status
startswithr   r   r   r   has_body   s
    

zTask.has_body)returnc                 C   sL   | j sBd }| jD ]\}}| dkr| }q|d krB| jd d| _d S )N
Connection)rU   closeT)wrote_headerrI   
capitalizelowerr8   rN   )r   Zconnection_close_header
headername	headervalr   r   r   set_close_on_finish   s    
zTask.set_close_on_finishc                 C   s  | j }| jjdd }g }d }d }d }| jD ]^\}}ddd |dD }|dkrh| jr0|}nq0|dkrt|}|dkr|}|	||f q0|| _|d kr| j
d k	r| jrt| j
}| j	d|f |d	kr|d
kr|s|   q| j	d n|   nV|dkrL|dkr|   |sT| jr:| j	d d| _| jsT|   ntd| jjjj}	|s~|	r| j	d|	f n| j	d|	pdf |s| j	dt| jf d| j  d| j }
dd t| jdd dD }|
g| }dd| }|dS )NZ
CONNECTION -c                 S   s   g | ]}|  qS r   )rX   ).0xr   r   r   
<listcomp>   s     z.Task.build_response_header.<locals>.<listcomp>zContent-LengthDateServerrE   r   )rU   z
Keep-AliverF   rV   )zTransfer-EncodingchunkedTzneither HTTP/1.0 or HTTP/1.1ZViaZwaitresszHTTP/ c                 S   s   g | ]}d | qS )z%s: %sr   )r_   Zhvr   r   r   ra     s    c                 S   s   | d S )Nr   r   )r`   r   r   r   <lambda>      z,Task.build_response_header.<locals>.<lambda>)keyz%s

z
latin-1)rJ   rH   headersgetrY   rI   joinsplitrS   r8   content_lengthstrr\   chunked_responserN   AssertionErrorrG   serverrO   identr   
start_timerQ   sortedencode)r   rJ   r
   rI   Zcontent_length_headerZdate_headerZserver_headerrZ   r[   rs   
first_lineZ
next_lineslinesresr   r   r   build_response_header   sp    






zTask.build_response_headerc                 C   s:   g }| j D ]$\}}| dkr q
|||f q
|| _ d S )Ncontent-length)rI   rY   r8   )r   rI   header_nameheader_valuer   r   r   remove_content_length_header  s    z!Task.remove_content_length_headerc                 C   s   t   | _d S r   )r<   rt   r   r   r   r   r#   (  s    z
Task.startc                 C   s&   | j s| d | jr"| jd d S )Nrg   s   0

)rW   writerp   rG   
write_soonr   r   r   r   rL   +  s    
zTask.finishc                 C   s  | j std| j}| js2|  }|| d| _|r| jr|}| j}| jr|t	t
|dd   dd }||d 7 }nP|d k	r|d || j  }|  jt
|7  _||kr| js| jd|  d| _|r|| n8|r|  jt
|7  _| js| jd| j  d| _d S )Nz1start_response was not called before body writtenT   ri   s   
z`application-written content exceeded the number of bytes specified by Content-Length header (%s)zfapplication-written content was ignored due to HTTP response that may not contain a message-body: (%s))completeRuntimeErrorrG   rW   rz   r   rS   rn   rp   hexr2   upperrv   content_bytes_writtenlogged_write_excessr   r9   logged_write_no_bodyrQ   )r   datarG   ZrhZtowriteclr   r   r   r   2  sD    

"z
Task.write)r@   rA   rB   rN   rQ   rW   rt   rn   r   r   r   r   rp   r   r   r-   propertyrS   r\   rz   r~   r#   rL   r   r   r   r   r   rD      s*   


[
rD   c                   @   s   e Zd ZdZdZdd ZdS )	ErrorTaskz(An error task produces an error responseTc                 C   sV   | j jjj}| jj}||\}}}|| _| j	| | 
  t|| _| | d S r   )rG   rr   rO   rs   rH   errorZto_responserQ   rI   extendr\   r2   rn   r   )r   rs   erQ   rj   bodyr   r   r   rK   `  s    
zErrorTask.executeN)r@   rA   rB   rC   r   rK   r   r   r   r   r   [  s   r   c                   @   s$   e Zd ZdZdZdd Zdd ZdS )WSGITaskz8A WSGI task produces a response from a WSGI application.Nc           
   	      s\     }d fdd	} jj||}d}z|jtkr j}|	|}|r||krj|d k	rd 
  | _ d  j| d}W d S d }|D ]P}|d krt|} jd krd }	t|drt|}	|	dkr| _|r | q j}|d k	r8 j|kr8 jjd	kr8    jjd	kr8 jd
 j| W 5 |rVt|drV|  X d S )Nc                    s8   j r|std|r8z jr(|d ng  _W 5 d }X d _ | jtk	rTtd|  d| ksdd| krltd|  _|D ]\}}|jtk	rtd|d	||f|jtk	rtd
|d	||fd|ksd|krtdd|ksd|krtd| }|dkrt	| _
qv|tkrvtd| qv j|  jS )Nz?start_response called a second time without providing exc_info.r   Tzstatus %s is not a string
z5carriage return/line feed character present in statuszHeader name z is not a string in zHeader value z;carriage return/line feed character present in header valuez:carriage return/line feed character present in header namer{   zS%s is a "hop-by-hop" header; it cannot be used by a WSGI application (see PEP 3333))r   rq   rW   rI   	__class__ro   
ValueErrorrQ   rY   intrn   
hop_by_hopr   r   )rQ   rj   exc_infokvklr   r   r   start_responses  s\    






z(WSGITask.execute.<locals>.start_responseTrV   rg   F__len__r   HEADzVapplication returned too few bytes (%s) for specified Content-Length (%s) via app_iter)N)get_environmentrG   rr   ZapplicationhasattrrV   r   r   rn   preparer~   r   r   r2   r   rH   commandr\   r   r9   )
r   environr   Zapp_iterZcan_close_app_iterr   sizeZfirst_chunk_lenchunkZapp_iter_lenr   r   r   rK   p  sR    A





zWSGITask.executec                 C   sL  | j }|dk	r|S | j}|j}| j}|j}|jj}|drJd|d }|r~||kr\d}n"|d }||r~|t	|d }|j
d |j
d t|j
d |j t|j|j|jjd| j |||j|j|jdtjdd	d	| tdd
}t|j D ]>\}}	|	 }	t|d}
|
dkr$d| }
|
|kr|	||
< q| jj|d< || _ |S )zReturns a WSGI environment.N/r]   r   r   zHTTP/%s)r   r   TF)ZREMOTE_ADDRZREMOTE_HOSTZREMOTE_PORTREQUEST_METHODZSERVER_PORTZSERVER_NAMESERVER_SOFTWAREZSERVER_PROTOCOLZSCRIPT_NAMEZ	PATH_INFOZREQUEST_URIZQUERY_STRINGzwsgi.url_schemezwsgi.versionzwsgi.errorszwsgi.multithreadzwsgi.multiprocesszwsgi.run_oncez
wsgi.inputzwsgi.file_wrapperzwsgi.input_terminatedZHTTP_zwaitress.client_disconnected) r   rH   pathrG   rr   rO   
url_prefixrR   lstripr2   addrro   r   r   Zeffective_portZserver_namers   rJ   request_uriquery
url_schemesysstderrZget_body_streamr   dictrj   itemsstriprename_headersrk   Zcheck_client_disconnected)r   r   rH   r   rG   rr   r   Zurl_prefix_with_trailing_slashrh   valueZmykeyr   r   r   r     s`    



zWSGITask.get_environment)r@   rA   rB   rC   r   rK   r   r   r   r   r   r   k  s   ~r   )collectionsr   socketr   r   r<   buffersr   Z	utilitiesr   r   r   r   	frozensetr   r   rD   r   r   r   r   r   r   <module>   s"   c N