
    vKg(                        S SK r S SKJr  S SKJr  S SKJr  S SKJr  S SK	r	S SK
r
S SKrS SKrS SKrS SKrS SKJrJrJr  S SKrS SKrS SKJrJr  S SKJr  S SKJr  S S	KJrJ r J!r!J"r"J#r#J$r$J%r%J&r&J'r'  S SK(r\ RR                  S
:  a  S SK*J+r+  \," \-" \.\R^                  Ra                  S5      SS 5      5      S:  r1Sr2Sr3Sr4Sr5\
Rl                  " S5      r7S r8 " S S5      r9\SS\3\4\2\2S.S j5       r:SS\3\4S.S jr;S9SS\3\4\2\2S.S jjr<S9SS\3\4S.S jjr=S r>SS\3\4S.S jr?\3\44S jr@S\3\4\2\2\R                  S .S! jrB " S" S#\C5      rD " S$ S%\D5      rE " S& S'\D5      rF " S( S)\C5      rG " S* S+\D5      rH " S, S-5      rI " S. S/5      rJ " S0 S15      rKS2 rL " S3 S4\R                  R                  5      rO " S5 S65      rP " S7 S85      rQg):    N)OrderedDict)asynccontextmanager)partial)
ip_address)ListOptionalUnion)ConnectionTypeWSConnection)ConnectionState)	AcceptConnectionBytesMessageCloseConnectionPingPongRejectConnection
RejectDataRequestTextMessage)      )BaseExceptionGroup.   )r      <      i   i   ztrio-websocketc                 H    [        U [        R                  5      (       a  S $ U $ N
isinstancetrio	Cancelledexcs    T/var/www/highfloat_scraper/venv/lib/python3.13/site-packages/trio_websocket/_impl.py_ignore_cancelr'   -   s    c4>>224;;    c                   .    \ rS rSrSrSrS rS rS rSr	g)_preserve_current_exception1   a  A context manager which should surround an ``__exit__`` or
``__aexit__`` handler or the contents of a ``finally:``
block. It ensures that any exception that was being handled
upon entry is not masked by a `trio.Cancelled` raised within
the body of the context manager.

https://github.com/python-trio/trio/issues/1559
https://gitter.im/python-trio/general?at=5faf2293d37a1a13d6a582cf
_armedc                     SU l         g NFr,   selfs    r&   __init__$_preserve_current_exception.__init__=   s	    r(   c                 B    [         R                  " 5       S   S LU l        g )Nr   )sysexc_infor-   r0   s    r&   	__enter__%_preserve_current_exception.__enter__@   s    llnQ't3r(   c                    Ub  U R                   (       d  g[        (       a(  [        R                  R	                  [
        U5      nUS L $ [        U[        5      (       a  UR                  S 5      nUS L $ [        U5      nUS L $ )NFc                 @    [        U [        R                  5      (       + $ r   r    r$   s    r&   <lambda>6_preserve_current_exception.__exit__.<locals>.<lambda>J   s    
3PTP^P^@_<_r(   )	r-   _TRIO_MULTI_ERRORr"   
MultiErrorfilterr'   r!   r   subgroup)r1   tyvaluetbfiltered_exceptions        r&   __exit__$_preserve_current_exception.__exit__C   s    =!%!7!7!N
 "T))	 122!&0_!` "T)) "0!6!T))r(   N)
__name__
__module____qualname____firstlineno____doc__	__slots__r2   r7   rE   __static_attributes__ r(   r&   r*   r*   1   s     I4
*r(   r*   )subprotocolsextra_headersmessage_queue_sizemax_message_sizeconnect_timeoutdisconnect_timeoutc               Z  #    [         R                  " 5        ISh  vN n
 [         R                  " U5         [        XUX#UUUUS9	I Sh  vN nSSS5         W7v    [         R                  " U	5         UR                  5       I Sh  vN   SSS5        SSS5      ISh  vN   g N N]! , (       d  f       Na= f! [         R                   a    [
        Se[         a  n[        UeSnAff = f Ne! , (       d  f       Ni= f! [         R                   a    [        Sef = f!  [         R                  " U	5         WR                  5       I Sh  vN    SSS5        f ! , (       d  f       f = f! [         R                   a    [        Sef = f= f N! , ISh  vN  (       d  f       g= f7f)aS  
Open a WebSocket client connection to a host.

This async context manager connects when entering the context manager and
disconnects when exiting. It yields a
:class:`WebSocketConnection` instance.

:param str host: The host to connect to.
:param int port: The port to connect to.
:param str resource: The resource, i.e. URL path.
:param Union[bool, ssl.SSLContext] use_ssl: If this is an SSL context, then
    use that context. If this is ``True`` then use default SSL context. If
    this is ``False`` then disable SSL.
:param subprotocols: An iterable of strings representing preferred
    subprotocols.
:param list[tuple[bytes,bytes]] extra_headers: A list of 2-tuples containing
    HTTP header key/value pairs to send with the connection request. Note
    that headers used by the WebSocket protocol (e.g.
    ``Sec-WebSocket-Accept``) will be overwritten.
:param int message_queue_size: The maximum number of messages that will be
    buffered in the library's internal message queue.
:param int max_message_size: The maximum message size as measured by
    ``len()``. If a message is received that is larger than this size,
    then the connection is closed with code 1009 (Message Too Big).
:param float connect_timeout: The number of seconds to wait for the
    connection before timing out.
:param float disconnect_timeout: The number of seconds to wait when closing
    the connection before timing out.
:raises HandshakeError: for any networking error,
    client-side timeout (:exc:`ConnectionTimeout`, :exc:`DisconnectionTimeout`),
    or server rejection (:exc:`ConnectionRejected`) during handshakes.
Nuse_sslrO   rP   rQ   rR   )
r"   open_nursery
fail_afterconnect_websocketTooSlowErrorConnectionTimeoutOSErrorHandshakeErroracloseDisconnectionTimeout)hostportresourcerW   rO   rP   rQ   rR   rS   rT   new_nursery
connectiones                r&   open_websocketrg   P   sP    J   ""k
	(1#4[L"/'9%5	$7 7
 2	55__%78$++--- 9! #""7 21    	.#- 	( a'	( . 98$$ 5*455__%78$++--- 988$$ 5*45% #"""s8  F+B'F+FB<B+B)B+B<D!D5C1	C/
C1DF+!F"F+)B++
B9	5B<8F9B<<$C, C''C,,F/C11
C?	;D>F?DDF!F#E-9E	EE	E-F
E*&E-)F*E--F			FFF+F(FF($F+)rO   rP   rQ   rR   c                Z  #    USL a  [         R                  " 5       n	O5USL a  Sn	O-[        U[         R                  5      (       a  Un	O[	        S5      e[
        R                  SU	c  SOSXU5        U	c  [        R                  " X5      I Sh  vN n
O[        R                  " XU	SS9I Sh  vN n
US	;   a  UnOU S
U 3n[        U
[        [        R                  5      UUXVUUS9nU R                  UR                  5        UR                   R#                  5       I Sh  vN   U$  N N{ N
7f)ae  
Return an open WebSocket client connection to a host.

This function is used to specify a custom nursery to run connection
background tasks in. The caller is responsible for closing the connection.

If you don't need a custom nursery, you should probably use
:func:`open_websocket` instead.

:param nursery: A Trio nursery to run background tasks in.
:param str host: The host to connect to.
:param int port: The port to connect to.
:param str resource: The resource, i.e. URL path.
:param Union[bool, ssl.SSLContext] use_ssl: If this is an SSL context, then
    use that context. If this is ``True`` then use default SSL context. If
    this is ``False`` then disable SSL.
:param subprotocols: An iterable of strings representing preferred
    subprotocols.
:param list[tuple[bytes,bytes]] extra_headers: A list of 2-tuples containing
    HTTP header key/value pairs to send with the connection request. Note
    that headers used by the WebSocket protocol (e.g.
    ``Sec-WebSocket-Accept``) will be overwritten.
:param int message_queue_size: The maximum number of messages that will be
    buffered in the library's internal message queue.
:param int max_message_size: The maximum message size as measured by
    ``len()``. If a message is received that is larger than this size,
    then the connection is closed with code 1009 (Message Too Big).
:rtype: WebSocketConnection
TFNz1`use_ssl` argument must be bool or ssl.SSLContextzConnecting to ws%s://%s:%d%s s)ssl_contexthttps_compatible)P     :ra   pathclient_subprotocolsclient_extra_headersrQ   rR   )sslcreate_default_contextr!   
SSLContext	TypeErrorloggerdebugr"   open_tcp_streamopen_ssl_over_tcp_streamWebSocketConnectionr   r
   CLIENT
start_soon_reader_task_open_handshakewait)nurseryra   rb   rc   rW   rO   rP   rQ   rR   rk   streamhost_headerre   s                r&   rZ   rZ      s(    @ $002	E		GS^^	,	,KLL
LL/!sDB++D7744T#d< <yav&$V^**+(-)+J z../

$
$
)
)
+++# 8< ,s7   B
D+D%D++D',A2D+D)D+'D+)D+c                :    [        X5      u  pp[        XXX#UUXgS9
$ )a	  
Open a WebSocket client connection to a URL.

This async context manager connects when entering the context manager and
disconnects when exiting. It yields a
:class:`WebSocketConnection` instance.

:param str url: A WebSocket URL, i.e. `ws:` or `wss:` URL scheme.
:param ssl_context: Optional SSL context used for ``wss:`` URLs. A default
    SSL context is used for ``wss:`` if this argument is ``None``.
:type ssl_context: ssl.SSLContext or None
:param subprotocols: An iterable of strings representing preferred
    subprotocols.
:param list[tuple[bytes,bytes]] extra_headers: A list of 2-tuples containing
    HTTP header key/value pairs to send with the connection request. Note
    that headers used by the WebSocket protocol (e.g.
    ``Sec-WebSocket-Accept``) will be overwritten.
:param int message_queue_size: The maximum number of messages that will be
    buffered in the library's internal message queue.
:param int max_message_size: The maximum message size as measured by
    ``len()``. If a message is received that is larger than this size,
    then the connection is closed with code 1009 (Message Too Big).
:param float connect_timeout: The number of seconds to wait for the
    connection before timing out.
:param float disconnect_timeout: The number of seconds to wait when closing
    the connection before timing out.
:raises HandshakeError: for any networking error,
    client-side timeout (:exc:`ConnectionTimeout`, :exc:`DisconnectionTimeout`),
    or server rejection (:exc:`ConnectionRejected`) during handshakes.
)rW   rO   rP   rQ   rR   rS   rT   )_url_to_hostrg   )urlrk   rO   rP   rQ   rR   rS   rT   ra   rb   rc   s              r&   open_websocket_urlr      s3    D )5S(F%D$h!-)'	P Pr(   c                T   #    [        X5      u  pxp[        XXX#XEUS9	I Sh  vN $  N7f)a  
Return an open WebSocket client connection to a URL.

This function is used to specify a custom nursery to run connection
background tasks in. The caller is responsible for closing the connection.

If you don't need a custom nursery, you should probably use
:func:`open_websocket_url` instead.

:param nursery: A nursery to run background tasks in.
:param str url: A WebSocket URL.
:param ssl_context: Optional SSL context used for ``wss:`` URLs.
:type ssl_context: ssl.SSLContext or None
:param subprotocols: An iterable of strings representing preferred
    subprotocols.
:param list[tuple[bytes,bytes]] extra_headers: A list of 2-tuples containing
    HTTP header key/value pairs to send with the connection request. Note
    that headers used by the WebSocket protocol (e.g.
    ``Sec-WebSocket-Accept``) will be overwritten.
:param int message_queue_size: The maximum number of messages that will be
    buffered in the library's internal message queue.
:param int max_message_size: The maximum message size as measured by
    ``len()``. If a message is received that is larger than this size,
    then the connection is closed with code 1009 (Message Too Big).
:rtype: WebSocketConnection
rV   N)r   rZ   )
r   r   rk   rO   rP   rQ   rR   ra   rb   rc   s
             r&   connect_websocket_urlr      s:     : )5S(F%D"7$#)+ + + +s   (&(c                    [        U 5      n [        R                  R                  U 5      nUR                  S;  a  [        S5      eUc  UR                  S:H  nOUR                  S:X  a  [        S5      eUR                  nUR                  b  UR                  nOU(       a  SOSnUR                  nU(       d  SnS	U ;   a  US	UR                  -   -  nX4XQ4$ )
at  
Convert a WebSocket URL to a (host,port,resource) tuple.

The returned ``ssl_context`` is either the same object that was passed in,
or if ``ssl_context`` is None, then a bool indicating if a default SSL
context needs to be created.

:param str url: A WebSocket URL.
:type ssl_context: ssl.SSLContext or None
:returns: A tuple of ``(host, port, resource, ssl_context)``.
)wswssz,WebSocket URL scheme must be "ws:" or "wss:"r   r   z+SSL context must be None for ws: URL schemern   rm   /?)
strurllibparseurlsplitscheme
ValueErrorhostnamerb   rq   query)r   rk   partsra   rb   path_qss         r&   r   r     s     c(CLL!!#&E||=(GHHlle+		FGG>>Dzzzz!srjjG 
cz3$$w++r(   c                   #    [        U[        [        R                  5      X#XEUUS9nU R	                  UR
                  5        UR                  R                  5       I Sh  vN   U$  N7f)a  
Wrap an arbitrary stream in a WebSocket connection.

This is a low-level function only needed in rare cases. In most cases, you
should use :func:`open_websocket` or :func:`open_websocket_url`.

:param nursery: A Trio nursery to run background tasks in.
:param stream: A Trio stream to be wrapped.
:type stream: trio.abc.Stream
:param str host: A host string that will be sent in the ``Host:`` header.
:param str resource: A resource string, i.e. the path component to be
    accessed on the server.
:param subprotocols: An iterable of strings representing preferred
    subprotocols.
:param list[tuple[bytes,bytes]] extra_headers: A list of 2-tuples containing
    HTTP header key/value pairs to send with the connection request. Note
    that headers used by the WebSocket protocol (e.g.
    ``Sec-WebSocket-Accept``) will be overwritten.
:param int message_queue_size: The maximum number of messages that will be
    buffered in the library's internal message queue.
:param int max_message_size: The maximum message size as measured by
    ``len()``. If a message is received that is larger than this size,
    then the connection is closed with code 1009 (Message Too Big).
:rtype: WebSocketConnection
rp   N)r|   r   r
   r}   r~   r   r   r   )	r   r   ra   rc   rO   rP   rQ   rR   re   s	            r&   wrap_client_streamr   =  sf     8 %V^**+(-)+J z../

$
$
)
)
+++ ,s   AA) A'!A)c                    #    [        U[        [        R                  5      UUS9nU R	                  UR
                  5        UR                  5       I Sh  vN nU$  N7f)a  
Wrap an arbitrary stream in a server-side WebSocket.

This is a low-level function only needed in rare cases. In most cases, you
should use :func:`serve_websocket`.

:param nursery: A nursery to run background tasks in.
:param stream: A stream to be wrapped.
:param int message_queue_size: The maximum number of messages that will be
    buffered in the library's internal message queue.
:param int max_message_size: The maximum message size as measured by
    ``len()``. If a message is received that is larger than this size,
    then the connection is closed with code 1009 (Message Too Big).
:type stream: trio.abc.Stream
:rtype: WebSocketRequest
rQ   rR   N)r|   r   r
   SERVERr~   r   _get_request)r   r   rQ   rR   re   requests         r&   wrap_server_streamr   d  sX     $ %V^**+-)+J z../++--GN .s   AAAA)handler_nurseryrQ   rR   rS   rT   task_statusc          
         #    Uc  [        [        R                  X!S9n
O[        [        R                  UX1SS9n
U
" 5       I Sh  vN n[	        XXEXgUS9nUR                  U	S9I Sh  vN   g N( N7f)u"  
Serve a WebSocket over TCP.

This function supports the Trio nursery start protocol: ``server = await
nursery.start(serve_websocket, …)``. It will block until the server
is accepting connections and then return a :class:`WebSocketServer` object.

Note that if ``host`` is ``None`` and ``port`` is zero, then you may get
multiple listeners that have *different port numbers!*

:param handler: An async function that is invoked with a request
    for each new connection.
:param host: The host interface to bind. This can be an address of an
    interface, a name that resolves to an interface address (e.g.
    ``localhost``), or a wildcard address like ``0.0.0.0`` for IPv4 or
    ``::`` for IPv6. If ``None``, then all local interfaces are bound.
:type host: str, bytes, or None
:param int port: The port to bind to.
:param ssl_context: The SSL context to use for encrypted connections, or
    ``None`` for unencrypted connection.
:type ssl_context: ssl.SSLContext or None
:param handler_nursery: An optional nursery to spawn handlers and background
    tasks in. If not specified, a new nursery will be created internally.
:param int message_queue_size: The maximum number of messages that will be
    buffered in the library's internal message queue.
:param int max_message_size: The maximum message size as measured by
    ``len()``. If a message is received that is larger than this size,
    then the connection is closed with code 1009 (Message Too Big).
:param float connect_timeout: The number of seconds to wait for a client
    to finish connection handshake before timing out.
:param float disconnect_timeout: The number of seconds to wait for a client
    to finish the closing handshake before timing out.
:param task_status: Part of Trio nursery start protocol.
:returns: This function runs until cancelled.
N)ra   T)ra   rl   r   rQ   rR   rS   rT   r   )r   r"   open_tcp_listenersopen_ssl_over_tcp_listenersWebSocketServerrun)handlerra   rb   rk   r   rQ   rR   rS   rT   r   r   	listenersservers                r&   serve_websocketr     s{     N $T%<%<dN$T%E%EtT;(**IW')-/F ***
--- +
 .s$   AA0A,"A0&A.'A0.A0c                       \ rS rSrSrSrg)r^   i  zR
There was an error during connection or disconnection with the websocket
server.
rN   NrG   rH   rI   rJ   rK   rM   rN   r(   r&   r^   r^     s    r(   r^   c                       \ rS rSrSrSrg)r\   i  z<There was a timeout when connecting to the websocket server.rN   Nr   rN   r(   r&   r\   r\     s    Fr(   r\   c                       \ rS rSrSrSrg)r`   i  zAThere was a timeout when disconnecting from the websocket server.rN   Nr   rN   r(   r&   r`   r`     s    Kr(   r`   c                   2   ^  \ rS rSrSrU 4S jrS rSrU =r$ )ConnectionClosedi  zj
A WebSocket operation cannot be completed because the connection is closed
or in the process of closing.
c                 .   > [         TU ]  5         Xl        gz8
Constructor.

:param reason:
:type reason: CloseReason
N)superr2   reason)r1   r   	__class__s     r&   r2   ConnectionClosed.__init__  s     	r(   c                 N    U R                   R                   SU R                   S3$ )Return representation. <>)r   rG   r   r0   s    r&   __repr__ConnectionClosed.__repr__  s$    ..))*!DKK=::r(   )r   	rG   rH   rI   rJ   rK   r2   r   rM   __classcell__r   s   @r&   r   r     s    ; ;r(   r   c                   2   ^  \ rS rSrSrU 4S jrS rSrU =r$ )ConnectionRejectedi  ze
A WebSocket connection could not be established because the server rejected
the connection attempt.
c                 F   > [         TU ]  5         Xl        X l        X0l        gr   )r   r2   status_codeheadersbody)r1   r   r   r   r   s       r&   r2   ConnectionRejected.__init__  s      	&	r(   c                 N    U R                   R                   SU R                   S3$ )r   z<status_code=r   )r   rG   r   r0   s    r&   r   ConnectionRejected.__repr__  s'    ..))*-8H8H7IKKr(   )r   r   r   r   r   s   @r&   r   r     s    L Lr(   r   c                   T    \ rS rSrSrS r\S 5       r\S 5       r\S 5       r	S r
Srg	)
CloseReasoni  z7Contains information about why a WebSocket was closed. c                 ,   Xl          [        R                  " U5      R                  U l        X l        g! [
         aU    SUs=::  a  S::  a  O  O	SU l         N*SUs=::  a  S::  a  O  O	SU l         NCSUs=::  a  S::  a  O  O	S	U l         N\S
U l         Nef = f)z=
Constructor.

:param int code:
:param Optional[str] reason:
  i  RFC_RESERVEDi  i  IANA_RESERVEDi  i  PRIVATE_RESERVEDINVALID_CODEN)_codewsframeprotor   name_namer   _reasonr1   coder   s      r&   r2   CloseReason.__init__  s     

	,%11$7<<DJ   	,t#t#+
%%,
%%/
+
	,s!   %4 !BB0B	BBc                     U R                   $ )z$(Read-only) The numeric close code. )r   r0   s    r&   r   CloseReason.code       zzr(   c                     U R                   $ )z+(Read-only) The human-readable close code. )r   r0   s    r&   r   CloseReason.name  r   r(   c                     U R                   $ )z((Read-only) An arbitrary reason string. )r   r0   s    r&   r   CloseReason.reason  s     ||r(   c                     U R                   R                   SU R                   SU R                   SU R                   S3$ )z#Show close code, name, and reason. z<code=z, name=z	, reason=r   )r   rG   r   r   r   r0   s    r&   r   CloseReason.__repr__  s?    ..))*		{'$))Idkk]!M 	Mr(   )r   r   r   N)rG   rH   rI   rJ   rK   r2   propertyr   r   r   r   rM   rN   r(   r&   r   r     sL    B*      Mr(   r   c                   *    \ rS rSrSrS rS rS rSrg)Futurei  z9Represents a value that will be available in the future. c                 F    SU l         [        R                  " 5       U l        g)zConstructor. N)_valuer"   Event_value_eventr0   s    r&   r2   Future.__init__  s     JJLr(   c                 D    Xl         U R                  R                  5         g)z<
Set a value, which will notify any waiters.

:param value:
N)r   r   set)r1   rB   s     r&   	set_valueFuture.set_value  s     r(   c                 j   #    U R                   R                  5       I Sh  vN   U R                  $  N7f)zd
Wait for this future to have a value, then return it.

:returns: The value set by ``set_value()``.
N)r   r   r   r0   s    r&   
wait_valueFuture.wait_value(  s.      $$&&&{{ 	's   313)r   r   N)	rG   rH   rI   rJ   rK   r2   r   r   rM   rN   r(   r&   r   r     s    D)
 r(   r   c                       \ rS rSrSrS r\S 5       r\S 5       r\S 5       r	\S 5       r
\S 5       rS	S	S
.S jrS	S	S.S jrSrg	)WebSocketRequesti2  z
Represents a handshake presented by a client to a server.

The server may modify the handshake or leave it as is. The server should
call ``accept()`` to finish the handshake and obtain a connection object.
c                     Xl         X l        g)zZ
Constructor.

:param WebSocketConnection connection:
:type event: wsproto.events.Request
N_connection_event)r1   re   events      r&   r2   WebSocketRequest.__init__9  s     &r(   c                 .    U R                   R                  $ )zQ
HTTP headers represented as a list of (name, value) pairs.

:rtype: list[tuple]
)r   rP   r0   s    r&   r   WebSocketRequest.headersC  s     {{(((r(   c                 .    U R                   R                  $ )z&
The requested URL path.

:rtype: str
)r   targetr0   s    r&   rq   WebSocketRequest.pathL  s     {{!!!r(   c                 @    [        U R                  R                  5      $ )zB
A tuple of protocols proposed by the client.

:rtype: tuple[str]
)tupler   rO   r0   s    r&   proposed_subprotocols&WebSocketRequest.proposed_subprotocolsU  s     T[[--..r(   c                 .    U R                   R                  $ )z;
The connection's local endpoint.

:rtype: Endpoint or str
)r   localr0   s    r&   r  WebSocketRequest.local^  s     %%%r(   c                 .    U R                   R                  $ )z<
The connection's remote endpoint.

:rtype: Endpoint or str
)r   remoter0   s    r&   r
  WebSocketRequest.remoteg  s     &&&r(   NsubprotocolrP   c                   #    Uc  / nU R                   R                  U R                  X5      I Sh  vN   U R                   $  N7f)aI  
Accept the request and return a connection object.

:param subprotocol: The selected subprotocol for this connection.
:type subprotocol: str or None
:param extra_headers: A list of 2-tuples containing key/value pairs to
    send as HTTP headers.
:type extra_headers: list[tuple[bytes,bytes]] or None
:rtype: WebSocketConnection
N)r   _acceptr   )r1   r  rP   s      r&   acceptWebSocketRequest.acceptp  sD       M&&t{{KOOO 	Ps   /AAA)rP   r   c                   #    U=(       d    / nU=(       d    SnU R                   R                  XU5      I Sh  vN   g N7f)a  
Reject the handshake.

:param int status_code: The 3 digit HTTP status code. In order to be
    RFC-compliant, this should NOT be 101, and would ideally be an
    appropriate code in the range 300-599.
:param list[tuple[bytes,bytes]] extra_headers: A list of 2-tuples
    containing key/value pairs to send as HTTP headers.
:param body: If provided, this data will be sent in the response
    body, otherwise no response body will be sent.
:type body: bytes or None
r(   N)r   _reject)r1   r   rP   r   s       r&   rejectWebSocketRequest.reject  s6      &+{s&&{4HHHs   6A >A r   )rG   rH   rI   rJ   rK   r2   r   r   rq   r  r  r
  r  r  rM   rN   r(   r&   r   r   2  s     ) ) " " / / & & ' ' +/d    :>D I Ir(   r   c                f   Su  p#[        U [        R                  5      (       a  U R                  nO7[        U [        R                  5      (       a  U R
                  R                  nSnU(       a7  U(       a  UR                  5       OUR                  5       tpEn[        XEU5      nU$ [        U 5      nU$ )a  
Construct an endpoint from a stream.

:param trio.Stream stream:
:param bool local: If true, return local endpoint. Otherwise return remote.
:returns: An endpoint instance or ``repr()`` for streams that cannot be
    represented as an endpoint.
:rtype: Endpoint or str
r/   T)
r!   r"   SocketStreamsocket	SSLStreamtransport_streamgetsocknamegetpeernameEndpointrepr)r   r  r  is_ssladdrrb   _endpoints           r&   _get_stream_endpointr#    s     !NF&$++,,	FDNN	+	+((//16++-F<N<N<PQD/ O <Or(   c                   l   \ rS rSrSr\R                  " 5       rSSSS\\	S.S jr
\S 5       r\S 5       r\S 5       r\S	 5       r\S
 5       r\S 5       r\S 5       r\S 5       rS&S jrS rS rS'S jrS'S jrS rS rS rS rS rS rS'S jrS r S r!S r"S r#S r$S r%S  r&S! r'S" r(S# r)S$ r*S%r+g)(r|   i  zA WebSocket connection. Nrp   c                   SU l         [        U R                  R                  5      U l        Xl        [        R                  " 5       U l        X l	        SU l
        / U l        Xl        SU l        UR                  (       a  [        X4UU=(       d    / S9U l        OSU l        X@l        SU l        ['        5       U l        SU l        ['        5       U l        SU l        [        R0                  " U5      u  U l        U l        [7        5       U l        [;        5       U l        [        R>                  " 5       U l         [        R>                  " 5       U l!        [        R>                  " 5       U l"        g)a  
Constructor.

Generally speaking, users are discouraged from directly instantiating a
``WebSocketConnection`` and should instead use one of the convenience
functions in this module, e.g. ``open_websocket()`` or
``serve_websocket()``. This class has some tricky internal logic and
timing that depends on whether it is an instance of a client connection
or a server connection. The convenience functions handle this complexity
for you.

:param SocketStream stream:
:param ws_connection wsproto.WSConnection:
:param str host: The hostname to send in the HTTP request headers. Only
    used for client connections.
:param str path: The URL path for this connection.
:param list client_subprotocols: A list of desired subprotocols. Only
    used for client connections.
:param list[tuple[bytes,bytes]] client_extra_headers: Extra headers to
    send with the connection request. Only used for client connections.
:param int message_queue_size: The maximum number of messages that will be
    buffered in the library's internal message queue.
:param int max_message_size: The maximum message size as measured by
    ``len()``. If a message is received that is larger than this size,
    then the connection is closed with code 1009 (Message Too Big).
Nr   T)ra   r   rO   rP   r(   )#_close_reasonnextr   CONNECTION_ID_id_streamr"   StrictFIFOLock_stream_lock_wsproto_message_size_message_parts_max_message_size_reader_runningclientr   _initial_request_path_subprotocolr  _handshake_headers_reject_status_reject_headers_reject_bodyopen_memory_channel_send_channel_recv_channelr   _pingsr   _connection_proposalr   r   _close_handshake#_for_testing_peer_closed_connection)	r1   r   ws_connectionra   rq   rr   rs   rQ   rR   s	            r&   r2   WebSocketConnection.__init__  s   B 59445 //1%79!1#7>D028b8:D! %)D!
+/"''$w151I1I2 .D.!m %+H!  $zz| !%

 48::<0r(   c                     U R                   $ )zq
(Read-only) The reason why the connection was or is being closed,
else ``None``.

:rtype: Optional[CloseReason]
)r&  r0   s    r&   closedWebSocketConnection.closed  s     !!!r(   c                 .    U R                   R                  $ )z'(Read-only) Is this a client instance? r-  r2  r0   s    r&   	is_clientWebSocketConnection.is_client  s     }}###r(   c                 8    U R                   R                  (       + $ )z'(Read-only) Is this a server instance? rG  r0   s    r&   	is_serverWebSocketConnection.is_server  s     ==''''r(   c                 *    [        U R                  SS9$ )z@
The local endpoint of the connection.

:rtype: Endpoint or str
Tr  r#  r*  r0   s    r&   r  WebSocketConnection.local	  s     $DLL==r(   c                 *    [        U R                  SS9$ )zA
The remote endpoint of the connection.

:rtype: Endpoint or str
FrN  rO  r0   s    r&   r
  WebSocketConnection.remote  s     $DLL>>r(   c                     U R                   $ )z
The requested URL path. For clients, this is set when the connection is
instantiated. For servers, it is set after the handshake completes.

:rtype: str
)r4  r0   s    r&   rq   WebSocketConnection.path  s     zzr(   c                     U R                   $ )z
(Read-only) The negotiated subprotocol, or ``None`` if there is no
subprotocol.

This is only valid after the opening handshake is complete.

:rtype: str or None
)r5  r0   s    r&   r  WebSocketConnection.subprotocol%  s        r(   c                     U R                   $ )z
The HTTP headers that were sent by the remote during the handshake,
stored as 2-tuples containing key/value pairs. Header keys are always
lower case.

:rtype: tuple[tuple[str,str]]
)r6  r0   s    r&   handshake_headers%WebSocketConnection.handshake_headers1  s     &&&r(   c                    #    [        5          U R                  X5      I Sh  vN   SSS5        g N! , (       d  f       g= f7f)a  
Close the WebSocket connection.

This sends a closing frame and suspends until the connection is closed.
After calling this method, any further I/O on this WebSocket (such as
``get_message()`` or ``send_message()``) will raise
``ConnectionClosed``.

This method is idempotent: it may be called multiple times on the same
connection without any errors.

:param int code: A 4-digit code number indicating the type of closure.
:param str reason: An optional string describing the closure.
N)r*   _acloser   s      r&   r_   WebSocketConnection.aclose<  s2      )*,,t,,, +*, +*s$   A202	A2
A Ac                   #    U R                   (       a  g  U R                  R                  [        R                  :X  a2  [        SS 5      U l         U R                  [        XS95      I S h  vN   ORU R                  R                  [        R                  [        R                  4;   a  U R                  R                  5         U R                  R                  5       I S h  vN   U R                  R                  5       I S h  vN   U R!                  5       I S h  vN   g  N NA N!! [         a     N+f = f N! U R!                  5       I S h  vN    f = f7f)Nr   r   r   )r&  r-  stater   OPENr   _sendr   
CONNECTING	REJECTINGr?  r   r<  r_   r   r   _close_streamr   s      r&   r[  WebSocketConnection._acloseN  s     	'}}""o&:&:: &1t%<"jjd!JKKK$$)C)C#--)/ /%%))+ $$++---'',,... $$&&& L .. 		 '$$$&&&s   EAD% *D+A4D% D! !D% D#D% ED5ED% !D% #D% %
D2/D7 1D22D7 5E7EEEEc                    #     U R                   R                  5       I Sh  vN nU$  N! [        R                  [        R                  4 a    [        U R                  5      Sef = f7f)aC  
Receive the next WebSocket message.

If no message is available immediately, then this function blocks until
a message is ready.

If the remote endpoint closes the connection, then the caller can still
get messages sent prior to closing. Once all pending messages have been
retrieved, additional calls to this method will raise
``ConnectionClosed``. If the local endpoint closes the connection, then
pending messages are discarded and calls to this method will immediately
raise ``ConnectionClosed``.

:rtype: str or bytes
:raises ConnectionClosed: if the connection is closed.
N)r<  receiver"   ClosedResourceErrorEndOfChannelr   r&  )r1   messages     r&   get_messageWebSocketConnection.get_messageh  sb     "	A ..6688G  9(($*;*;< 	A"4#5#56D@	As%   A(* (* A(* ;A%%A(c                   #    U R                   (       a  [        U R                   5      eXR                  ;   a  [        SU S35      eUc+  [        R
                  " S[        R                  " S5      5      n[        R                  " 5       nX R                  U'   U R                  [        US95      I Sh  vN   UR                  5       I Sh  vN   g N N7f)a  
Send WebSocket ping to remote endpoint and wait for a correspoding pong.

Each in-flight ping must include a unique payload. This function sends
the ping and then waits for a corresponding pong from the remote
endpoint.

*Note: If the remote endpoint recieves multiple pings, it is allowed to
send a single pong. Therefore, the order of calls to ``ping()`` is
tracked, and a pong will wake up its corresponding ping as well as all
previous in-flight pings.*

:param payload: The payload to send. If ``None`` then a random 32-bit
    payload is created.
:type payload: bytes or None
:raises ConnectionClosed: if connection is closed.
:raises ValueError: if ``payload`` is identical to another in-flight
    ping.
zPayload value z is already in flight.Nz!I    payload)r&  r   r=  r   structpackrandomgetrandbitsr"   r   ra  r   r   )r1   rp  r   s      r&   pingWebSocketConnection.ping  s     ( "4#5#566kk!~gY6LMNN?kk$(:(:2(>?G

$Gjjg.///jjl 	0s$   B1C3C4CCCCc                    #    U R                   (       a  [        U R                   5      eU R                  [        US95      I Sh  vN   g N7f)z
Send an unsolicted pong.

:param payload: The pong's payload. If ``None``, then no payload is
    sent.
:type payload: bytes or None
:raises ConnectionClosed: if connection is closed
ro  N)r&  r   ra  r   )r1   rp  s     r&   pongWebSocketConnection.pong  s8      "4#5#566jjg.///s   AAA
Ac                    #    U R                   (       a  [        U R                   5      e[        U[        5      (       a
  [	        US9nO*[        U[
        5      (       a
  [        US9nO[        S5      eU R                  U5      I Sh  vN   g N7f)z
Send a WebSocket message.

:param message: The message to send.
:type message: str or bytes
:raises ConnectionClosed: if connection is closed, or being closed
datazmessage must be str or bytesN)	r&  r   r!   r   r   bytesr   r   ra  )r1   rj  r   s      r&   send_message WebSocketConnection.send_message  sm      "4#5#566gs##W-E'' g.E;<<jjs   BBBBc                 N    U R                   (       a  SOSnU SU R                   3$ )zConnection ID and type. r2  r   -)rH  r)  )r1   type_s     r&   __str__WebSocketConnection.__str__  s$     NN$(($$r(   c                    #    X l         UR                  U l        U R                  [	        U R                   US95      I Sh  vN   U R
                  R                  5         g N7f)a(  
Accept the handshake.

This method is only applicable to server-side connections.

:param wsproto.events.Request request:
:param subprotocol:
:type subprotocol: str or None
:param list[tuple[bytes,bytes]] extra_headers: A list of 2-tuples
    containing key/value pairs to send as HTTP headers.
r  N)r5  r   r4  ra  r   r   r   )r1   r   r  rP   s       r&   r  WebSocketConnection._accept  sX      (^^
jj)d6G6G') * 	* 	*  "	*s   >A" A  A"c                   #    U(       a4  UR                  S[        [        U5      5      R                  S5      45        [	        X[        U5      S9nU R                  U5      I Sh  vN   U(       a"  [        US9nU R                  U5      I Sh  vN   [        SS5      U l	        U R                  R                  5         g NY N27f)ad  
Reject the handshake.

:param int status_code: The 3 digit HTTP status code. In order to be
    RFC-compliant, this must not be 101, and should be an appropriate
    code in the range 300-599.
:param list[tuple[bytes,bytes]] headers: A list of 2-tuples containing
    key/value pairs to send as HTTP headers.
:param bytes body: An optional response body.
zContent-lengthascii)r   r   has_bodyNr{  i  zRejected WebSocket handshake)appendr   lenencoder   boolra  r   r   r&  r?  r   )r1   r   r   r   reject_connreject_bodys         r&   r  WebSocketConnection._reject  s      NN,c#d)n.C.CG.LMN&;$Z!jj%%%$$/K**[)))(/MN!!# 	& *s$   A#C%B?&(CC1CCc                 z  #    [         R                  R                  nU R                  R                  [
        R                  :X  a,  U R                  R                  [        UR                  S95        U R                  c  U R                  U5      I Sh  vN   SU l        U R                  R                  5         g N&7f)z
If a stream is closed outside of this class, e.g. due to network
conditions or because some other code closed our stream object, then we
cannot perform the close handshake. We just need to clean up internal
state.
)r   NF)r   r   ABNORMAL_CLOSUREr-  r_  r   r`  sendr   rB   r&  _close_web_socketr1  r?  r   )r1   close_reasons     r&   _abort_web_socket%WebSocketConnection._abort_web_socket  s      $//@@==/"6"66MML4F4FGH%((666$ 	!!#	 7s   BB;B9'B;c                    #    SU l          [        5          U R                  R                  5       I Sh  vN   SSS5        g N! , (       d  f       g= f! [        R
                   a     gf = f7f)zClose the TCP connection. FN)r1  r*   r*  r_   r"   BrokenResourceErrorr0   s    r&   rd  !WebSocketConnection._close_stream  sX     $	,.ll))+++ /.+ /.'' 		sZ   A.
A AAAA  A.A
AA A.A A+(A.*A++A.c                    #    [        X5      U l        [        U R                  5      n[        R	                  SX5        U R
                  R                  5       I Sh  vN   g N7f)z
Mark the WebSocket as closed. Close the message channel so that if any
tasks are suspended in get_message(), they will wake up with a
ConnectionClosed exception.
z%s websocket closed %rN)r   r&  r   rx   ry   r;  r_   )r1   r   r   r%   s       r&   r  %WebSocketConnection._close_web_socket  sK      )6t112-t9  '')))s   AA#A!A#c                    #    U R                   (       d  [        S5      eU R                  c  [        S5      eU R                  R                  5       I Sh  vN nSU l        U$  N7f)z
Return a proposal for a WebSocket handshake.

This method can only be called on server connections and it may only be
called one time.

:rtype: WebSocketRequest
z1This method is only valid for server connections.NzTNo proposal available. Did you call this method multiple times or at the wrong time?)rK  RuntimeErrorr>  r   )r1   proposals     r&   r    WebSocketConnection._get_request  sb      ~~RSS$$,  8 9 922==??$(! @s   AA$A"A$c                 X   #    [        X5      nU R                  R                  U5        g7f)z
Handle a connection request.

This method is async even though it never awaits, because the event
dispatch requires an async function.

:param event:
N)r   r>  r   )r1   r   r  s      r&   _handle_request_event)WebSocketConnection._handle_request_event"  s%      $D0!!++H5s   (*c                    #    UR                   U l        [        UR                  5      U l        U R
                  R                  5         g7f)zQ
Handle an AcceptConnection event.

:param wsproto.eventsAcceptConnection event:
N)r  r5  r  rP   r6  r   r   r1   r   s     r&   _handle_accept_connection_event3WebSocketConnection._handle_accept_connection_event.  s:      "--"'(;(;"<  "s   AA	c                    #    UR                   U l        [        UR                  5      U l        UR
                  (       d  [        U R                  U R                  SS9eg7f)z1
Handle a RejectConnection event.

:param event:
Nr   )r   r7  r  r   r8  r  r   r  s     r&   _handle_reject_connection_event3WebSocketConnection._handle_reject_connection_event8  sR      $//$U]]3~~$T%8%8$:N:N  s   AAc                    #    U =R                   UR                  -  sl         UR                  (       a)  [        U R                  U R
                  U R                   S9eg7f)z+
Handle a RejectData event.

:param event:
r  N)r9  r|  body_finishedr   r7  r8  r  s     r&   _handle_reject_data_event-WebSocketConnection._handle_reject_data_eventD  sP      	UZZ'$T%8%8$:N:N&&( ( s   AAc                 <  #    U R                   R                  [        R                  :X  ao  [	        UR
                  UR                  =(       d    S5      U l        U R                  R                  5         U R                  UR                  5       5      I Sh  vN   U R                  UR
                  UR                  =(       d    S5      I Sh  vN   U R                  R                  5         U R                  (       a  U R                  5       I Sh  vN   gg N NK N
7f)zE
Handle a close event.

:param wsproto.events.CloseConnection event:
N)r-  r_  r   REMOTE_CLOSINGr   r   r   r&  r@  r   ra  responser  r?  rK  rd  r  s     r&   _handle_close_connection_event2WebSocketConnection._handle_close_connection_eventO  s      ==/"@"@@ "-UZZ9M!ND4488:**U^^-...$$UZZ1EFFF!!#
 >>$$&&&  /F 's7   BDD6DDADDDDDc                   #    U =R                   [        UR                  5      -  sl         U R                  R	                  UR                  5        U R                   U R
                  :  az  SU R
                   S3nSU l         / U l        [        SU5      U l        U R                  [        SUS95      I Sh  vN   U R                  R                  5       I Sh  vN   SU l        gUR                  (       ae  [        U[        5      (       a  SOS	R!                  U R                  5      nSU l         / U l         U R"                  R%                  U5      I Sh  vN   gg N N N
! [&        R(                  [&        R*                  4 a     gf = f7f)
zo
Handle a message event.

:param event:
:type event: wsproto.events.BytesMessage or wsproto.events.TextMessage
zExceeded maximum message size: z bytesr   i  r^  NFr(   ri   )r.  r  r|  r/  r  r0  r   r&  ra  r   r<  r_   r1  message_finishedr!   r   joinr;  r  r"   rh  r  )r1   r   errmsgs       r&   _handle_message_event)WebSocketConnection._handle_message_eventd  sN     	c%**o-""5::. 6 663D4J4J3K6RC!"D"$D!,T3!7D**_$sCDDD$$++---#(D ##$UL993rd))* !"D"$D((--c222 $ E- 3,,d.F.FG  	s[   B3F5E6!FEAF6E! EE! FFE! !$FFFFc                    #    [         R                  SXR                  5        U R                  UR	                  5       5      I Sh  vN   g N7f)z
Handle a PingReceived event.

Wsproto queues a pong frame automatically, so this handler just needs to
send it.

:param wsproto.events.Ping event:
z
%s ping %rN)rx   ry   rp  ra  r  r  s     r&   _handle_ping_event&WebSocketConnection._handle_ping_event  s2      	\47jj)***s   AAAAc                 f  #    [        UR                  5      n U R                  U   nU R                  (       ag  U R                  R	                  S5      u  p1X#:w  a  SOSn[
        R                  SXU5        UR                  5         X#:X  a  gU R                  (       a  Mf  gg! [         a     gf = f7f)a  
Handle a PongReceived event.

When a pong is received, check if we have any ping requests waiting for
this pong response. If the remote endpoint skipped any earlier pings,
then we wake up those skipped pings, too.

This function is async even though it never awaits, because the other
event handlers are async, too, and event dispatch would be more
complicated if some handlers were sync.

:param event:
Nr   z [skipped]  z%s pong%s%r)r}  rp  r=  KeyErrorpopitemrx   ry   r   )r1   r   rp  keyskippeds        r&   _handle_pong_event&WebSocketConnection._handle_pong_event  s      &	KK(E
 kk,,Q/JC'.~m3GLLs;IIK~ kkk	  	 	s.   B1B! A5B1B1!
B.+B1-B..B1c                   #    [         U R                  [        U R                  [        U R
                  [        U R                  [        U R                  [        U R                  [        U R                  [        U R                  [         U R                  0	nU R"                  (       a$   U R%                  U R"                  5      I Sh  vN   U R*                   ISh  vN   U R(                  (       Ga^  U R,                  R/                  5        H:  n[1        U5      n X   n[2        R5                  SU U5        U" U5      I Sh  vN   M<      U R:                  R=                  [>        5      I Sh  vN n[I        U5      S:X  aW  [2        R5                  SU 5        U R,                  RJ                  [L        RN                  :w  a  U RG                  5       I Sh  vN   Ox[2        R5                  SU [I        U5      5        U R,                  RJ                  [L        RN                  :w  a   U R,                  RQ                  U5        U R(                  (       a  GM^  SSS5      ISh  vN   [2        R5                  S	U 5        g GN! [&         a    SU l         GNf = f GN GNT! [6         a    [2        R9                  SU U5         GM  [&         a    SU l           GM  f = f GNi! [@        RB                  [@        RD                  4 a    U RG                  5       I Sh  vN     M  f = f GNK! [R        RT                  RV                   ao  n[2        R5                  SX5        URX                  (       a$  U R%                  URX                  5      I Sh  vN    U R[                  5       I Sh  vN     SnAGNlSnAff = f GNU! , ISh  vN  (       d  f       GNk= f7f)
z@A background task that reads network data and generates events. NFz%s received event: %sz$%s received unknown event type: "%s"r   z*%s received zero bytes (connection closed)z%s received %d bytesz%s remote protocol error: %sz%s reader task finished).r   r  r   r  r   r  r   r  r   r  r   r  r   r  r   r  r   r3  ra  r   r1  r;  r-  eventstyperx   ry   r  warningr*  receive_someRECEIVE_BYTESr"   r  rh  r  r  r_  r   CLOSEDreceive_datawsproto	utilitiesRemoteProtocolError
event_hintrd  )r1   handlersr   
event_typer   r|  r  s          r&   r    WebSocketConnection._reader_task  s     dBB$44T@@$))$))dBB66T//33

   -jj!6!6777 %%%&&&!]]113E!%eJ
"*"6%<d&(%en,, 4!%!:!:=!IID t9>LL!M }}**o.D.DD"446663T3t9E==&&/*@*@@32248C &&& &%R 	.5[ 8# -',$- & -# ('Mt&( (+ /4, J00$2J2JK 00222 7 #,,@@ 3%CTO>>"&**S^^"<<<"00222	3G &%%%sS  B$O'I9 I6I9 
OJO;N2&J JJN2
"K,K-K1A N2LAN2 L;N2ON/O6I9 9J
OJOJ!K8N2<KN2KN2K7LLLN2LN2N,=AN'NN'NN'!N2'N,,N2/O2O
8N;9O
Oc                   #    U R                   R                  U5      nU R                   ISh  vN   [        R	                  SU [        U5      5         U R                  R                  U5      I Sh  vN   SSS5      ISh  vN   g NY N! [        R                  [        R                  4 a0    U R                  5       I Sh  vN    [        U R                  5      Sef = f N`! , ISh  vN  (       d  f       g= f7f)z
Send an event to the remote WebSocket.

The reader task and one or more writers might try to send messages at
the same time, so this method uses an internal lock to serialize
requests to send data.

:param wsproto.events.Event event:
Nz%s sending %d bytes)r-  r  r,  rx   ry   r  r*  send_allr"   r  rh  r  r   r&  )r1   r   r|  s      r&   ra  WebSocketConnection._send  s      }}!!%($$$LL.c$i@Ell++D111 %$$ 2,,d.F.FG E,,...&t'9'9:DE	 %$$$st   ,C?BC?!C%B2B
3B7C?C#C?
B7C CC  C%#C?%C<+C.,C<8C?)r?  r&  r>  r@  r6  r)  r3  r0  r/  r.  r   r4  r=  r1  r<  r9  r8  r7  r;  r*  r,  r5  r-  )r   Nr   ),rG   rH   rI   rJ   rK   	itertoolscountr(  MESSAGE_QUEUE_SIZEMAX_MESSAGE_SIZEr2   r   rD  rH  rK  r  r
  rq   r  rX  r_   r[  rk  ru  rx  r~  r  r  r  r  rd  r  r   r  r  r  r  r  r  r  r  r   ra  rM   rN   r(   r&   r|   r|     s>   #OO%M6: t-)D@L " " $ $ ( ( > > ? ?   	! 	! ' '-$'4.>0 $%
#$$,$"	*$
6#
	('*<
+:>6@Er(   r|   c                   4    \ rS rSrSrS r\S 5       rS rSr	g)r  i  z"Represents a connection endpoint. c                 <    [        U5      U l        X l        X0l        g r   )r   addressrb   r  )r1   r  rb   r  s       r&   r2   Endpoint.__init__  s    !'*	r(   c                 h   U R                   (       a  SOSnU R                  S:X  a  U R                   (       a!  U R                  S:X  a  U R                   (       a  SnOS[        U R                  5      -   nU R                  R                  S:X  a  U SU R                   U 3$ U S	U R                   S
U 3$ )zKReturn a URL representation of a TCP endpoint, e.g.
``ws://127.0.0.1:80``. r   r   rm   rn   ri   ro      z://z://[])r  rb   r   r  version)r1   r   port_strs      r&   r   Endpoint.url	  s     ++4IIODKKIIHS^+H<<1$XSxj99dll^1XJ77r(   c                 V    SU R                    SU R                   SU R                   S3$ )z Return endpoint info as string. zEndpoint(address="z", port=z	, is_ssl=))r  rb   r  r0   s    r&   r   Endpoint.__repr__  s*    #DLL>$))Idkk]Z[\\r(   )r  r  rb   N)
rG   rH   rI   rJ   rK   r2   r   r   r   rM   rN   r(   r&   r  r    s$    - 8 8]r(   r  c                   v    \ rS rSrSrS\\\\S.S jr\	S 5       r
\	S 5       r\R                  S.S	 jrS
 rSrg)r   i  z
WebSocket server.

The server class handles incoming connections on one or more ``Listener``
objects. For each incoming connection, it creates a ``WebSocketConnection``
instance and starts some background tasks,
Nr   c                    [        U5      S:X  a  [        S5      eXl        X0l        X l        X@l        XPl        X`l        Xpl        g)a  
Constructor.

Note that if ``host`` is ``None`` and ``port`` is zero, then you may get
multiple listeners that have _different port numbers!_ See the
``listeners`` property.

:param handler: the async function called with a :class:`WebSocketRequest`
    on each new connection.  The call will be made
    once the HTTP handshake completes, which notably implies that the
    connection's `path` property will be valid.
:param listeners: The WebSocket will be served on each of the listeners.
:param handler_nursery: An optional nursery to spawn connection tasks
    inside of. If ``None``, then a new nursery will be created
    internally.
:param float connect_timeout: The number of seconds to wait for a client
    to finish connection handshake before timing out.
:param float disconnect_timeout: The number of seconds to wait for a client
    to finish the closing handshake before timing out.
r   z)Listeners must contain at least one item.N)	r  r   _handler_handler_nursery
_listeners_message_queue_sizer0  _connect_timeout_disconnect_timeout)r1   r   r   r   rQ   rR   rS   rT   s           r&   r2   WebSocketServer.__init__%  sD    0 y>QHII /##5 !1 /#5 r(   c                     [        U R                  5      S:  a  [        S5      eU R                  S   n UR                  $ ! [
         a    [        S[        U5       35      Sef = f)ao  Returns the requested or kernel-assigned port number.

In the case of kernel-assigned port (requested with port=0 in the
constructor), the assigned port will be reflected after calling
starting the `listen` task.  (Technically, once listen reaches the
"started" state.)

This property only works if you have a single listener, and that
listener must be socket-based.
r   z>Cannot get port because this server has more than 1 listeners.r   z"This socket does not have a port: N)r  r  r  r   rb   AttributeErrorr  )r1   listeners     r&   rb   WebSocketServer.portG  sq     t!#  * + +>>!$	`==  	`!CDNCSTU[__	`s   A #A$c                    / nU R                    H  nSu  p4[        U[        R                  5      (       a  UR                  nO7[        U[        R
                  5      (       a  UR                  R                  nSnU(       a4  UR                  5       nUR                  [        US   US   U5      5        M  UR                  [        U5      5        M     U$ )z
Return a list of listener metadata. Each TCP listener is represented as
an ``Endpoint`` instance. Other listener types are represented by their
``repr()``.

:returns: Listeners
:rtype list[Endpoint or str]:
r/   Tr   r   )r  r!   r"   SocketListenerr  SSLListenertransport_listenerr  r  r  r  )r1   r   r  r  r  socknames         r&   r   WebSocketServer.listeners\  s     	H(NF(D$7$788!Hd&6&677!44;;!--/  (1+x{F!KL  h0 ( r(   r   c                D  #    [         R                  " 5        ISh  vN n[        [         R                  U R                  U R
                  U R                  S9nUR                  U5      I Sh  vN   [        R                  SSR                  U R                   Vs/ sH  n[        U5      PM     sn5      5        UR                  U 5        [         R                  " 5       I Sh  vN   SSS5      ISh  vN   g N Ns  snf  N N! , ISh  vN  (       d  f       g= f7f)uw  
Start serving incoming connections requests.

This method supports the Trio nursery start protocol: ``server = await
nursery.start(server.run, …)``. It will block until the server is
accepting connections and then return a :class:`WebSocketServer` object.

:param task_status: Part of the Trio nursery start protocol.
:returns: This method never returns unless cancelled.
N)r   zListening on %s,)r"   rX   r   serve_listeners_handle_connectionr  r  startrx   ry   r  r   r   startedsleep_forever)r1   r   r   r  ls        r&   r   WebSocketServer.runu  s      $$&&'%d&:&:'' $ 5 57O --000LL*$..9.Q#a&.9:<%$$&&& '&& 19& '&&&su   D C9D AD-C;.-DC=/4D#D$D(D 3D4D ;D=DD DDDD c           	      4  #    [         R                  " 5        ISh  vN n[        U[        [        R
                  5      U R                  U R                  S9nUR                  UR                  5        [         R                  " U R                  5       nUR                  5       I Sh  vN nSSS5        WR                  (       aD  UR                  R                  5         UR!                  5       I Sh  vN    SSS5      ISh  vN   g U R#                  W5      I Sh  vN   [         R                  " U R$                  5         UR!                  5       I Sh  vN   SSS5        SSS5      ISh  vN   g GNY N! , (       d  f       N= f N N Np N9! , (       d  f       N== f! [         R                  " U R$                  5         UR!                  5       I Sh  vN    SSS5        f ! , (       d  f       f = f= f N! , ISh  vN  (       d  f       g= f7f)z
Handle an incoming connection by spawning a connection background task
and a handler task inside a new nursery.

:param stream:
:type stream: trio.abc.Stream
Nr   )r"   rX   r|   r   r
   r   r  r0  r~   r   move_on_afterr  r   cancelled_caughtcancel_scopecancelr_   r  r  )r1   r   r   re   connect_scoper   s         r&   r   "WebSocketServer._handle_connection  s|     $$&&',V^223#'#;#;!%!7!79J z667##D$9$9:m * 7 7 99 ;--$$++-mmo%% '&&.mmG,,,''(@(@A %++--- B '&& : ;: & ' -
 . BAT''(@(@A %++--- BAA '&&&s  HE5HA3G>E:'E8(E:,AG>2F3G>8HFH
F$FF$# G>FFFG>$H/G<0H8E::
F	G>HF$F
F!	G>$!G9G(	GG(		G9(
G62G99G><H>HHHH)r  r  r  r  r  r0  r  )rG   rH   rI   rJ   rK   r  r  CONN_TIMEOUTr2   r   rb   r   r"   TASK_STATUS_IGNOREDr   r   rM   rN   r(   r&   r   r     s]     ?C-)<' 6D ` `(  0 (,'?'? '*.r(   r   r   )Rr5   collectionsr   
contextlibr   	functoolsr   	ipaddressr   r  loggingrs  rt   rq  urllib.parser   typingr   r   r	   r"   trio.abcr  r
   r   wsproto.connectionr   wsproto.frame_protocolframe_protocolr   wsproto.eventsr   r   r   r   r   r   r   r   r   wsproto.utilitiesversion_infoexceptiongroupr   r  mapint__version__splitr=   r  r  r  r  	getLoggerrx   r'   r*   rg   rZ   r   r   r   r   r   r  r   	Exceptionr^   r\   r`   r   r   r   r   r   r#  abcAsyncResourcer|   r  r   rN   r(   r&   <module>r&     s   
 # *       
   ( (   0 . -
 
 
 g1#c4#3#3#9#9##>r#BCDwN   			+	,<* *> HL)<L \75 75v T)<L=@'Pd)<L \'PT!+T)<L!+H!,J T)<L$P *<L8 -?%|#1I1I1.hY G GL> L;y ;(L L2)M )MX 4]I ]I@0R	E$((00 R	Ej] ]:H. H.r(   