o
    ª›hf  ã                   @   sª   d 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
mZmZmZ ddlmZ ddlZddlmZmZ dZd	ZG d
d„ dejƒZG dd„ dejjƒZdS )z>An ISAPI extension base class implemented using a thread-pool.é    N)Ú
OVERLAPPED)ÚINFINITE)ÚCloseHandleÚCreateIoCompletionPortÚGetQueuedCompletionStatusÚPostQueuedCompletionStatus)ÚSetThreadToken)ÚExtensionErrorÚisapiconé   é   c                   @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )ÚWorkerThreadc                 C   s,   d| _ || _|| _tj | ¡ |  d¡ d S )NFT)ÚrunningÚio_req_portÚ	extensionÚ	threadingÚThreadÚ__init__Ú	setDaemon)Úselfr   r   © r   úNc:\Users\shubh\Videos\agent\nova\Lib\site-packages\isapi/threaded_extension.pyr      s
   zWorkerThread.__init__c                 C   sv   d| _ | j r9t| jtƒ\}}}}|tkr|d u rd S | jj |¡}|d u r-td|› d�ƒ‚|||||ƒ | j sd S d S )NTzBad request 'ú')	r   r   r   r   ÚISAPI_SHUTDOWNr   Údispatch_mapÚgetÚRuntimeError)r   ÚerrCodeÚbytesÚkeyÚ
overlappedÚ
dispatcherr   r   r   Úrun%   s   ÿôzWorkerThread.runc                 C   s   | j  |¡ d S ©N)r   ÚDispatch)r   Zcblockr   r   r   Úcall_handler5   s   zWorkerThread.call_handlerN)Ú__name__Ú
__module__Ú__qualname__r   r"   r%   r   r   r   r   r      s    	r   c                   @   sP   e Zd ZdZdZ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 )ÚThreadPoolExtensionz<Base class for an ISAPI extension based around a thread-poolé   i˜:  c                 C   s   g | _ t| ji| _d S r#   )ÚworkersÚISAPI_REQUESTÚDispatchConnectionr   )r   r   r   r   r   C   s   
ÿzThreadPoolExtension.__init__c                 C   sZ   t jj | |¡ tdd ddƒ| _g | _t| jƒD ]}t	| | jƒ}| 
¡  | j |¡ qd S )Néÿÿÿÿr   )ÚisapiÚsimpleÚSimpleExtensionÚGetExtensionVersionr   r   r+   ÚrangeÚmax_workersr   ÚstartÚappend)r   ÚviÚiÚworkerr   r   r   r2   M   s   ýz'ThreadPoolExtension.GetExtensionVersionc                 C   s"   t ƒ }||_t| jdt|ƒ tjS )Nr   )r   Úobjectr   r   r,   r
   ZHSE_STATUS_PENDING)r   Úcontrol_blockr    r   r   r   ÚHttpExtensionProcZ   s   z%ThreadPoolExtension.HttpExtensionProcc                 C   sˆ   | j D ]}d|_q| j D ]
}t| jdtd ƒ qt ¡ | jd  }| j }|r:t ¡ |kr,nt d¡ dd„ |D ƒ}|s%i | _t	| jƒ d S )NFr   iè  gš™™™™™É?c                 S   s   g | ]}|  ¡ r|‘qS r   )Úis_alive)Ú.0Úwr   r   r   Ú
<listcomp>n   s    z:ThreadPoolExtension.TerminateExtension.<locals>.<listcomp>)
r+   r   r   r   r   ÚtimeÚworker_shutdown_waitÚsleepr   r   )r   Ústatusr9   Úend_timeÚaliver   r   r   ÚTerminateExtension`   s   


ûz&ThreadPoolExtension.TerminateExtensionc              	   C   sh   |j }| ¡ }td |ƒ z!z|  |¡ W n   |  |¡ Y W td d ƒ d S W td d ƒ d S td d ƒ w r#   )r:   ZGetImpersonationTokenr   r$   ÚHandleDispatchError)r   r   r   r   r    r;   ZhRequestTokenr   r   r   r-   u   s   
ûz&ThreadPoolExtension.DispatchConnectionc                 C   s   t dƒ‚)aœ  Overridden by the sub-class to handle connection requests.

        This class creates a thread-pool using a Windows completion port,
        and dispatches requests via this port.  Sub-classes can generally
        implement each connection request using blocking reads and writes, and
        the thread-pool will still provide decent response to the end user.

        The sub-class can set a max_workers attribute (default is 20).  Note
        that this generally does *not* mean 20 threads will all be concurrently
        running, via the magic of Windows completion ports.

        There is no default implementation - sub-classes must implement this.
        z$sub-classes should override Dispatch)ÚNotImplementedError)r   Úecbr   r   r   r$   ƒ   s   zThreadPoolExtension.Dispatchc           	      C   s  t j|_t ¡ \}}}d}zvz;ddl}| ddd¡ t|d� td|d� t 	||¡t 
||¡ }| ¡ }td | d	 |¡¡| |¡¡|d� W n( tyR   Y n)   td
ƒ t ¡  tdƒ t |||¡ Y W d}| ¡  dS W d}| ¡  dS W d}| ¡  dS d}| ¡  w )zÜHandles errors in the Dispatch method.

        When a Dispatch method call fails, this method is called to handle
        the exception.  The default implementation formats the traceback
        in the browser.
        Nr   z200 OKzContent-type: text/html

F)Úfilez+<H3>Traceback (most recent call last):</H3>z<PRE>{}<B>{}</B></PRE>Ú z#FAILED to render the error message!zORIGINAL extension error:)r
   ZHSE_STATUS_ERRORZHttpStatusCodeÚsysÚexc_infoÚhtmlZSendResponseHeadersÚprintÚ	tracebackÚ	format_tbÚformat_exception_onlyÚpopÚformatÚescapeÚjoinr	   Ú	print_excÚprint_exceptionZDoneWithSession)	r   rJ   Zexc_typÚexc_valÚexc_tbÚlimitrO   ÚlistÚboldr   r   r   rH   “   sR   ÿ
ÿ
þþ
ûìö	ÿ
z'ThreadPoolExtension.HandleDispatchErrorN)r&   r'   r(   Ú__doc__r4   rB   r   r2   r<   rG   r-   r$   rH   r   r   r   r   r)   =   s    
r)   )r_   rM   r   rA   rQ   Z
pywintypesr   Z
win32eventr   Z	win32filer   r   r   r   Zwin32securityr   Zisapi.simpler/   r	   r
   r,   r   r   r   r0   r1   r)   r   r   r   r   Ú<module>   s    "