o
    )Zha                     @   s&  d 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ddlm	Z	 ddl
mZ ddl
mZ ddlmZmZ ddlmZmZmZmZmZ ddlmZ dd	lmZmZmZmZmZ ddlZejridd
lmZm Z  e!dZ"e#dZ$G dd deZ%G dd deZ&e'dkre(e% e  dS dS )z5Non-blocking HTTP client implementation using pycurl.    N)BytesIO)httputil)ioloop)utf8
native_str)HTTPRequestHTTPResponse	HTTPErrorAsyncHTTPClientmain)app_log)DictAnyCallableUnionOptional)DequeTupleztornado.curl_httpclients   |
c                
       s  e Zd Z	d7dedeeeef  ddf fddZd8 fdd	Z	d
e
deegdf ddfddZdededededdf
ddZdeddfddZdededdfddZd8ddZd8ddZd8ddZd8d d!Z		d9d"ejd#ee d$ee ddfd%d&Zdeddfd'd(Zdejfd)d*Zd"ejd
e
d+ed,ejddf
d-d.Zd,ejd/eegdf d0eddfd1d2Zd3ed4eddfd5d6Z   Z!S ):CurlAsyncHTTPClient
   Nmax_clientsdefaultsreturnc                    s   t  j|d t  _ jtj j  jtj j	  fddt
|D  _ jd d   _t  _i  _d  _t jd _ j  t } j|  j| d S )N)r   c                    s   g | ]}   qS  )_curl_create).0iselfr   N/var/www/html/lang_env/lib/python3.10/site-packages/tornado/curl_httpclient.py
<listcomp><   s    z2CurlAsyncHTTPClient.initialize.<locals>.<listcomp>  )super
initializepycurlZ	CurlMulti_multisetoptZM_TIMERFUNCTION_set_timeoutZM_SOCKETFUNCTION_handle_socketrange_curls
_free_listcollectionsdeque	_requests_fds_timeoutr   ZPeriodicCallback_handle_force_timeout_force_timeout_callbackstartCurl
add_handleremove_handle)r   r   r   Zdummy_curl_handle	__class__r   r   r#   4   s"   

zCurlAsyncHTTPClient.initializec                    sZ   | j   | jd ur| j| j | jD ]}|  q| j  t   d | _ d | _d S N)	r2   stopr0   io_loopremove_timeoutr*   closer%   r"   r   curlr7   r   r   r=   V   s   






zCurlAsyncHTTPClient.closerequestcallbackc                 C   s.   | j ||| j f |   | d d S Nr   )r.   appendr;   time_process_queuer'   )r   r@   rA   r   r   r   
fetch_imple   s   zCurlAsyncHTTPClient.fetch_impleventfdmultidatac              	   C   s   t jtjjt jtjjt jtjjt j	tjjtjjB i}|t j
kr2|| jv r0| j| | j|= dS dS || }|| jv rA| j| | j|| j| || j|< dS )z_Called by libcurl when it wants to change the file descriptors
        it cares about.
        N)r$   Z	POLL_NONEr   IOLoopNONEZPOLL_INREADZPOLL_OUTWRITEZ
POLL_INOUTZPOLL_REMOVEr/   r;   Zremove_handleradd_handler_handle_events)r   rG   rH   rI   rJ   Z	event_mapZioloop_eventr   r   r   r(   l   s   





	z"CurlAsyncHTTPClient._handle_socketmsecsc                 C   s<   | j dur| j| j  | j| j |d  | j| _ dS )z(Called by libcurl to schedule a timeout.Ng     @@)r0   r;   r<   Zadd_timeoutrD   _handle_timeout)r   rQ   r   r   r   r'      s
   

z CurlAsyncHTTPClient._set_timeouteventsc              
   C   s   d}|t jj@ r|tjO }|t jj@ r|tjO }	 z| j||\}}W n tj	y< } z|j
d }W Y d}~nd}~ww |tjkrCnq|   dS )zXCalled by IOLoop when there is activity on one of our
        file descriptors.
        r   TN)r   rK   rM   r$   Z
CSELECT_INrN   ZCSELECT_OUTr%   socket_actionerrorargsE_CALL_MULTI_PERFORM_finish_pending_requests)r   rH   rS   actionretnum_handleser   r   r   rP      s    


z"CurlAsyncHTTPClient._handle_eventsc              
   C   s   d| _ 	 z| jtjd\}}W n tjy( } z|jd }W Y d}~nd}~ww |tjkr/nq|   | j	 }|dkrD| 
| dS dS )z7Called by IOLoop when the requested timeout has passed.NTr   )r0   r%   rT   r$   ZSOCKET_TIMEOUTrU   rV   rW   rX   timeoutr'   )r   rZ   r[   r\   Znew_timeoutr   r   r   rR      s    

z#CurlAsyncHTTPClient._handle_timeoutc              
   C   s`   	 z	| j  \}}W n tjy" } z|jd }W Y d}~nd}~ww |tjkr)nq|   dS )zpCalled by IOLoop periodically to ask libcurl to process any
        events it may have forgotten about.
        Tr   N)r%   Z
socket_allr$   rU   rV   rW   rX   )r   rZ   r[   r\   r   r   r   r1      s   
z)CurlAsyncHTTPClient._handle_force_timeoutc                 C   s\   	 | j  \}}}|D ]}| | q|D ]\}}}| ||| q|dkr'nq|   dS )zbProcess any requests that were completed by the last
        call to multi.socket_action.
        Tr   N)r%   Z	info_read_finishrE   )r   Znum_qZok_listZerr_listr?   Zerrnumerrmsgr   r   r   rX      s   z,CurlAsyncHTTPClient._finish_pending_requestsc              
   C   s   	 d}| j rm| jrm|d7 }| j  }| j \}}}t t |||t | j	  d|_
z| |||j
d |j
d  W n! ty` } z| j | |t|d|d W Y d }~nd }~ww | j| | j rm| js	|sqd S q)	NTr      )headersbufferr@   rA   queue_start_timecurl_start_timecurl_start_ioloop_timerb   ra   W  )r@   coderU   )r+   r.   poppopleftr   HTTPHeadersr   rD   r;   currentinfo_curl_setup_request	ExceptionrC   r   r%   r5   )r   startedr?   r@   rA   rc   r\   r   r   r   rE      s>   
		#z"CurlAsyncHTTPClient._process_queuer?   
curl_errorcurl_messagec           
      C   s`  |j }d |_ | j| | j| |d }|r5|d usJ t||}|d us)J |j}d }|  d }nd }|t	j
}|t	j}|d t|d |d  |t	j|t	j|t	j|t	j|t	j|t	j|t	jd}	z(|d t|d ||d ||||d d	d | j |d  |d
 |	d
 W d S  ty   | |d  Y d S w )Nrb   r   re   rc   )queueZ
namelookupconnectZ
appconnectZpretransferZstarttransfertotalredirectrA   r@   ra   zX-Http-Reasonrd   )
r@   rg   ra   rb   effective_urlrU   reasonZrequest_time
start_time	time_info)rl   r%   r6   r+   rC   	CurlErrorrg   r=   getinfor$   Z	HTTP_CODEZEFFECTIVE_URLseekdictZNAMELOOKUP_TIMEZCONNECT_TIMEZAPPCONNECT_TIMEZPRETRANSFER_TIMEZSTARTTRANSFER_TIMEZ
TOTAL_TIMEZREDIRECT_TIMEr   getr;   rD   rn   handle_callback_exception)
r   r?   rp   rq   rl   rb   rU   rg   rv   ry   r   r   r   r^     sZ   










zCurlAsyncHTTPClient._finishc                 C   s   t jd|dd d S )NzException in callback %rT)exc_info)r   rU   )r   rA   r   r   r   r   :  s   z-CurlAsyncHTTPClient.handle_callback_exceptionc                 C   sl   t  }ttjr|t jd |t j| j	 t
t dr4|t jt jt jB  |t jt jt jB  |S )Nr`   	PROTOCOLS)r$   r4   curl_logisEnabledForloggingDEBUGr&   VERBOSEZDEBUGFUNCTION_curl_debughasattrr   Z
PROTO_HTTPZPROTO_HTTPSZREDIR_PROTOCOLSr>   r   r   r   r   =  s   z CurlAsyncHTTPClient._curl_createrb   ra   c                    s$    tjtj djvrdjd< djvrdjd< dd j D }|D ]}t|r7t	d| q*  tj
|   tjtj|j jradtttf dtffd	d
}n|j}  tj|   tjj   tjj jd usJ   tjtdj  jd usJ   tjtdj  jr  tj tj n  tj d j!r  tj"j! j#r̈  tj$d n  tj$d  j%r0j&r0  tj'j%   tj(j& j)rj*d usJ t+,j)j*}  tj-| j.d u sj.dkr  tj/tj0 n6j.dkr)  tj/tj1 n't	dj. z 2tj' W n t3yI     tj'd Y nw  2tj- j4rc  tj5d   tj6d n  tj5d   tj6d j7d ur  tj8j7 n	 j9du r  tj:tj; n  tj:tj< tj=tj>tj?tj@d}	tAg d}
|	B D ]	}  |d qjC|	v r͈ 2tjD   |	jC d njEs׈jC|
v r  tjDjC ntFdjC jCdv }jGd u}jEs|r|r|r|st	d|rdndjCf |s|rljCdkrt	dtHtIjGp&ddtdd f fdd }  tjJjK   tjL| jCd!krX  tjMtNjGpTd n  tj?d   tjOtNjGpid jPd urjQd uszJ jRd u sjRdkr  tjStj0 njRdkr  tjStj1 nt	d"jR t+,jPjQ}  tjT| tUVd#jCjjP n 2tjT tUVd$jCj jWd ur݈  tjXjW jYd ur  tjZjY j[d urt	d%t\] dkr  tj^d j_d ur_  d S d S )&NZExpect ZPragmac                 S   s0   g | ]\}}d t |dt |df qS )s   %s: %sASCIIz	ISO8859-1)r   encode)r   kvr   r   r   r    a  s    z;CurlAsyncHTTPClient._curl_setup_request.<locals>.<listcomp>z+Illegal characters in header (CR or LF): %rbr   c                    s&    j d usJ j j |  t| S r9   )streaming_callbackr;   add_callbacklen)r   )r@   r   r   r   write_functions  s   z?CurlAsyncHTTPClient._curl_setup_request.<locals>.write_functionr!   z Mozilla/5.0 (compatible; pycurl)zgzip,deflatebasicdigestzUnsupported proxy_auth_mode %sr`      r   F)GETPOSTPUTHEAD)DELETEOPTIONSPATCHTzunknown method )r   r   r   zLBody must %sbe None for method %s (unless allow_nonstandard_methods is true)znot r   z!Body must be None for GET requestcmdc                    s   |  j krd d S d S rB   )ZIOCMD_RESTARTREADr|   )r   )r?   request_bufferr   r   ioctl  s   
z6CurlAsyncHTTPClient._curl_setup_request.<locals>.ioctlr   zUnsupported auth_mode %sz%s %s (username: %r)%s %sz,ssl_options not supported in curl_httpclient)`r&   r$   URLr   urlra   get_allCR_OR_LF_REsearch
ValueErrorZ
HTTPHEADERZHEADERFUNCTION	functoolspartial_curl_header_callbackheader_callbackr   r   bytes	bytearrayintwriteZWRITEFUNCTIONZFOLLOWLOCATIONZfollow_redirectsZ	MAXREDIRSmax_redirectsconnect_timeoutZCONNECTTIMEOUT_MSrequest_timeoutZ
TIMEOUT_MS
user_agentZ	USERAGENTZnetwork_interfaceZ	INTERFACEZdecompress_responseENCODINGZ
proxy_hostZ
proxy_portZPROXYZ	PROXYPORTZproxy_usernameZproxy_passwordr   Zencode_username_passwordZPROXYUSERPWDZproxy_auth_modeZ	PROXYAUTHZHTTPAUTH_BASICZHTTPAUTH_DIGESTZunsetopt	TypeErrorZvalidate_certZSSL_VERIFYPEERZSSL_VERIFYHOSTca_certsZCAINFOZ
allow_ipv6Z	IPRESOLVEZIPRESOLVE_V4ZIPRESOLVE_WHATEVERZHTTPGETr   ZUPLOADZNOBODYsetvaluesmethodZCUSTOMREQUESTZallow_nonstandard_methodsKeyErrorbodyr   r   ZREADFUNCTIONreadZIOCTLFUNCTIONZPOSTFIELDSIZEr   Z
INFILESIZEZauth_usernameZauth_passwordZ	auth_modeZHTTPAUTHZUSERPWDr   debugclient_certZSSLCERTZ
client_keyZSSLKEYZssl_options	threadingactive_countZNOSIGNALZprepare_curl_callback)r   r?   r@   rb   ra   Zencoded_headersliner   credentialsZcurl_optionsZcustom_methodsoZbody_expectedZbody_presentr   Zuserpwdr   )r?   r@   r   r   r   rm   I  s  






"

	z'CurlAsyncHTTPClient._curl_setup_requestr   header_line_bytesc                 C   s   t |d}|d ur| j|| | }|dr9|  zt|\}}}d| }W n tj	y8   Y d S w |s=d S |
| d S )Nlatin1zHTTP/zX-Http-Reason: %s)r   decoder;   r   rstrip
startswithclearr   Zparse_response_start_lineZHTTPInputError
parse_line)r   ra   r   r   Zheader_line__rw   r   r   r   r      s   
z)CurlAsyncHTTPClient._curl_header_callback
debug_type	debug_msgc                 C   s~   d}|dkrt |}td|  d S |dv r.t |}| D ]}td|| | q d S |dkr=td|| | d S d S )N)I<>r   r   r   z%s)r`   r   r      z%s %r)r   r   r   strip
splitlines)r   r   r   Zdebug_typesr   r   r   r   r   7  s   zCurlAsyncHTTPClient._curl_debug)r   N)r   N)NN)"__name__
__module____qualname__r   r   r   strr   r#   r=   r   r   r   rF   r   r(   r'   rP   rR   r1   rX   rE   r$   r4   r^   r   r   r   r   rj   rm   r   r   __classcell__r   r   r7   r   r   3   sv    "




,
6
 X
r   c                   @   s"   e Zd ZdededdfddZdS )rz   errnomessager   Nc                 C   s   t | d| || _d S )Nrf   )r	   __init__r   )r   r   r   r   r   r   r   E  s   
zCurlError.__init__)r   r   r   r   r   r   r   r   r   r   rz   D  s    rz   __main__))__doc__r,   r   r   r$   rer   rD   ior   tornador   r   Ztornado.escaper   r   Ztornado.httpclientr   r   r	   r
   r   Ztornado.logr   typingr   r   r   r   r   TYPE_CHECKINGr   r   	getLoggerr   compiler   r   rz   r   	configurer   r   r   r   <module>   s<   

    

