
    vgU                       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m	Z	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 dd	lmZm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$ ddlm%Z%m&Z&m'Z' ddl(m)Z)m*Z* ddl+m,Z,m-Z- ddl.m/Z/ g dZ0 e1ej2        3                    dd                    Z4 G d de/          Z5d&dZ6 G d d          Z7	 	 d'd(d%Z8dS ))    )annotationsN)AsyncIterator	GeneratorSequence)TracebackType)AnyCallable   )ClientProtocolbackoff)HeadersLike)InvalidStatusSecurityError)ClientExtensionFactory) enable_client_permessage_deflate)validate_subprotocols)
USER_AGENTResponse)
CONNECTINGEvent)
LoggerLikeOriginSubprotocol)WebSocketURI	parse_uri   )TimeoutErrorasyncio_timeout)
Connection)connectunix_connectClientConnectionWEBSOCKETS_MAX_REDIRECTS10c                  L     e Zd ZdZddddddd fdZdefddZd fdZ xZS ) r"   a$  
    :mod:`asyncio` implementation of a WebSocket client connection.

    :class:`ClientConnection` provides :meth:`recv` and :meth:`send` coroutines
    for receiving and sending messages.

    It supports asynchronous iteration to receive messages::

        async for message in websocket:
            await process(message)

    The iterator exits normally when the connection is closed with close code
    1000 (OK) or 1001 (going away) or without a close code. It raises a
    :exc:`~websockets.exceptions.ConnectionClosedError` when the connection is
    closed with any other code.

    The ``ping_interval``, ``ping_timeout``, ``close_timeout``, ``max_queue``,
    and ``write_limit`` arguments have the same meaning as in :func:`connect`.

    Args:
        protocol: Sans-I/O connection.

       
         ping_intervalping_timeoutclose_timeout	max_queuewrite_limitprotocolr   r+   float | Noner,   r-   r.   *int | None | tuple[int | None, int | None]r/   int | tuple[int, int | None]returnNonec                   |  t                                          ||||||           | j                                        | _        d S )Nr*   )super__init__loopcreate_futureresponse_rcvd)selfr0   r+   r,   r-   r.   r/   	__class__s          V/var/www/pixelcanvas.ch/venv/lib/python3.11/site-packages/websockets/asyncio/client.pyr8   zClientConnection.__init__8   s\     	%'%'# 	 	
 	
 	
 4893J3J3L3L    Nadditional_headersHeadersLike | Noneuser_agent_header
str | Nonec                  K   |                      t                    4 d{V  | j                                        | _        || j        j                            |           |r|| j        j        d<   | j                            | j                   ddd          d{V  n# 1 d{V swxY w Y   t          j	        | j
        | j        gt          j                   d{V  | j        j        | j        j        dS )z1
        Perform the opening handshake.

        )expected_stateNz
User-Agent)return_when)send_contextr   r0   r    requestheadersupdatesend_requestasynciowaitr;   connection_lost_waiterFIRST_COMPLETEDhandshake_exc)r<   r@   rB   s      r>   	handshakezClientConnection.handshakeM   s      $$J$?? 	5 	5 	5 	5 	5 	5 	5 	5=0022DL!-$++,>???  G5F$\2M&&t|444	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 	5 l!<=/
 
 
 	
 	
 	
 	
 	
 	
 	
 =&2--- 32s   A0B&&
B03B0eventr   c                    | j         :t          |t                    sJ || _         | j                            d           dS t                                          |           dS )z.
        Process one incoming event.

        N)response
isinstancer   r;   
set_resultr7   process_event)r<   rR   r=   s     r>   rW   zClientConnection.process_eventj   sg     = eX.....!DM))$///// GG!!%(((((r?   )r0   r   r+   r1   r,   r1   r-   r1   r.   r2   r/   r3   r4   r5   )r@   rA   rB   rC   r4   r5   )rR   r   r4   r5   )	__name__
__module____qualname____doc__r8   r   rQ   rW   __classcell__)r=   s   @r>   r"   r"      s         8 ')%'&(@B49M M M M M M M M. 26(2. . . . .:) ) ) ) ) ) ) ) ) )r?   r"   exc	Exceptionr4   Exception | Nonec                    t          | t          t          t          j        f          rdS t          | t
                    r| j        j        dv rdS | S )a  
    Determine whether a connection error is retryable or fatal.

    When reconnecting automatically with ``async for ... in connect(...)``, if a
    connection attempt fails, :func:`process_exception` is called to determine
    whether to retry connecting or to raise the exception.

    This function defines the default behavior, which is to retry on:

    * :exc:`EOFError`, :exc:`OSError`, :exc:`asyncio.TimeoutError`: network
      errors;
    * :exc:`~websockets.exceptions.InvalidStatus` when the status code is 500,
      502, 503, or 504: server or proxy errors.

    All other exceptions are considered fatal.

    You can change this behavior with the ``process_exception`` argument of
    :func:`connect`.

    Return :obj:`None` if the exception is retryable i.e. when the error could
    be transient and trying to reconnect with the same parameters could succeed.
    The exception will be logged at the ``INFO`` level.

    Return an exception, either ``exc`` or a new exception, if the exception is
    fatal i.e. when trying to reconnect will most likely produce the same error.
    That exception will be raised, breaking out of the retry loop.

    N)i  i  i  i  )rU   EOFErrorOSErrorrL   r   r   rT   status_code)r]   s    r>   process_exceptionrd   y   sZ    : #'7+?@AA t#}%% #,*B G + + tJr?   c                  z    e Zd ZdZddddededddddddddd	d@d,ZdAd.ZdBd2ZdCd4Z	dAd5Z
e	ZdAd6ZdDd=ZdEd?ZdS )Fr    uM  
    Connect to the WebSocket server at ``uri``.

    This coroutine returns a :class:`ClientConnection` instance, which you can
    use to send and receive messages.

    :func:`connect` may be used as an asynchronous context manager::

        from websockets.asyncio.client import connect

        async with connect(...) as websocket:
            ...

    The connection is closed automatically when exiting the context.

    :func:`connect` can be used as an infinite asynchronous iterator to
    reconnect automatically on errors::

        async for websocket in connect(...):
            try:
                ...
            except websockets.exceptions.ConnectionClosed:
                continue

    If the connection fails with a transient error, it is retried with
    exponential backoff. If it fails with a fatal error, the exception is
    raised, breaking out of the loop.

    The connection is closed automatically after each iteration of the loop.

    Args:
        uri: URI of the WebSocket server.
        origin: Value of the ``Origin`` header, for servers that require it.
        extensions: List of supported extensions, in order in which they
            should be negotiated and run.
        subprotocols: List of supported subprotocols, in order of decreasing
            preference.
        additional_headers (HeadersLike | None): Arbitrary HTTP headers to add
            to the handshake request.
        user_agent_header: Value of  the ``User-Agent`` request header.
            It defaults to ``"Python/x.y.z websockets/X.Y"``.
            Setting it to :obj:`None` removes the header.
        compression: The "permessage-deflate" extension is enabled by default.
            Set ``compression`` to :obj:`None` to disable it. See the
            :doc:`compression guide <../../topics/compression>` for details.
        process_exception: When reconnecting automatically, tell whether an
            error is transient or fatal. The default behavior is defined by
            :func:`process_exception`. Refer to its documentation for details.
        open_timeout: Timeout for opening the connection in seconds.
            :obj:`None` disables the timeout.
        ping_interval: Interval between keepalive pings in seconds.
            :obj:`None` disables keepalive.
        ping_timeout: Timeout for keepalive pings in seconds.
            :obj:`None` disables timeouts.
        close_timeout: Timeout for closing the connection in seconds.
            :obj:`None` disables the timeout.
        max_size: Maximum size of incoming messages in bytes.
            :obj:`None` disables the limit.
        max_queue: High-water mark of the buffer where frames are received.
            It defaults to 16 frames. The low-water mark defaults to ``max_queue
            // 4``. You may pass a ``(high, low)`` tuple to set the high-water
            and low-water marks. If you want to disable flow control entirely,
            you may set it to ``None``, although that's a bad idea.
        write_limit: High-water mark of write buffer in bytes. It is passed to
            :meth:`~asyncio.WriteTransport.set_write_buffer_limits`. It defaults
            to 32 KiB. You may pass a ``(high, low)`` tuple to set the
            high-water and low-water marks.
        logger: Logger for this client.
            It defaults to ``logging.getLogger("websockets.client")``.
            See the :doc:`logging guide <../../topics/logging>` for details.
        create_connection: Factory for the :class:`ClientConnection` managing
            the connection. Set it to a wrapper or a subclass to customize
            connection handling.

    Any other keyword arguments are passed to the event loop's
    :meth:`~asyncio.loop.create_connection` method.

    For example:

    * You can set ``ssl`` to a :class:`~ssl.SSLContext` to enforce TLS settings.
      When connecting to a ``wss://`` URI, if ``ssl`` isn't provided, a TLS
      context is created with :func:`~ssl.create_default_context`.

    * You can set ``server_hostname`` to override the host name from ``uri`` in
      the TLS handshake.

    * You can set ``host`` and ``port`` to connect to a different host and port
      from those found in ``uri``. This only changes the destination of the TCP
      connection. The host name from ``uri`` is still used in the TLS handshake
      for secure connections and in the ``Host`` header.

    * You can set ``sock`` to provide a preexisting TCP socket. You may call
      :func:`socket.create_connection` (not to be confused with the event loop's
      :meth:`~asyncio.loop.create_connection` method) to create a suitable
      client socket and customize it.

    Raises:
        InvalidURI: If ``uri`` isn't a valid WebSocket URI.
        OSError: If the TCP connection fails.
        InvalidHandshake: If the opening handshake fails.
        TimeoutError: If the opening handshake times out.

    Ndeflater'   r&   i   r(   r)   )origin
extensionssubprotocolsr@   rB   compressionrd   open_timeoutr+   r,   r-   max_sizer.   r/   loggercreate_connectionuristrrg   Origin | Nonerh   'Sequence[ClientExtensionFactory] | Noneri   Sequence[Subprotocol] | Noner@   rA   rB   rC   rj   rd   'Callable[[Exception], Exception | None]rk   r1   r+   r,   r-   rl   
int | Noner.   r2   r/   r3   rm   LoggerLike | Nonern   type[ClientConnection] | Nonekwargsr   r4   r5   c               V  
 || _         t                     |dk    rt                    n|t          d|           t	          j        d          t          d	
fd}|| _        ||f| _        || _	        |	| _
        | _        || _        d S )
Nrf   zunsupported compression: zwebsockets.clientwsurir   r4   r"   c                T    t          | 	          } |
          }|S )N)rg   rh   ri   rl   rm   r*   )r   )rz   r0   
connectionr-   rn   rh   rm   r.   rl   rg   r+   r,   ri   r/   s      r>   protocol_factoryz*connect.__init__.<locals>.protocol_factory8  s\    %%)!  H +*+)+#'  J r?   )rz   r   r4   r"   )ro   r   r   
ValueErrorlogging	getLoggerr"   r}   handshake_argsrd   rk   rm   connection_kwargs)r<   ro   rg   rh   ri   r@   rB   rj   rd   rk   r+   r,   r-   rl   r.   r/   rm   rn   rx   r}   s     ```     ````````  r>   r8   zconnect.__init__  s   8 #!,///)##9*EEJJ$FFFGGG>&':;;F$ 0	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	* !1
 "3(!'r?   r"   c                   K   t          j                    }t           j                   j                                        }d fd}j        rV|                    dd           |                    dj                   |	                    d          t          d          n$|	                    d          t          d	          |                    d
d          r |j        |fi | d{V \  }}nb|	                    d          6|                    dj                   |                    dj                    |j        |fi | d{V \  }}|S )zCreate TCP or Unix connection.r4   r"   c                 .                                    S N)r}   )r<   rz   s   r>   factoryz*connect.create_connection.<locals>.factory^  s    ((///r?   sslTserver_hostnameNz*ssl=None is incompatible with a wss:// URIz-ssl argument is incompatible with a ws:// URIunixFsockhostportr4   r"   )rL   get_running_loopr   ro   r   copysecure
setdefaultr   getr~   popcreate_unix_connectionr   rn   )r<   r9   rx   r   _r|   rz   s   `     @r>   rn   zconnect.create_connectionW  s     '))$(##',,..	0 	0 	0 	0 	0 	0 	0 < 	ReT***/<<<zz%  ( !MNNN ) zz%  , !PQQQ::fe$$ 	L"=$"=g"P"P"P"PPPPPPPMAzzzz&!!)!!&%*555!!&%*555"8$"8"K"KF"K"KKKKKKKMAzr?   r]   r^   Exception | strc                    t          |t                    r|j        j        dv rd|j        j        v s|S t          | j                  }t          j        	                    | j        |j        j        d                   }t          |          }| j
                            d          t          d| d          S |j        r|j        st          d|           S |j        |j        k    s |j        |j        k    s|j        |j        k    ru| j
                            dd	          rt          d
| d          S | j
                            d          | j
                            d          t          d
| d          S |S )z
        Determine whether a connection error is a redirect that can be followed.

        Return the new URI if it's a valid redirect. Else, return an exception.

        )i,  i-  i.  i/  i3  i4  Locationr   Nzcannot follow redirect to z with a preexisting socketz)cannot follow redirect to non-secure URI r   Fz'cannot follow cross-origin redirect to z with a Unix socketr   r   z with an explicit host or port)rU   r   rT   rc   rI   r   ro   urllibparseurljoinr   r   r~   r   r   r   r   )r<   r]   	old_wsurinew_uri	new_wsuris        r>   process_redirectzconnect.process_redirects  s    sM**	(  cl222Jdh''	,&&tx1Ej1QRRg&&	 !%%f--9PWPPP  
  	XI$4 	X !VW!V!VWWW 	 000~//~// %))&%88 !*g * * *   &**622>)--f55A!5g 5 5 5  
 r?   &Generator[Any, None, ClientConnection]c                N    |                                                                  S r   )__await_impl__	__await__r<   s    r>   r   zconnect.__await__  s     ""$$..000r?   c                  K   	 t          | j                  4 d {V  t          t                    D ] }|                                  d {V | _        	  | j        j        | j          d {V  | j                                         | j        c cd d d           d {V  S # t          j
        $ r | j                                          t          $ r\}| j                                         |                     |          }t          |t                    r|| _        Y d }~||u r ||d }~ww xY wt#          dt           d          # 1 d {V swxY w Y   d S # t$          $ r t%          d          d w xY w)Nz
more than z
 redirectsztimed out during handshake)r   rk   rangeMAX_REDIRECTSrn   r|   rQ   r   start_keepaliverL   CancelledErrorclose_transportr^   r   rU   rp   ro   r   r   )r<   r   r]   
uri_or_excs       r>   r   zconnect.__await_impl__  s     %	G&t'899  P  P  P  P  P  P  P  P}-- P PA,0,B,B,D,D&D&D&D&D&D&DDO/7do79LMMMMMMMM2 77999#..= P  P  P  P  P  P  P  P  P  P  P  P  P  P
 #1   77999$ 6 6 6 77999%)%:%:3%?%?
%j#66 %'1DH$HHHH%,,!",#5%60 ((N](N(N(NOOOA P  P  P  P  P  P  P  P  P  P  P  P  P  P  P  PD  	G 	G 	G;<<$F	Gs_   E  7EB$0!EE  $2D2A
D- E%D--D22E
EE  EE   E;c                   K   |  d {V S r    r   s    r>   
__aenter__zconnect.__aenter__  s      zzzzzzr?   exc_typetype[BaseException] | None	exc_valueBaseException | None	tracebackTracebackType | Nonec                H   K   | j                                          d {V  d S r   )r|   close)r<   r   r   r   s       r>   	__aexit__zconnect.__aexit__  s4       o##%%%%%%%%%%%r?   AsyncIterator[ClientConnection]c           
    8  K   d }	 	 | 4 d {V }|W V  d d d           d {V  n# 1 d {V swxY w Y   d }n# t           $ r}	 |                     |          }n# t           $ r}|}Y d }~nd }~ww xY w||u r ||||t                      }t          |          }| j                            d|t          j        t          |          |          d         	                                           t          j        |           d {V  Y d }~d }~ww xY w)NTz0connect failed; reconnecting in %.1f seconds: %sr   )r^   rd   r   nextrm   infor   format_exception_onlytypestriprL   sleep)r<   delaysr0   r]   new_exc
raised_excdelays          r>   	__aiter__zconnect.__aiter__  s     *.%	$ # # # # # # #8"NNNN# # # # # # # # # # # # # # # # # # # # # # # # # # #F C    
)"44S99GG  ) ) )(GGGGGG)
 c>>&!s* >$YYFV  F3DIIsCCAFLLNN	   mE*********;	%	sR   ; '; 
1; 1; 
DAD
A2&A-(D-A22BDD)&ro   rp   rg   rq   rh   rr   ri   rs   r@   rA   rB   rC   rj   rC   rd   rt   rk   r1   r+   r1   r,   r1   r-   r1   rl   ru   r.   r2   r/   r3   rm   rv   rn   rw   rx   r   r4   r5   r   )r]   r^   r4   r   )r4   r   )r   r   r   r   r   r   r4   r5   )r4   r   )rX   rY   rZ   r[   r   rd   r8   rn   r   r   r   __iter__r   r   r   r   r?   r>   r    r       s       f fZ !%>B5915(2"+EV%'&(%'&($@B49$(;?1I( I( I( I( I( I(V   8; ; ; ;~1 1 1 1&G &G &G &GT H   & & & &' ' ' ' ' 'r?   r    pathrC   ro   rx   r   c                Z    ||                     d          d}nd}t          d|d| d|S )a  
    Connect to a WebSocket server listening on a Unix socket.

    This function accepts the same keyword arguments as :func:`connect`.

    It's only available on Unix.

    It's mainly useful for debugging servers listening on Unix sockets.

    Args:
        path: File system path to the Unix socket.
        uri: URI of the WebSocket server. ``uri`` defaults to
            ``ws://localhost/`` or, when a ``ssl`` argument is provided, to
            ``wss://localhost/``.

    Nr   zws://localhost/zwss://localhost/T)ro   r   r   r   )r   r    )r   ro   rx   s      r>   r!   r!     sD    * {::e$#CC$C;sD;;F;;;r?   )r]   r^   r4   r_   )NN)r   rC   ro   rC   rx   r   r4   r    )9
__future__r   rL   r   osr   urllib.parser   collections.abcr   r   r   typesr   typingr   r	   clientr   r   datastructuresr   
exceptionsr   r   extensions.baser   extensions.permessage_deflater   rI   r   http11r   r   r0   r   r   r   r   r   ro   r   r   compatibilityr   r   r|   r   __all__intenvironr   r   r"   rd   r    r!   r   r?   r>   <module>r      sk   " " " " " "   				         > > > > > > > > > >                       , , , , , , , , ( ( ( ( ( ( 5 5 5 5 5 5 5 5 4 4 4 4 4 4 L L L L L L + + + + + + ) ) ) ) ) ) ) ) ( ( ( ( ( ( ( ( 4 4 4 4 4 4 4 4 4 4 ) ) ) ) ) ) ) ) 8 8 8 8 8 8 8 8 " " " " " " :
9
9BJNN#=tDDEEW) W) W) W) W)z W) W) W)t& & & &Tu u u u u u u ur < < < < < < <r?   