K idZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl Z ddl m Z ddl Z ddlZddlmZmZddlmZmZmZddl mZmZmZddlmZddlmZmZdd lmZm Z dd l!m"Z"dd l m#Z#dd l$m%Z%dd l&m'Z'ddl(m)Z)ddl*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5ddl6m7Z7e+r'ddl8m9Z9Gdde9Z:Gdde9Z;Gdde9ZaImplementation of the WebSocket protocol. `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 `_. .. 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 httpclienthttputil)IOLoop)StreamClosedErrorIOStream)gen_logapp_log)Resolver)simple_httpclient)Queue) TCPClient)_websocket_mask) TYPE_CHECKINGcastAnyOptionalDictUnionList AwaitableCallableTupleType) TracebackType)Protocolc,eZdZdedefdZdedefdZy) _CompressordatareturncyNselfr%s W/mnt/ssd/data/python-lab/Trading/venv/lib/python3.12/site-packages/tornado/websocket.pycompressz_Compressor.compress= modecyr(r))r+r0s r,flushz_Compressor.flush@r.r/N)__name__ __module__ __qualname__bytesr-intr2r)r/r,r$r$<s(  5  c e r/r$c$eZdZdZdededefdZy) _Decompressorr/r% max_lengthr&cyr(r))r+r%r:s r, decompressz_Decompressor.decompressFr.r/N)r3r4r5unconsumed_tailr6r7r<r)r/r,r9r9Cs! 5 c e r/r9ceZdZ ddeedeeddfdZdeeefdedfdZ d eddfd Z d eddfd Z d ee e d ee deeddfdZy)_WebSocketDelegateN close_code close_reasonr&cyr(r)r+r@rAs r,on_ws_connection_closez)_WebSocketDelegate.on_ws_connection_closeMs r/messagezAwaitable[None]cyr(r)r+rEs r, on_messagez_WebSocketDelegate.on_messageRr.r/r%cyr(r)r*s r,on_pingz_WebSocketDelegate.on_pingUr.r/cyr(r)r*s r,on_pongz_WebSocketDelegate.on_pongXr.r/typvaluetbcyr(r)r+rMrNrOs r, log_exceptionz _WebSocketDelegate.log_exception[s r/NN)r3r4r5rr7strrDrr6rHrJrLr BaseExceptionr!rRr)r/r,r?r?Is SW &sm BJ3-     eCJ&7 HEV|jjSr()striplower)ss r,z&WebSocketHandler.get..saggioo'r/ Connection,upgradez"Connection" must be "Upgrade".OriginzSec-Websocket-Originiz#Cross origin websockets not allowedizUpgrade RequiredSec-WebSocket-Versionz7, 8, 13) open_args open_kwargsrmheadersgetr} set_statusfinishrdebugmapsplit check_originget_websocket_protocolrraccept_connection set_header)r+rurnlog_msgr connectionorigins r,rzWebSocketHandler.gets! <<   # #Ir 2 8 8 :k I OOC :G KK MM' "  ,,&& '\2)F)L)LS)Q  J & OOC 7G KK MM' "  t||++ +\\))--h7F\\))--.DdKF  d&7&7&? OOC ;G KK MM' " !88:   $$66t< < < OOC!3 4 OO3Z @ =sG0H2H3+Hc:|jjddS)aThe interval for sending websocket pings. If this is non-zero, the websocket will send a ping every ping_interval seconds. The client will respond with a "pong". The connection can be configured to timeout on late pong delivery using ``websocket_ping_timeout``. Set ``websocket_ping_interval = 0`` to disable pings. Default: ``0`` websocket_ping_intervalNsettingsrr+s r,razWebSocketHandler.ping_intervals}}  !:DAAr/c:|jjddS)a-Timeout if no pong is received in this many seconds. To be used in combination with ``websocket_ping_interval > 0``. If a ping response (a "pong") is not received within ``websocket_ping_timeout`` seconds, then the websocket connection will be closed. This can help to clean up clients which have disconnected without cleanly closing the websocket connection. Note, the ping timeout cannot be longer than the ping interval. Set ``websocket_ping_timeout = 0`` to disable the ping timeout. Default: equal to the ``ping_interval``. .. versionchanged:: 6.5.0 Default changed from the max of 3 pings or 30 seconds. The ping timeout can no longer be configured longer than the ping interval. websocket_ping_timeoutNrrs r,rbzWebSocketHandler.ping_timeout)s.}}  !94@@r/cB|jjdtS)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)rrrhrs r,rcz!WebSocketHandler.max_message_sizeBs!}}  (*C  r/rEbinary Future[None]c|j|jjr tt|trt j j|}|jj||S)aHSends 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) rr is_closingr[ isinstancedicttornadoescape json_encode write_messager+rErs r,rzWebSocketHandler.write_messageOsd0    %););)F)F)H&( ( gt $nn009G!!///GGr/ subprotocolscy)aOverride 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+rs r,select_subprotocolz#WebSocketHandler.select_subprotocolms.r/cJ|jJ|jjS)zYThe subprotocol returned by `select_subprotocol`. .. versionadded:: 5.1 )rrselected_subprotocolrs r,rz%WebSocketHandler.selected_subprotocols( !!---!!666r/cy)aOverride 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 detail here: https://docs.python.org/3.13/library/zlib.html#zlib.compressobj .. versionadded:: 4.1 .. versionchanged:: 4.5 Added ``compression_level`` and ``mem_level``. Nr)rs r,get_compression_optionsz(WebSocketHandler.get_compression_optionss,r/cy)aInvoked 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+rurns r,openzWebSocketHandler.opens r/ct)zHandle incoming messages on the WebSocket This method must be overridden. .. versionchanged:: 4.5 ``on_message`` can be a coroutine. NotImplementedErrorrGs r,rHzWebSocketHandler.on_messages "!r/r%ct|}|j|jjr t|jj |y)aSend 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)rrrrr[ write_pingr*s r,pingzWebSocketHandler.pingsG Dz    %););)F)F)H&( ( %%d+r/cy)z6Invoked when the response to a ping frame is received.Nr)r*s r,rLzWebSocketHandler.on_pong r/cy)z*Invoked when the a ping frame is received.Nr)r*s r,rJzWebSocketHandler.on_pingrr/cy)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)rs r,on_closezWebSocketHandler.on_closes r/codereasoncd|jr$|jj||d|_yy)aCCloses 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 `_. ``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)rrcloser+rrs r,rzWebSocketHandler.closes0       $ $T6 2!%D  r/rct|}|j}|j}|jjj d}||k(S)aOverride 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 `_ `articles `_ 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)rnetlocr}rmrr)r+r parsed_originhosts r,rzWebSocketHandler.check_originsK^!( %%||##''/~r/rNcV|jJ|jj|y)a1Set 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)rr set_nodelayr+rNs r,rzWebSocketHandler.set_nodelay8s*!!--- &&u-r/c|jr!|jjd|_|js(d|_|j|j yy)NT)rron_connection_closersr _break_cyclesrs r,rz$WebSocketHandler.on_connection_closeIsP       2 2 4!%D $$$(D ! MMO    %r/r@rAc@||_||_|jyr(r@rArrCs r,rDz'WebSocketHandler.on_ws_connection_closeR%(   "r/cb|jdk7s |jrt| yyNe) get_statusrsrqrr+rts r,rzWebSocketHandler._break_cyclesYs, ??  #t'<'< G ! #(=r/WebSocketProtocolc|jjjd}|dvrHt|j|j |j |j}t|d|Sy)Nr)7813rfF) rmrrr`rarbrcrWebSocketProtocol13)r+websocket_versionparamss r,rz'WebSocketHandler.get_websocket_protocolbsl LL00445LM  0 0%"00!..!%!6!6$($@$@$B F 'tUF; ;r/cRdD]}t||t|jS)N)writeredirectr set_cookierr2r)setattr#_raise_not_supported_for_websocketsdetach)r+methods r,_detach_streamzWebSocketHandler._detach_streamns2 GF D&"E F G{{}r/Fr/r&NrS).r3r4r5r\rweb Applicationr HTTPServerRequestrrgrpropertyrrirarbr7rcrr6rTrboolrrrrrrrrHrrLrJrrrrrrDrrrr __classcell__rts@r,rkrksN` &[[,, &++ & &  &2As2Ac2Ad2Ah Bx B BAhuoAA0  #    JOHUCc3h78HBFH H<tCyXc]27hsm77$sCx.)A0 #  )D/1J "%U "3 "48Q ",sEz*,T,* E d  E d   &(3-& &QU&(63646p..$."!OS#"3-#>Fsm# #$ 1D(E   r/rkrurnr&ctd)Nz$Method not supported for Web Sockets) RuntimeError)rurns r,rr}s = >>r/c VeZdZdZd dZdedededd fd Zd!d Zd!d Z e jd"d e e de eddfdZe jdefdZe jdeddfdZe j d#deeeeeeffdeddfdZee jde efdZe jdeddfdZe jdeeefdej8ddfdZe jd!dZe jd!dZe jdeddfdZ y)$rz+Base class for WebSocket protocol versions.handlerr&Nc<||_d|_d|_d|_yrp)rstreamclient_terminatedserver_terminatedr+rs r,rgzWebSocketProtocol.__init__s   !&!&r/callbackrurnzOptional[Future[Any]]cD ||i|}|Jtj|}|jJ|jjj |d|S#t $r>|j jtj|jYywxYw)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"|jSr()result)fs r,rz1WebSocketProtocol._run_callback..s r/) r convert_yieldedrio_loop add_future ExceptionrrRsysexc_info_abort)r+rrurnrs r, _run_callbackzWebSocketProtocol._run_callbacks t.v.F !,,V4{{... ##..v7KLM  &DLL & &  7 KKM sAABBc$|jyr()rrs r,rz%WebSocketProtocol.on_connection_closes  r/cd|_d|_|j|jj|jy)z?Instantly aborts the WebSocket connection by closing the socketTN)rrrrrs r,rzWebSocketProtocol._aborts5!%!% ;; " KK    r/rrctr(rrs r,rzWebSocketProtocol.close !##r/ctr(rrs r,rzWebSocketProtocol.is_closingr r/cKtwr(rrs r,rz#WebSocketProtocol.accept_connection!## rErrctr(rrs r,rzWebSocketProtocol.write_message "##r/ctr(rrs r,rz&WebSocketProtocol.selected_subprotocols "##r/r%ctr(rr*s r,rzWebSocketProtocol.write_pingr r/keyrctr(r)r+rrs r,_process_server_headersz)WebSocketProtocol._process_server_headersrr/ctr(rrs r, start_pingingzWebSocketProtocol.start_pingingr r/cKtwr(rrs r,_receive_frame_loopz%WebSocketProtocol._receive_frame_loopr rxctr(rr+rs r,rzWebSocketProtocol.set_nodelayr r/)rr?r&NrrSr)!r3r4r5r\rgrrrrrabcabstractmethodrr7rTrrrrkrrr6rrrrrr HTTPHeadersrrrrr)r/r,rrs5'  ),8; * $(3-$ $QU$$ $D$$ $/?$D$$ IN$S%c3h78$BF$ $$ $hsm$$ $u$$$ $e$$/7/C/C$ $$  $$ $$ $T$d$$r/rc VeZdZ d dedeedeeeefddfdZ d dZ de de fd Z y) _PerMessageDeflateCompressorN persistent max_wbitsrdr&c|tj}d|cxkrtjksntd|tj||_|d|vr*tj j j|_n |d|_|d|vrd|_ n |d|_ |r|j|_ yd|_ y)N.Invalid max_wbits value %r; allowed range 8-%dcompression_level mem_level) zlib MAX_WBITS ValueError _max_wbitsrrGZipContentEncoding GZIP_LEVEL_compression_level _mem_level_create_compressor _compressor)r+r"r#rds r,rgz%_PerMessageDeflateCompressor.__init__s  IY0$..0@  $ '"*==&-kk&E&E&P&PD #&9:M&ND #  &+=P*PDO1+>DO #668D #D r/ctj|jtj|j |j Sr()r) compressobjr/DEFLATEDr,r0rs r,r1z/_PerMessageDeflateCompressor._create_compressors3  # #T]]T__4Ddoo  r/r%c|jxs|j}|j||jtj z}|j dsJ|ddS)N)r2r1r-r2r) Z_SYNC_FLUSHendswith)r+r% compressors r,r-z%_PerMessageDeflateCompressor.compresss`%%B)@)@)B ""4(:+;+;D(>   ' '*, , r/r()r&r9) r3r4r5rrr7rrTrrgr@r6r<r)r/r,r=r= se 9= &&C=& & &d38n5 &  &04ur/r=c eZdZdZdZdZdZdZeezezZdZ dZ dd d e d e d dfd Z ed eefdZej$deed dfdZded dfdZded dfdZedeeefd efdZded efdZded dfdZdej:d eeee eefffdZ!deeefdej:d dfdZ" d=dede ee#fdee ee#fd e ee#ffdZ$ d=dede ee#fdee ee#fd dfdZ% d>de d e&d!ed"e&d d#f d$Z' d?d%eeee ee#ffd&e d d#fd'Z(d!ed dfd(Z)d@d)Z*d*e&d efd+Z+d@d,Z,d e&d!ed d-fd.Z-dAd/ee&d0eed dfd1Z.d e fd2Z/d3e d dfd4Z0ed e1fd5Z2ed e1fd6Z3d@d7Z4ed8e1d9e1d:e1d e1fd;Z5d@d<Z6y)BrzImplementation of the WebSocket protocol from RFC 6455. This class supports versions 7 and 8 of the protocol in addition to the final version 13. @ Nrr? mask_outgoingrr&cxtj||||_||_d|_d|_d|_d|_d|_d|_ d|_ d|_ |j|_ d|_d|_d|_d|_d|_d|_d|_d|_d|_d|_d|_y)NFr)rrgrLr _final_frame _frame_opcode _masked_frame _frame_mask _frame_length_fragmented_message_buffer_fragmented_message_opcode_waitingrd_compression_optionsrAr2_frame_compressed_message_bytes_in_message_bytes_out_wire_bytes_in_wire_bytes_out_received_pongr@rA_ping_coroutine)r+rrLrs r,rgzWebSocketProtocol13.__init__Cs ""41* !!!!*.'*.' $*$>$>!!!%"#"#  # #r/c|jSr(_selected_subprotocolrs r,rz(WebSocketProtocol13.selected_subprotocolgs)))r/rNc||_yr(r_rs r,rz(WebSocketProtocol13.selected_subprotocolks %*"r/cK |j| |j |d{y#t$r<|jdd}|j|t j |YywxYw7M#tj$r|jYyt$r*t j dd|jYywxYww)Nrz!Missing/Invalid WebSocket headersz$Malformed WebSocket request receivedTr) _handle_websocket_headersr+rrrr_accept_connectionasyncioCancelledErrorr)r+rrs r,rz%WebSocketProtocol13.accept_connectionos   * *7 3 ))'2 2 2    s #9G NN7 # MM' "    3%%  KKM   MM@4 P KKM  s_C0A:A8A:CAA52C4A55C8A::#CC/CCCCcPd}ttfd|s tdy)zVerifies all invariant- and required headers If a header is missing or have an incorrect value ValueError will be raised )rSec-Websocket-KeyzSec-Websocket-VersioncNjjj|Sr()rmrr)rrs r,rz?WebSocketProtocol13._handle_websocket_headers..s!8!8!$>|$L!  $ $,, < <<   79R9R S227??3J3JK  C1v--$2K2K2W((3q64;T;TU,A6A78@A78"".++,@#a&I! $ ^,39k2<3143K3KG3TU,,.   &',,(9(9QW=P=PQK&!!! &&(((]NP"  !G ! !3<<> 2 KKM   )s`;I9H0BI9 I9'C=I9%-H7H5H7I9*I7+ I95H77:I41I93I44I9rc|jdd}|r@|jdDcgc]%}tj|j 'c}SgScc}w)Nr~rxr)rrr _parse_headerr|)r+rres r,rz,WebSocketProtocol13._parse_extensions_headersQ[[!;R@ ?I?O?OPS?TU!H**17795U U Vs*Acb|djdk(sJ|djdk(sJ|j|}|d|k(sJ|j|}|D]7}|ddk(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. rwryrrzSec-Websocket-AcceptrrzNclientr|zunsupported extension %rry)r}rurrVrr+rr)r+rracceptrrs r,rz+WebSocketProtocol13._process_server_headerssy!'')[888|$**, 999**3/-.&888227;  BC1v--$2K2K2W((3q6: !;SAA  B %,KK0H$$O!r/sideagreed_parametersrdct|dz|v}|j|dzd}|tj|d<nt ||d<||d<|S)zlConverts a websocket agreed_parameters set to keyword arguments for our compressor objects. _no_context_takeover)r"_max_window_bitsNr#rd)rrr)r*r7)r+rrrdoptions wbits_headers r,_get_compressor_optionsz+WebSocketProtocol13._get_compressor_optionssj55>OO ),,T4F-FM  #'>>GK #&|#4GK )<%&r/c hd}|D]}||vstd|z|dk(rdnd}tdi|j||||_t dd|j j i|j||||_y)N>r}server_max_window_bitsclient_no_context_takeoverserver_no_context_takeoverz$unsupported compression parameter %rr{rrcr))r+r!rr2r=rrcrA)r+rrrd allowed_keysr other_sides r,rz'WebSocketProtocol13._create_compressorss % OC,& !G#!MNN O#'("2X 7 **41BDWX < ![[99 **-/B r/finopcoder%flagsrcxt|}|dzr|s td|dkDr td|r |j}nd}tjd||z|z}|j rd}nd}|dkr|tjd||zz }n@|d kr|tjd d|z|z }n|tjd d |z|z }|j r$t jd } | t| |z}||z }|xjt|z c_ |jj|S)Nr%z$control frames may not be fragmented}z/control frame payloads may not exceed 125 bytesrBrG~iz!BHz!BQ) lenr+FINstructpackrLosurandomrr[rr) r+rrr%rdata_lenfinbitframemask_bitmasks r, _write_framez WebSocketProtocol13._write_frames.t9 C< !GHH#~ !RSS XXFF C&5!89   HH c> V[[h&9: :E   V[[hA AE V[[hA AE   ::a=D/$55D   E *{{  ''r/rErc|rd}nd}t|trtjj |}tjj |}t|t sJ|xjt|z c_d}|jr*|jj|}||jz} |jd|||dfd }tj |S#t$r twxYw)z9Sends the given message to the client of this Web Socket.r|rT)rcVK d{y7#t$r twxYwwr()r r[)futsr,wrapperz2WebSocketProtocol13.write_message..wrapperWs* - $ -*,, -s ))&)r)rrrrrrr6rYrr2r-RSV1rr r[rg ensure_future)r+rErrrrrs @r,rz!WebSocketProtocol13.write_message<s FF gt $nn009G..%%g.'5))) 3w</   &&//8G TYY E  )##D&'#GC - $$WY//! )&( ( )s C55D cNt|tsJ|jdd|y)zSend ping frame.T N)rr6rr*s r,rzWebSocketProtocol13.write_ping_s$$&&& $T*r/cK |js%|jd{|js%|jj |j |jy7B#t$r|jYNwxYwwr()r_receive_framer rrrDr@rArs r,rz'WebSocketProtocol13._receive_frame_loopdsm ,,))+++,, ++DOOT=N=NO,   KKM s7BA(A&A(1B&A((BBBBncK|jj|d{}|xj|z c_|S7wr()r read_bytesrZ)r+rr%s r, _read_byteszWebSocketProtocol13._read_bytesls8[[++A.. q  /s ?=?cK|jdd{}tjd|\}}||jz}||jz}||j z}|dz}|j 2|dk7r-t||jz|_ ||jz}|r|jyt|dz}|dz} |r| dk\r|jy| dkr| |_ no| dk(r3|jdd{}tjd|d} n7| dk(r2|jdd{}tjd |d} | } |j| t|jz } | |jjkDr#|j!d d |jy|r|jd d{|_|j| d{}|r$|j"Jt%|j"|}|r|s|jy|dk(rc|j|jy|jj'||r_|j(}t+|j}d|_ n6|j|jy|s||_t-||_ |r |j/||} | | d{yyy7777(7 7w) NrBBr%rrGrrz!Hz!Qzmessage too bigr)rrunpackrRSV_MASK OPCODE_MASKrArrrWrrRrSrrrcrrQrextendrTr6 bytearray_handle_message) r+r%headermask_payloadlenis_final_frame reserved_bitsropcode_is_control is_masked payloadlennew_lenhandled_futures r,rz"WebSocketProtocol13._receive_frameqs%%a(("(--d";$((*. $***"SL    )fk&*-$))*C%DD " diiZ 'M  KKM 4/0 $t+  s!2 KKM   !+D  3 ))!,,DtT215J 3 ))!,,DtT215J  * * 6 s4::; ;G T[[11 1 JJt. / KKM  %)%5%5a%88D %%j11 ##/ //"4#3#3T:D "  q[..6   + + 2 24 888T<<=26/..: !28/2;D// !11&$?N)$$$* Y)6-- 91H%slLK6C1L K9 7LK<BLK?L5L6C8L.L/L9L<L?LLLzOptional[Future[None]]c|jry|jr*|jJ |jj|}|dk(rV|xjt|z c_ |jd}|j|jj|S|dk(rD|xjt|z c_|j|jj|S|dk(rsd|_t|dk\r!tjd |ddd |_t|dkDrt#|dd|_|j |j y|d k(r; |j'dd ||j|jj*|y|d k(r-d|_|j|jj.|S|j y#t$r%|j dd|j YywxYw#t$r|j YywxYw#t($r|j YwxYw) z>Execute on_message, returning its Future if it is a coroutine.Nrz#message too big after decompressionr|zutf-8rr%T>Hrr )rrWrAr<r^rrrXrdecodeUnicodeDecodeErrorrrrHrrr@rrArr rJr\rL)r+rr%decodeds r,rz#WebSocketProtocol13._handle_messages  ! !  ! !%%1 11 ))44T: S=  " "c$i / " ++g.%%dll&=&=wG G s]  " "c$i / "%%dll&=&=tD D s]%)D "4yA~"(--d2Ah"?"B4y1}$.tABx$8! JJt 's] !!$T2   t||33T : s]"&D %%dll&:&:DA A KKMQ,  4!FG  &   *%   s5G#(H&H3#+HHH0/H03IIrrc"|jsf|jjsE||d}|d}ntjd|}||t |z } |j dd|d|_|jr]|j6|jjj|jd|_ |jjnf|jZ|jjj|jjjdz|j|_ |j r"|j j#d|_yy#t$r|jY!wxYw)z Closes the WebSocket connection.Nir/rTr%)rrclosedrrrrr rrrUrremove_timeoutr add_timeouttimer]cancel)r+rr close_datas r,rzWebSocketProtocol13.closesL%%;;%%'D?D D D r()rrrrS)7r3r4r5r\rrRSV2RSV3rrrrr`rgrrrTrsetterrkrre staticmethodrr6rurwrfr rrrrrrrrrr7rrrrrrrrrrrirarbrrrr)r/r,rr2s C D D Dd{T!HK F!$%!$!$! !$  !$H*hsm**  +(3-+D+!+/?D(B1ABdB;%U "3;;; +;  1)0@1)T1)f++ eCc3h'( )Pe$P/7/C/CP P29=  S>&d38n5  c3h 09=    S> &d38n5    8AB((!$(,1(:=( (DJO!0S%c3h78!0BF!0 !0F+u++ P35 Q%f1c11;S1f((3-( (QU(@XDX#T#d#u "e"" M757E77RW77r/rceZdZdZdZddddeddfdejdee e de e fgdfdee e efdeedeeded eee d eed dffd Zd.d Zd/deedee d dfdZd.fd Z d/deedee d dfdZdej0d dfdZde ej6ej8fdej:d dffd Z d0de e e e e effded dfdZ d1dee dgdfd e!e de e ffd Z"de e e fd ee!dfd!Z#de de e fd ee!dfd"Z$d2d#e d dfd$Z%d#e d dfd%Z&d#e d dfd&Z'd e(fd'Z)e*d ee fd(Z+d)d*d+ee,d,ee-d dfd-Z.xZ/S)3WebSocketClientConnectionzWebSocket client connection. This class should not be instantiated directly; use the `websocket_connect` function instead. Nrmon_message_callbackrdrarbrcrresolverr&c t|_td|_t j t jd|_||_ d|_ d|_ t|||||_ |jjd\} } } ddd| } | | z| z|_|j j#dd t%|jd d |d j'||j d <|d|j d<d|_t+||_t. |ad|d|j2d|j,ddy)Nr|rJrf:httphttps)wswssryrwr)rwrzSec-WebSocket-Keyrrryz*permessage-deflate; client_max_window_bitsr~F)rcyr(r)r)r/r,rz4WebSocketClientConnection.__init__..sr/i@i)rconnect_futurer read_queuerrrsrrr_on_message_callbackr@rAr`rurl partitionrrqrjoinfollow_redirectsr tcp_clientrqrg_on_http_response) r+rmrrdrarbrcrrschemeseprestrts r,rgz"WebSocketClientConnection.__init__usJ%h(##BJJrN3$7! &'%- 3   $KK11#6Tw/7slT) &'%/%9)-     #8;8NGOO4 5  *= OO6 7 $) #X6      " "  OO   r/cR|jtjdtyy)Nz"Unclosed WebSocketClientConnection)protocolwarningswarnResourceWarningrs r,__del__z!WebSocketClientConnection.__del__s" == $ MM> P %r/rrcd|j$|jj||d|_yy)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)rrrs r,rzWebSocketClientConnection.closes. == $ MM  f - DM %r/c|jjs#|jjt|j d|j j t|!yr() rdone set_exceptionr _on_messager rrqrrs r,rz-WebSocketClientConnection.on_connection_closesV""'')    - -.?.A B   #%r/r@rAc@||_||_|jyr(rrCs r,rDz0WebSocketClientConnection.on_ws_connection_closerr/responsec|jjsW|jr&|jj|jy|jjt dyy)NzNon-websocket response)rrerrorrrW)r+rs r,r z+WebSocketClientConnection._on_http_responsesU""'')~~##11(..A##11"#;< *r/ start_linercKt|tjsJ|jdk7rt|||d{y|j ,|jj|j d|_||_ |j|_ |jj|j|j|jj|j_t#j$j'|jj(|jj+d|_t/|j0|y7"wr)rr ResponseStartLinerrqheaders_received_timeoutrrrrrrrrrrr r add_callbackrrfinal_callbackrr)r+rrrts r,r"z*WebSocketClientConnection.headers_receiveds *h&@&@AAA ??c !'*:w? ? ?  == $ LL ' ' 6 DM 335  --dhh E#557 %%dmm&G&GH ##% #*4+>+>E+ @s?E'E$D"E'rErrcj|j td|jj||S)aJSends 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)rr[rrs r,rz'WebSocketClientConnection.write_messages4 == &'JK K}}**76*BBr/rzFuture[Union[None, str, bytes]]c|jj}|/|jjt j |||S)axReads 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. )rrrrrgr)r+r awaitables r, read_messagez&WebSocketClientConnection.read_messagesAOO'')   LL # #G$9$9)$Dh Or/c$|j|Sr()rrGs r,rHz$WebSocketClientConnection.on_message%s((r/ct|jr|j|y|jj|Sr()rrputrGs r,rz%WebSocketClientConnection._on_message(s3  $ $  % %g .??&&w/ /r/r%c|t|}|j t|jj|y)aSend 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)rrr[rr*s r,rzWebSocketClientConnection.ping1s2Dz == &( (   &r/cyr(r)r*s r,rLz!WebSocketClientConnection.on_pongD r/cyr(r)r*s r,rJz!WebSocketClientConnection.on_pingGr/r/c2t|d|jS)NT)rLr)rrrs r,rz0WebSocketClientConnection.get_websocket_protocolJs"4tDKKPPr/c.|jjS)zOThe subprotocol selected by the server. .. versionadded:: 5.1 )rrrs r,rz.WebSocketClientConnection.selected_subprotocolMs }}111r/rMzOptional[Type[BaseException]]rNrOcJ|J|Jtjd||||fy)NzUncaught exception %srd)rrrQs r,rRz'WebSocketClientConnection.log_exceptionUs2     -uUB?OPr/rrSrr(r)0r3r4r5r\rrhr HTTPRequestrrrrTr6rrrir7rrrgrrrrD HTTPResponser r RequestStartLiner!rr"rrrr)rHrrrLrJrrrrrUr!rRrrs@r,rrls H TX8<)-(, 9,0'+< ''< &hdC6F0G/H$/N&OP< &d38n5 <   < uo < < tCy)< 8$<  < |Q!(3-! !QU! &OS#"3-#>Fsm# #**A*AdF(33X5O5OOPF%%F  F>JOCS%c3h78CBFC C$SW8%F$G$MNO 5sE)* +()%U "3)48Q)0T3-.0 )D/ "0'''& E d  E d Q(9Q2hsm22Q ,Q &Q ] # Q  Qr/rrrz!Future[WebSocketClientConnection]connect_timeoutrrdrarbrcrrz$Awaitable[WebSocketClientConnection]c t|tjr+|J|} tj| j | _ntj||} t tjtj| tjj} t| ||||||| } |Jtjdtdtjj| j || j S)aGClient-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. .. deprecated:: 6.5 The ``callback`` argument is deprecated and will be removed in Tornado 7.0. Use the returned Future instead. Note that ``on_message_callback`` is not deprecated and may still be used. )r7)rrdrarbrcrrzZThe callback argument to websocket_connect is deprecated. Use the returned Future instead.r) stacklevel)rr r4r rrr _RequestProxy _DEFAULTSrrrDeprecationWarningr rrr) rrr7rrdrarbrcrrrmconns r,websocket_connectr>`s~#z--.&&&#..w?((oN  **@*@*J*JKG %//#!)! D  /   ##D$7$7B   r/)Wr\rrgrr functoolsrorrrrr urllib.parserrr)tornado.concurrentrrtornado.escaperrrr r r tornado.ioloopr tornado.iostreamr r tornado.logrrtornado.netutilrrtornado.queuesrtornado.tcpclientr tornado.utilrtypingrrrrrrrrrrr typesr!typing_extensionsr"r$r9r?rh lru_cachelogrrrWr[r^r`rRequestHandlerrkrABCrr!r=r_HTTPConnectionrrTr4rir6r7r>r)r/r,rRsq    ! I77--!8($% '(     *h X6-&)%%gkk2 Y  >  y  7 7qw{{11qh?s?c?d?X$X$v--`##Lw+wtqQ 1 A AqQlQU'+OS48%)$(5(,#'] sJ*** +]x!D Et KLM]e_]"(E$U2B,C+Dd+J"KL ] "$sCx.1 ] E? ]5/]]49%]x ],]r/