
    wgz8                         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	  ej                  d      Z G d d      Zy)    N   )packet)payloadzengineio.serverc                       e Zd ZddgZg dZddgZdZdZ G d d	      Z	 	 	 	 	 	 d dZ	d Z
d Zd!dZd Zd Zd Zd Zd Zd Zd Zd Zd"dZd!dZd Zd!dZd Zd Zd Zd Zd Zy
)#
BaseServergzipdeflate)connect
disconnectmessagepolling	websocketTr   c                   $    e Zd ZdZdZdZdZdZdZy)BaseServer.reasonzDisconnection reasons.zserver disconnectzclient disconnectzping timeoutztransport closeztransport errorN)	__name__
__module____qualname____doc__SERVER_DISCONNECTCLIENT_DISCONNECTPING_TIMEOUTTRANSPORT_CLOSETRANSPORT_ERROR     Y/home/mcse/projects/flask/flask-venv/lib/python3.12/site-packages/engineio/base_server.pyreasonr      s     $//%++r   r   Nc                    || _         t        |t              r|d   | _        |d   | _        n|| _        d| _        || _        || _        || _        || _        || _	        |	| _
        |
| _        || _        i | _        i | _        t               | _        ||n| j"                  | _        d | _        d | _        ||t*        j,                  _        t        |t0              s|| _        nt4        | _        | j2                  j6                  t8        j:                  k(  r|r*| j2                  j=                  t8        j>                         n)| j2                  j=                  t8        j@                         | j2                  jC                  t9        jD                                | jG                         }|	||v r|gng }d | _$        d | _%        |D ]e  }	 tM        jN                  d|z         jH                  | _$        d| jH                  v r| jH                  d   nd}|| jQ                         k7  r^|| _%         n | jJ                  tU        d      | jQ                         r(d| jH                  vs| jH                  d   stU        d      | jQ                         s(d| jH                  v r| jH                  d   rtU        d      |=t        |tV              r|g}|D cg c]  }|| jX                  v r| }}|stU        d	      |xs | jX                  | _-        | j2                  j]                  d
| jJ                         y # tR        $ r Y vw xY wc c}w )Nr   r   zengineio.async_drivers.asyncioFzInvalid async_mode specifiedz1The selected async_mode is not asyncio compatiblezKThe selected async_mode requires asyncio and must use the AsyncServer classzNo valid transports providedzServer initialized for %s.)/ping_timeout
isinstancetupleping_intervalping_interval_grace_periodmax_http_buffer_sizeallow_upgradeshttp_compressioncompression_thresholdcookiecors_allowed_originscors_credentialsasync_handlerssocketshandlerssetlog_message_keys_default_monitor_clientsstart_service_taskservice_task_handleservice_task_eventr   Packetjsonboolloggerdefault_loggerlevelloggingNOTSETsetLevelINFOERROR
addHandlerStreamHandlerasync_modes_async
async_mode	importlibimport_moduleis_asyncio_basedImportError
ValueErrorstrvalid_transports
transportsinfo)selfrD   r#   r    r%   r&   r'   r(   r)   r*   r+   r8   r6   r,   monitor_clientsrL   kwargsmodesmodeasyncio_based	transports                        r   __init__zBaseServer.__init__#   s    )mU+!.q!1D.;A.>D+!.D./D+$8!, 0%:"$8! 0, #* #2040M0M 	#' "&!%FMM&$' DK(DK{{  GNN2KK((6KK((7&&w'<'<'>?  "!$.%$7ZLRE 	D
'55-466<f  !DKK/ !%I 65:  D$9$9$;;"&	 ??";<<  "$++-Y' * + +$$&9+CI& > ? ?!*c*(\
5? A	&$*?*?? $ AJ A !?@@$=(=(=5tG+   As   AL+L+	L;+	L87L8c                      y)NFr   rN   s    r   rG   zBaseServer.is_asyncio_basedr   s    r   c                 
    g dS )N)eventletgevent_uwsgigevent	threadingr   rW   s    r   rB   zBaseServer.async_modesu   s    BBr   c                 ^      j                   vrt        d       fd}||S  ||       y)a  Register an event handler.

        :param event: The event name. Can be ``'connect'``, ``'message'`` or
                      ``'disconnect'``.
        :param handler: The function that should be invoked to handle the
                        event. When this parameter is not given, the method
                        acts as a decorator for the handler function.

        Example usage::

            # as a decorator:
            @eio.on('connect')
            def connect_handler(sid, environ):
                print('Connection request')
                if environ['REMOTE_ADDR'] in blacklisted:
                    return False  # reject

            # as a method:
            def message_handler(sid, msg):
                print('Received message: ', msg)
                eio.send(sid, 'response')
            eio.on('message', message_handler)

        The handler function receives the ``sid`` (session ID) for the
        client as first argument. The ``'connect'`` event handler receives the
        WSGI environment as a second argument, and can return ``False`` to
        reject the connection. The ``'message'`` handler receives the message
        payload as a second argument. The ``'disconnect'`` handler does not
        take a second argument.
        zInvalid eventc                 &    | j                   <   | S N)r.   )handlereventrN   s    r   set_handlerz"BaseServer.on.<locals>.set_handler   s    #*DMM% Nr   N)event_namesrI   )rN   ra   r`   rb   s   ``  r   onzBaseServer.onx   s8    > (((_--	 ?Gr   c                 @    | j                  |      j                  rdS dS )zReturn the name of the transport used by the client.

        The two possible values returned by this function are ``'polling'``
        and ``'websocket'``.

        :param sid: The session of the client.
        r   r   )_get_socketupgraded)rN   sids     r   rT   zBaseServer.transport   s"     #..s3<<{K)Kr   c                 ,     | j                   d   |i |S )zCreate a queue object using the appropriate async model.

        This is a utility function that applications can use to create a queue
        without having to worry about using the correct call for the selected
        async mode.
        queuerC   rN   argsrP   s      r   create_queuezBaseServer.create_queue        $t{{7#T4V44r   c                      | j                   d   S )zReturn the queue empty exception for the appropriate async model.

        This is a utility function that applications can use to work with a
        queue without having to worry about using the correct call for the
        selected async mode.
        queue_emptyrk   rW   s    r   get_queue_empty_exceptionz$BaseServer.get_queue_empty_exception   s     {{=))r   c                 ,     | j                   d   |i |S )zCreate an event object using the appropriate async model.

        This is a utility function that applications can use to create an
        event without having to worry about using the correct call for the
        selected async mode.
        ra   rk   rl   s      r   create_eventzBaseServer.create_event   ro   r   c                    t        j                  t        j                  d      | j                  j                  dd      z         }| j                  dz   dz  | _        |j                  d      j                  dd      j                  d	d
      S )zGenerate a unique session id.      bigr   i utf-8/_+-)base64	b64encodesecretstoken_bytessequence_numberto_bytesdecodereplace)rN   ids     r   generate_idzBaseServer.generate_id   sz    #d&:&:&C&CAu&MMO $ 4 4q 8HDyy!))#s3;;CEEr   c                     |j                  dd      dz   |z   }|j                         D ]8  \  }}|dk(  rt        |      r |       }|du r	|d|z   z  }+|d|z   dz   |z   z  }: |S )zGenerate the sid cookie.nameio=Tz; )getitemscallable)rN   rh   
attributesr)   	attributevalues         r   _generate_sid_cookiezBaseServer._generate_sid_cookie   s    -3c9 * 0 0 2 	9IuF"}$**$*S0588	9 r   c                     | j                   r | j                  |      j                  s|dk(  rg S | j                  d   | j	                  dd       g S dgS )z=Return the list of possible upgrades for a client connection.r   zThe WebSocket transport is not available, you must install a WebSocket server that is compatible with your async mode to enable it. See the documentation for details.zno-websocket)r&   rf   rg   rC   _log_error_once)rN   rh   rT   s      r   	_upgradeszBaseServer._upgrades   sb    ""d&6&6s&;&D&D[(I;;{#+  @ 	 
 I}r   c                     	 | j                   |   }|j                  r| j                   |= t        d      |S # t        $ r t        d      w xY w)z-Return the socket object for a given session.zSession not foundzSession is disconnected)r-   KeyErrorclosed)rN   rh   ss      r   rf   zBaseServer._get_socket   sX    	0S!A 88S!455  	0.//	0s	   7 Ac                     |C|g }|dgz  }d|t        j                  |      j                  |      j                  d      dS ddgddS )	z$Generate a successful HTTP response.)Content-Typeztext/plain; charset=UTF-8z200 OK)packets)jsonp_indexry   statusheadersresponser   z
text/plains   OK)r   Payloadencode)rN   r   r   r   s       r   _okzBaseServer._ok   ss    EFFG&& ' @ G G$/ !H !117B B
 ' >? %' 'r   c                     |d}t         j                  j                  j                  |      }ddg|j	                  d      dS )z+Generate a bad request HTTP error response.zBad Requestz400 BAD REQUESTr   ry   r   r   r5   r6   dumpsr   rN   r   s     r   _bad_requestzBaseServer._bad_request  sE    ?#G--$$**73+:;#NN735 	5r   c                     ddgddS )z0Generate a method not found HTTP error response.z405 METHOD NOT FOUNDr   s   Method Not Foundr   r   rW   s    r   _method_not_foundzBaseServer._method_not_found  s    0:;/1 	1r   c                     |d}t         j                  j                  j                  |      }ddg|j	                  d      dS )z,Generate a unauthorized HTTP error response.Unauthorizedz401 UNAUTHORIZED)r   zapplication/jsonry   r   r   r   s     r   _unauthorizedzBaseServer._unauthorized  sE    ?$G--$$**73,@A#NN735 	5r   c           
         g }d|v rd|v r|j                  dj                  |d   |d                d|v sd|v r|j                  d|d         j                  d      d   j	                         }|j                  dj                  ||j                  d|d         j                  d      d   j	                                      | j
                  |}|S | j
                  d	k(  rd }|S t        | j
                  t              r| j
                  g}|S t        | j
                        r+|j                  d
      }| j                  |      r|g}|S g }|S | j
                  }|S )Nzwsgi.url_scheme	HTTP_HOSTz{scheme}://{host})schemehostHTTP_X_FORWARDED_PROTOHTTP_X_FORWARDED_HOST,r   *HTTP_ORIGIN)	appendformatr   splitstripr*   r!   rJ   r   )rN   environdefault_originsr   allowed_originsorigins         r   _cors_allowed_originsz BaseServer._cors_allowed_origins  s   'K7,B""#6#=#=018L $> $N O'72+w6 ,-.005c
1>>Ceg   &&':'A'A!/1E)GGLuH!!")$$)EG (B (- . $$,-O  &&#-"O  1137#889O  d//0[[/F,,V4  &hO  ;=   #77Or   c                     | j                   g k(  rg S g }| j                  |      }d|v r||d   |v rd|d   fg}|d   dk(  r|dgz  }d|v r|d|d   fgz  }| j                  r|dgz  }|S )	z1Return the cross-origin-resource-sharing headers.r   zAccess-Control-Allow-OriginREQUEST_METHODOPTIONS)zAccess-Control-Allow-MethodszOPTIONS, GET, POST#HTTP_ACCESS_CONTROL_REQUEST_HEADERSzAccess-Control-Allow-Headers)z Access-Control-Allow-Credentialstrue)r*   r   r+   )rN   r   r   r   s       r   _cors_headerszBaseServer._cors_headers8  s    $$*I44W=G# (GM,B -!5w}7MNOG#$	1NOOG0G;7 EFH I IG  DEEGr   c                     t        j                         }t        j                  |d      5 }|j	                  |       ddd       |j                         S # 1 sw Y   |j                         S xY w)z%Apply gzip compression to a response.w)fileobjrR   N)r   BytesIOr   GzipFilewritegetvalue)rN   r   bytesiogzs       r   _gzipzBaseServer._gzipL  sW    **,]]75 	HHX	!!	!!s   AA.c                 ,    t        j                  |      S )z(Apply deflate compression to a response.)zlibcompress)rN   r   s     r   _deflatezBaseServer._deflateS  s    }}X&&r   c                     || j                   vr:| j                  j                  |dz          | j                   j                  |       y| j                  j	                  |       y)zWLog message with logging.ERROR level the first time, then log
        with given level.zC (further occurrences of this error will be logged with level INFO)N)r0   r8   erroraddrM   )rN   r   message_keys      r   r   zBaseServer._log_error_onceW  sY     d333KKg )@ @ A!!%%k2KKW%r   )N      i@B TTi   NNTFNTNNr_   )NNN)r   r   r   compression_methodsrc   rK   r1   r   r   rU   rG   rB   rd   rT   rn   rr   rt   r   r   r   rf   r   r   r   r   r   r   r   r   r   r   r   r   r   r      s    !9-6K!;/#O, , HJ>B>B37;?GKMH^C(TL5*5F	'5158("'&r   r   )r~   r   rE   r   r;   r   r    r   r   	getLoggerr9   r   r   r   r   <module>r      s?       	     """#45P& P&r   