o
    f|                     @   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Zd dlZzd dlZW n e	y3   d dl
ZY nw 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 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 d dlmZ G dd dZG dd dZG dd dZG dd dZG dd dZG dd dejZ G dd dej!Z"G dd dejZ#G dd de#Z$G dd  d e#Z%G d!d" d"Z&G d#d$ d$Z'G d%d& d&Z(d'd( Z)G d)d* d*Z*G d+d, d,Z+G d-d. d.eZ,dS )/    N)urllib)sha1)as_bytes)	as_string)asyncore_25)	http_date)http_server)	producers)filesys)default_handler)auth_handlerc                   @   s   e Zd ZdS )NOT_DONE_YETN)__name__
__module____qualname__ r   r   B/var/www/html/venv/lib/python3.10/site-packages/supervisor/http.pyr      s    r   c                   @   s"   e Zd ZdZdddZdd ZdS )deferring_chunked_producera'  A producer that implements the 'chunked' transfer coding for HTTP/1.1.
    Here is a sample usage:
            request['Transfer-Encoding'] = 'chunked'
            request.push (
                    producers.chunked_producer (your_producer)
                    )
            request.done()
    Nc                 C   s   || _ || _d| _d S N皙?)producerfootersdelay)selfr   r   r   r   r   __init__)   s   
z#deferring_chunked_producer.__init__c                 C   sj   | j r3| j  }|tu rtS |r dt| }t|d | d S d | _ | jr1ddg| j d S dS dS )Nz%xs   
   0s   

s   0

    )r   morer   lenr   r   join)r   datasr   r   r   r   .   s   
zdeferring_chunked_producer.moreNr   r   r   __doc__r   r   r   r   r   r   r      s    
	r   c                   @       e Zd ZdZdd Zdd ZdS )deferring_composite_producerz$combine a fifo of producers into onec                 C   s   || _ d| _d S r   )r	   r   )r   r	   r   r   r   r   A   s   
z%deferring_composite_producer.__init__c                 C   sJ   t | jr#| jd }| }|tu rtS |r|S | jd t | jsdS )Nr   r   )r   r	   r   r   pop)r   pdr   r   r   r   E   s   



z!deferring_composite_producer.moreNr#   r   r   r   r   r&   ?   s    r&   c                   @   s"   e Zd ZdZdddZdd ZdS )	deferring_globbing_producerz
    'glob' the output from a producer into a particular buffer size.
    helps reduce the number of calls to send().  [this appears to
    gain about 30% performance on requests to a single channel]
       c                 C   s   || _ d| _|| _d| _d S )Nr   r   )r   bufferbuffer_sizer   )r   r   r-   r   r   r   r   Z      
z$deferring_globbing_producer.__init__c                 C   s   t | j| jk r:| j }|tu rtS |r1z| j| | _W n ty0   t| jt| | _Y nw nt | j| jk s| j}d| _|S Nr   )r   r,   r-   r   r   r   	TypeErrorr   )r   r    rr   r   r   r   `   s   
z deferring_globbing_producer.moreN)r+   r#   r   r   r   r   r*   S   s    
r*   c                   @   r%   )deferring_hooked_producerz
    A producer that will call <function> when it empties,.
    with an argument of the number of bytes produced.  Useful
    for logging/instrumentation purposes.
    c                 C   s   || _ || _d| _d| _d S )Nr   r   )r   functionbytesr   )r   r   r3   r   r   r   r   x   r.   z"deferring_hooked_producer.__init__c                 C   sP   | j r&| j  }|tu rtS |sd | _ | | j |S |  jt|7  _|S dS r/   )r   r   r   r3   r4   r   )r   resultr   r   r   r   ~   s   
zdeferring_hooked_producer.moreNr#   r   r   r   r   r2   q   s    r2   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )deferring_http_requesta   The medusa http_request class uses the default set of producers in
    medusa.producers.  We can't use these because they don't know anything
    about deferred responses, so we override various methods here.  This was
    added to support tail -f like behavior on the logtail handler c           	      O   sN  t t j| j}| }d}d}d}| jdkr*|dkr'd| vr"d}n;d| d< n6d}n3| jdkrV|d	kr6d}n'd| vrUd
| v rG| d
 dksFd}n| jrSd| d
< d}d}n
d}n| jdu r]d}t| 	 }|rjd	| d< |rzt
t| j}t||g}n| jd| t| j}t|| j}|rt|}| j| d| j_|r| j  dS dS )z I didn't want to override this, but there's no way around
        it in order to support deferreds - CM

        finalize this transaction - send output to the http channelr      z1.0z
keep-alivezContent-Lengthz
Keep-Alive
Connectionz1.1closezTransfer-EncodingchunkedN)r   
get_header
CONNECTIONheaderlowerversionuse_chunkedr	   simple_producerbuild_reply_headerr   r&   outgoinginsertr2   logr*   channelpush_with_producercurrent_requestclose_when_done)	r   argkw
connectionclose_itwrap_in_chunkingglobbingoutgoing_headeroutgoing_producerr   r   r   done   sb   




zdeferring_http_request.donec              	   C   s\   | j jr| j jd }| j jd }nd}d}| j jj|d|| t | j| j|f  dS )z We need to override this because UNIX domain sockets return
        an empty string for the addr rather than a (host, port) combination r   r7   	localhostz%d - - [%s] "%s" %d %d
N)	rF   addrserverloggerrE   log_date_stringtimerequest
reply_code)r   r4   hostportr   r   r   rE      s   
zdeferring_http_request.logc                 C   s  i }dddd}t  }|  \}}}}|r|| }|r0|d dkr0|dd  }|r0|d dks"d|v r9t|}|rA|dd  }| jj}| j |d	< t	|j
|d
< |j|d< |j|d< d| j |d< | jj|d< d|d< d| |d< t jt j||d |d< |r||d< d|d< | jjr| jjd |d< nd|d< | jD ]6}	|	dd\}
}|
 }
| }|
|v r|r||||
< qdd|
d  }
|r|
|vr|||
< q|S )NCONTENT_LENGTHCONTENT_TYPECONNECTION_TYPE)zcontent-lengthzcontent-typerL   r   /r7   %REQUEST_METHODSERVER_PORTSERVER_NAMESERVER_SOFTWAREzHTTP/SERVER_PROTOCOLzchannel.creation_time SCRIPT_NAME	PATH_INFOPATH_TRANSLATEDQUERY_STRINGzCGI/1.1GATEWAY_INTERFACEREMOTE_ADDRz	127.0.0.1:zHTTP_%s_-)osgetcwd	split_urir   unquoterF   rU   commandupperstrr\   server_nameSERVER_IDENTr?   creation_timepathnormpathr   rT   r=   splitr>   stripget)r   env
header2envworkdirr{   paramsqueryfragmentrU   r=   keyvaluer   r   r   cgi_environment   sZ   




z&deferring_http_request.cgi_environmentc                 C   s   ddd}|   }|ddv s|ddkrd}nd	}d
|v r.|d
  }t|\}}n
|d  }|d }|du sB|| |krE|}n|d | }d||f }|dd dkr_|dd }|S )z Functionality that medusa's http request doesn't have; set an
        attribute named 'server_url' on the request based on the Host: header
        80443)httphttpsHTTPS)onONSERVER_PORT_SECURE1r   r   	HTTP_HOSTrd   rc   Nrn   z%s://%sr`   )r   r   r~   r   	splitport)r   default_portenvironprotocolr[   hostnamer\   
server_urlr   r   r   get_server_url/  s$   
z%deferring_http_request.get_server_urlN)r   r   r   r$   rR   rE   r   r   r   r   r   r   r6      s    S5r6   c                   @   s2   e Zd ZdZdZdZd
ddZdd Zdd	 ZdS )deferring_http_channeli   r   Nc                 C   sL   |d u rt   }| jr || j }|| jks|dk r|| _dS dS tj| S )Nr   TF)rX   r   last_writable_checkr   http_channelwritable)r   nowelapsedr   r   r   r   U  s   
zdeferring_http_channel.writablec                 C   s   	 t | jrQ| j }|du r| js| j  |   dS t|tr0| j  |  j|7  _dS | }|t	u r>|j
| _
dS |rK| j| | _d| _
dS | j  ndS q)z Implement deferreds r7   NF)r   producer_fifofirstac_out_bufferr'   r9   
isinstancer4   r   r   r   )r   r(   r    r   r   r   refill_bufferd  s.   




z$deferring_http_channel.refill_bufferc                 C   s  | j r
| j   dS t| j}d| _|d}|r)|d s)|dd }|r)|d r|s1|   dS |d }t|\}}}t|dd }t	|\}}d|v rb|r]t
|d | }nt
|}t| |||||}	| j  | jj  |du r| dt| d	 |	d
 dS | jjD ]H}
|
|	rz|	| _ |
|	 W  dS    | jj  t \\}}}}}}| jd||||f d	 z
|	d W Y  dS    Y Y  dS q|	d dS )z We only override this to use 'deferring_http_request' class
        instead of the normal http_request class; it sucks to need to override
        this r   z
r   r7   Nra   ?zBad HTTP request: %serror  z'Server Error: %s, %s: file: %s line: %si    )rH   found_terminatorr   	in_bufferr}   rI   r   crack_requestjoin_headers
splitqueryrt   r6   request_counter	incrementrU   total_requestslog_inforeprr   handlersmatchhandle_request
exceptionsasyncorecompact_traceback)r   r=   linesrY   ru   urir?   rpathrqueryr1   hfilefunlinetvtbinfor   r   r   r     sh   






z'deferring_http_channel.found_terminatorr"   )	r   r   r   ac_out_buffer_sizer   r   r   r   r   r   r   r   r   r   L  s    
 r   c                   @   s.   e Zd ZeZdZdd Zdd Zd	ddZdS )
supervisor_http_serverNc                 C   s^   ddl m} |s|tj}||}|| _tj|  | 	| g | _
|d |   dS )zj Override __init__ to do logger setup earlier so it can
        go to our logger object instead of stdout r   rV   N)supervisor.medusarV   file_loggersysstdoutunresolving_loggerr   
dispatcherr   
set_socketr   setblockingset_reuse_addr)r   socklogger_objectrV   r   r   r   prebind  s   


zsupervisor_http_server.prebindc                 C   sr   ddl m} ddlm} | d | | _| | _| | _| | _| | _	| 
d|tt | j| jf  d S )Nr   )counter)VERSION_STRING   z2Medusa (V%s) started at %s
	Hostname: %s
	Port:%s
)supervisor.medusa.counterr   supervisor.medusa.http_serverr   listentotal_clientsr   r   	bytes_outbytes_inr   rX   ctimerx   r\   )r   r   r   r   r   r   postbind  s"   
zsupervisor_http_server.postbindinfoc                 C   s,   d}t | dd d ur| j}| j|| d S )Nrg   ip)getattrr   rV   rE   )r   messagetyper   r   r   r   r     s   zsupervisor_http_server.log_info)r   )	r   r   r   r   channel_classr   r   r   r   r   r   r   r   r     s    r   c                   @   s   e Zd ZdZdd ZdS )supervisor_af_inet_http_serverz+ AF_INET version of supervisor HTTP server c                 C   s   || _ || _ttjtj}| || | ||f |s=| dd t }zt	|}W n tj
y<   td| w z
t|d | _W n tj
yZ   | dd || _Y nw |   d S )NzComputing default hostnamewarningzCould not determine IP address for hostname %s, please try setting an explicit IP address in the "port" setting of your [inet_http_server] section.  For example, instead of "port = 9001", try "port = 127.0.0.1:9001."r   zCannot do reverse lookup)r   r\   socketAF_INETSOCK_STREAMr   bindr   gethostnamegethostbynamer   
ValueErrorgethostbyaddrrx   r   )r   r   r\   r   r   r   r   r   r   r     s0   
z'supervisor_af_inet_http_server.__init__N)r   r   r   r$   r   r   r   r   r   r   	  s    r   c                   @   r%   )supervisor_af_unix_http_serverz+ AF_UNIX version of supervisor HTTP server c           
      C   s  || _ || _d|t f }zt| W n	 ty   Y nw 	 ttjtj}z|	| t
|| zt|| W nF ty   | |}|rPttjd| }tj| zt| W n   Y |  td Y W zt| W q ty   Y qw w zt||d |d  W n) ty }	 z|	jd tjkrd}t||t|tt d f  d }	~	ww | || W zt| W n ty   Y nw zt| W w  ty   Y w w d| _|    d S )Nz%s.%dr7   zUnlinking stale socket %s
g333333?r   zNot permitted to chown %s to uid/gid %s; adjust "sockchown" value in config file or on command line to values that the current user (%s) can successfully chownz<unix domain socket>)!r   r\   rq   getpidunlinkOSErrorr   AF_UNIXr   r   chmodlink	checkusedr   errno
EADDRINUSEr   stderrwriter9   rX   sleepchownargsEPERMr   r   pwdgetpwuidgeteuidr   rx   r   )
r   
socketname	sockchmod	sockchownr   tempnamer   usedmsgwhyr   r   r   r   *  s   


z'supervisor_af_unix_http_server.__init__c                 C   sX   t  t jt j}z|| |td |d |  W dS  t jy+   Y dS w )NzGET / HTTP/1.0

r7   FT)	r   r   r   connectsendr   recvr9   r   )r   r  r!   r   r   r   r   q  s   


z(supervisor_af_unix_http_server.checkusedN)r   r   r   r$   r   r   r   r   r   r   r   '  s    Gr   c                   @   sD   e 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 )tail_f_producerc                 C   sB   t || _|| _d| _|   |  }||kr|| | _d S d S r   )weakrefrefrY   filenamer   _open_fsizesz)r   rY   r  headr  r   r   r   r   ~  s   ztail_f_producer.__init__c                 C   s   |    d S r"   )_closer   r   r   r   __del__  s   ztail_f_producer.__del__c              	   C   s|   |    z|  }W n ttfy   Y dS w || j }|dk r%d| _dS |dkr<| j| d | j|}|| _|S tS )Nr   r   z==> File truncated <==
   )	_followr  r   r   r  r   seekreadr   )r   newszbytes_addedr4   r   r   r   r     s    
ztail_f_producer.morec                 C   s0   t | jd| _t| j tj | _d| _	d S )Nrbr   )
openr  r   rq   fstatfilenostatST_INOinor  r  r   r   r   r    s   
ztail_f_producer._openc                 C   s   | j   d S r"   )r   r9   r  r   r   r   r       ztail_f_producer._closec              	   C   sR   zt | jtj }W n ttfy   Y d S w | j|kr'|   |   d S d S r"   )	rq   r!  r  r"  r   r   r#  r  r  )r   r#  r   r   r   r    s   
ztail_f_producer._followc                 C   s   t | j tj S r"   )rq   r  r   r   r!  ST_SIZEr  r   r   r   r    s   ztail_f_producer._fsizeN)
r   r   r   r   r  r   r  r  r  r  r   r   r   r   r  }  s    
r  c                   @   ,   e Zd ZdZdZdd Zdd Zdd Zd	S )
logtail_handlerzLogtail HTTP Request Handlerz/logtailc                 C   
   || _ d S r"   supervisordr   r*  r   r   r   r        
zlogtail_handler.__init__c                 C      |j | jS r"   r   
startswithr{   r   rY   r   r   r   r     r$  zlogtail_handler.matchc                 C   s  |j dkr|d d S | \}}}}d|v rt|}|r3|d dkr3|dd  }|r3|d dks%|dd\}}z
|dd\}}W n tyR   |}d}Y nw ddlm}	 |	|\}
}| j	j
|
}|d u rq|d	 d S |j|}|d u r|d	 d S t|jd
| d }|d u stj|s|d	 d S t|tj }t||d< d|d< d|d< |t||d |  d S )NGETr   ra   r   r`   r7   r   )split_namespecr   z
%s_logfileLast-Modifiedtext/plain;charset=utf-8Content-TypenozX-Accel-Bufferingr   )ru   r   rs   r   rt   r}   r   supervisor.optionsr2  r*  process_groupsr   	processesr   configrq   r{   existsr!  ST_MTIMEr   build_http_datepushr  rR   )r   rY   r{   r   r   r   process_name_and_channelprocess_namerF   r2  
group_namegroupprocesslogfilemtimer   r   r   r     sH   





zlogtail_handler.handle_requestNr   r   r   IDENTr{   r   r   r   r   r   r   r   r'        r'  c                   @   r&  )
mainlogtail_handlerz!Main Logtail HTTP Request Handlerz/mainlogtailc                 C   r(  r"   r)  r+  r   r   r   r     r,  zmainlogtail_handler.__init__c                 C   r-  r"   r.  r0  r   r   r   r     r$  zmainlogtail_handler.matchc                 C   s   |j dkr|d d S | jjj}|d u stj|s"|d d S t|tj	 }t
||d< d|d< |t||d |  d S )Nr1  r   r   r3  r4  r5  r   )ru   r   r*  optionsrD  rq   r{   r;  r!  r<  r   r=  r>  r  rR   )r   rY   rD  rE  r   r   r   r     s   



z"mainlogtail_handler.handle_requestNrF  r   r   r   r   rI    rH  rI  c                  C   s6  g }t | j}| jD ]}|d }|tjkr'|d |d }}t|||d}n |tjkrA|d }	|d }
|d }t|	|
||d}ntd| d	d
l	m
} d	dl	m} d	dlm} g }| jD ]2\}}}z
||fi |}W n   t }| j| td| |||f | jd|  q^|d||f |||}t|}t|}||}tjtjt}tj|d}t|}t|}|d }|d }|r||i}t||}t||}t||}t||}t||}n
| j d|d   |!| |!| |!| |!| |!| |||f q
|S )Nfamilyr[   r\   )r   r   r   r   zCannot determine socket type %rr   )supervisor_xmlrpc_handler)SystemNamespaceRPCInterface)supervisor_ui_handlerzCould not make %s rpc interfacezRPC interface %r initializedsystemuiusernamepasswordz:Server %r running without any HTTP authentication checkingsection)"
LogWrapperrV   server_configsr   r   r   r   r   r   supervisor.xmlrpcrL  rM  supervisor.webrN  rpcinterface_factories	traceback
format_excwarnappendr   r'  rI  rq   r{   abspathdirname__file__r   r
   os_filesystemr   supervisor_auth_handlercriticalinstall_handler) rJ  r*  serverswrapperr:  rK  r[   r\   hsr  r  r  rL  rM  rN  subinterfacesnamefactoryr)   insttbxmlrpchandlertailhandlermaintailhandler	uihandlerheretemplatedir
filesystemdefaulthandlerrQ  rR  usersr   r   r   make_http_servers  s|   














ru  c                   @   r%   )rT  z\Receives log messages from the Medusa servers and forwards
    them to the Supervisor loggerc                 C   r(  r"   r   )r   rV   r   r   r   r   f  r,  zLogWrapper.__init__c                 C   sB   | dr|dd }d| v r| j| dS | j| dS )zMedusa servers call this method.  There is no log level so
        we have to sniff the message.  We want "Server Error" messages
        from medusa.http_server logged as errors at least.
Nr   r   )endswithr>   rV   r   trace)r   r  r   r   r   rE   i  s
   
zLogWrapper.logN)r   r   r   r$   r   rE   r   r   r   r   rT  c  s    rT  c                   @   s   e Zd Zdd Zdd ZdS )encrypted_dictionary_authorizerc                 C   r(  r"   )dict)r   rz  r   r   r   r   u  r,  z(encrypted_dictionary_authorizer.__init__c                 C   sR   |\}}|| j v r'| j | }|dr#tt| }|dd  |kS ||kS dS )Nz{SHA}   F)rz  r/  r   r   	hexdigest)r   	auth_inforQ  rR  stored_passwordpassword_hashr   r   r   	authorizex  s   


z)encrypted_dictionary_authorizer.authorizeN)r   r   r   r   r  r   r   r   r   ry  t  s    ry  c                   @   s   e Zd ZdddZdS )ra  defaultc                 C   s   t | ||| t|| _d S r"   )r   r   ry  
authorizer)r   rz  handlerrealmr   r   r   r     s   z supervisor_auth_handler.__init__N)r  )r   r   r   r   r   r   r   r   ra    s    ra  )-rq   r!  rX   r   r   r   r  rY  r   ImportErrorgetpasssupervisor.compatr   r   r   r   r   r   r   r   r   r	   r
   r   supervisor.medusa.auth_handlerr   r   r   r&   r*   r2   http_requestr6   r   r   r   r   r   r  r'  rI  ru  rT  ry  ra  r   r   r   r   <module>   sV      @ 	5V6E"I