U
    +5øi#&  ã                   @   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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ƒZ"dS )é    N)Údatetime)Úrandint)ÚSSLError)Úutil)ÚForbiddenProxyRequestÚInvalidHeaderÚInvalidHeaderNameÚInvalidHTTPVersionÚInvalidProxyLineÚInvalidRequestLineÚInvalidRequestMethodÚInvalidSchemeHeadersÚLimitRequestHeadersÚLimitRequestLineÚUnsupportedTransferCodingÚConfigurationProblemÚObsoleteFolding)Ú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   ú9/tmp/pip-unpacked-wheel-pa3uujlc/gunicorn/workers/base.pyÚ
<listcomp>    s     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__C   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-   Únotifyr1   r   r   r   r3   F   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)ÚNotImplementedErrorr1   r   r   r   ÚrunN   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)Úfnamer1   r   r   Úchanged{   s    
z$Worker.init_process.<locals>.changed)Zextra_filesÚcallbackTN)r%   ÚenvÚitemsr;   Úenvironr   Zset_owner_processÚuidÚgidr6   Ú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&   r5   )r.   ÚkÚvÚpÚsrC   Zreloader_clsr   r1   r   Úinit_processV   s:    ÿ




ÿ
zWorker.init_processc              
   C   sš   z| j  ¡ | _W n„ tk
r” } zf| jjs,‚ | j |¡ zFt ¡ \}}}| j	 
|j¡ t ¡ }tj||d� t | ¡ ¡| _W 5 ~X W 5 d }~X Y nX d S )N)Úfile)r#   ZwsgiÚSyntaxErrorr%   rN   r,   Ú	exceptionr)   Úexc_infor'   Zadd_extra_fileÚfilenameÚioÚStringIOÚ	tracebackÚprint_tbr   Zmake_fail_appÚgetvalue)r.   ÚeÚexc_tbÚ_Úexc_valZ	tb_stringr   r   r   rO   ‘   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_fdr7   )ÚSIGNALSr   ÚSIG_DFLÚSIGQUITÚhandle_quitÚSIGTERMÚhandle_exitÚSIGINTÚSIGWINCHÚhandle_winchÚSIGUSR1Úhandle_usr1ÚSIGABRTÚhandle_abortÚsiginterruptÚhasattrrd   r=   )r.   rT   r   r   r   rM   ¨   s    

zWorker.init_signalsc                 C   s   | j  ¡  d S )N)r,   Zreopen_files©r.   ÚsigÚframer   r   r   ro   ¼   s    zWorker.handle_usr1c                 C   s
   d| _ d S )NF)r+   rt   r   r   r   rj   ¿   s    zWorker.handle_exitc                 C   s*   d| _ | j | ¡ t d¡ t d¡ d S )NFr9   r   )r+   r%   r>   r?   r@   r)   rA   rt   r   r   r   rh   Â   s    
zWorker.handle_quitc                 C   s    d| _ | j | ¡ t d¡ d S )NFr7   )r+   r%   Zworker_abortr)   rA   rt   r   r   r   rq   É   s    zWorker.handle_abortc                 C   sÎ  t  ¡ }|pd}t|ttttttt	t
ttttttfƒ�räd}d}t|tƒrZdt|ƒ }�nft|tƒrtdt|ƒ }�nLt|tƒrŽdt|ƒ }�n2t|tƒr¬dt|ƒ }d}�nt|tƒrÈdt|ƒ }d	}nøt|tƒràdt|ƒ }nàt|ttfƒ�rdt|ƒ }|�sÀt|d
ƒ�rÀ|j}nªt|tƒ�r0dt|ƒ }n�t|t	ƒ�rRd}dt|ƒ }d}nnt|t
ƒ�rldt|ƒ }nTt|tƒ�r†d}d}d}n:t|tƒ�r dt|ƒ }n t|tƒ�rÀd}dt|ƒ }d}d}	| j |	j|d t|ƒd�¡ n6t|dƒ�r| j d|j¡ n| j d¡ d	}d}d}|d k	�r’t  ¡ | }
t||| jƒ}|d |d< t|d ƒ|d< t||| jƒ}d||f |_t|ƒ|_| j ||||
¡ zt  !||||¡ W n" t"k
�rÈ   | j #d¡ Y nX d S )N)Ú éÿÿÿÿi�  zBad RequestzInvalid Request Line '%s'zInvalid Method '%s'zInvalid HTTP Version '%s'z%siõ  iô  ÚreqzRequest Header Fields Too LargezError parsing headers: '%s'i¯  z'%s'Ú	ForbiddenzRequest forbiddeni“  z%Invalid request from ip={ip}: {error}r   )ÚipÚerrorÚurizError handling request %sz$Error handling request (no URI read)zInternal Server Errorrw   ZREMOTE_ADDRr7   ZREMOTE_PORTz%s %szFailed to send error message.)$r   ÚnowÚ
isinstancer   r   r	   r   r   r   r   r
   r   r   r   r   r   r   Ústrrs   ry   r,   ÚwarningÚformatrX   r}   r   r%   r   ÚstatusÚlenZresponse_lengthÚaccessr   Zwrite_errorÚ	ExceptionÚdebug)r.   ry   ÚclientÚaddrÚexcZrequest_startZ
status_intÚreasonZmesgÚmsgZrequest_timerG   Úrespr   r   r   Úhandle_errorÎ   sš           ù






 

zWorker.handle_errorc                 C   s   | j  d¡ d S )Nzworker: SIGWINCH ignored.)r,   r‡   )r.   ru   rB   r   r   r   rm     s    zWorker.handle_winchN)Ú__name__Ú
__module__Ú__qualname__Úsplitre   r=   r0   r2   r3   r5   rU   rO   rM   ro   rj   rh   rq   rŽ   rm   r   r   r   r   r      s"   ÿ;Or   )#r[   r;   r   r)   r?   r]   r   Úrandomr   Ússlr   Zgunicornr   Zgunicorn.http.errorsr   r   r   r	   r
   r   r   r   r   r   r   r   r   Zgunicorn.http.wsgir   r   Zgunicorn.reloaderr   Zgunicorn.workers.workertmpr   r   r   r   r   r   Ú<module>   s   <	