
    g                        d 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ZddlZddl	m
Z
 ddlZddlZddlmZmZ ddlmZ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mZ dd
l m!Z! ddlm"Z" ddl#m$Z$ ddl%m&Z& ddl'm(Z( ddl)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4 ddl5m6Z6 e*r'ddl7m8Z8  G d de8      Z9 G d de8      Z: G d de8      Z;dZ< G d de=      Z> G d de>      Z? G d de=      Z@ G d d eA      ZB G d! d"ej                  j                        ZEd#e,d$e,d%dfd&ZF G d' d(ej                        ZH G d) d*eA      ZI G d+ d,eA      ZJ G d- d.eH      ZK G d/ d0e"j                        ZMdddddde<ddf	d1e/eNej                  f   d2e-e2d3gdf      d4e-eP   d5e-e2e/deNeQf   gdf      d6e-e.eNe,f      d7e-eP   d8e-eP   d9eRd:e-e0eN      d;e-e!   d%d<fd=ZSy)>a  Implementation of the WebSocket protocol.

`WebSockets <http://dev.w3.org/html5/websockets/>`_ allow for bidirectional
communication between the browser and server. WebSockets are supported in the
current versions of all major browsers.

This module implements the final version of the WebSocket protocol as
defined in `RFC 6455 <http://tools.ietf.org/html/rfc6455>`_.

.. versionchanged:: 4.0
   Removed support for the draft 76 protocol version.
    N)urlparse)Future"future_set_result_unless_cancelled)utf8
native_str
to_unicode)gen
httpclienthttputil)IOLoopPeriodicCallback)StreamClosedErrorIOStream)gen_logapp_log)Resolver)simple_httpclient)Queue)	TCPClient)_websocket_mask)TYPE_CHECKINGcastAnyOptionalDictUnionList	AwaitableCallableTupleType)TracebackType)Protocolc                   ,    e Zd ZdedefdZdedefdZy)_Compressordatareturnc                      y N selfr&   s     F/var/www/openai/venv/lib/python3.12/site-packages/tornado/websocket.pycompressz_Compressor.compress;           modec                      y r)   r*   )r,   r1   s     r-   flushz_Compressor.flush>   r/   r0   N)__name__
__module____qualname__bytesr.   intr3   r*   r0   r-   r%   r%   :   s(    	 	5 		c 	e 	r0   r%   c                   $    e Zd ZdZdededefdZy)_Decompressorr0   r&   
max_lengthr'   c                      y r)   r*   )r,   r&   r;   s      r-   
decompressz_Decompressor.decompressD   r/   r0   N)r4   r5   r6   unconsumed_tailr7   r8   r=   r*   r0   r-   r:   r:   A   s!    	5 	c 	e 	r0   r:   c                       e Zd Z	 ddee   dee   ddfdZdeeef   ded   fdZ	d	eddfd
Z
d	eddfdZdeee      dee   dee   ddfdZy)_WebSocketDelegateN
close_codeclose_reasonr'   c                      y r)   r*   r,   rA   rB   s      r-   on_ws_connection_closez)_WebSocketDelegate.on_ws_connection_closeK   s     r0   messagezAwaitable[None]c                      y r)   r*   r,   rF   s     r-   
on_messagez_WebSocketDelegate.on_messageP   r/   r0   r&   c                      y r)   r*   r+   s     r-   on_pingz_WebSocketDelegate.on_pingS   r/   r0   c                      y r)   r*   r+   s     r-   on_pongz_WebSocketDelegate.on_pongV   r/   r0   typvaluetbc                      y r)   r*   r,   rN   rO   rP   s       r-   log_exceptionz _WebSocketDelegate.log_exceptionY   s     r0   NN)r4   r5   r6   r   r8   strrE   r   r7   rI   rK   rM   r!   BaseExceptionr"   rS   r*   r0   r-   r@   r@   G   s    
 SW	&sm	BJ3-		
	eCJ&7 	HEV<W 		 	$ 		 	$ 		$}-.	 M*	 '		
 	r0   r@   i   c                       e Zd Zy)WebSocketErrorNr4   r5   r6   r*   r0   r-   rX   rX   e       r0   rX   c                       e Zd ZdZy)WebSocketClosedErrorzLRaised by operations on a closed connection.

    .. versionadded:: 3.2
    N)r4   r5   r6   __doc__r*   r0   r-   r\   r\   i   s    
 	r0   r\   c                       e Zd Zy)_DecompressTooLargeErrorNrY   r*   r0   r-   r_   r_   r   rZ   r0   r_   c                   N    e Zd Zddedfdee   dee   dedeeee	f      ddf
dZ
y)_WebSocketParamsNping_intervalping_timeoutmax_message_sizecompression_optionsr'   c                 <    || _         || _        || _        || _        y r)   rb   rc   rd   re   )r,   rb   rc   rd   re   s        r-   __init__z_WebSocketParams.__init__w   s$     +( 0#6 r0   )r4   r5   r6   _default_max_message_sizer   floatr8   r   rU   r   rh   r*   r0   r-   ra   ra   v   sZ     *.(, 98<
7
7 uo
7 	
7
 &d38n5
7 

7r0   ra   c                   v    e Zd ZdZdej
                  j                  dej                  de	ddf fdZ
de	de	ddfd	Zedee   fd
       Zedee   fd       Zedefd       Z	 d+deeeeee	f   f   deddfdZdee   dee   fdZedee   fd       Zdeeee	f      fdZdededeed      fdZdeeef   deed      fdZd,deeef   ddfdZ deddfdZ!deddfdZ"d-dZ#d.dee   dee   ddfdZ$dedefd Z%d!eddfd"Z&d-d#Z'	 d.d$ee   d%ee   ddfd&Z(d- fd'Z)ded(   fd)Z*de+fd*Z, xZ-S )/WebSocketHandlera  Subclass this class to create a basic WebSocket handler.

    Override `on_message` to handle incoming messages, and use
    `write_message` to send messages to the client. You can also
    override `open` and `on_close` to handle opened and closed
    connections.

    Custom upgrade response headers can be sent by overriding
    `~tornado.web.RequestHandler.set_default_headers` or
    `~tornado.web.RequestHandler.prepare`.

    See http://dev.w3.org/html5/websockets/ for details on the
    JavaScript interface.  The protocol is specified at
    http://tools.ietf.org/html/rfc6455.

    Here is an example WebSocket handler that echos back all received messages
    back to the client:

    .. testcode::

      class EchoWebSocket(tornado.websocket.WebSocketHandler):
          def open(self):
              print("WebSocket opened")

          def on_message(self, message):
              self.write_message(u"You said: " + message)

          def on_close(self):
              print("WebSocket closed")

    .. testoutput::
       :hide:

    WebSockets are not standard HTTP connections. The "handshake" is
    HTTP, but after the handshake, the protocol is
    message-based. Consequently, most of the Tornado HTTP facilities
    are not available in handlers of this type. The only communication
    methods available to you are `write_message()`, `ping()`, and
    `close()`. Likewise, your request handler class should implement
    `open()` method rather than ``get()`` or ``post()``.

    If you map the handler above to ``/websocket`` in your application, you can
    invoke it in JavaScript with::

      var ws = new WebSocket("ws://localhost:8888/websocket");
      ws.onopen = function() {
         ws.send("Hello, world");
      };
      ws.onmessage = function (evt) {
         alert(evt.data);
      };

    This script pops up an alert box that says "You said: Hello, world".

    Web browsers allow any site to open a websocket connection to any other,
    instead of using the same-origin policy that governs other network
    access from JavaScript.  This can be surprising and is a potential
    security hole, so since Tornado 4.0 `WebSocketHandler` requires
    applications that wish to receive cross-origin websockets to opt in
    by overriding the `~WebSocketHandler.check_origin` method (see that
    method's docs for details).  Failure to do so is the most likely
    cause of 403 errors when making a websocket connection.

    When using a secure websocket connection (``wss://``) with a self-signed
    certificate, the connection from a browser may fail because it wants
    to show the "accept this certificate" dialog but has nowhere to show it.
    You must first visit a regular HTML page using the same certificate
    to accept it before the websocket connection will succeed.

    If the application setting ``websocket_ping_interval`` has a non-zero
    value, a ping will be sent periodically, and the connection will be
    closed if a response is not received before the ``websocket_ping_timeout``.

    Messages larger than the ``websocket_max_message_size`` application setting
    (default 10MiB) will not be accepted.

    .. versionchanged:: 4.5
       Added ``websocket_ping_interval``, ``websocket_ping_timeout``, and
       ``websocket_max_message_size``.
    applicationrequestkwargsr'   Nc                 `    t        |   ||fi | d | _        d | _        d | _        d| _        y NF)superrh   ws_connectionrA   rB   _on_close_called)r,   rm   rn   ro   	__class__s       r-   rh   zWebSocketHandler.__init__   s8     	g88!  %r0   argsc                 B  K   || _         || _        | j                  j                  j	                  dd      j                         dk7  r:| j                  d       d}| j                  |       t        j                  |       y | j                  j                  }t        d |j	                  dd      j                  d            }d	|vr:| j                  d       d
}| j                  |       t        j                  |       y d| j                  j                  v r&| j                  j                  j	                  d      }n&| j                  j                  j	                  dd       }|K| j                  |      s:| j                  d       d}| j                  |       t        j                  |       y | j                         | _        | j                  r$| j                  j                  |        d {    y | j                  dd       | j!                  dd       y 7 *w)NUpgrade 	websocket  z"Can "Upgrade" only to "WebSocket".c                 >    | j                         j                         S r)   )striplower)ss    r-   <lambda>z&WebSocketHandler.get.<locals>.<lambda>   s    aggioo'r0   
Connection,upgradez"Connection" must be "Upgrade".OriginzSec-Websocket-Origini  z#Cross origin websockets not allowedi  zUpgrade RequiredSec-WebSocket-Versionz7, 8, 13)	open_argsopen_kwargsrn   headersgetr~   
set_statusfinishr   debugmapsplitcheck_originget_websocket_protocolrs   accept_connection
set_header)r,   rv   ro   log_msgr   
connectionorigins          r-   r   zWebSocketHandler.get   s    ! <<##Ir288:kIOOC :GKK MM'"
 ,,&&'\2)F)L)LS)Q

 J&OOC 7GKK MM'" t||+++\\))--h7F\\))--.DdKF
 d&7&7&?OOC ;GKK MM'"!88:$$66t<<<OOC!34OO3Z@ =s   G0H2H3+Hc                 :    | j                   j                  dd      S )zpThe interval for websocket keep-alive pings.

        Set websocket_ping_interval = 0 to disable pings.
        websocket_ping_intervalNsettingsr   r,   s    r-   rb   zWebSocketHandler.ping_interval  s     }}  !:DAAr0   c                 :    | j                   j                  dd      S )zIf no ping is received in this many seconds,
        close the websocket connection (VPNs, etc. can fail to cleanly close ws connections).
        Default is max of 3 pings or 30 seconds.
        websocket_ping_timeoutNr   r   s    r-   rc   zWebSocketHandler.ping_timeout  s     }}  !94@@r0   c                 B    | j                   j                  dt              S )zMaximum allowed message size.

        If the remote peer sends a message larger than this, the connection
        will be closed.

        Default is 10MiB.
        websocket_max_message_size)r   r   ri   r   s    r-   rd   z!WebSocketHandler.max_message_size&  s!     }}  (*C
 	
r0   rF   binaryFuture[None]c                     | j                   | j                   j                         r
t               t        |t              rt
        j                  j                  |      }| j                   j                  ||      S )aH  Sends the given message to the client of this Web Socket.

        The message may be either a string or a dict (which will be
        encoded as json).  If the ``binary`` argument is false, the
        message will be sent as utf8; in binary mode any byte string
        is allowed.

        If the connection is already closed, raises `WebSocketClosedError`.
        Returns a `.Future` which can be used for flow control.

        .. versionchanged:: 3.2
           `WebSocketClosedError` was added (previously a closed connection
           would raise an `AttributeError`)

        .. versionchanged:: 4.3
           Returns a `.Future` which can be used for flow control.

        .. versionchanged:: 5.0
           Consistently raises `WebSocketClosedError`. Previously could
           sometimes raise `.StreamClosedError`.
        r   )	rs   
is_closingr\   
isinstancedicttornadoescapejson_encodewrite_messager,   rF   r   s      r-   r   zWebSocketHandler.write_message3  sd    0 %););)F)F)H&((gt$nn009G!!///GGr0   subprotocolsc                      y)a  Override to implement subprotocol negotiation.

        ``subprotocols`` is a list of strings identifying the
        subprotocols proposed by the client.  This method may be
        overridden to return one of those strings to select it, or
        ``None`` to not select a subprotocol.

        Failure to select a subprotocol does not automatically abort
        the connection, although clients may close the connection if
        none of their proposed subprotocols was selected.

        The list may be empty, in which case this method must return
        None. This method is always called exactly once even if no
        subprotocols were proposed so that the handler can be advised
        of this fact.

        .. versionchanged:: 5.1

           Previously, this method was called with a list containing
           an empty string instead of an empty list if no subprotocols
           were proposed by the client.
        Nr*   )r,   r   s     r-   select_subprotocolz#WebSocketHandler.select_subprotocolQ  s    . r0   c                 J    | j                   J | j                   j                  S )zYThe subprotocol returned by `select_subprotocol`.

        .. versionadded:: 5.1
        )rs   selected_subprotocolr   s    r-   r   z%WebSocketHandler.selected_subprotocolj  s(     !!---!!666r0   c                      y)a  Override to return compression options for the connection.

        If this method returns None (the default), compression will
        be disabled.  If it returns a dict (even an empty one), it
        will be enabled.  The contents of the dict may be used to
        control the following compression options:

        ``compression_level`` specifies the compression level.

        ``mem_level`` specifies the amount of memory used for the internal compression state.

         These parameters are documented in details here:
         https://docs.python.org/3.6/library/zlib.html#zlib.compressobj

        .. versionadded:: 4.1

        .. versionchanged:: 4.5

           Added ``compression_level`` and ``mem_level``.
        Nr*   r   s    r-   get_compression_optionsz(WebSocketHandler.get_compression_optionss  s    , r0   c                      y)a  Invoked when a new WebSocket is opened.

        The arguments to `open` are extracted from the `tornado.web.URLSpec`
        regular expression, just like the arguments to
        `tornado.web.RequestHandler.get`.

        `open` may be a coroutine. `on_message` will not be called until
        `open` has returned.

        .. versionchanged:: 5.1

           ``open`` may be a coroutine.
        Nr*   )r,   rv   ro   s      r-   openzWebSocketHandler.open  s     	r0   c                     t         )zHandle incoming messages on the WebSocket

        This method must be overridden.

        .. versionchanged:: 4.5

           ``on_message`` can be a coroutine.
        NotImplementedErrorrH   s     r-   rI   zWebSocketHandler.on_message  s
     "!r0   r&   c                     t        |      }| j                  | j                  j                         r
t               | j                  j	                  |       y)a  Send ping frame to the remote end.

        The data argument allows a small amount of data (up to 125
        bytes) to be sent as a part of the ping message. Note that not
        all websocket implementations expose this data to
        applications.

        Consider using the ``websocket_ping_interval`` application
        setting instead of sending pings manually.

        .. versionchanged:: 5.1

           The data argument is now optional.

        N)r   rs   r   r\   
write_pingr+   s     r-   pingzWebSocketHandler.ping  sG      Dz%););)F)F)H&((%%d+r0   c                      y)z6Invoked when the response to a ping frame is received.Nr*   r+   s     r-   rM   zWebSocketHandler.on_pong      r0   c                      y)z*Invoked when the a ping frame is received.Nr*   r+   s     r-   rK   zWebSocketHandler.on_ping  r   r0   c                      y)a`  Invoked when the WebSocket is closed.

        If the connection was closed cleanly and a status code or reason
        phrase was supplied, these values will be available as the attributes
        ``self.close_code`` and ``self.close_reason``.

        .. versionchanged:: 4.0

           Added ``close_code`` and ``close_reason`` attributes.
        Nr*   r   s    r-   on_closezWebSocketHandler.on_close  s     	r0   codereasonc                 d    | j                   r$| j                   j                  ||       d| _         yy)aC  Closes this Web Socket.

        Once the close handshake is successful the socket will be closed.

        ``code`` may be a numeric status code, taken from the values
        defined in `RFC 6455 section 7.4.1
        <https://tools.ietf.org/html/rfc6455#section-7.4.1>`_.
        ``reason`` may be a textual message about why the connection is
        closing.  These values are made available to the client, but are
        not otherwise interpreted by the websocket protocol.

        .. versionchanged:: 4.0

           Added the ``code`` and ``reason`` arguments.
        N)rs   closer,   r   r   s      r-   r   zWebSocketHandler.close  s0      $$T62!%D r0   r   c                     t        |      }|j                  }|j                         }| j                  j                  j                  d      }||k(  S )a  Override to enable support for allowing alternate origins.

        The ``origin`` argument is the value of the ``Origin`` HTTP
        header, the url responsible for initiating this request.  This
        method is not called for clients that do not send this header;
        such requests are always allowed (because all browsers that
        implement WebSockets support this header, and non-browser
        clients do not have the same cross-site security concerns).

        Should return ``True`` to accept the request or ``False`` to
        reject it. By default, rejects all requests with an origin on
        a host other than this one.

        This is a security protection against cross site scripting attacks on
        browsers, since WebSockets are allowed to bypass the usual same-origin
        policies and don't use CORS headers.

        .. warning::

           This is an important security measure; don't disable it
           without understanding the security implications. In
           particular, if your authentication is cookie-based, you
           must either restrict the origins allowed by
           ``check_origin()`` or implement your own XSRF-like
           protection for websocket connections. See `these
           <https://www.christian-schneider.net/CrossSiteWebSocketHijacking.html>`_
           `articles
           <https://devcenter.heroku.com/articles/websocket-security>`_
           for more.

        To accept all cross-origin traffic (which was the default prior to
        Tornado 4.0), simply override this method to always return ``True``::

            def check_origin(self, origin):
                return True

        To allow connections from any subdomain of your site, you might
        do something like::

            def check_origin(self, origin):
                parsed_origin = urllib.parse.urlparse(origin)
                return parsed_origin.netloc.endswith(".mydomain.com")

        .. versionadded:: 4.0

        Host)r   netlocr~   rn   r   r   )r,   r   parsed_originhosts       r-   r   zWebSocketHandler.check_origin  sK    ^ !(%%||##''/ ~r0   rO   c                 V    | j                   J | j                   j                  |       y)a1  Set the no-delay flag for this stream.

        By default, small messages may be delayed and/or combined to minimize
        the number of packets sent.  This can sometimes cause 200-500ms delays
        due to the interaction between Nagle's algorithm and TCP delayed
        ACKs.  To reduce this delay (at the expense of possibly increasing
        bandwidth usage), call ``self.set_nodelay(True)`` once the websocket
        connection is established.

        See `.BaseIOStream.set_nodelay` for additional details.

        .. versionadded:: 3.1
        N)rs   set_nodelayr,   rO   s     r-   r   zWebSocketHandler.set_nodelay  s*     !!---&&u-r0   c                     | j                   r!| j                   j                          d | _         | j                  s(d| _        | j                          | j	                          y y )NT)rs   on_connection_closert   r   _break_cyclesr   s    r-   r   z$WebSocketHandler.on_connection_close-  sP    224!%D$$$(D!MMO  %r0   rA   rB   c                 @    || _         || _        | j                          y r)   rA   rB   r   rD   s      r-   rE   z'WebSocketHandler.on_ws_connection_close6       %(  "r0   c                 b    | j                         dk7  s| j                  rt        |           y y Ne   )
get_statusrt   rr   r   r,   ru   s    r-   r   zWebSocketHandler._break_cycles=  s,     ??#t'<'<G!# (=r0   WebSocketProtocolc                     | j                   j                  j                  d      }|dv rHt        | j                  | j
                  | j                  | j                               }t        | d|      S y )Nr   )7813rg   F)	rn   r   r   ra   rb   rc   rd   r   WebSocketProtocol13)r,   websocket_versionparamss      r-   r   z'WebSocketHandler.get_websocket_protocolF  sl     LL00445LM 00%"00!..!%!6!6$($@$@$B	F 'tUF;;r0   c                 R    dD ]  }t        | |t                | j                         S )N)writeredirectr   
set_cookier   r3   r   )setattr#_raise_not_supported_for_websocketsdetach)r,   methods     r-   _detach_streamzWebSocketHandler._detach_streamR  s+    
F D&"EF
 {{}r0   Fr0   r'   NrT   ).r4   r5   r6   r]   r   webApplicationr   HTTPServerRequestr   rh   r   propertyr   rj   rb   rc   r8   rd   r   r7   rU   r   boolr   r   r   r   r   r   r   rI   r   rM   rK   r   r   r   r   r   rE   r   r   r   r   __classcell__ru   s   @r-   rl   rl      s   Ob
&[[,,
& ++
& 	
&
 

&2As 2Ac 2Ad 2Ah Bx B B Ahuo A A 

# 

 

 JOHUCc3h78HBFH	H<tCy Xc] 2 7hsm 7 7$sCx.)A 0#  )D/1J  	"%U
"3 	"48Q 	",sEz* ,T ,*E d E d &(3- & &QU &(63 64 6p. .$ ."! OS#"3-#>Fsm#	#$
1D(E 
 r0   rl   rv   ro   r'   c                      t        d      )Nz$Method not supported for Web Sockets)RuntimeError)rv   ro   s     r-   r   r   a  s    
=
>>r0   c            	       V   e Zd ZdZd dZdedededd	fd
Zd!dZd!dZ	e
j                  d"dee   dee   ddfd       Ze
j                  defd       Ze
j                  deddfd       Ze
j                  	 d#deeeeeef   f   deddfd       Zee
j                  dee   fd              Ze
j                  deddfd       Ze
j                  deeef   dej8                  ddfd       Ze
j                  d!d       Ze
j                  d!d       Ze
j                  deddfd       Z y)$r   z+Base class for WebSocket protocol versions.handlerr'   Nc                 <    || _         d | _        d| _        d| _        y rq   )r   streamclient_terminatedserver_terminatedr,   r   s     r-   rh   zWebSocketProtocol.__init__h  s     !&!&r0   callbackrv   ro   zOptional[Future[Any]]c                 D   	  ||i |}|Jt        j                  |      }| j                  J | j                  j                  j	                  |d        |S # t
        $ r>  | j                  j                  t        j                           | j                          Y yw xY w)zRuns the given callback with exception handling.

        If the callback is a coroutine, returns its Future. On error, aborts the
        websocket connection and returns None.
        Nc                 "    | j                         S r)   )result)fs    r-   r   z1WebSocketProtocol._run_callback.<locals>.<lambda>  s
    r0   )r	   convert_yieldedr   io_loop
add_future	Exceptionr   rS   sysexc_info_abort)r,   r   rv   ro   r   s        r-   _run_callbackzWebSocketProtocol._run_callbackn  s    	t.v.F !,,V4{{...##..v7KLM  	&DLL&&7KKM	s   A ABBc                 $    | j                          y r)   )r  r   s    r-   r   z%WebSocketProtocol.on_connection_close  s    r0   c                     d| _         d| _        | j                  | j                  j                          | j                          y)z?Instantly aborts the WebSocket connection by closing the socketTN)r   r   r   r   r   s    r-   r  zWebSocketProtocol._abort  s5    !%!%;;"KK

r0   r   r   c                     t               r)   r   r   s      r-   r   zWebSocketProtocol.close      !##r0   c                     t               r)   r   r   s    r-   r   zWebSocketProtocol.is_closing  r  r0   c                    K   t               wr)   r   r   s     r-   r   z#WebSocketProtocol.accept_connection       !##   rF   r   r   c                     t               r)   r   r   s      r-   r   zWebSocketProtocol.write_message       "##r0   c                     t               r)   r   r   s    r-   r   z&WebSocketProtocol.selected_subprotocol  s     "##r0   r&   c                     t               r)   r   r+   s     r-   r   zWebSocketProtocol.write_ping  r  r0   keyr   c                     t               r)   r   )r,   r  r   s      r-   _process_server_headersz)WebSocketProtocol._process_server_headers  r  r0   c                     t               r)   r   r   s    r-   start_pingingzWebSocketProtocol.start_pinging  r  r0   c                    K   t               wr)   r   r   s    r-   _receive_frame_loopz%WebSocketProtocol._receive_frame_loop  r  r  xc                     t               r)   r   r,   r  s     r-   r   zWebSocketProtocol.set_nodelay  r  r0   )r   r@   r'   Nr   rT   r   )!r4   r5   r6   r]   rh   r   r   r  r   r  abcabstractmethodr   r8   rU   r   r   r   rl   r   r   r7   r   r   r   r   r   r   HTTPHeadersr  r  r  r   r*   r0   r-   r   r   e  s   5' ),8;	 * 	$(3- $ $QU $ $ 	$D $ $ 	$/? $D $ $ 	IN$S%c3h78$BF$	$ $
 $hsm $  $ 	$u $ $ $ 	$e$$/7/C/C$	$ $
 	$ $ 	$ $ 	$T $d $ $r0   r   c            
       V    e Zd Z	 d
dedee   deeeef      ddfdZ	ddZ
dedefd	Zy)_PerMessageDeflateCompressorN
persistent	max_wbitsre   r'   c                    |t         j                  }d|cxk  rt         j                  k  sn t        d|t         j                        || _        |d|vr*t        j
                  j                  j                  | _        n
|d   | _        |d|vrd| _	        n
|d   | _	        |r| j                         | _        y d | _        y )N   .Invalid max_wbits value %r; allowed range 8-%dcompression_level	mem_level)zlib	MAX_WBITS
ValueError
_max_wbitsr   r   GZipContentEncoding
GZIP_LEVEL_compression_level
_mem_level_create_compressor_compressor)r,   r#  r$  re   s       r-   rh   z%_PerMessageDeflateCompressor.__init__  s     IY0$..0@ 
 $  '"*==&-kk&E&E&P&PD#&9:M&ND#&+=P*PDO1+>DO#668D#Dr0   c                     t        j                  | j                  t         j                  | j                   | j
                        S r)   )r*  compressobjr0  DEFLATEDr-  r1  r   s    r-   r2  z/_PerMessageDeflateCompressor._create_compressor  s3    ##T]]T__4Ddoo
 	
r0   r&   c                     | j                   xs | j                         }|j                  |      |j                  t        j
                        z   }|j                  d      sJ |d d S )N     )r3  r2  r.   r3   r*  Z_SYNC_FLUSHendswith)r,   r&   
compressors      r-   r.   z%_PerMessageDeflateCompressor.compress  s`    %%B)@)@)B
""4(:+;+;D<M<M+NN}}0111CRyr0   r)   )r'   r%   )r4   r5   r6   r   r   r8   r   rU   r   rh   r2  r7   r.   r*   r0   r-   r"  r"    s\    
 9=	!$!$ C=!$ &d38n5	!$
 
!$F

U u r0   r"  c                   Z    e Zd Z	 ddedee   dedeeeef      ddf
dZ	ddZ
d	edefd
Zy)_PerMessageDeflateDecompressorNr#  r$  rd   re   r'   c                     || _         |t        j                  }d|cxk  rt        j                  k  sn t        d|t        j                        || _        |r| j                         | _        y d | _        y )Nr&  r'  )_max_message_sizer*  r+  r,  r-  _create_decompressor_decompressor)r,   r#  r$  rd   re   s        r-   rh   z'_PerMessageDeflateDecompressor.__init__  sp     "2IY0$..0@ 
 $))+  "&Dr0   c                 B    t        j                  | j                         S r)   )r*  decompressobjr-  r   s    r-   rA  z3_PerMessageDeflateDecompressor._create_decompressor	  s    !!4??"233r0   r&   c                     | j                   xs | j                         }|j                  |dz   | j                        }|j                  r
t               |S )Nr8  )rB  rA  r=   r@  r>   r_   )r,   r&   decompressorr   s       r-   r=   z)_PerMessageDeflateDecompressor.decompress  sU    ))HT-F-F-H((&&(>(>
 ''*,,r0   r)   )r'   r:   )r4   r5   r6   r   r   r8   r   rU   r   rh   rA  r7   r=   r*   r0   r-   r>  r>    se     9=&& C=& 	&
 &d38n5& 
&04u  r0   r>  c                      e Zd ZdZdZdZdZdZeez  ez  ZdZ	dZ
dd	d
ededdfdZedee   fd       Zej$                  dee   ddfd       ZdeddfdZdeddfdZedeeef   defd       ZdedefdZdeddfdZdej:                  deeee eef   f      fdZ!deeef   dej:                  ddfdZ"	 d9dede ee#f   dee ee#f      de ee#f   fdZ$	 d9dede ee#f   dee ee#f      ddfdZ%	 d:ded e&d!ed"e&dd#f
d$Z'	 d;d%eeee ee#f   f   d&edd#fd'Z(d!eddfd(Z)d<d)Z*d*e&defd+Z+d<d,Z,d e&d!edd-fd.Z-d=d/ee&   d0ee   ddfd1Z.defd2Z/edee0   fd3       Z1edee0   fd4       Z2d<d5Z3d<d6Z4d7eddfd8Z5y)>r   zImplementation of the WebSocket protocol from RFC 6455.

    This class supports versions 7 and 8 of the protocol in addition to the
    final version 13.
       @             Nr   r@   mask_outgoingr   r'   c                    t         j                  | |       || _        || _        d| _        d | _        d | _        d | _        d | _        d | _	        d | _
        d | _        |j                  | _        d | _        d | _        d | _        d| _        d| _        d| _        d| _        d | _        d| _        d| _        d | _        d | _        y )NFr   g        )r   rh   rM  r   _final_frame_frame_opcode_masked_frame_frame_mask_frame_length_fragmented_message_buffer_fragmented_message_opcode_waitingre   _compression_optionsrB  r3  _frame_compressed_message_bytes_in_message_bytes_out_wire_bytes_in_wire_bytes_outping_callback	last_ping	last_pongrA   rB   )r,   r   rM  r   s       r-   rh   zWebSocketProtocol13.__init__'  s     	""41*!!!!*.'*.'$*$>$>!!!% "#"#   ! r0   c                     | j                   S r)   _selected_subprotocolr   s    r-   r   z(WebSocketProtocol13.selected_subprotocolL  s    )))r0   rO   c                     || _         y r)   ra  r   s     r-   r   z(WebSocketProtocol13.selected_subprotocolP  s
    %*"r0   c                   K   	 | j                  |       	 | j                  |       d {    y # t        $ r< |j                  d       d}|j                  |       t	        j
                  |       Y y w xY w7 M# t        j                  $ r | j                          Y y t        $ r* t	        j
                  dd       | j                          Y y w xY ww)Nr{   !Missing/Invalid WebSocket headersz$Malformed WebSocket request receivedTr  )
_handle_websocket_headersr,  r   r   r   r   _accept_connectionasyncioCancelledErrorr  )r,   r   r   s      r-   r   z%WebSocketProtocol13.accept_connectionT  s     	**73	))'222  	s#9GNN7#MM'"	 3%% 	KKM 	MM@4PKKM	s_   C0 A: A8A: CAA52C4A55C8A: :#CC/CCCCc                 P    d}t        t        fd|            st        d      y)zVerifies all invariant- and required headers

        If a header is missing or have an incorrect value ValueError will be
        raised
        )r   Sec-Websocket-KeyzSec-Websocket-Versionc                 N    j                   j                  j                  |       S r)   )rn   r   r   )r   r   s    r-   r   z?WebSocketProtocol13._handle_websocket_headers.<locals>.<lambda>o  s    !8!8!<!<Q!?r0   re  N)allr   r,  )r,   r   fieldss    ` r-   rg  z-WebSocketProtocol13._handle_websocket_headersh  s-     H3?HI@AA Jr0   r  c                     t        j                         }|j                  t        |              |j                  d       t	        t        j                  |j                                     S )zoComputes the value for the Sec-WebSocket-Accept header,
        given the value for Sec-WebSocket-Key.
        s$   258EAFA5-E914-47DA-95CA-C5AB0DC85B11)hashlibsha1updater   r   base64	b64encodedigest)r  rr  s     r-   compute_accept_valuez(WebSocketProtocol13.compute_accept_valuer  sH    
 ||~DI;<&**4;;=9::r0   c                     t         j                  t        t        |j                  j
                  j                  d                  S )Nrl  )r   rw  r   rU   rn   r   r   r   s     r-   _challenge_responsez'WebSocketProtocol13._challenge_response|  s5    "77goo--112EFG
 	
r0   c           	        K   |j                   j                  j                  d      }|r-|j                  d      D cg c]  }|j	                          }}ng }|j                  |      | _        | j                  r,| j                  |v sJ |j                  d| j                         | j                  |j                   j                        }|D ]w  }|d   dk(  s| j                  | j                  d|d   | j                         d|d   v r|d   d   |d   d= |j                  dt        j                  d|d                 n |j                  d	       |j                  d
       |j                  dd       |j                  dd       |j                  d| j                  |             |j!                          |j#                         | _        | j'                          	  |j(                  |j*                  i |j,                  }|
| d {    | j9                          d {    y c c}w 7 "# t.        $ r4  |j0                  t3        j4                           | j7                          Y y w xY w7 Lw)NSec-WebSocket-Protocolr   r   permessage-deflateserver   client_max_window_bitsSec-WebSocket-ExtensionszContent-Typer   rx   rz   r   zSec-WebSocket-Accept)rn   r   r   r   r}   r   r   r   _parse_extensions_headerrW  _create_compressorsr   _encode_headerclear_headerr   ry  r   r   r   r  r   r   r   r  rS   r  r  r  r  )r,   r   subprotocol_headerr   r   
extensionsextopen_results           r-   rh  z&WebSocketProtocol13._accept_connection  sT    $__44889QR/A/G/G/LM/L!AGGI/LLML$+$>$>|$L!$$,,<<<79R9RS227??3J3JK
C1v--$2K2K2W ((3q64;T;TU,A6A78@ A78"".++,@#a&I ! $ 	^,39k2<3143K3KG3TU,,.	&',,(9(9QW=P=PQK&!!! &&(((] NP " 	!G!!3<<>2KKM	
 	)s`   ;I9H0BI9I9'C=I9%-H7 H5H7 I9*I7+
I95H7 7:I41I93I44I9r   c                     |j                  dd      }|r@|j                  d      D cg c]%  }t        j                  |j	                               ' c}S g S c c}w )Nr  ry   r   )r   r   r   _parse_headerr}   )r,   r   r  es       r-   r  z,WebSocketProtocol13._parse_extensions_header  sW     [[!;R@
?I?O?OPS?TU?T!H**17795?TUU	 Vs   *Ac                 b   |d   j                         dk(  sJ |d   j                         dk(  sJ | j                  |      }|d   |k(  sJ | j                  |      }|D ]7  }|d   dk(  r"| j                  | j	                  d	|d
          -t        d|       |j                  dd      | _        y)zProcess the headers sent by the server to this client connection.

        'key' is the websocket handshake challenge/response key.
        rx   rz   r   r   zSec-Websocket-Acceptr   r|  Nclientr~  zunsupported extension %rr{  )r~   rw  r  rW  r  r,  r   r   )r,   r  r   acceptr  r  s         r-   r  z+WebSocketProtocol13._process_server_headers  s     y!'')[888|$**,	999**3/-.&888227;
C1v--$2K2K2W((3q6: !;SAA	  %,KK0H$$O!r0   sideagreed_parametersre   c                     t        |dz   |v      }|j                  |dz   d      }|t        j                  |d<   nt	        |      |d<   ||d<   |S )zlConverts a websocket agreed_parameters set to keyword arguments
        for our compressor objects.
        _no_context_takeover)r#  _max_window_bitsNr$  re   )r   r   r*  r+  r8   )r,   r  r  re   optionswbits_headers         r-   _get_compressor_optionsz+WebSocketProtocol13._get_compressor_options  sj     55>OO
 ),,T4F-FM#'>>GK #&|#4GK )<%&r0   c           	         t        g d      }|D ]  }||vst        d|z         |dk(  rdnd}t        di | j                  |||      | _        t        dd| j                  j                  i| j                  |||      | _        y )N)server_no_context_takeoverclient_no_context_takeoverserver_max_window_bitsr  z$unsupported compression parameter %rr}  r  rd   r*   )	setr,  r"  r  r3  r>  r   rd   rB  )r,   r  r  re   allowed_keysr  
other_sides          r-   r  z'WebSocketProtocol13._create_compressors  s     
 %C,& !G#!MNN % #'("2X
7 
**41BDWX
 < 
![[99
**-/B
r0   finopcoder&   flagsr   c                 x   t        |      }|dz  r|st        d      |dkD  rt        d      |r| j                  }nd}t        j                  d||z  |z        }| j
                  rd}nd}|dk  r|t        j                  d||z        z  }n@|d	k  r|t        j                  d
d|z  |      z  }n|t        j                  dd|z  |      z  }| j
                  r$t        j                  d      }	|	t        |	|      z   }||z  }| xj                  t        |      z  c_	        | j                  j                  |      S )Nr&  z$control frames may not be fragmented}   z/control frame payloads may not exceed 125 bytesr   BrH  ~   i  z!BHz!BQ      )lenr,  FINstructpackrM  osurandomr   r\  r   r   )
r,   r  r  r&   r  data_lenfinbitframemask_bitmasks
             r-   _write_framez WebSocketProtocol13._write_frame  s.    t9C<  !GHH#~ !RSSXXFFC&5!89HHc>V[[h&9::EV[[hAAEV[[hAAE::a=D/$55DE
*{{  ''r0   rF   r   c                    |rd}nd}t        |t              rt        j                  j	                  |      }t        j                  j                  |      }t        |t              sJ | xj                  t        |      z  c_        d}| j                  r*| j                  j                  |      }|| j                  z  }	 | j                  d|||      dfd}t        j                    |             S # t        $ r t               w xY w)z9Sends the given message to the client of this Web Socket.   r~  r   T)r  c                  V   K   	   d {    y 7 # t         $ r t               w xY wwr)   )r   r\   )futs   r-   wrapperz2WebSocketProtocol13.write_message.<locals>.wrapper>  s*     -		$ -*,,-s    )  ) &)r   )r   r   r   r   r   r   r7   rZ  r  r3  r.   RSV1r  r   r\   ri  ensure_future)r,   rF   r   r  r  r  r  s         @r-   r   z!WebSocketProtocol13.write_message#  s     FFgt$nn009G..%%g.'5)))3w</&&//8GTYYE	)##D&'#GC	- $$WY// ! 	)&((	)s    C5 5D	c                 N    t        |t              sJ | j                  dd|       y)zSend ping frame.T	   N)r   r7   r  r+   s     r-   r   zWebSocketProtocol13.write_pingF  s$    $&&&$T*r0   c                   K   	 | j                   s%| j                          d {    | j                   s%| j                  j                  | j                  | j                         y 7 B# t        $ r | j                          Y Nw xY wwr)   )r   _receive_framer   r  r   rE   rA   rB   r   s    r-   r  z'WebSocketProtocol13._receive_frame_loopK  sm     	,,))+++ ,, 	++DOOT=N=NO ,  	KKM	s7   BA( A&A( 1B&A( (BBBBnc                    K   | j                   j                  |       d {   }| xj                  |z  c_        |S 7 wr)   )r   
read_bytesr[  )r,   r  r&   s      r-   _read_byteszWebSocketProtocol13._read_bytesS  s8     [[++A..q  /s   ?=?c                   K   | j                  d       d {   }t        j                  d|      \  }}|| j                  z  }|| j                  z  }|| j
                  z  }|dz  }| j                  2|dk7  r-t        || j                  z        | _	        || j                   z  }|r| j                          y t        |dz        }|dz  }	|r|	dk\  r| j                          y |	dk  r|	| _        no|	dk(  r3| j                  d       d {   }t        j                  d|      d   }	n7|	dk(  r2| j                  d       d {   }t        j                  d	|      d   }	|	}
| j                  |
t        | j                        z  }
|
| j                  j                  kD  r#| j!                  d
d       | j                          y |r| j                  d       d {   | _        | j                  |	       d {   }|r$| j"                  J t%        | j"                  |      }|r|s| j                          y |dk(  rc| j                  | j                          y | j                  j'                  |       |r_| j(                  }t+        | j                        }d | _        n6| j                  | j                          y |s|| _        t-        |      | _        |r | j/                  ||      }|| d {    y y y 7 7 7 7 (7 7 w)Nr  BBr&  r   rH  r  r  z!Hz!Q  zmessage too bigr  )r  r  unpackr  RSV_MASKOPCODE_MASKrB  r   r  rX  r  rS  rT  r  r   rd   r   rR  r   extendrU  r7   	bytearray_handle_message)r,   r&   headermask_payloadlenis_final_framereserved_bitsr  opcode_is_control	is_masked
payloadlennew_lenhandled_futures               r-   r  z"WebSocketProtocol13._receive_frameX  s    %%a(("(--d";$((*.$***"SL)fk &*-$))*C%DD"diiZ'MKKM4/0	$t+
 s!2KKM!+D3))!,,DtT215J3))!,,DtT215J**6s4::;;GT[[111JJt./KKM %)%5%5a%88D%%j11##///"4#3#3T:D  "q[..6++224888T<<=26/..:!28/2;D//!11&$?N)$$$ * Y )6 - -  91H %sl   LK6C1L	K9
7LK<BLK?L5L6C8L.L/L9L<L?LLLzOptional[Future[None]]c                    | j                   ry| j                  r*| j                  J 	 | j                  j                  |      }|dk(  rV| xj                  t        |      z  c_        	 |j                  d      }| j                  | j                  j                  |      S |dk(  rD| xj                  t        |      z  c_        | j                  | j                  j                  |      S |dk(  rsd| _         t        |      dk\  r!t        j                  d	|dd       d
   | _        t        |      dkD  rt#        |dd       | _        | j                  | j                          y|dk(  r;	 | j'                  dd|       | j                  | j                  j*                  |       y|dk(  rMt-        j.                         j1                         | _        | j                  | j                  j4                  |      S | j                          y# t        $ r% | j                  dd       | j                          Y yw xY w# t        $ r | j                          Y yw xY w# t(        $ r | j                          Y w xY w)z>Execute on_message, returning its Future if it is a coroutine.Nr  z#message too big after decompressionr~  zutf-8r  r&  T>Hr   r  
   )r   rX  rB  r=   r_   r   r  rY  r  decodeUnicodeDecodeErrorr  r   rI   r  r  rA   r   rB   r  r   rK   r   currenttimer_  rM   )r,   r  r&   decodeds       r-   r  z#WebSocketProtocol13._handle_message  s#   !!!!%%111))44T: S=""c$i/"++g. %%dll&=&=wGGs]""c$i/"%%dll&=&=tDDs]%)D"4yA~"(--d2Ah"?"B4y1}$.tABx$8!JJt'  s]!!$T2 t||33T:  s]#^^-224DN%%dll&:&:DAAKKMQ , 

4!FG & * % s5   H (H4 &I +H10H14III/.I/r   r   c                 "   | j                   sf| j                  j                         sE||d}|d}nt        j                  d|      }||t        |      z  }	 | j                  dd|       d| _         | j                  r]| j                  6| j                  j                  j                  | j                         d| _
        | j                  j                          nf| j                  Z| j                  j                  j                  | j                  j                  j                         dz   | j                        | _
        | j                   r"| j                   j#                          d| _        yy# t        $ r | j                          Y !w xY w)z Closes the WebSocket connection.N  r0   r  Tr&     )r   r   closedr  r  r   r  r   r  r   rV  r  remove_timeoutr   add_timeoutr  r]  stop)r,   r   r   
close_datas       r-   r   zWebSocketProtocol13.close  sL   %%;;%%'<F$6D<!$J!'T4!8J%$v,.J"%%dC< &*D"!!}}(##224==A $KK]]" !KK//;;##((*Q.DM ##%!%D  ) "KKM"s   E1 1FFc                 n    | j                   j                         xs | j                  xs | j                  S )zReturn ``True`` if this connection is closing.

        The connection is considered closing if either side has
        initiated its closing handshake or if the stream has been
        shut down uncleanly.
        )r   r  r   r   r   s    r-   r   zWebSocketProtocol13.is_closing  s-     {{!!#Wt'='=WAWAWWr0   c                 8    | j                   j                  }||S y)Nr   )r   rb   )r,   intervals     r-   rb   z!WebSocketProtocol13.ping_interval  s    ;;,,Or0   c                     | j                   j                  }||S | j                  J t        d| j                  z  d      S )N      )r   rc   rb   max)r,   timeouts     r-   rc   z WebSocketProtocol13.ping_timeout  sF    ++**N!!---1t)))2..r0   c                     | j                   J | j                   dkD  rqt        j                         j                         x| _        | _        t        | j                  | j                   dz        | _        | j                  j                          yy)z9Start sending periodic pings to keep the connection aliveNr   r  )
rb   r   r  r  r^  r_  r   periodic_pingr]  startr   s    r-   r  z!WebSocketProtocol13.start_pinging  s|    !!---!.4nn.>.C.C.EEDNT^!1""D$6$6$="D $$& "r0   c                    | j                         r'| j                  | j                  j                          yt        j                         j                         }|| j                  z
  }|| j                  z
  }| j                  J | j                  J |d| j                  z  k  r || j                  kD  r| j                          y| j                  d       || _        y)zSend a ping to keep the websocket alive

        Called periodically if the websocket_ping_interval is set and non-zero.
        Nr  r0   )r   r]  r  r   r  r  r_  r^  rb   rc   r   r   )r,   nowsince_last_pongsince_last_pings       r-   r  z!WebSocketProtocol13.periodic_ping   s    
 ??!3!3!?##%
 nn##%..!!---  ,,,a$"4"444$"3"33JJLr0   r  c                 :    | j                   j                  |       y r)   )r   r   r  s     r-   r   zWebSocketProtocol13.set_nodelay;  s    "r0   r)   )r   r   r   rT   )6r4   r5   r6   r]   r  r  RSV2RSV3r  r  r   r   ra   rh   r   r   rU   r   setterrl   r   rg  staticmethodr   r7   rw  ry  rh  r   r   r   r    r   r  r  r   r  r  r8   r  r   r   r  r  r  r  r   r   rj   rb   rc   r  r  r   r*   r0   r-   r   r     si    CDDDd{T!HKF"!%"! "! !	"!
 
"!J *hsm * *   +(3- +D + !+/? D (B1A Bd B ;%U
"3 ; ; ;
+; 
 

1)0@ 1)T 1)f++	eCc3h'(	)Pe$P/7/C/CP	P2 9=	  S> &d38n5	
 
c3h0 9=	

  S>
 &d38n5	

 

< AB((!$(,1(:=(	(D JO!0S%c3h78!0BF!0	!0F+u + +
P3 5 
Q%f1c 1 1;S 1f&(3- & &QU &@XD X x   /huo / /'6#T #d #r0   r   c                       e Zd ZdZdZddddeddfdej                  dee	e
deef   gdf      deeeef      dee   dee   ded	eee      d
ee   ddf fdZd.dZd/dee   dee   ddfdZd. fdZ	 d/dee   dee   ddfdZdej0                  ddfdZde
ej6                  ej8                  f   dej:                  ddf fdZ	 d0de
eeeeef   f   deddfdZ 	 d1dee	dgdf      de!e
deef      fd Z"de
eef   dee!d      fd!Z#de
deef   dee!d      fd"Z$d2d#eddfd$Z%d#eddfd%Z&d#eddfd&Z'de(fd'Z)e*dee   fd(       Z+d)d*d+ee,   d,ee-   ddfd-Z. xZ/S )3WebSocketClientConnectionzWebSocket client connection.

    This class should not be instantiated directly; use the
    `websocket_connect` function instead.
    Nrn   on_message_callbackre   rb   rc   rd   r   resolverr'   c	           
         t               | _        t        d      | _        t	        j
                  t        j                  d            | _        || _	        d | _
        d | _        t        ||||      | _        |j                  j                  d      \  }	}
}ddd|	   }	|	|
z   |z   |_        |j                   j#                  dd	| j                  d
d       |dj%                  |      |j                   d<   |d|j                   d<   d|_        t)        |      | _        t,        | ]  d |d | j0                  d| j*                  dd       y )Nr~  rK  rg   :httphttps)wswssrz   rx   r   )rx   r   zSec-WebSocket-Keyr   r   r{  z*permessage-deflate; client_max_window_bitsr  F)r  c                       y r)   r*   r*   r0   r-   r   z4WebSocketClientConnection.__init__.<locals>.<lambda>~  s    Dr0   i  @i   )r   connect_futurer   
read_queuert  ru  r  r  r  _on_message_callbackrA   rB   ra   r   url	partitionr   rs  joinfollow_redirectsr   
tcp_clientrr   rh   _on_http_response)r,   rn   r  re   rb   rc   rd   r   r  schemeseprestru   s               r-   rh   z"WebSocketClientConnection.__init__H  sE    %h(##BJJrN3$7! &'%- 3	
 $KK11#6Tw/7slT)&'%)XX)-		
 #8;8NGOO45* = OO67
 $) #X6""OO		
r0   c                 R    | j                   t        j                  dt               y y )Nz"Unclosed WebSocketClientConnection)protocolwarningswarnResourceWarningr   s    r-   __del__z!WebSocketClientConnection.__del__  s"    ==$ MM>P %r0   r   r   c                 d    | j                   $| j                   j                  ||       d| _         yy)zCloses the websocket connection.

        ``code`` and ``reason`` are documented under
        `WebSocketHandler.close`.

        .. versionadded:: 3.2

        .. versionchanged:: 4.0

           Added the ``code`` and ``reason`` arguments.
        N)r  r   r   s      r-   r   zWebSocketClientConnection.close  s.     ==$MMf- DM %r0   c                     | j                   j                         s#| j                   j                  t                      | j	                  d        | j
                  j                          t        | !          y r)   )	r  doneset_exceptionr   _on_messager
  r   rr   r   r   s    r-   r   z-WebSocketClientConnection.on_connection_close  sV    ""'')--.?.AB#%r0   rA   rB   c                 @    || _         || _        | j                          y r)   r   rD   s      r-   rE   z0WebSocketClientConnection.on_ws_connection_close  r   r0   responsec                     | j                   j                         sW|j                  r&| j                   j                  |j                         y | j                   j                  t	        d             y y )NzNon-websocket response)r  r  errorr  rX   )r,   r  s     r-   r  z+WebSocketClientConnection._on_http_response  sU    ""'')~~##11(..A##11"#;<	 *r0   
start_liner   c                   K   t        |t        j                        sJ |j                  dk7  rt        |   ||       d {    y | j                  ,| j                  j                  | j                         d | _        || _	        | j                         | _        | j                  j                  | j                  | j                         | j                  j                         | j                  _        t#        j$                         j'                  | j                  j(                         | j                  j+                          d | _        t/        | j0                  |        y 7 "wr   )r   r   ResponseStartLiner   rr   headers_received_timeoutr  r  r   r   r  r  r  r   r   r   r   r  add_callbackr  r  final_callbackr   r  )r,   r  r   ru   s      r-   r!  z*WebSocketClientConnection.headers_received  s    
 *h&@&@AAA??c!'*:w???==$LL''6 DM335--dhhE#557%%dmm&G&GH##% #*4+>+>E+ @s   ?E'E$D"E'rF   r   r   c                 j    | j                   t        d      | j                   j                  ||      S )aJ  Sends a message to the WebSocket server.

        If the stream is closed, raises `WebSocketClosedError`.
        Returns a `.Future` which can be used for flow control.

        .. versionchanged:: 5.0
           Exception raised on a closed stream changed from `.StreamClosedError`
           to `WebSocketClosedError`.
        z!Client connection has been closedr   )r  r\   r   r   s      r-   r   z'WebSocketClientConnection.write_message  s4     == &'JKK}}**76*BBr0   r   zFuture[Union[None, str, bytes]]c                     | j                   j                         }|/| j                  j                  t	        j
                  |      |       |S )ax  Reads a message from the WebSocket server.

        If on_message_callback was specified at WebSocket
        initialization, this function will never return messages

        Returns a future whose result is the message, or None
        if the connection is closed.  If a callback argument
        is given it will be called with the future when it is
        ready.
        )r  r   r  r  ri  r  )r,   r   	awaitables      r-   read_messagez&WebSocketClientConnection.read_message  sA     OO'')	LL##G$9$9)$DhOr0   c                 $    | j                  |      S r)   )r  rH   s     r-   rI   z$WebSocketClientConnection.on_message  s    ((r0   c                 t    | j                   r| j                  |       y | j                  j                  |      S r)   )r  r  putrH   s     r-   r  z%WebSocketClientConnection._on_message  s3     $$%%g.??&&w//r0   r&   c                 |    t        |      }| j                  
t               | j                  j                  |       y)a  Send ping frame to the remote end.

        The data argument allows a small amount of data (up to 125
        bytes) to be sent as a part of the ping message. Note that not
        all websocket implementations expose this data to
        applications.

        Consider using the ``ping_interval`` argument to
        `websocket_connect` instead of sending pings manually.

        .. versionadded:: 5.1

        N)r   r  r\   r   r+   s     r-   r   zWebSocketClientConnection.ping  s2     Dz== &((  &r0   c                      y r)   r*   r+   s     r-   rM   z!WebSocketClientConnection.on_pong      r0   c                      y r)   r*   r+   s     r-   rK   z!WebSocketClientConnection.on_ping  r.  r0   c                 2    t        | d| j                        S )NT)rM  r   )r   r   r   s    r-   r   z0WebSocketClientConnection.get_websocket_protocol  s    "4tDKKPPr0   c                 .    | j                   j                  S )zOThe subprotocol selected by the server.

        .. versionadded:: 5.1
        )r  r   r   s    r-   r   z.WebSocketClientConnection.selected_subprotocol   s     }}111r0   rN   zOptional[Type[BaseException]]rO   rP   c                 J    |J |J t        j                  d||||f       y )NzUncaught exception %srf  )r   r  rR   s       r-   rS   z'WebSocketClientConnection.log_exception(  s2        -uUB?OPr0   r   rT   r   r)   r   )0r4   r5   r6   r]   r  ri   r
   HTTPRequestr   r   r   rU   r7   r   r   rj   r8   r   r   rh   r  r   r   rE   HTTPResponser  r   RequestStartLiner   r   r!  r   r   r   r(  rI   r  r   rM   rK   r   r   r   r   rV   r"   rS   r   r   s   @r-   r  r  ?  s    H
 TX8<)-(, 9,0'+<
''<
 &hdC6F0G/H$/N&OP<
 &d38n5	<

  <
 uo<
 <
 tCy)<
 8$<
 
<
|Q!(3- ! !QU ! & OS#"3-#>Fsm#	#**A*A d F(33X5O5OOPF %%F 
	F> JOCS%c3h78CBFC	C$ SW8%F$G$MNO 
5sE)*	+()%U
"3 )48Q )0T3-.0	)D/	"0' ' '&E d E d Q(9 Q 2hsm 2 2Q,Q &Q ]#	Q
 
Qr0   r  r  r   z!Future[WebSocketClientConnection]connect_timeoutr  re   rb   rc   rd   r   r  z$Awaitable[WebSocketClientConnection]c
           
         t        | t        j                        r+|J | }
t        j                  |
j
                        |
_        nt        j                  | |      }
t        t        j                  t        j                  |
t        j                  j                              }
t        |
|||||||	      }|.t        j                         j                  |j                  |       |j                  S )aa  Client-side websocket support.

    Takes a url and returns a Future whose result is a
    `WebSocketClientConnection`.

    ``compression_options`` is interpreted in the same way as the
    return value of `.WebSocketHandler.get_compression_options`.

    The connection supports two styles of operation. In the coroutine
    style, the application typically calls
    `~.WebSocketClientConnection.read_message` in a loop::

        conn = yield websocket_connect(url)
        while True:
            msg = yield conn.read_message()
            if msg is None: break
            # Do something with msg

    In the callback style, pass an ``on_message_callback`` to
    ``websocket_connect``. In both styles, a message of ``None``
    indicates that the connection has been closed.

    ``subprotocols`` may be a list of strings specifying proposed
    subprotocols. The selected protocol may be found on the
    ``selected_subprotocol`` attribute of the connection object
    when the connection is complete.

    .. versionchanged:: 3.2
       Also accepts ``HTTPRequest`` objects in place of urls.

    .. versionchanged:: 4.1
       Added ``compression_options`` and ``on_message_callback``.

    .. versionchanged:: 4.5
       Added the ``ping_interval``, ``ping_timeout``, and ``max_message_size``
       arguments, which have the same meaning as in `WebSocketHandler`.

    .. versionchanged:: 5.0
       The ``io_loop`` argument (deprecated since version 4.1) has been removed.

    .. versionchanged:: 5.1
       Added the ``subprotocols`` argument.

    .. versionchanged:: 6.3
       Added the ``resolver`` argument.
    )r6  )r  re   rb   rc   rd   r   r  )r   r
   r3  r   r   r   r   _RequestProxy	_DEFAULTSr  r   r  r  r  )r  r   r6  r  re   rb   rc   rd   r   r  rn   conns               r-   websocket_connectr;  3  s    t #z--.&&& #..w?((oN  **@*@*J*JKG %//#!)!	D ##D$7$7Br0   )Tr]   r  ri  rt  rq  r  r  r  r   urllib.parser   r  r*  tornado.concurrentr   r   tornado.escaper   r   r   r	   r
   r   tornado.ioloopr   r   tornado.iostreamr   r   tornado.logr   r   tornado.netutilr   r   tornado.queuesr   tornado.tcpclientr   tornado.utilr   typingr   r   r   r   r   r   r   r   r   r    r!   typesr"   typing_extensionsr#   r%   r:   r@   ri   r  rX   r\   r_   objectra   r   RequestHandlerrl   r   ABCr   r"  r>  r   _HTTPConnectionr  rU   r3  rj   r7   r8   r;  r*   r0   r-   <module>rM     sY       	 
   !   I 7 7 - - 3 8 ( $ %   ' (     *h  X 6 - 	Y 		> 		y 	7v 7Zw{{11 Zz?s ?c ?d ?X$ X$v-6 -`#V #Lf#+ f#RqQ 1 A A qQl QU'+OS48%)$(5(,#'R	sJ***	+Rx!D Et KLMR e_R "(E$U2B,C+Dd+J"KL	R
 "$sCx.1R E?R 5/R R 49%R x R ,Rr0   