
    il                        d dl mZ d dlm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Zn# e$ r dZY nw xY w	 d dlZn# e$ r dZY nw xY wddlmZ ddlmZ ddlmZ dd	lmZ  ej        d
          Z G d dej                  ZdS )    )	b64encode)SimpleCookieN)JSONDecodeError   )base_client)
exceptions)packet)payloadzengineio.clientc                        e Zd ZdZ	 	 ddZd Zd ZddZd	 ZddZ	d Z
d Zd Z fdZd Zd Zd Zd Z	 	 ddZd Zd Zd Zd Z xZS )Clienta  An Engine.IO client.

    This class implements a fully compliant Engine.IO web client with support
    for websocket and long-polling transports.

    :param logger: To enable logging set to ``True`` or pass a logger object to
                   use. To disable logging set to ``False``. The default is
                   ``False``. Note that fatal errors are logged even when
                   ``logger`` is ``False``.
    :param json: An alternative JSON module to use for encoding and decoding
                 packets. Custom json modules must have ``dumps`` and ``loads``
                 functions that are compatible with the standard library
                 versions. This is a process-wide setting, all instantiated
                 servers and clients must use the same JSON module.
    :param request_timeout: A timeout in seconds for requests. The default is
                            5 seconds.
    :param http_session: an initialized ``requests.Session`` object to be used
                         when sending requests to the server. Use it if you
                         need to add special client options such as proxy
                         servers, SSL certificates, custom CA bundle, etc.
    :param ssl_verify: ``True`` to verify SSL certificates, or ``False`` to
                       skip SSL certificate verification, allowing
                       connections to servers with self signed certificates.
                       The default is ``True``.
    :param handle_sigint: Set to ``True`` to automatically handle disconnection
                          when the process is interrupted, or to ``False`` to
                          leave interrupt handling to the calling application.
                          Interrupt handling can only be enabled when the
                          client instance is created in the main thread.
    :param websocket_extra_options: Dictionary containing additional keyword
                                    arguments passed to
                                    ``websocket.create_connection()``.
    :param timestamp_requests: If ``True`` a timestamp is added to the query
                               string of Socket.IO requests as a cache-busting
                               measure. Set to ``False`` to disable.
    N	engine.ioc                    | j         dk    rt          d          ddg|7t          |t                    r|g}fd|D             }|st          d          |p| _         t          | d| j        d	         z             ||pi |          S )
a  Connect to an Engine.IO server.

        :param url: The URL of the Engine.IO server. It can include custom
                    query string parameters if required by the server.
        :param headers: A dictionary with custom headers to send with the
                        connection request.
        :param transports: The list of allowed transports. Valid transports
                           are ``'polling'`` and ``'websocket'``. If not
                           given, the polling transport is connected first,
                           then an upgrade to websocket is attempted.
        :param engineio_path: The endpoint where the Engine.IO server is
                              installed. The default value is appropriate for
                              most cases.

        Example usage::

            eio = engineio.Client()
            eio.connect('http://localhost:5000')
        disconnectedz%Client is not in a disconnected statepolling	websocketNc                     g | ]}|v |	S  r   ).0	transportvalid_transportss     :/usr/local/lib/python3.11/dist-packages/engineio/client.py
<listcomp>z"Client.connect.<locals>.<listcomp>[   s.     < < <	&*::: $:::    zNo valid transports provided	_connect_r   )state
ValueError
isinstancestr
transportsgetattr)selfurlheadersr   engineio_pathr   s        @r   connectzClient.connect@   s    * :''DEEE%{3!*c** *(\
< < < <Z < < <J A !?@@@$8(8>wt[4?1+==>>B/ / 	/r   c                 J    | j         r| j                                          dS dS )zWait until the connection with the server ends.

        Client applications can use this function to block the main thread
        during the life of the connection.
        N)read_loop_taskjoinr!   s    r   waitzClient.waitc   s4      	'$$&&&&&	' 	'r   c                 l    |                      t          j        t          j        |                     dS )a  Send a message to the server.

        :param data: The data to send to the server. Data can be of type
                     ``str``, ``bytes``, ``list`` or ``dict``. If a ``list``
                     or ``dict``, the data will be serialized as JSON.
        dataN)_send_packetr	   PacketMESSAGE)r!   r-   s     r   sendzClient.sendl   s/     	&-TBBBCCCCCr   Fc                    | j         dk    r|                     t          j        t          j                             | j                            d           d| _         |                     d|p| j        j	        d           | j
        dk    r| j                                         |s| j                                         d| _         	 t          j                            |            n# t$          $ r Y nw xY w|                                  dS )	zDisconnect from the server.

        :param abort: If set to ``True``, do not wait for background tasks
                      associated with the connection to end.
        	connectedNdisconnecting
disconnectF	run_asyncr   r   )r   r.   r	   r/   CLOSEqueueput_trigger_eventreasonCLIENT_DISCONNECTcurrent_transportwscloser'   r(   r   connected_clientsremover   _reset)r!   abortr<   s      r   r5   zClient.disconnectu   s    :$$fmFL99:::JNN4   (DJ & G$+*G*/   1 1 1 %44 +#((***'DJ-44T::::   s   	C) )
C65C6c                 ^    t          j        |||d          }|                                 |S )a  Start a background task.

        This is a utility function that applications can use to start a
        background task.

        :param target: the target function to execute.
        :param args: arguments to pass to the function.
        :param kwargs: keyword arguments to pass to the function.

        This function returns an object that represents the background task,
        on which the ``join()`` method can be invoked to wait for the task to
        complete.
        T)targetargskwargsdaemon)	threadingThreadstart)r!   rF   rG   rH   ths        r   start_background_taskzClient.start_background_task   s6     V$v%)+ + +



	r   r   c                 *    t          j        |          S )z'Sleep for the requested amount of time.)timesleep)r!   secondss     r   rQ   zClient.sleep   s    z'"""r   c                 $    t          j        |i |S )zCreate a queue object.)r9   Queuer!   rG   rH   s      r   create_queuezClient.create_queue   s    {D+F+++r   c                     t           j        S )zlReturn the queue empty exception raised by queues created by the
        ``create_queue()`` method.
        )r9   Emptyr)   s    r   get_queue_empty_exceptionz Client.get_queue_empty_exception   s     {r   c                 $    t          j        |i |S )zCreate an event object.)rJ   EventrU   s      r   create_eventzClient.create_event   s    ////r   c                     t                                                       	 	 | j                                         | j                                         n# | j        $ r Y d S w xY wF)N)superrC   r9   
get_nowait	task_donequeue_empty)r!   	__class__s    r   rC   zClient._reset   sv    	
%%'''
$$&&&&#   		s   2A 
A%$A%c                    t           | j                            d           dS |                     ||d          | _        | j                            d| j        z              |                     d| j        |                                 z   || j                  }|t          |t                    r*|                                  t          j        |pd          |j        dk     s|j        d	k    ri|                                  	 |                                }n# t           $ r d}Y nw xY wt          j        d
                    |j                  |          	 t%          j        |j                            d                    }n## t,          $ r t          j        d          dw xY w|j        d         }|j        t2          j        k    rt          j        d          | j                            dt          |j                  z              |j        d         | _        |j        d         | _        t=          |j        d                   dz  | _        t=          |j        d                   dz  | _         d| _!        | xj        d| j        z   z  c_        d| _"        tF          j$        %                    |            | &                    dd           |j        dd         D ]}| '                    |           d| j        v r"d| j(        v r| )                    |||          rdS | *                    | j+                  | _,        | *                    | j-                  | _.        dS )z<Establish a long-polling connection to the Engine.IO server.Nz?requests package is not installed -- cannot send HTTP requests!r   z!Attempting polling connection to GET)r#   timeoutz Connection refused by the server   ,  z,Unexpected status code {} in server responseutf-8encoded_payloadzUnexpected response from serverr   z"OPEN packet not returned by serverz!Polling connection accepted with sidupgradespingInterval     @@pingTimeout&sid=r3   r%   Fr6   r   r   )/requestsloggererror_get_engineio_urlbase_urlinfo_send_request_get_url_timestamprequest_timeoutr   r   rC   r   ConnectionErrorstatus_codejsonr   formatr
   Payloadcontentdecoder   packetspacket_typer	   OPENr-   rk   rl   intping_intervalping_timeoutr>   r   r   rA   appendr;   _receive_packetr   _connect_websocketrN   _write_loopwrite_loop_task_read_loop_pollingr'   )	r!   r"   r#   r$   rargpopen_packetpkts	            r   _connect_pollingzClient._connect_polling   s   K 4 5 5 5F..sM9MM<t}LMMM4=4#:#:#<#<<g(  * * 9
1c**9KKMMM,779 9 9=3!-3"6"6KKMMMffhh"   ,>EEM# #$') ) )	=	0@0@0I0IJJJAA 	= 	= 	=,13 38<=	= il"fk11,46 6 6/#k6F2G2GG	I 	I 	I#E*#(4 !1.!ABBVK 0 ?@@6I!*48++ 
%,,T222I7779QRR= 	& 	&C  %%%%$-''K4?,J,J&&sG]CC   $99$:JKK"88#% %s   D D*)D*-F	 	 F)c                    t           | j                            d           dS |                     ||d          }| j        r-| j                            d|z              d}|d| j        z   z  }n&d}|| _        | j                            d|z              d}i }| j        r	t                      }| j        j	        D ]}	|	j
        ||	j        <   |                    d	d
                                          }|                                D ].\  }
}|
                                dk    r|r|dz  }||z  }||
=  n/d|vr| j        j        t#          | j        j        t$                    st'          d          d                    | j        j        d         | j        j        d                                       d          }t-          |                              d          }d|z   |d<   t#          | j        j        t$                    r)| j        j        d         | j        j        d         d|d<   n| j        j        rd| j        j        i|d<   | j        j        rd}|                    d          r>| j        j                            d| j        j                            d                    }n=| j        j                            d| j        j                            d                    }|r]t8          j                            d|v r|nd|z             }|j        |d<   |j         |d <   |j!        s|j"        r|j!        |j"        fnd|d!<   t#          | j        j#        tH                    r,d|v r| j        j#        |d         d"<   n%d"| j        j#        i|d<   n| j        j#        sd| _%        | j%        s=d|v r(|d         &                    d#tN          j(        i           nd#tN          j(        i|d<   |&                    | j)        *                    d$i                      ||d$<   ||d<   d|d%<   | j+        |d&<   |&                    | j)                   	 t          j,        || -                                z   fi |}nS# t\          t^          t           j0        f$ r4 |r| j        1                    d'           Y dS te          j.        d(          w xY w|rtg          j4        tf          j5        d)*                                          }	 |6                    |           n@# tn          $ r3}| j        1                    d+tI          |                     Y d}~dS d}~ww xY w	 |8                                }n@# tn          $ r3}| j        1                    d,tI          |                     Y d}~dS d}~ww xY wtg          j4        |-          }|j9        tf          j:        k    s|j;        d)k    r| j        1                    d.           dS tg          j4        tf          j<                                                  }	 |6                    |           n@# tn          $ r3}| j        1                    d+tI          |                     Y d}~dS d}~ww xY wd| _=        | j                            d/           ne	 |8                                }n6# tn          $ r)}te          j.        d0tI          |          z             d}~ww xY wtg          j4        |-          }|j9        tf          j>        k    rte          j.        d1          | j                            d2tI          |j;                  z              |j;        d3         | _        |j;        d4         | _?        t          |j;        d5                   d6z  | _A        t          |j;        d7                   d6z  | _B        d| _=        d8| _C        t          jE        F                    |            | G                    d9d:           || _H        | jH        I                    | jA        | jB        z              | J                    | jK                  | _L        | J                    | jM                  | _N        dS );z?Establish or upgrade to a WebSocket connection with the server.NzKwebsocket-client package not installed, only polling transport is availableFr   z Attempting WebSocket upgrade to Trp   z#Attempting WebSocket connection to  ;)headersepcookiez; Authorizationz&Only basic authentication is supportedz{}:{}r   r   rh   zBasic )certfilekeyfilessloptr   zws://r?   httpwsshttpsz://z	scheme://http_proxy_hosthttp_proxy_porthttp_proxy_authca_certs	cert_reqsr   enable_multithreadre   z*WebSocket upgrade failed: connection errorzConnection errorprober,   z7WebSocket upgrade failed: unexpected send exception: %sz7WebSocket upgrade failed: unexpected recv exception: %sencoded_packetz(WebSocket upgrade failed: no PONG packetz WebSocket upgrade was successfulzUnexpected recv exception: zno OPEN packetz#WebSocket connection accepted with rk   rl   rm   rn   ro   r3   r%   r6   )Or   rr   rs   rt   rk   rv   ru   r   r   cookiesvaluenameoutputstripitemslowerauthr   tupler   r}   encoder   r   certproxies
startswithgeturllibparseurlparsehostnameportusernamepasswordverifyr   
ssl_verifyupdatessl	CERT_NONEwebsocket_extra_optionspopry   create_connectionrx   rz   OSErrorWebSocketExceptionwarningr   r	   r/   PINGr1   	Exceptionrecvr   PONGr-   UPGRADEr>   r   rl   r   r   r   r   r   rA   r   r;   r?   
settimeoutrN   r   r   _read_loop_websocketr'   )r!   r"   r#   r$   websocket_urlupgrader   extra_optionsckr   r   r   
basic_auth	proxy_url
parsed_urlr?   r   er   r   s                       r   r   zClient._connect_websocket   s	   K ? @ @ @5..sM;OO8 		GK2]BD D DGWtx//MMG)DMK5EG G G
 9 ;	(B)+ / /"(,6;iirsi3399;;G!(  <<>>X-- (4u$GE . g--$).2L!$).%88 O$%MNNN$^^IN1%ty~a'8: ::@&// &z2299'BB
+3j+@( $).%00 G $	q 1#y~a0+2 +2h''  G+5ty~*Fh' y  # 	 ++G44 ? $	 1 5 5di/33F;;!= !=II !%	 1 5 5ty044W==!? !?I 	#!'!6!6%*i%7%7		(94"6 "6J 8B7JM"347AM"34 &."2<2E",j.ABB! ""34 $)*C00 (},,:>):JM(+J77/949;K.LM(++Y% ("' 	G=((h'..S]/KLLLL+6*Fh' 	t377"EEFFF")h")h.2*+#'#7i T9:::		E, 7 7 9 99L L=JL LBB)*FG 	E 	E 	E E##@B B Buu 01CDDD	E  2	<fk888??AAA



   ##MFF   uuuuu	
GGII   ##MFF   uuuuu	
 -q111C&+--W1D1D##>@ @ @ufn--4466A



   ##MFF   uuuuu	
 &1D"K?@@@@<GGII < < < 01CFF:< < << !-q999K&&+55 01ABBBK5K<L8M8MMO O O"'.DH',Z8DM!$[%5n%E!F!F!OD #K$4]$C D Dv MD%0D"$DJ)00666	U;;;4-0AABBB  $99$:JKK"88%' 'tsr   'Q8 88S3ST 
U!(UUU- -
V*7(V%%V*/Y 
Z(Y==Z)Z> >
[1$[,,[1c                    |j         t          t          j                  k     rt          j        |j                  nd}| j                            d|t          |j        t                    s|j        nd           |j         t          j	        k    r| 
                    d|j        d           d	S |j         t          j        k    r9|                     t          j        t          j        |j                             d	S |j         t          j        k    r#|                     d| j        j                   d	S |j         t          j        k    rd	S | j                            d|j                    d	S )
z(Handle incoming packets from the server.UNKNOWNzReceived packet %s data %s<binary>messageTr6   )rD   r<   z%Received unexpected packet of type %sN)r   lenr	   packet_namesrr   rv   r   r-   bytesr0   r;   r   r.   r/   r   r8   r5   r<   SERVER_DISCONNECTNOOPrs   )r!   r   packet_names      r   r   zClient._receive_packet  sO    V%8!9!999 )#/::?H 	(+&sx77GCHHZ	I 	I 	I ?fn,,	38tDDDDD_++fmFKBBCCCCC_,,OO$t{/LOMMMMM_++DKE!o/ / / / /r   c                     | j         dk    rdS | j                            |           | j                            dt
          j        |j                 t          |j	        t                    s|j	        nd           dS )z(Queue a packet to be sent to the server.r3   NzSending packet %s data %sr   )r   r9   r:   rr   rv   r	   r   r   r   r-   r   )r!   r   s     r   r.   zClient._send_packet  s{    :$$F
s'0&sx77GCHHZ	I 	I 	I 	I 	Ir   c                 @   | j         t          j                    | _         | j        sd| j         _        	 | j                             |||||          S # t          j        j        $ r6}| j        	                    d|||           t          |          cY d }~S d }~ww xY w)NF)r#   r-   re   z+HTTP %s request to %s failed with error %s.)r   rq   Sessionr   r   requestr   RequestExceptionrr   rv   r   )r!   methodr"   r#   bodyre   excs          r   rw   zClient._send_request  s     9 (**DI 	%$DI	9$$VS'-4 % 6 6 6"3 	 	 	KJ#S#/ / /s88OOOOOO	s   A B'+BBBc                 f   |                     dd          }|| j        v r|r | j        | j        |         g|R  S 	 	  | j        |         | S # t          $ r2 |dk    r*t	          |          dk    r | j        |                     cY S  w xY w#  | j                            |dz              Y dS xY wdS )zInvoke an event handler.r7   Fr5   r   z handler errorN)r   handlersrN   	TypeErrorr   rr   	exception)r!   eventrG   rH   r7   s        r   r;   zClient._trigger_event  s    JJ{E22	DM!! D1t1$-2FNNNNND	"3t}U3T::$ " " " L00 #D		Q $84=#7#9#9999!"DK))%2B*BCCCCCC! "!s#   A 8B	B B		B B.c                     | j         dk    r| j        r| j                            d| j        z              |                     d| j        |                                 z   t          | j        | j	                  dz             }|t          |t                    r7| j                            |pd           | j                            d           n|j        dk     s|j        d	k    r;| j                            d
|j                   | j                            d           n	 t!          j        |j                            d                    }nD# t(          $ r7 | j                            d           | j                            d           Y n6w xY w|j        D ]}|                     |           | j         dk    r| j        | j        r3| j                            d           | j                                         | j         dk    rg|                     d| j        j        d           	 t6          j                            |            n# t(          $ r Y nw xY w|                                  | j                            d           dS )z-Read packets by polling the Engine.IO server.r3   zSending polling GET request to rd      re   N*Connection refused by the server, abortingrf   rg   6Unexpected status code %s in server response, abortingrh   ri   z'Unexpected packet from server, aborting"Waiting for write loop task to endr5   Fr6   Exiting read loop task)r   r   rr   rv   ru   rw   rx   maxr   r   r   r   r   r9   r:   r{   r
   r~   r   r   r   r   r   r(   r;   r<   TRANSPORT_ERRORr   rA   rB   rC   )r!   r   r   r   s       r   r   zClient._read_loop_polling  s   jK''D,@'K1DMAC C C""t}t'>'>'@'@@D.0ABBQF # H HA yJq#..y##EEG G G
t$$$}s""ams&:&:## %9:;-I I I
t$$$OAI4D4DW4M4MNNN   ##=? ? ?
t$$$	
 y * *$$S))))1 jK''D,@'4  	(KABBB %%''':$$dk.I*/   1 1 1-44T::::   KKMMM122222s$   $-E >FF0I 
IIc                    | j         dk    r d}	 | j                                        }t          |          dk    r| j        j        st          j                    n# t
          j        $ r8 | j        	                    d           | j
                            d           Y njt
          j        $ r8 | j        	                    d           | j
                            d           Y n%t          $ r}t          |          t          u r&|j        dk    r| j                            d           n(| j                            dt#          |                     | j
                            d           Y d}~nd}~ww xY w	 t%          j        |	          }nY# t          $ rL}| j                            d
t#          |                     | j
                            d           Y d}~n)d}~ww xY w|                     |           | j         dk     | j        r3| j                            d           | j                                         | j         dk    rg|                     d| j        j        d           	 t4          j                            |            n# t:          $ r Y nw xY w|                                  | j                            d           dS )z5Read packets from the Engine.IO WebSocket connection.r3   Nr   z*Server has stopped communicating, aborting)WebSocket connection was closed, aborting	   z)WebSocket connection is closing, abortingz1Unexpected error receiving packet: "%s", abortingr   z0Unexpected error decoding packet: "%s", abortingr   r5   Fr6   r   )r   r?   r   r   r3   r   "WebSocketConnectionClosedExceptionWebSocketTimeoutExceptionrr   r   r9   r:   r   typer   errnorv   r   r	   r/   r   r   r(   r;   r<   r   r   rA   rB   r   rC   )r!   r   r   r   s       r   r   zClient._read_loop_websocket
  s   jK''AGLLNNq66Q;;tw'8;#FHHH6   ##@B B B
t$$$?   ##?A A A
t$$$ 	 	 	77g%%!'Q,,K$$CE E E E K$$KA      
t$$$	m1555     FAP P P
t$$$	
   %%%E jK''H  	(KABBB %%''':$$dk.I*/   1 1 1-44T::::   KKMMM122222sR   AA AE9#AE9(	E91A>E44E9=F 
G)AG$$G)5J 
J"!J"c                    | j         dk    rt          | j        | j                  dz   }d}	 | j                            |          g}n+# | j        $ r | j                            d           Y n:w xY w|dgk    r| j        	                                 g }nn	 	 |
                    | j                            d                     n# | j        $ r Y n1w xY w|d	         $|dd	         }| j        	                                 nm|sn| j        d
k    rt          j        |          }|                     d| j        |                                ddi| j                  }|D ]}| j        	                                 |t%          |t&                    r| j                            |pd           n|j        dk     s|j        dk    r(| j                            d|j                   d| _        nn	 |D ]k}|                                }|j        r| j                            |           n| j                            |           | j        	                                 ln<# t6          j        t:          t<          f$ r | j                            d           Y nw xY w| j         dk    | j                            d           dS )zhThis background task sends packages to the server as they are
        pushed to the send queue.
        r3   r   Nr   zpacket queue is empty, abortingTF)blockr   )r   POSTzContent-Typez
text/plain)r   r#   re   r   rf   rg   r   r   zExiting write loop task) r   r   r   r   r9   r   ra   rr   rs   r`   r   r>   r
   r~   rw   ru   r   ry   r   r   r   r{   r   binaryr?   send_binaryr1   r   r   BrokenPipeErrorr   rv   )r!   re   r   r   r   r   r   s          r   r   zClient._write_loop=  sG    jK'' $,d.?@@1DGG:>>'>::;#   !!"CDDD 4&  
$$&&&tz~~E~'B'BCCCC+   r{*")#2#,
,,...  %22OG444&&DM

+\: 0 ' 2 2 # + +CJ((****9
1c 2 29K''IIK K K=3&&!-3*>*>K'' )=>?mM M M+/D(	 +?& / /),: 9 G//???? GLL888
,,..../ "D'2   K''CE E EE	m jK''v 	233333s6   A
 
$A21A2.C	 	
CC4A.I# #6JJ)NNr   )FN)r   )NNN)__name__
__module____qualname____doc__r%   r*   r1   r5   rN   rQ   rV   rY   r\   rC   r   r   r   r.   rw   r;   r   r   r   __classcell__)rb   s   @r   r   r      s       # #H 59)!/ !/ !/ !/F' ' 'D D D   0  &# # # #, , ,  0 0 0    ;% ;% ;%zf f fP/ / /&I I I 37   D D D*'3 '3 '3R13 13 13f?4 ?4 ?4 ?4 ?4 ?4 ?4r   r   )base64r   http.cookiesr   loggingr9   r   rJ   rP   r   engineio.jsonr   rq   ImportErrorr   r   r   r   r	   r
   	getLoggerdefault_logger
BaseClientr   r   r   r   <module>r     s|         % % % % % %   



       ) ) ) ) ) )OOOO   HHH   III                        ""#455a	4 a	4 a	4 a	4 a	4[# a	4 a	4 a	4 a	4 a	4s   1 ;;A AA