
    i              	          d dl Z d dlZd dlZd dlZd dlmZ d dlmZ d dl	Z	d dl
Z
d dlZd dlZd dlZ	 d dlmZmZ n# e$ r d dlmZ d dlmZ Y nw xY wd dlmZ d dlmZ d d	lmZ d d
lmZ dD ] Z	  eei i dg          Z n# e$ r dZY w xY wej        ej        ej        hZdZ ddgZ!dZ" e# e$ e%dd                     e$ e%dd                    z    e$ e%dd                    z    e$ e%dd                    z             Z& G d de'          Z( G d d          Z) G d d          Z* G d de'          Z+ G d de'          Z, G d  d!e-          Z. G d" d#e*          Z/dS )$    N)Random)error)md5sha1)r   )sha)	semaphore)wsgi)socket)	get_errno)zwsaccel.utf8validatorzautobahn.utf8validator i   WebSocketWSGI	WebSockets$   258EAFA5-E914-47DA-95CA-C5AB0DC85B11  i    i  i  i  i  c                         e Zd Zd fd	Z xZS )
BadRequest400 Bad RequestNc                     t          t          |                                            || _        || _        || _        d S N)super	Exception__init__statusbodyheaders)selfr   r   r   	__class__s       =/usr/local/lib/python3.11/dist-packages/eventlet/websocket.pyr   zBadRequest.__init__9   s8    i'')))	    )r   NN__name__
__module____qualname__r   __classcell__r   s   @r   r   r   8   s=                 r   r   c                   f    e Zd ZdZefdZe	 	 	 	 dd            Zd Zd Z	d Z
d	 Zd
 Zd Zd ZdS )r   a  Wraps a websocket handler function in a WSGI application.

    Use it like this::

      @websocket.WebSocketWSGI
      def my_handler(ws):
          from_browser = ws.wait()
          ws.send("from server")

    The single argument to the function will be an instance of
    :class:`WebSocket`.  To close the socket, simply return from the
    function.  Note that the server will log the websocket request at
    the time of closure.

    An optional argument max_frame_length can be given, which will set the
    maximum incoming *uncompressed* payload length of a frame. By default, this
    is set to 8MiB. Note that excessive values here might create a DOS attack
    vector.
    c                 Z    || _         d | _        d| _        g | _        d | _        || _        d S )NT)handlerprotocol_versionsupport_legacy_versionssupported_protocolsorigin_checkermax_frame_length)r   r(   r-   s      r   r   zWebSocketWSGI.__init__U   s7     $'+$#% " 0r   NFc                 8      fd}||S  ||          S )Nc                 L     |           }|_         |_        r|_        |S r   )r*   r,   r+   )r(   instclsr,   r*   r+   s     r   	decoratorz+WebSocketWSGI.configured.<locals>.decoratorc   s5    3w<<D+BD("0D" ?+>(Kr    )r1   r(   r+   r,   r*   r2   s   ` ``` r   
configuredzWebSocketWSGI.configured]   sK    	 	 	 	 	 	 	 	 ?y!!!r   c                     d |                     dd                                                              d          D             }d|v r,|                     dd                                          dk    s |dd	g           g S 	 d
|v r|                     |          }n+| j        r|                     |          }nt                      nC# t          $ r6}|j        }|j        pd}|j	        pg } ||d	g|z              |gcY d }~S d }~ww xY wd|v r |d                      	 | 
                    |           n.# t          $ r!}t          |          t          vr Y d }~nd }~ww xY w|                    d           dt          j        _        g S )Nc                 6    g | ]}|                                 S r3   strip).0parts     r   
<listcomp>z*WebSocketWSGI.__call__.<locals>.<listcomp>o   s6     !O !O !O JJLL!O !O !Or   HTTP_CONNECTIONr   ,upgradeHTTP_UPGRADE	websocketr   )
ConnectioncloseHTTP_SEC_WEBSOCKET_VERSIONr   zeventlet.set_idleT)getlowersplit_handle_hybi_requestr*   _handle_legacy_requestr   r   r   r   r(   OSErrorr   ACCEPTABLE_CLIENT_ERRORS_send_closing_framer	   
WSGI_LOCALalready_handled)	r   environstart_responsehttp_connection_partswser   r   r   s	            r   __call__zWebSocketWSGI.__call__n   s   !O !O$5r::@@BBHHMM!O !O !O 222NB//5577;FFN,/F.GHHHI	+w66..w77- #0099 ll" 	 	 	XF6=SDio2GN636@B B B6MMMMMM	 '))(G'(***	LL 	 	 	||#;;; <;;;;	 	t$$$ +/'	s7   AC 
D+DDD$D: :
E%E  E%c                    d|v r|d                                          }nd|v r	|d         }nt          d          d|v rd| _        d|vrt                      nd| _        | j        dk    r|                     |d                   }|                     |d                   }d|d	         _        |d	                             d          }t          j        d
||          |z   }t          |          
                                }d}|                    d          dk    rd}|d|                    d          |                    d          |                    d          }	|                    d          }
|
|	d|
z   z  }	| j        dk    rFd|                    d                                          z   dz   |	                                z   dz   }n| j        dk    rud|                    d                                          z   dz   |                    dd                                          z   dz   |	                                z   dz   |z   }nt          d          |                    |           t          ||| j                  S )Neventlet.inputgunicorn.socket8No eventlet.input or gunicorn.socket present in environ.HTTP_SEC_WEBSOCKET_KEY1L   HTTP_SEC_WEBSOCKET_KEY2K      z
wsgi.inputz>IIrQ   zwsgi.url_schemehttpswssz://	HTTP_HOSTSCRIPT_NAME	PATH_INFOQUERY_STRING?sg   HTTP/1.1 101 Web Socket Protocol Handshake
Upgrade: WebSocket
Connection: Upgrade
WebSocket-Origin: HTTP_ORIGINs   
WebSocket-Location:    

sj   HTTP/1.1 101 WebSocket Protocol Handshake
Upgrade: WebSocket
Connection: Upgrade
Sec-WebSocket-Origin: s   
Sec-WebSocket-Protocol: HTTP_SEC_WEBSOCKET_PROTOCOLdefaults   
Sec-WebSocket-Location: z#Unknown WebSocket protocol version.)
get_socketr   r)   r   _extract_numbercontent_lengthreadstructpackr   digestrD   encode
ValueErrorsendallr   )r   rN   sockkey1key2key3keyresponseschemelocationqshandshake_replys               r   rH   z$WebSocketWSGI._handle_legacy_request   s   w&&+,7799DD')),-DDVWWW$//$&D!(77 ll" 8 %'D! B&&''0I(JKKD''0I(JKKD 45GL!0<(--a00D+eT40047C3xx((H ;;())W44FFFKK$$$KK&&&KK$$$	
 [[((>b H B&&& )0M(B(B(I(I(K(KLO(( +3//*;*;	< ?J	J O "b((* -4KK,F,F,M,M,O,OPS,,
 99EELLNNO
R,, /7oo.?.?@C ## O BCCC_%%%w(=>>>r   c                    |d S i }|                     d          D ]>}|                     d          }i }|dd          D ]}|                     d          }t          |          dk    r0d||d                                                                         <   Z|d                                                             d                                          ||d                                                                         <   |                    |d                                                                         g                               |           @|S )Nr=   ;   =Tr   ")rF   lenr8   rE   
setdefaultappend)r   headerresextpartsconfigr:   key_vals           r   _parse_extension_headerz%WebSocketWSGI._parse_extension_header   s<   >4<<$$ 		H 		HCIIcNNEFabb	 _ _**S//w<<1$$9=F71:++--3355669@9I9I9K9K9Q9QRU9V9V9\9\9^9^F71:++--335566NN58>>++1133R88??GGGG
r   c                 V   |sd S |                     d          }|d S |D ]}|                     dd          |                     dd          d}t          t          j        d          }|                     d          }|F|du r||d<   n<t	          |                     d|                    |d<   d	|d         cxk    rdk    sn |                     d
          }|G|du r||d
<   n=t	          |                     d
|                    |d
<   d	|d
         cxk    rdk    sn |c S d S )Npermessage-deflateserver_no_context_takeoverFclient_no_context_takeover)r   r      server_max_window_bitsTr\   client_max_window_bits)rD   minzlib	MAX_WBITSint)r   
extensionsdeflater   want_config	max_wbitsmwbs          r   _negotiate_permessage_deflatez+WebSocketWSGI._negotiate_permessage_deflate   s    	4..!566?4 	 	F
 /5jj9UW\.].].4jj9UW\.].] K DNB//I**566C$;;<EK 899 FJJ'?KKLL   89-E!FLLLL"LLLL **566C$;;<EK 899 FJJ'?KKLL   89-E!FLLLL"LLLL tr   c           	         |sd S g }|                                 D ]\  }}|                                g}|                                 D ]o\  }}|du r
|du r(|                    |                                           6|                    |dt          |                                                     p|                    d                    |                     d                    |          S )NFTr   s   ; s   , )itemsro   r   strjoin)r   parsed_extensionsr   namer   	ext_partsrv   values           r   _format_extension_headerz&WebSocketWSGI._format_extension_header  s      	4-3355 		0 		0LD&I$llnn M M
UE>>d]]$$SZZ\\2222$$c%jjj&A%I%I%K%KLLLLLLI..////zz%   r   c                    d|v r|d                                          }nd|v r	|d         }nt          d          |d         }|dvrt          ddg          t          |          | _        d	|vrt                      |                    d
| j        dk    r|                    dd          nd          }| j        9|                     |                    d          |          st          d          |                    dd           }d }|r/d |                    d          D             D ]}|| j        v r|} n|d	         }t          j
        t          |                                t          z                                                       }	dddd|	z   g}
|r*|
                    d|                                z              i }|                     |                    d                    }|                     |          }|||d<   |                     |          }||
                    d|z              |                    d                    |
          dz              t+          ||| j        ||| j                  S )NrU   rV   rW   rC   )813z426 Upgrade Required)zSec-WebSocket-Versionz8, 13)r   r   HTTP_SEC_WEBSOCKET_KEYrd   r\   HTTP_SEC_WEBSOCKET_ORIGINr   r_   z403 Forbidden)r   rf   c              3   >   K   | ]}|                                 V  d S r   r7   )r9   is     r   	<genexpr>z5WebSocketWSGI._handle_hybi_request.<locals>.<genexpr>6  s*      >>Aaggii>>>>>>r   r=   s    HTTP/1.1 101 Switching Protocolss   Upgrade: websockets   Connection: Upgrades   Sec-WebSocket-Accept: s   Sec-WebSocket-Protocol: HTTP_SEC_WEBSOCKET_EXTENSIONSr   s   Sec-WebSocket-Extensions: s   
re   )protocolr   r-   )rh   r   r   r   r)   rD   r,   rF   r+   base64	b64encoder   ro   PROTOCOL_GUIDrn   r   r   r   r   rq   r   RFC6455WebSocketr-   )r   rN   rr   hybi_versionorigin	protocolsnegotiated_protocolprv   rw   r{   r   r   r   formatted_exts                  r   rG   z"WebSocketWSGI._handle_hybi_request  s   w&&+,7799DD')),-DDVWWW;<},,$:&H%IK K K K #L 1 1#722,,%** [[4b999025 5 *&&w{{;'?'?HH 9 8888KK =tDD	" 	>>)=)=>>>  000*+'E 1 ./#D)E$F$F$M$M$O$OPP>014x?A  	_""#>ATA[A[A]A]#]^^^11'++>]2^2^__
44Z@@6=23556GHH$""#@=#PQQQW\\/22[@AAAgt/D)<+<151FH H H 	Hr   c                 v    d}d}|D ]!}|t           j        v r||z  }|dk    r|dz  }"t          |          |z  S )z
        Utility function which, given a string like 'g98sd  5[]221@1', will
        return 9852211. Used to parse the Sec-WebSocket-Key headers.
        r   r    r~   )stringdigitsr   )r   r   outspaceschars        r   ri   zWebSocketWSGI._extract_numberU  sY    
  	 	Dv}$$t!3xx6!!r   )NNNF)r!   r"   r#   __doc__DEFAULT_MAX_FRAME_LENGTHr   classmethodr4   rS   rH   r   r   r   rG   ri   r3   r   r   r   r   @   s         ( 2J 1 1 1 1 '+"&+0	" " " [" ( ( (T<? <? <?|   $ $ $L! ! ! 7H 7H 7Hr" " " " "r   c                   @    e Zd ZdZddZd Zd Zd Zd Zdd	Z	d
 Z
dS )r   a{  A websocket object that handles the details of
    serialization/deserialization to the socket.

    The primary way to interact with a :class:`WebSocket` object is to
    call :meth:`send` and :meth:`wait` in order to pass messages back
    and forth with the browser.  Also available are the following
    properties:

    path
        The path value of the request.  This is the same as the WSGI PATH_INFO variable,
        but more convenient.
    protocol
        The value of the Websocket-Protocol header.
    origin
        The value of the 'Origin' header.
    environ
        The full WSGI environment for this request.

    rY   c                    |                     dt          j                  | _        d                    |                     d          |                     dd          |                     dd          z   |                     d          |                     d          	          | _        || _        |                     d
          | _        |                     d          | _        |                     d          | _	        || _
        || _        d| _        d| _        t          j                    | _        t#          j                    | _        dS )z
        :param socket: The eventlet socket
        :type socket: :class:`eventlet.greenio.GreenSocket`
        :param environ: The wsgi environment
        :param version: The WebSocket spec version to follow (default is 76)
        zwsgi.errorsz-server={shost}/{spath} client={caddr}:{cport}r_   r`   r   ra   REMOTE_ADDRREMOTE_PORT)shostspathcaddrcportrd   HTTP_WEBSOCKET_PROTOCOLFr   N)rD   sysstderrlogformatlog_contextr
   r   r   pathrN   versionwebsocket_closed_bufcollectionsdeque_msgsr   	Semaphore	_sendlock)r   rr   rN   r   s       r   r   zWebSocket.__init__y  s    ;;}cj99JQQ++k**++mR007;;{B3O3OO++m,,GKK4N4N R 
 

 kk-00$=>>KK,,	 %	 &((
",..r   c                     t          |t                    r|                    d          }n6t          |t                    s!t          |                                          }d|z   dz   }|S )zwPack the message inside ``00`` and ``FF``

        As per the dataframing section (5.3) for the websocket spec
        utf-8       )
isinstancer   ro   bytesr   messagepackeds      r   _pack_messagezWebSocket._pack_message  sf    
 gs## 	,nnW--GGGU++ 	,'ll))++G7"W,r   c                 v   g }d}| j         }|r|d         }|dk    r[|                    d          }|dk    rnz|                    |d|                             dd                     ||dz   d         }n9|dk    r!|d         dk    sJ d	|z              d
| _        nt          d|z            ||| _         |S )a1   Parses for messages in the buffer *buf*.  It is assumed that
        the buffer contains the start character for a message, but that it
        may contain only part of the rest of the message.

        Returns an array of messages, and the buffer remainder that
        didn't contain any full messages.r   r   r~   r   replaceN   z Unexpected closing handshake: %rTz6Don't understand how to parse this type of message: %r)r   findr   decoder   rp   )r   msgsend_idxbuf
frame_types        r   _parse_messageszWebSocket._parse_messages  s     i 	aQJQ((7++b==C'	N11'9EEFFF'A+,,'s""1v{{{$F$L{{{(,% !Y\_!_```  	a  	r   c                    |                      |          }| j                                         	 | j                            |           | j                                         dS # | j                                         w xY w)zSend a message to the browser.

        *message* should be convertable to a string; unicode objects should be
        encodable as utf-8.  Raises socket.error with errno of 32
        (broken pipe) if the socket has already been closed by the client.N)r   r   acquirer
   rq   releaser   s      r   sendzWebSocket.send  s|     ##G,, 	   	%K'''N""$$$$$DN""$$$$s   A% %B c                 "   | j         sp| j        rdS | j                            d          }|dk    rdS | xj        |z  c_        |                                 }| j                             |           | j         p| j                                         S )a"  Waits for and deserializes messages.

        Returns a single message; the oldest not yet processed. If the client
        has already closed the connection, returns None.  This is different
        from normal socket behavior because the empty string is a valid
        websocket message.Ni  r   )r   r   r
   recvr   r   extendpopleft)r   deltar   s      r   waitzWebSocket.wait  s     * 
	$$ tK$$T**E||tIIII''))DJd### * 
	$ z!!###r   Fc                     | j         dk    r?| j        s:	 | j                            d           n# t          $ r |s Y nw xY wd| _        dS dS dS )z3Sends the closing frame to the client, if required.rY   s    TN)r   r   r
   rq   rI   )r   ignore_send_errorss     r   rK   zWebSocket._send_closing_frame  s    <2d&;##K0000    *  
 %)D!!! s   / ??c                    	 |                      d           | j                            d           n`# t          $ rS}|j        t          j        k    r4| j                            d                    | j	        |                     Y d}~nd}~ww xY w| j        
                                 dS # | j        
                                 w xY w)cForcibly close the websocket; generally it is preferable to
        return from the handler method.T {ctx} socket shutdown error: {e}ctxrR   N)rK   r
   shutdownrI   errnoENOTCONNr   writer   r   rB   )r   rR   s     r   rB   zWebSocket.close  s    	 $$T***K  &&&& 	e 	e 	ew%.((AHHTM]abHccddd	e KDKs,   /2 B- 
BA	B
B- 
BB- -CN)rY   F)r!   r"   r#   r   r   r   r   r   r   rK   rB   r3   r   r   r   r   d  s         (/ / / /0
 
 
  :% % %$ $ $(
) 
) 
) 
)
  
  
  
  
 r   c                       e Zd ZdS )ConnectionClosedErrorNr!   r"   r#   r3   r   r   r  r            Dr   r  c                        e Zd Z fdZ xZS )FailedConnectionErrorc                 h    t                                          ||           || _        || _        d S r   )r   r   r   r   )r   r   r   r   s      r   r   zFailedConnectionError.__init__  s/    )))r   r    r%   s   @r   r
  r
    s8                r   r
  c                       e Zd ZdS )ProtocolErrorNr  r3   r   r   r  r    r  r   r  c                        e Zd Zddddef fd	Z G d d          Zd Zd Zd	 Z G d
 d          Z	e
dd            Zd Zd ZddZ	 	 ddZd Zd Zd ZddZddZ xZS )r      NFc                     t                                          |||           |                                 | _        || _        || _        |pi | _        d | _        d | _        || _	        d | _
        d S r   )r   r   _iter_framesiteratorclientr   r   _deflate_enc_deflate_decr-   _remote_close_data)	r   rr   rN   r   r   r  r   r-   r   s	           r   r   zRFC6455WebSocket.__init__  sr    w000))++ $*   0"&r   c                   "    e Zd Zd Zd ZddZdS )RFC6455WebSocket.UTF8Decoderc                     t           rt                                           | _        nd | _        t          j        d          } |            | _        d S )Nutf8)utf8validatorUtf8Validator	validatorcodecsgetincrementaldecoderdecoder)r   decoderclasss     r   r   z%RFC6455WebSocket.UTF8Decoder.__init__  sG     &!.!<!<!>!>!%!7??L'<>>DLLLr   c                 x    | j         r| j                                          | j                                         d S r   )r  resetr   )r   s    r   r#  z"RFC6455WebSocket.UTF8Decoder.reset  s:    ~ '$$&&&L     r   Fc                     | j         r0| j                             |          \  }}}}|st          d          | j                            ||          S )NzData is not valid unicode)r  validaterp   r   r   )r   datafinalvalideocpc_it_is          r   r   z#RFC6455WebSocket.UTF8Decoder.decode!  s[    ~ B(,(?(?(E(E%tS# B$%@AAA<&&tU333r   Nr  )r!   r"   r#   r   r#  r   r3   r   r   UTF8Decoderr    sF        	* 	* 	*	! 	! 	!
	4 	4 	4 	4 	4 	4r   r,  c                       j                             d          d S  fd}                     j        rdnd          r
 |            S  j         |             _         j        S )Nr   c                      t          j        t           j        t           j                             j        rdndt           j                             S )Nr   r   )r   compressobjZ_DEFAULT_COMPRESSIONDEFLATEDrD   r  r   optionsr   s   r   _makez;RFC6455WebSocket._get_permessage_deflate_enc.<locals>._make-  sU    #D$>%,[[T[ 2O1I1I6N15&A &A %AB B Br   r   r   )r   rD   r  r  )r   r4  r3  s   ` @r   _get_permessage_deflate_encz,RFC6455WebSocket._get_permessage_deflate_enc(  s    /%%&:;;?4	B 	B 	B 	B 	B 	B ;;t{ 9338: : 	% 577N ($)EGG!$$r   c                       j                             d          |sd S  fd}                     j        rdnd          r
 |            S  j         |             _         j        S )Nr   c                  |    t          j                             j        rdndt           j                             S )Nr   r   )r   decompressobjrD   r  r   r2  s   r   r4  z;RFC6455WebSocket._get_permessage_deflate_dec.<locals>._makeA  sK    %w{{t{ 4Q3K3K8P37>(C (C 'C D D Dr   r   r   )r   rD   r  r  )r   rsv1r4  r3  s   `  @r   _get_permessage_deflate_decz,RFC6455WebSocket._get_permessage_deflate_dec<  s    /%%&:;;?$?4	D 	D 	D 	D 	D 	D
 ;;t{ 9338: : 	% 577N ($)EGG!$$r   c                     d}t          |          |k     rR| j                            |t          |          z
            }|st                      ||z   }t          |          |k     R|S )Nr   )r   r
   r   r  )r   numbytesr&  ds       r   
_get_byteszRFC6455WebSocket._get_bytesO  so    $ii(""  CII!566A .+---!8D	 $ii(""
 r   c                   $    e Zd ZddZddZd ZdS )RFC6455WebSocket.MessageNc                 Z    || _         g | _        d| _        || _        || _        || _        d S )NF)r   r&  finishedopcodedecompressorr-   )r   rC  r-   r   rD  s        r   r   z!RFC6455WebSocket.Message.__init__Y  s4    "DLDI!DM DK ,D$4D!!!r   Fc                 H    || _         | j                            |           d S r   )rB  r&  r   )r   r&  r'  s      r   pushzRFC6455WebSocket.Message.pusha  s%    !DMIT"""""r   c                 X   d                     | j                  }| j        dz  s^| j        rW| j                            |dz   | j                  }| j        j        r(t          dd                    | j                            | j	        r | j	        
                    || j                  }|S )Nr   r\          z;Incoming compressed frame exceeds length limit of {} bytes.)r   r&  rC  rD  
decompressr-   unconsumed_tailr
  r   r   r   rB  )r   r&  s     r   getvaluez!RFC6455WebSocket.Message.getvaluee  s    88DI&&D;? ut'8 u(33D;N4NPTPeff$4 u/U\\]a]rssu u u | @|**4??Kr   )NNr  )r!   r"   r#   r   rF  rL  r3   r   r   Messager@  X  sK        	5 	5 	5 	5	# 	# 	# 	#	 	 	 	 	r   rM  r   c                      |t                     }t          |          }d                     fd|D                       S )Nr   c              3   b   K   | ])}t          |         |z   d z           z  f          V  *dS )   N)r   )r9   r   r&  maskoffsets     r   r   z/RFC6455WebSocket._apply_mask.<locals>.<genexpr>w  sE      PPqtAwvzQ.>)??ABBPPPPPPr   )r   ranger   )r&  rQ  lengthrR  cnts   `` ` r   _apply_maskzRFC6455WebSocket._apply_maskr  sM    >YYFFmmxxPPPPPPCPPPPPPr   c                 $   |dk    r|| _         |sd}nt          |          dk    rt          j        d|          d         }|r	|t          vrt          dd          	 |                                                     |dd          d	          }n'# t          t          f$ r t          dd
          w xY wd}| 
                    |df           t                      |dk    r|                     |d           d S |dk    rd S t          dd          )Nr\   r   r~   !Hr     zUnexpected close status code.   Tz)Close message data should be valid UTF-8.r   
close_data	   
   control_codezUnknown control frame received.)r  r   rl   unpack_fromVALID_CLOSE_STATUSr
  r,  r   UnicodeDecodeErrorrp   rB   r  r   )r   rC  r&  r   s       r   _handle_control_framez&RFC6455WebSocket._handle_control_framey  sY   Q;;&*D# TQ+D$77: 9/A!A!A/79 9 9E++--44T!""XtDDDD*J7 E E E/CE E EE
 JJ62,J///')))q[[IIdI-----s]]D'79 9 9s   0B "B0c              #     K   d }	 	 |                      |          }|j        dz  r.|                     |j        |                                           O|r||urt	          d          |}|j        r|                                }d }|V  # t          $ r= t          j                    \  }}}| 	                    |j
        |j        f           Y d S t          $ r Y d S t          $ r | 	                    d            w xY w)NT)r   r\   zUnexpected message change.r[  )i  zInternal Server Error)_recv_framerC  rd  rL  RuntimeErrorrB  r
  r   exc_inforB   r   r   r  r   )r   fragmented_messager   r&  exc_typexc_valexc_tbs          r   r  zRFC6455WebSocket._iter_frames  s^     !	**3E*FF>A% ..(8(8(:(:< < <% E'9K*K*K&'CDDD%,"# -6688D)-&JJJ % 	E 	E 	E'*|~~$GWfJJ7>7?"CJDDDDDD$ 	 	 	FF 	 	 	JJ"AJBBB	s   BB AD	D !Dc                 n   | j         } |d          }t          j        d|          \  }}|dz	  dk    }|dz	  dz  }|dz  }|r|rd| j        vrt	          dd          |d	z  }	|	d
vrt	          dd          |dz  dk    }
|
s| j        st	          dd          |dz  }|	dz  r)|st	          dd          |dk    rt	          dd          n(|	r|rt	          dd          |	s|st	          dd          |dk    r%t          j        d |d                    d         }n*|dk    r$t          j        d |d                    d         }|| j        k    r)t	          dd                    || j                            |
rt          j        d |d                    }d}|r|	dz  rO|	dk    r|                                 nd }| 	                    |          }| 
                    |	| j        ||          }|s|                    d|           n||k     r| j                            ||z
            }|st                      t          |          }|
r|                     ||||          }||z   }	 |                    ||           n%# t"          t$          f$ r t	          d d!          w xY w||k     |S )"NrZ  z!BB   r~   rP  r   rY  zhRSV1, RSV2, RSV3: MUST be 0 unless an extension is negotiated that defines meanings for non-zero values.r   )r   r~   rZ  r\   r]  r^  zUnknown opcode received.   z9A client MUST mask all frames that it sends to the server   r\   z&Control frames must not be fragmented.}   zBAll control frames MUST have a payload length of 125 bytes or lessz=Received a non-continuation opcode within fragmented message.zAReceived continuation opcode with no previous fragments received.~   rX  r   z!QrI  z=Incoming frame of {} bytes is above length limit of {} bytes.!BBBB)r   rD  r   )r'  )rT  rR  r   zText data must be valid utf-8)r>  rl   unpackr   r
  r  r-   r   r,  r:  rM  rF  r
   r   r  r   rV  rc  rp   )r   r   r   r   abrB  rsv123r9  rC  maskedrT  rQ  receivedr   rD  r=  dlens                     r   rf  zRFC6455WebSocket._recv_frame  s    a}UF++16Q;a!z 	N N,DOCC+MN N N R---'.HIIISC 	Hdk 	H' /G H H HSA: 	( ?+D 3> ? ? ?||+%& & & 
  		( 		(''( ( (  	( 	(''( ( ( S==]4a11!4FFs]]]4a11!4FD)))'.m.t.t-// // 0 0 0 	3=$$q''22D 	n&1* 	n,2aKKd&&(((TG;;DAALll64+@'`llmmG 	?LLHL----V##K$$Vh%677 2/1111vv P((Dh(OOA#d??LL(L3333*J7 ? ? ?/=? ? ?? V## s   2J
 
"J,Tc                 :   d}t          |t                    r|                    d          }d}d}|                                 }|pddz  }	|rW|rU|	sS|                    |          }||                    t          j                  z  }|dd          dk    sJ |d d         }d}t          |          }
|
sd}|rT|d	vrt          d
          |s|st          d          |
dk    rt          d          t          j        d|dz            }n)|rdn|rdnd|z  }t          j        d||rdndz            }|rdnd}|
dk    rt          j        d|dz  |
          }n8|
dk    rt          j        d|dz  |
          }nt          j        d||
z            }|rjt          t          j                              fdt          d          D             }t                              |||
          }t          j        dg|R  }nd}d                    ||||f          S )NFr   Tr   r\   rH  @   )r\   r]  r^  zUnknown control opcode.z#Control frame cannot be a fragment.rq  z$Control frame data too large (>125).z!Bro  r~   rZ  i  z!BQrp  z!BHrr  c                 :    g | ]}                     d           S )r\   )getrandbits)r9   _rands     r   r;   z2RFC6455WebSocket._pack_message.<locals>.<listcomp>0  s'    :::AD$$Q'':::r   rP  rs  r   )r   r   ro   r5  compressflushr   Z_SYNC_FLUSHr   r  rl   rm   r   timerS  r   rV  r   )r   r   rx  continuationr'  r`  is_textcompress_bit
compressoris_control_framerT  r   rC  
lengthdatarQ  maskdatar  s                   @r   r   zRFC6455WebSocket._pack_message  s   gs## 	nnW--GG5577
 )-A2
  	"z 	"*: 	" ))'22Gz''(9:::G233<#66666crclG!LW 	F 
	J;..#$=>>> K5 K#$IJJJ||#$JKKK[|f'<==FF&RQQ7.Aaa\-QF[v51Ga'HIIF%,VV1
E>>UJ,<fEEJJc\\UJ,<fEEJJT:+>??J 	 $)++&&D::::q:::D&227D&IIG{72T222HHHxxXw?@@@r   c                      | j         D ]}|c S d S r   )r  )r   r   s     r   r   zRFC6455WebSocket.wait8  s&     	 	AHHH	 	r   c                     | j                                          	 | j                            |           | j                                          d S # | j                                          w xY wr   )r   r   r
   rq   r   )r   frames     r   _sendzRFC6455WebSocket._send<  se       	%K&&&N""$$$$$DN""$$$$s   A A+c                 `    | j         |d<    | j        |fi |}|                     |           d S )Nrx  )r  r   r  )r   r   kwpayloads       r   r   zRFC6455WebSocket.sendC  s?    {8$$$W3333

7r   c                 ,   | j         dv r| j        s|H|\  }}t          |t                    r|                    d          }t          j        d|          |z   }nd}	 |                     |d           n# t          $ r |s Y nw xY wd| _        d S d S d S )N)r\   r  r   rX  r   r\   r_  T)	r   r   r   r   ro   rl   rm   r   rI   )r   r   r\  r   msgr&  s         r   rK   z$RFC6455WebSocket._send_closing_frameH  s    <7""4+@"%(c3'' .**W--C{40036		$Q	////    *  
 %)D!!! #"""s   A6 6BBc                    	 |                      |d           | j                            t          j                   n`# t          $ rS}|j        t
          j        k    r4| j                            d	                    | j
        |                     Y d}~nd}~ww xY w| j                                         dS # | j                                         w xY w)r   T)r\  r   r   r   N)rK   r
   r   SHUT_WRrI   r  r  r   r  r   r   rB   )r   r\  rR   s      r   rB   zRFC6455WebSocket.closeZ  s    	 $$
t$TTTK  0000 	e 	e 	ew%.((AHHTM]abHccddd	e KDKs-   ;> B9 
BA	BB9 BB9 9C)Nr   r   )FFTN)FN)r!   r"   r#   r   r   r,  r5  r:  r>  rM  staticmethodrV  rd  r  rf  r   r   r  r   rK   rB   r$   r%   s   @r   r   r     s       .04Z^":' ' ' ' ' '4 4 4 4 4 4 4 4*% % %(% % %&         4 Q Q Q \Q9 9 9:  2K K K KZ -2CG:A :A :A :Ax  % % %  
) ) ) )$
  
  
  
  
  
  
  
 r   r   )0r   r  r   r  randomr   r
   r   SocketErrorr   rl   r   r  r   hashlibr   r   ImportErrorr   eventletr   r	   eventlet.greeneventlet.supportr   _mod
__import__r  
ECONNRESETEPIPE	ESHUTDOWNrJ   r   __all__r   setlistrS  rb  r   r   r   r   r  r
  rp   r  r   r3   r   r   <module>r     s                ' ' ' ' ' '   



   !!!!!!!!!                    ! ! ! ! ! ! & & & & & &
 @ 	 	D"
4R"66 	    
 ",ek5?K " K
(7SDtT		DtT		 	DtT			 	DtT			 	        a" a" a" a" a" a" a" a"H	O  O  O  O  O  O  O  O d	 	 	 	 	I 	 	 	    I   	 	 	 	 	J 	 	 	_  _  _  _  _ y _  _  _  _  _ s!   ; AA/B  B
	B
