a
    ehU                     @   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   I/var/www/html/requester/venv/lib/python3.9/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 d    q| j
 }W d    n1 s0    Y  z|  W q  ty   | jd| Y q 0 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||v r:|d }q(|| |d7 }| | j| |  jd7  _|d }q ||kr|  j|| 7  _| j	  W d    n1 s0    Y  d S )Nr   r   )
r   r   lenr'   addr&   r1   r(   r   
notify_all)r   countr   r$   Zrunningr   r   r   set_thread_countX   s    


z'ThreadedTaskDispatcher.set_thread_countc                 C   sz   | j ` | j| | j  t| j}t| j| j | j }||krX| j	
d||  W d    n1 sl0    Y  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 d    dS W d    n1 s0    Y  dS )Nr   z%d thread(s) still runningg?zCanceling %d pending task(s)TF)r6   r   timer   r   r8   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   r6   r9   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vr$d}|| _d S )N)1.01.1rD   )channelrequestresponse_headersversion)r   rF   rG   rI   r   r   r   r      s    zTask.__init__c                 C   sF   z|    |   |   W n$ ty@   d| _| jjjr< Y n0 d S )NT)r#   executefinishOSErrorclose_on_finishrF   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 u rB| jd d| _d S )N
Connection)rT   closeT)wrote_headerrH   
capitalizelowerr7   rM   )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 u r| j
d u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   )rW   ).0xr   r   r   
<listcomp>       z.Task.build_response_header.<locals>.<listcomp>zContent-LengthDateServerrD   r   )rT   z
Keep-AliverE   rU   )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   r`     s   c                 S   s   | d S )Nr   r   )r_   r   r   r   <lambda>  ra   z,Task.build_response_header.<locals>.<lambda>)keyz%s

z
latin-1)rI   rG   headersgetrX   rH   joinsplitrR   r7   content_lengthstrr[   chunked_responserM   AssertionErrorrF   serverrN   identr   
start_timerP   sortedencode)r   rI   r
   rH   Zcontent_length_headerZdate_headerZserver_headerrY   rZ   rr   
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)rH   rX   r7   )r   rH   header_nameheader_valuer   r   r   remove_content_length_header  s    z!Task.remove_content_length_headerc                 C   s   t   | _d S r   )r;   rs   r   r   r   r   r#   (  s    z
Task.startc                 C   s&   | j s| d | jr"| jd d S )Nra   s   0

)rV   writero   rF   
write_soonr   r   r   r   rK   +  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 u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   rh   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RuntimeErrorrF   rV   ry   r   rR   rm   ro   hexr2   upperru   content_bytes_writtenlogged_write_excessr   r8   logged_write_no_bodyrP   )r   datarF   ZrhZtowriteclr   r   r   r~   2  sD    

"z
Task.write)r?   r@   rA   rM   rP   rV   rs   rm   r   r   r   r   ro   r   r   r-   propertyrR   r[   ry   r}   r#   rK   r~   r   r   r   r   rC      s*   


[
rC   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   )rF   rq   rN   rr   rG   errorZto_responserP   rH   extendr[   r2   rm   r~   )r   rr   erP   ri   bodyr   r   r   rJ   `  s    
zErrorTask.executeN)r?   r@   rA   rB   r   rJ   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u r j}||}|r||krj|d urd   | _ 	d  j
| d}W |rt|dr|  d S d }|D ]P}|d u rt|} jd u rd }	t|drt|}	|	dkr| _|r 	| q j}|d urL j|krL jjd	krL    jjd	krL jd
 j| W |rt|dr|  n|rt|dr|  0 d S )Nc                    s<   j r|std|r<z jr(|d ng  _W d }nd }0 d _ | jturXtd|  d| v shd| v rptd|  _|D ]\}}|jturtd|d	||f|jturtd
|d	||fd|v sd|v rtdd|v sd|v rtd| }|dkrt	| _
qz|tv rztd| qz 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 namerz   zS%s is a "hop-by-hop" header; it cannot be used by a WSGI application (see PEP 3333))r   rp   rV   rH   	__class__rn   
ValueErrorrP   rX   intrm   
hop_by_hopr   r~   )rP   ri   exc_infokvklr   r   r   start_responses  s\    





z(WSGITask.execute.<locals>.start_responseTra   FrU   __len__r   HEADzVapplication returned too few bytes (%s) for specified Content-Length (%s) via app_iter)N)get_environmentrF   rq   Zapplicationr   r   rm   preparer}   r~   r   hasattrrU   r2   r   rG   commandr[   r   r8   )
r   environr   Zapp_iterZcan_close_app_iterr   sizeZfirst_chunk_lenchunkZapp_iter_lenr   r   r   rJ   p  s\    A


$



zWSGITask.executec                 C   sL  | j }|du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u r$d| }
|
|v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_URI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   rG   pathrF   rq   rN   
url_prefixrQ   lstripr2   addrrn   r   r   Zeffective_portZserver_namerr   rI   request_uriquery
url_schemesysstderrZget_body_streamr   dictri   itemsstriprename_headersrj   Zcheck_client_disconnected)r   r   rG   r   rF   rq   r   Zurl_prefix_with_trailing_slashrg   valueZmykeyr   r   r   r     s`    



zWSGITask.get_environment)r?   r@   rA   rB   r   rJ   r   r   r   r   r   r   k  s   ~r   )collectionsr   socketr   r   r;   buffersr   Z	utilitiesr   r   r   r   	frozensetr   r   rC   r   r   r   r   r   r   <module>   s"   c N