o
    ⯪g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   S/var/www/html/chatdoc2/venv/lib/python3.10/site-packages/tornado/curl_httpclient.py
<listcomp><   s    z2CurlAsyncHTTPClient.initialize.<locals>.<listcomp>  )super
initializepycurl	CurlMulti_multisetoptM_TIMERFUNCTION_set_timeoutM_SOCKETFUNCTION_handle_socketrange_curls
_free_listcollectionsdeque	_requests_fds_timeoutr   PeriodicCallback_handle_force_timeout_force_timeout_callbackstartCurl
add_handleremove_handle)r   r   r   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)	r6   stopr3   io_loopremove_timeoutr-   closer&   r"   r   curlr<   r   r   rB   V   s   






zCurlAsyncHTTPClient.closerequestcallbackc                 C   s.   | j ||| j f |   | d d S Nr   )r1   appendr@   time_process_queuer)   )r   rE   rF   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$   	POLL_NONEr   IOLoopNONEPOLL_INREADPOLL_OUTWRITE
POLL_INOUTPOLL_REMOVEr2   r@   remove_handleradd_handler_handle_events)r   rL   rM   rN   rO   	event_map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     @@)r3   r@   rA   add_timeoutrI   _handle_timeout)r   r^   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   rQ   rT   r$   
CSELECT_INrV   CSELECT_OUTr&   socket_actionerrorargsE_CALL_MULTI_PERFORM_finish_pending_requests)r   rM   ra   actionretnum_handleser   r   r   r[      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   )r3   r&   rd   r$   SOCKET_TIMEOUTre   rf   rg   rh   timeoutr)   )r   rj   rk   rl   new_timeoutr   r   r   r`      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&   
socket_allr$   re   rf   rg   rh   )r   rj   rk   rl   r   r   r   r5      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&   	info_read_finishrJ   )r   num_qok_listerr_listrD   errnumerrmsgr   r   r   rh      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bufferrE   rF   queue_start_timecurl_start_timecurl_start_ioloop_timerz   ry   W  )rE   codere   )r.   r1   poppopleftr   HTTPHeadersr   rI   r@   currentinfo_curl_setup_request	ExceptionrH   r   r&   r9   )r   startedrD   rE   rF   r{   rl   r   r   r   rJ      s>   
		#z"CurlAsyncHTTPClient._process_queuerD   
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 )Nrz   r   r}   r{   )queue
namelookupconnect
appconnectpretransferstarttransfertotalredirectrF   rE   ry   zX-Http-Reasonr|   )
rE   r   ry   rz   effective_urlre   reasonrequest_time
start_time	time_info)r   r&   r:   r.   rH   	CurlErrorr   rB   getinfor$   	HTTP_CODEEFFECTIVE_URLseekdictNAMELOOKUP_TIMECONNECT_TIMEAPPCONNECT_TIMEPRETRANSFER_TIMESTARTTRANSFER_TIME
TOTAL_TIMEREDIRECT_TIMEr   getr@   rI   r   handle_callback_exception)
r   rD   r   r   r   rz   re   r   r   r   r   r   r   rr     sZ   










zCurlAsyncHTTPClient._finishc                 C   s   t jd|dd d S )NzException in callback %rT)exc_info)r   re   )r   rF   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 )Nrx   	PROTOCOLS)r$   r8   curl_logisEnabledForloggingDEBUGr'   VERBOSEDEBUGFUNCTION_curl_debughasattrr   
PROTO_HTTPPROTO_HTTPSREDIR_PROTOCOLSrC   r   r   r   r   =  s   z CurlAsyncHTTPClient._curl_createrz   ry   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 )&NExpect 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 r>   )streaming_callbackr@   add_callbacklen)r   )rE   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 %srx      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 rG   )IOCMD_RESTARTREADr   )r   )rD   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   urlry   get_allCR_OR_LF_REsearch
ValueError
HTTPHEADERHEADERFUNCTION	functoolspartial_curl_header_callbackheader_callbackr   r   bytes	bytearrayintwriteWRITEFUNCTIONFOLLOWLOCATIONfollow_redirects	MAXREDIRSmax_redirectsconnect_timeoutCONNECTTIMEOUT_MSrequest_timeout
TIMEOUT_MS
user_agent	USERAGENTnetwork_interface	INTERFACEdecompress_responseENCODING
proxy_host
proxy_portPROXY	PROXYPORTproxy_usernameproxy_passwordr   encode_username_passwordPROXYUSERPWDproxy_auth_mode	PROXYAUTHHTTPAUTH_BASICHTTPAUTH_DIGESTunsetopt	TypeErrorvalidate_certSSL_VERIFYPEERSSL_VERIFYHOSTca_certsCAINFO
allow_ipv6	IPRESOLVEIPRESOLVE_V4IPRESOLVE_WHATEVERHTTPGETr   UPLOADNOBODYsetvaluesmethodCUSTOMREQUESTallow_nonstandard_methodsKeyErrorbodyr   r   READFUNCTIONreadIOCTLFUNCTIONPOSTFIELDSIZEr   
INFILESIZEauth_usernameauth_password	auth_modeHTTPAUTHUSERPWDr   debugclient_certSSLCERT
client_keySSLKEYssl_options	threadingactive_countNOSIGNALprepare_curl_callback)r   rD   rE   rz   ry   encoded_headersliner   credentialscurl_optionscustom_methodsobody_expectedbody_presentr   userpwdr   )rD   rE   r   r   r   r   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   parse_response_start_lineHTTPInputError
parse_line)r   ry   r   r+  header_line__r   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<>r9  r:  r   z%s)rx   r   r      z%s %r)r   r   r  strip
splitlines)r   r6  r7  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#   rB   r   r   r   rK   r   r+   r)   r[   r`   r5   rh   rJ   r$   r8   rr   r   r   r   r   r   r   r   r   __classcell__r   r   r<   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 )r   errnomessager   Nc                 C   s   t | d| || _d S )Nr~   )r	   __init__rD  )r   rD  rE  r   r   r   rF  E  s   
zCurlError.__init__)r?  r@  rA  r   rB  rF  r   r   r   r   r   D  s    r   __main__))__doc__r/   r   r   r$   rer  rI   ior   tornador   r   tornado.escaper   r   tornado.httpclientr   r   r	   r
   r   tornado.logr   typingr   r   r   r   r   TYPE_CHECKINGr   r   	getLoggerr   compiler   r   r   r?  	configurer   r   r   r   <module>   s<   

    

