
    di.                        U d dl Z d dlZd dlZd dlmZ d dlmZmZ d dlm	Z	 ddl
mZmZ ddlmZmZ ddlmZmZmZ dd	lmZ d
gZej.                  dk(  r+ e	       Ze	ed<   dZde j6                  de j6                  fdZnde j6                  de j6                  fdZd ZdZdZdZ dZ!dZ"dZ#dZ$dZ%dZ&dZ'd Z(dZ)dZ*	  ejV                         de,dede,fd       Z- ejV                         de,de,dedede,f
d       Z. G d d
      Z/y)    N)suppress)AnyOptional)WeakKeyDictionary   )ffilib)	CurlECodeCurlMOpt)DEFAULT_CACERTCurl	CurlError)CurlCffiWarning	AsyncCurlwin32
_selectorsa  
    Proactor event loop does not implement add_reader family of methods required.
    Registering an additional selector thread for add_reader support.
    To avoid this warning use:
        asyncio.set_event_loop_policy(WindowsSelectorEventLoopPolicy())
    asyncio_loopreturnc           
           t         v r	t             S t         t        t        dt	        d                  s S t        j                  t        t        d       ddl	m
}  |       xt          <    j                   fd}| _        S )zGet selector-compatible loop

        Returns an object with ``add_reader`` family of methods,
        either the loop itself or a SelectorThread instance.

        Workaround Windows proactor removal of *reader methods.
        ProactorEventLoopN   
stacklevelr   )AddThreadSelectorEventLoopc                  `     _         t        j                   d        j                          y N)closer   pop)r   
loop_closeselector_loops   D/root/funda.leads/venv/lib/python3.12/site-packages/curl_cffi/aio.py_close_selector_and_loopz.get_selector.<locals>._close_selector_and_loop7   s'     ",LNN<.!    )r   
isinstancegetattrasynciotypewarningswarnPROACTOR_WARNINGr   _asyncio_selectorr   r   )r   r   r"   r   r    s   `  @@r!   get_selectorr,      s     :%l++''+>T
K
  &AFA3M4
 	

<0
 "''
	" 6r#   loopc                     | S r    )r-   s    r!   r,   r,   C   s    r#   r         
timeout_msclientpc                     t        j                  |      }|j                  r!|j                  j                          d|_        |j                  j                  |dz  |j                  t        t              |_        y)zD
    see: https://curl.se/libcurl/c/CURLMOPT_TIMERFUNCTION.html
    Ni  r   )	r   from_handle_timercancelr-   
call_laterprocess_dataCURL_SOCKET_TIMEOUTCURL_POLL_NONE)curlmr3   r4   
async_curls       r!   timer_functionr?   u   sl    
 )J   " 
 #22T	J r#   sockfdwhatdatac                    t        j                  |      }|j                  }||j                  v r"|j	                  |       |j                  |       |t        z  r=|j                  ||j                  |t               |j                  j                  |       |t        z  r=|j                  ||j                  |t               |j                  j                  |       |t        k(  r|j                  j                  |       y)z[This callback is called when libcurl decides it's time to interact with certain
    socketsr   )r   r6   r-   _sockfdsremove_readerremove_writerCURL_POLL_IN
add_readerr:   CURL_CSELECT_INaddCURL_POLL_OUT
add_writerCURL_CSELECT_OUTCURL_POLL_REMOVEremove)curlr@   rA   r4   rB   r>   r-   s          r!   socket_functionrQ      s    
 )J??D $$$6"6" l
 7 7Q' m
 7 7AQR' ""6*r#   c                       e Zd ZdZddefdZd Zd Zd Zde	fd	Z
d
ededefdZd
edefdZde	fdZde	fdZde	fdZde	fdZdedefdZd Zy)r   zhWrapper around curl_multi handle to provide asyncio support. It uses the libcurl
    socket_action APIs.Ncacertc                 d   t        j                         | _        |xs t        | _        i | _        i | _        t               | _        t        ||nt        j                               | _        | j                  j                  | j                               | _        d| _        | j#                          y)z
        Parameters:
            cacert: CA cert path to use, by default, certs from ``certifi`` are used.
            loop: EventLoop to use.
        N)r	   curl_multi_init_curlmr   _cacert_curl2future
_curl2curlsetrD   r,   r&   get_running_loopr-   create_task_force_timeout_timeout_checkerr7   _setup)selfrS   r-   s      r!   __init__zAsyncCurl.__init__   s     ))+/8:13"%% $D'*B*B*D
	 !%		 5 5d6I6I6K L59r#   c                    | j                  t        j                  t        j                         | j                  t        j
                  t        j                         t        j                  |       | _	        | j                  t        j                  | j                         | j                  t        j                  | j                         y r   )setoptr   TIMERFUNCTIONr	   r?   SOCKETFUNCTIONrQ   r   
new_handle_self_handle
SOCKETDATA	TIMERDATAr`   s    r!   r_   zAsyncCurl._setup   s{    H**C,>,>?H++S-@-@ANN40H''):):;H&&(9(9:r#   c                   K   | j                   j                          t        t        j                        5  | j                    d{    ddd       | j
                  j                         D ]b  \  }}t        j                  | j                  |j                         |j                         rA|j                         rR|j                  d       d t        j                  | j                         d| _	        | j                  D ]8  }| j                   j#                  |       | j                   j%                  |       : | j&                  r| j&                  j                          yy7 !# 1 sw Y   !xY ww)z?Close and cleanup running timers, readers, writers and handles.N)r^   r8   r   r&   CancelledErrorrX   itemsr	   curl_multi_remove_handlerV   _curldone	cancelled
set_resultcurl_multi_cleanuprD   r-   rE   rF   r7   )r`   rP   futurer@   s       r!   r   zAsyncCurl.close   s!     	$$&g,,- 	(''''	( !--335 	(LD&((djjA;;=)9)9);!!$'	( 	t{{+ mm 	,FII##F+II##F+	,
 ;;KK  % (	( 	(s<   4E7E*E'E*A"E7.E7?B(E7'E**E4/E7c                    K   	 | j                   sy| j                  t        t               t	        j
                  d       d{    E7 w)zpThis coroutine is used to safeguard from any missing signals from curl, and
        put everything back on trackg?N)rV   socket_actionr;   r<   r&   sleeprj   s    r!   r]   zAsyncCurl._force_timeout   sB      ;;2NC--$$$	  %s   AAA	ArP   c                     |j                          t        j                  | j                  |j                        }| j                  |       | j                  j                         }|| j                  |<   || j                  |j                  <   |S )znAdd a curl handle to be managed by curl_multi. This is the equivalent of
        `perform` in the async world.)
_ensure_cacertr	   curl_multi_add_handlerV   ro   _check_errorr-   create_futurerX   rY   )r`   rP   errcodert   s       r!   
add_handlezAsyncCurl.add_handle   sq     	++DKKD'"((*"($&*

#r#   r@   
ev_bitmaskr   c                     t        j                  d      }t        j                  | j                  |||      }| j                  |       |d   S )zYwrapper for curl_multi_socket_action,
        returns the number of running curl handles.int *r   )r   newr	   curl_multi_socket_actionrV   r{   )r`   r@   r   running_handler}   s        r!   rv   zAsyncCurl.socket_action   sJ     )..KK^
 	'"a  r#   c                 t   | j                   st        j                  dt        d       y| j	                  ||       t        j                  d      }	 	 t        j                  | j                   |      }|t
        j                  k(  ry|j                  t        k(  ri| j                  |j                     }|j                  j                  }|dk(  r| j!                  |       n.| j#                  ||j%                  |d             nt'        d       # t(        $ r t        j                  d	t        d       Y (w xY w)
z8Call curl_multi_info_read to read data for given socket.z0Curlm already closed! quitting from process_datar   r   Nr   r   performzNOT DONEzLUnexpected curl multi state in process_data, please open an issue on GitHub
)rV   r(   r)   r   rv   r   r   r	   curl_multi_info_readNULLmsgCURLMSG_DONErY   easy_handlerB   resultrr   set_exception
_get_errorprint	Exception)r`   r@   r   msg_in_queuecurl_msgrP   retcodes          r!   r:   zAsyncCurl.process_data  s    {{MMB
 6:.www'33DKKNsxx'<<</??8+?+?@D&mm22G!|-**4)1TU*%   7# 	s   3D BD %D76D7c                     t        j                  | j                  |j                        }| j	                  |       | j
                  j                  |j                  d        | j                  j                  |d       S r   )r	   rn   rV   ro   r{   rY   r   rX   )r`   rP   r}   s      r!   _pop_futurezAsyncCurl._pop_future'  s[    ..t{{DJJG'"DJJ-  $$T400r#   c                     | j                  |      }|r3|j                         s"|j                         s|j                          yyyy)z&Cancel a future for given curl handle.N)r   rp   rq   r8   r`   rP   rt   s      r!   remove_handlezAsyncCurl.remove_handle-  s;    !!$'&++-0@0@0BMMO 1C-6r#   c                     | j                  |      }|r4|j                         s#|j                         s|j                  d       yyyy)z,Mark a future as done for given curl handle.N)r   rp   rq   rr   r   s      r!   rr   zAsyncCurl.set_result3  s@    !!$'&++-0@0@0Bd# 1C-6r#   c                     | j                  |      }|r4|j                         s#|j                         s|j                  |       yyyy)z2Raise exception of a future for given curl handle.N)r   rp   rq   r   )r`   rP   	exceptionrt   s       r!   r   zAsyncCurl.set_exception9  s@    !!$'&++-0@0@0B  + 1C-6r#   r}   argsc           	          |t         j                  k(  ry t        j                  |      }dj	                  |D cg c]  }t        |       c}      }t        d| d| d| d      c c}w )N z
Failed in z
, multi: (z) z. See https://curl.se/libcurl/c/libcurl-errors.html first for more details. Please open an issue on GitHub to help debug this error.)r
   OKr	   curl_multi_strerrorjoinstrr   )r`   r}   r   errmsgaactions         r!   r{   zAsyncCurl._check_error?  so    ill"((140a3q601
7)2fX >P P
 	
 1s   A'c                 2   |t         j                  t         j                  t         j                  t         j                  t         j
                  t         j                  fv rt        j                  d|      }n|}t        j                  | j                  ||      S )z!Wrapper around curl_multi_setopt.zlong*)r   
PIPELININGMAXCONNECTSMAX_HOST_CONNECTIONSMAX_PIPELINE_LENGTHMAX_TOTAL_CONNECTIONSMAX_CONCURRENT_STREAMSr   r   r	   curl_multi_setoptrV   )r`   optionvaluec_values       r!   rc   zAsyncCurl.setoptJ  su      ))((**++
 
 gggu-GG$$T[[&'BBr#   ) N)__name__
__module____qualname____doc__r   ra   r_   r   r]   r   r~   intrv   r:   r   r   rr   r   r   r{   rc   r/   r#   r!   r   r      s    s $;!6%
t 
!C !S !S !"3 "C "H1 1$ $t $,$ ,	
C 	
 	
Cr#   )0r&   sysr(   
contextlibr   typingr   r   weakrefr   _wrapperr   r	   constr
   r   rP   r   r   r   utilsr   __all__platformr   __annotations__r*   AbstractEventLoopr,   r<   rG   rK   CURL_POLL_INOUTrN   r;   CURL_SOCKET_BADrI   rM   CURL_CSELECT_ERRr   CURLPIPE_NOTHINGCURLPIPE_HTTP1CURLPIPE_MULTIPLEX
def_externr   r?   rQ   r   r/   r#   r!   <module>r      sc    
     %  & 1 1 "-<<7$5$7J!7&//&		"	"&T744 9R9R        4 c C C  . # S 3 c c  :lC lCr#   