a
    �ÏOc�#  ã                   @   sÌ   d dl Z 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 d dl	m
Z
 d dlmZ d dlmZmZmZmZmZmZmZmZmZmZ d dlmZmZ d dlmZ d d	lmZ G d
d„ deƒZ dS )é    N)Údatetime)Úrandint)ÚSSLError)Úutil)
ÚForbiddenProxyRequestÚInvalidHeaderÚInvalidHeaderNameÚInvalidHTTPVersionÚInvalidProxyLineÚInvalidRequestLineÚInvalidRequestMethodÚInvalidSchemeHeadersÚLimitRequestHeadersÚLimitRequestLine)ÚResponseÚdefault_environ)Úreloader_engines)Ú	WorkerTmpc                   @   sŠ   e Zd Zdd„ d ¡ D ƒZg 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d„ Zdd„ Zdd„ Zdd„ ZdS )ÚWorkerc                 C   s   g | ]}t td | ƒ‘qS )zSIG%s)ÚgetattrÚsignal)Ú.0Úx© r   úL/var/www/html/gsl.tools/lib/python3.9/site-packages/gunicorn/workers/base.pyÚ
<listcomp>   ó    zWorker.<listcomp>z+ABRT HUP QUIT INT TERM USR1 USR2 WINCH CHLDc           	      C   sˆ   || _ d| _|| _|| _|| _|| _|| _d| _d| _d| _	d| _
|jdkrftd|jƒ}|j| | _ntj| _d| _|| _t|ƒ| _dS )zÎ        This is called pre-fork so it shouldn't do anything to the
        current process. If there's a need to make process wide
        changes you'll want to do that in ``self.init_process()``.
        z	[booting]FNr   T)ÚageÚpidÚppidÚsocketsÚappÚtimeoutÚcfgÚbootedZabortedÚreloaderÚnrZmax_requestsr   Zmax_requests_jitterÚsysÚmaxsizeÚaliveÚlogr   Útmp)	Úselfr   r   r    r!   r"   r#   r*   Újitterr   r   r   Ú__init__%   s$    
zWorker.__init__c                 C   s
   d| j  S )Nz<Worker %s>)r   ©r,   r   r   r   Ú__str__B   s    zWorker.__str__c                 C   s   | j  ¡  dS )z×        Your worker subclass must arrange to have this method called
        once every ``self.timeout`` seconds. If you fail in accomplishing
        this task, the master process will murder your workers.
        N)r+   Únotifyr/   r   r   r   r1   E   s    zWorker.notifyc                 C   s
   t ƒ ‚dS )z¼        This is the mainloop of a worker process. You should override
        this method in a subclass to provide the intended behaviour
        for your particular evil schemes.
        N)ÚNotImplementedErrorr/   r   r   r   ÚrunM   s    z
Worker.runc                    s,  ˆ j jr(ˆ j j ¡ D ]\}}|tj|< qtjˆ j jˆ j jˆ j j	d� t 
¡  t ¡ ˆ _ˆ jD ]}t |¡ t |¡ q\ˆ jD ]}t |¡ q|t ˆ j ¡ ¡ ˆ jˆ jd g ˆ _ˆ j ¡  ˆ  ¡  ˆ j jrô‡ fdd„}tˆ j j }|ˆ j j|d�ˆ _ˆ  ¡  ˆ j�rˆ j ¡  ˆ j  ˆ ¡ dˆ _ˆ  ¡  dS )zÑ        If you override this method in a subclass, the last statement
        in the function should be to call this method with
        super().init_process() so that the ``run()`` loop is initiated.
        )Ú
initgroupsr   c                    sJ   ˆ j  d| ¡ dˆ _t ˆ jd d¡ ˆ j ˆ ¡ t 	d¡ t
 d¡ d S )NzWorker reloading: %s modifiedFé   ó   1çš™™™™™¹?r   )r*   Úinfor)   ÚosÚwriteÚPIPEr#   Ú
worker_intÚtimeÚsleepr'   Úexit)Úfnamer/   r   r   Úchangedz   s    
z$Worker.init_process.<locals>.changed)Zextra_filesÚcallbackTN)r#   ÚenvÚitemsr9   Úenvironr   Zset_owner_processÚuidÚgidr4   ÚseedÚpiper;   Zset_non_blockingZclose_on_execr    r+   ÚfilenoZwait_fdsr*   Úinit_signalsÚreloadr   Zreload_engineZreload_extra_filesr%   Ú	load_wsgiÚstartZpost_worker_initr$   r3   )r,   ÚkÚvÚpÚsrA   Zreloader_clsr   r/   r   Úinit_processU   s:    ÿ




ÿ
zWorker.init_processc              
   C   sž   z| j  ¡ | _W nˆ ty˜ } zp| jjs*‚ | j |¡ zHt ¡ \}}}| j	 
|j¡ t ¡ }tj||d� t | ¡ ¡| _W ~n~0 W Y d }~n
d }~0 0 d S )N)Úfile)r!   ZwsgiÚSyntaxErrorr#   rL   r*   Ú	exceptionr'   Úexc_infor%   Zadd_extra_fileÚfilenameÚioÚStringIOÚ	tracebackÚprint_tbr   Zmake_fail_appÚgetvalue)r,   ÚeÚ_Úexc_valÚexc_tbZ	tb_stringr   r   r   rM   �   s    zWorker.load_wsgic                 C   s´   | j D ]}t |tj¡ qt tj| j¡ t tj| j¡ t tj| j¡ t tj| j	¡ t tj
| j¡ t tj| j¡ t tjd¡ t tj
d¡ ttdƒr°t | jd ¡ d S )NFÚset_wakeup_fdr5   )ÚSIGNALSr   ÚSIG_DFLÚSIGQUITÚhandle_quitÚSIGTERMÚhandle_exitÚSIGINTÚSIGWINCHÚhandle_winchÚSIGUSR1Úhandle_usr1ÚSIGABRTÚhandle_abortÚsiginterruptÚhasattrrb   r;   )r,   rR   r   r   r   rK   §   s    

zWorker.init_signalsc                 C   s   | j  ¡  d S )N)r*   Zreopen_files©r,   ÚsigÚframer   r   r   rm   »   s    zWorker.handle_usr1c                 C   s
   d| _ d S )NF)r)   rr   r   r   r   rh   ¾   s    zWorker.handle_exitc                 C   s*   d| _ | j | ¡ t d¡ t d¡ d S )NFr7   r   )r)   r#   r<   r=   r>   r'   r?   rr   r   r   r   rf   Á   s    
zWorker.handle_quitc                 C   s    d| _ | j | ¡ t d¡ d S )NFr5   )r)   r#   Zworker_abortr'   r?   rr   r   r   r   ro   È   s    zWorker.handle_abortc                 C   sL  t  ¡ }|pd}t|ttttttt	t
tttfƒ�rrd}d}t|tƒrRdt|ƒ }nüt|tƒrjdt|ƒ }nät|tƒr‚dt|ƒ }nÌt|ttfƒr²dt|ƒ }|s°t|dƒr°|j}nœt|tƒrÊdt|ƒ }n„t|t	ƒrâd	t|ƒ }nlt|t
ƒrúd
t|ƒ }nTt|tƒ�rd}d}d}n:t|tƒ�r.dt|ƒ }n t|tƒ�rNd}d
t|ƒ }d}d}	| j |	j|d t|ƒd�¡ n(t|dƒ�rŽ| j d|j¡ d}d}d}|d u�rt  ¡ | }
t||| jƒ}|d |d< t|d ƒ|d< t||| jƒ}d||f |_t|ƒ|_| j ||||
¡ zt ||||¡ W n  t�yF   | j d¡ Y n0 d S )N)Ú éÿÿÿÿi�  zBad RequestzInvalid Request Line '%s'zInvalid Method '%s'zInvalid HTTP Version '%s'z%sÚreqzError parsing headers: '%s'z'%s'Ú	ForbiddenzRequest forbiddeni“  z%Invalid request from ip={ip}: {error}r   )ÚipÚerrorÚurizError handling request %siô  zInternal Server Errorru   ZREMOTE_ADDRr5   ZREMOTE_PORTz%s %szFailed to send error message.) r   ÚnowÚ
isinstancer   r   r	   r   r   r   r   r
   r   r   r   Ústrrq   rw   r*   ÚdebugÚformatrV   r{   r   r#   r   ÚstatusÚlenZresponse_lengthÚaccessr   Zwrite_errorÚ	Exception)r,   rw   ÚclientÚaddrÚexcZrequest_startZ
status_intÚreasonZmesgÚmsgZrequest_timerE   Úrespr   r   r   Úhandle_errorÍ   st    ú	





 

zWorker.handle_errorc                 C   s   | j  d¡ d S )Nzworker: SIGWINCH ignored.)r*   r   )r,   rs   r@   r   r   r   rk     s    zWorker.handle_winchN)Ú__name__Ú
__module__Ú__qualname__Úsplitrc   r;   r.   r0   r1   r3   rS   rM   rK   rm   rh   rf   ro   r‹   rk   r   r   r   r   r      s"   ÿ;Br   )!rY   r9   r   r'   r=   r[   r   Úrandomr   Ússlr   Zgunicornr   Zgunicorn.http.errorsr   r   r   r	   r
   r   r   r   r   r   Zgunicorn.http.wsgir   r   Zgunicorn.reloaderr   Zgunicorn.workers.workertmpr   Úobjectr   r   r   r   r   Ú<module>   s   0