
    [if3                         d Z ddlZddlZddlZddlZdZdZdZdZdZ	dZ
dZd	Zd
ZdZdZdZdZdZdZdZdZdZ G d d      Zy)ze
WebSocket protocol handler for ASGI.

Implements RFC 6455 WebSocket protocol for ASGI applications.
    N         	   
   i  i  i  i  i  i  i  i  i  i  i  s$   258EAFA5-E914-47DA-95CA-C5AB0DC85B11c                   l    e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Zd ZddZy)WebSocketProtocolzWebSocket connection handler for ASGI applications.

    Uses callback-based data feeding instead of StreamReader for efficiency.
    Data is fed via feed_data() from the parent protocol's data_received().
    c                     || _         || _        || _        || _        d| _        d| _        d| _        d| _        g | _        d| _	        t        j                         | _        t               | _        t        j                         | _        d| _        y)zInitialize WebSocket protocol handler.

        Args:
            transport: asyncio transport for writing
            scope: ASGI WebSocket scope dict
            app: ASGI application callable
            log: Logger instance
        FN )	transportscopeapplogacceptedclosed
close_codeclose_reason
_fragments_fragment_opcodeasyncioQueue_receive_queue	bytearray_bufferEvent_data_event_eof)selfr   r   r   r   s        h/var/www/html/userprofiledev.eatanceapp.com/venv/lib/python3.12/site-packages/gunicorn/asgi/websocket.py__init__zWebSocketProtocol.__init__1   s~     #
  $ &mmo !{"==?	    c                 t    |r6| j                   j                  |       | j                  j                          yy)zFeed incoming data from the parent protocol's data_received().

        Args:
            data: bytes received on the connection
        N)r   extendr   set)r   datas     r   	feed_datazWebSocketProtocol.feed_dataP   s0     LL%  " r!   c                 F    d| _         | j                  j                          y)z+Signal that the connection has been closed.TN)r   r   r$   r   s    r   feed_eofzWebSocketProtocol.feed_eofZ   s    	r!   c                 4  K   | j                   j                  ddi       d{    t        j                  | j	                               }	 | j                  | j                  | j                  | j                         d{    |j                          	 | d{    | j                  s,| j                  r| j!                  t"        d       d{    yyy7 7 Z# t        $ r | j                  j                  d       Y ~w xY w7 k# t        j                  $ r Y ~w xY w7 P# |j                          	 | d{  7   n# t        j                  $ r Y nw xY w| j                  s-| j                  r | j!                  t"        d       d{  7   w w w xY ww)z#Run the WebSocket ASGI application.typezwebsocket.connectNz#Error in WebSocket ASGI applicationzApplication error)r   putr   create_task_read_framesr   r   _receive_send	Exceptionr   	exceptioncancelCancelledErrorr   r   _send_closeCLOSE_INTERNAL_ERROR)r   	read_tasks     r   runzWebSocketProtocol.run_   sh     !!%%v/B&CDDD ''(9(9(;<		R((4::t}}djjAAA 
 ;;4==&&';=PQQQ $1;# 	E B 	FHHDE	F
  )) 
 R ))  ;;4==&&';=PQQQ $1;s   !FC'F4C  CC FD	 DD	  1FD"FC $DD$ DD$ D	 	DFDF$F6E;D><EFEFE4FFFFc                 R   K   | j                   j                          d{   S 7 w)zASGI receive callable.N)r   getr(   s    r   r/   zWebSocketProtocol._receivev   s!     ((,,....s   '%'c                 \  K   |d   }|dk(  r8| j                   rt        d      | j                  |       d{    d| _         y|dk(  r| j                   st        d      | j                  rt        d      d	|v r1| j	                  t
        |d	   j                  d
             d{    yd|v r"| j	                  t        |d          d{    yy|dk(  rJ|j                  dt              }|j                  dd      }| j                  ||       d{    d| _        yy7 7 ~7 Z7 w)zASGI send callable.r+   zwebsocket.acceptzWebSocket already acceptedNTzwebsocket.sendzWebSocket not acceptedzWebSocket closedtextutf-8byteszwebsocket.closecodereasonr   )r   RuntimeError_send_acceptr   _send_frameOPCODE_TEXTencodeOPCODE_BINARYr:   CLOSE_NORMALr5   )r   messagemsg_typer?   r@   s        r   r0   zWebSocketProtocol._sendz   s-    6?))}}"#?@@##G,,, DM))=="#;<<{{"#566 &&{GFO4J4J74STTTG#&&}gg6FGGG $ **;;v|4D[[2.F""4000DK	 + - UG
 1sG   6D,D$A.D,'D&(%D,D(AD,D*D,&D,(D,*D,c                   K   d}| j                   d   D ]  \  }}|dk(  s|} n |st        d      t        j                  t	        j
                  |t        z         j                               j                  d      }dddd	| d
g}|j                  d      }|r|j                  d| d
       |j                  dg       }|D ]^  \  }}t        |t              r|j                  d      }t        |t              r|j                  d      }|j                  | d| d
       ` |j                  d
       | j                  j                  dj                  |      j!                  d             yw)z)Send WebSocket handshake accept response.Nheaderss   sec-websocket-keyz Missing Sec-WebSocket-Key headerasciiz"HTTP/1.1 101 Switching Protocols
zUpgrade: websocket
zConnection: Upgrade
zSec-WebSocket-Accept: z
subprotocolzSec-WebSocket-Protocol: zlatin-1z: r   )r   rA   base64	b64encodehashlibsha1WS_GUIDdigestdecoder:   append
isinstancer>   r   writejoinrE   )	r   rH   ws_keynamevalue
accept_keyrK   rM   extra_headerss	            r   rB   zWebSocketProtocol._send_accept   sb     ::i0KD%++ 1
 ABB %%LL')*113

&/ 	 3$%$ZL5	
 kk-0NN5k]$GH  Ir2(KD%$&{{9-%'Y/NNdV2eWD12 ) 	vRWWW-44Y?@s   E0EE0c                 8  K   	 | j                   s| j                          d{   }|n|\  }}|t        k(  r| j                  |       d{    n|t        k(  r| j                  t        |       d{    n|t        k(  rn|t        k(  r6| j                  j                  d|j                  d      d       d{    nR|t        k(  r'| j                  j                  d|d       d{    n"|t        k(  r| j                  |       d{    | j                   s| j                   s@d| _         | j                  j                  d| j&                  xs t(        d	       d{    yy7 N7 '7 7 7 7 l# t        j                  $ r  t         $ r&}| j"                  j%                  d|       Y d}~d}~ww xY w7 Z# | j                   sAd| _         | j                  j                  d| j&                  xs t(        d	       d{  7   w w xY ww)
z+Read and process incoming WebSocket frames.Nzwebsocket.receiver=   )r+   r<   )r+   r>   zWebSocket read error: %sTzwebsocket.disconnect)r+   r?   )r   _read_frameOPCODE_CLOSE_handle_closeOPCODE_PINGrC   OPCODE_PONGrD   r   r,   rT   rF   OPCODE_CONTINUATION_handle_continuationr   r4   r1   r   debugr   CLOSE_ABNORMAL)r   frameopcodepayloades        r   r.   zWebSocketProtocol._read_frames   s    *	kk"..00="'\),,W555[(**;@@@{*{*--11 3 'w 73    },--11 3!(3    2233G<<<9 kkH ;;"))--2 OO=~/    G 1 6 A

 =%% 	 	:HHNN5q99	: ;;"))--2 OO=~/    s   H F E2)F E5'F 6E87AF ?E; /F /E=0"F E?F %AH+G,H2F 5F 8F ;F =F ?F GF>9G >GG HAHHHHc                 r  K   | j                  d       d{   }|sy|d   |d   }}|dz	  dz  }|dz	  dz  }|dz	  dz  }|dz	  dz  }|d	z  }|s|s|r| j                  t        d
       d{    y|dz	  dz  }	|dz  }
|	s| j                  t        d       d{    y|
dk(  r6| j                  d       d{   }|syt        j                  d|      d   }
n:|
dk(  r5| j                  d       d{   }|syt        j                  d|      d   }
| j                  d       d{   }|sy| j                  |
       d{   }|y| j                  ||      }|t        k(  r| j                  | j                  t        d       d{    y| j                  j                  |       |r9dj                  | j                        }| j                  }g | _        d| _        ||fS t        dfS |t        t        fv r|s|| _        |g| _        t        dfS ||fS ||fS 7 
7 7 7 p7 87 7 7 w)z{Read a single WebSocket frame.

        Returns:
            tuple: (opcode, payload) or None if connection closed
        r   Nr   r                  zRSV bits set   zFrame not masked~   !Hr   !QzUnexpected continuationr!   )_read_exactr5   CLOSE_PROTOCOL_ERRORstructunpack_unmaskrd   r   r   rU   rX   rD   rF   )r   header
first_bytesecond_bytefinrsv1rsv2rsv3ri   maskedpayload_lenext_lenmasking_keyrj   full_payloadfinal_opcodes                   r   r_   zWebSocketProtocol._read_frame   s     ''**"()VAYK
Q!#a1$a1$a1$d" 44""#7HHH"a'!D( ""#79KLLL # ,,Q//G --g6q9KC ,,Q//G --g6q9K !,,Q// ((55? ,,w4 (($$,&&';=VWWWOO""7+"xx8#44"$(,%$l33'--]33(.%#*)+S11G$$ G$$S + I M
 0
 0 0
 6 Xs   H7H!AH7-H$.-H7H'H7:H*;:H75H-64H7*H0+H7H3AH7H5BH7$H7'H7*H7-H70H73H75H7c                   K   t        | j                        |k  r| j                  ry| j                  j	                          t        | j                        |k\  rn`| j                  j                          d{    | j                  rt        | j                        |k  ryt        | j                        |k  rt        | j                  d|       }| j                  d|= |S 7 kw)zRead exactly n bytes from internal buffer.

        Waits for data via the callback-fed buffer instead of StreamReader.
        N)lenr   r   r   clearwaitr>   )r   nr%   s      r   rv   zWebSocketProtocol._read_exact?  s     
 $,,!#yy""$ 4<< A%""'')))yyS.2 $,,!# T\\"1%&LL! *s   A6C&8C$9AC&;*C&c                 F    |s|S t        fdt        |      D              S )zUnmask WebSocket payload data.c              3   :   K   | ]  \  }}||d z     z    yw)rp   N ).0ibr   s      r   	<genexpr>z,WebSocketProtocol._unmask.<locals>.<genexpr>Y  s&     K8J1QQU++8Js   )r>   	enumerate)r   rj   r   s     `r   rz   zWebSocketProtocol._unmaskT  s!    NK	'8JKKKr!   c                 L  K   t        |      dk\  r=t        j                  d|dd       d   | _        |dd j	                  dd      | _        nt        | _        d| _        | j                  s.| j                  | j                  | j
                         d{    d	| _        y7 w)
zHandle incoming close frame.r   rt   Nr   r=   replace)errorsr   T)	r   rx   ry   r   rT   r   CLOSE_NO_STATUSr   r5   r   rj   s     r   ra   zWebSocketProtocol._handle_close[  s     w<1$mmD'"1+>qADO ' 2 279 2 MD-DO "D {{""4??D4E4EFFF Gs   BB$B"B$c                    K   yw)z=Handle continuation frame (already processed in _read_frame).Nr   r   s     r   re   z&WebSocketProtocol._handle_continuationj  s     s   c                   K   t        |t              r|j                  d      }t        |      }t	               }|j                  d|z         |dk  r|j                  |       nr|dk  r7|j                  d       |j                  t        j                  d|             n6|j                  d       |j                  t        j                  d|             |j                  |       | j                  j                  t        |             yw)	zRSend a WebSocket frame.

        Server frames are not masked (RFC 6455).
        r=      rs   i   rt   rr   ru   N)rV   strrE   r   r   rU   r#   rx   packr   rW   r>   )r   ri   rj   lengthrh   s        r   rC   zWebSocketProtocol._send_framen  s     
 gs#nnW-GW 	TF]# C<LL e^LLLLT623LLLLT623 	WU5\*s   D
Dc                    K   t        j                  d|      }|r||j                  d      dd z  }| j                  t        |       d{    d| _        y7 w)zSend a close frame.rt   r=   N{   T)rx   r   rE   rC   r`   r   )r   r?   r@   rj   s       r   r5   zWebSocketProtocol._send_close  sU     ++dD)v}}W-ds33G|W555 	6s   A	AAAN)r   )__name__
__module____qualname____doc__r    r&   r)   r8   r/   r0   rB   r.   r_   rv   rz   ra   re   rC   r5   r   r!   r   r	   r	   *   sZ    >#
R./6(AT,\P%d*LL+:r!   r	   )r   r   rN   rP   rx   rd   rD   rF   r`   rb   rc   rG   CLOSE_GOING_AWAYrw   CLOSE_UNSUPPORTEDr   rg   CLOSE_INVALID_DATACLOSE_POLICY_VIOLATIONCLOSE_MESSAGE_TOO_BIGCLOSE_MANDATORY_EXTr6   rR   r	   r   r!   r   <module>r      s   
                2g gr!   