
    AҐi1/                         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                   `    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dZy)WebSocketProtocolz3WebSocket connection handler for ASGI applications.c                     || _         || _        || _        || _        || _        d| _        d| _        d| _        d| _        g | _	        d| _
        t        j                         | _        y)a!  Initialize WebSocket protocol handler.

        Args:
            transport: asyncio transport for writing
            reader: asyncio StreamReader for reading
            scope: ASGI WebSocket scope dict
            app: ASGI application callable
            log: Logger instance
        FN )	transportreaderscopeapplogacceptedclosed
close_codeclose_reason
_fragments_fragment_opcodeasyncioQueue_receive_queue)selfr   r   r   r   r   s         P/var/www/descvideos/venv/lib/python3.12/site-packages/gunicorn/asgi/websocket.py__init__zWebSocketProtocol.__init__-   se     #
  $ &mmo    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.runI   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   get)r   s    r   r#   zWebSocketProtocol._receive`   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_NORMALr)   )r   messagemsg_typer3   r4   s        r   r$   zWebSocketProtocol._sendd   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   r5   base64	b64encodehashlibsha1WS_GUIDdigestdecoder.   append
isinstancer2   r   writejoinr9   )	r   r<   ws_keynamevalue
accept_keyr?   rA   extra_headerss	            r   r6   zWebSocketProtocol._send_accept   sl     ::i0 	KD%++	
 ABB %%LL')*113

&/ 	 3$%$ZL5	
 kk-0NN5k]$GH  Ir2( 	3KD%$&{{9-%'Y/NNdV2eWD12	3 	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.receiver1   )r   r0   )r   r2   zWebSocket read error: %sTzwebsocket.disconnect)r   r3   )r   _read_frameOPCODE_CLOSE_handle_closeOPCODE_PINGr7   OPCODE_PONGr8   r   r    rH   r:   OPCODE_CONTINUATION_handle_continuationr   r(   r%   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_exactr)   CLOSE_PROTOCOL_ERRORstructunpack_unmaskrX   r   r   rI   rL   r8   r:   )r   header
first_bytesecond_bytefinrsv1rsv2rsv3r]   maskedpayload_lenext_lenmasking_keyr^   full_payloadfinal_opcodes                   r   rS   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   	 | j                   j                  |       d{   }|S 7 # t        j                  $ r Y yt        $ r Y yw xY ww)z%Read exactly n bytes from the reader.N)r   readexactlyr   IncompleteReadErrorr%   )r   ndatas      r   rj   zWebSocketProtocol._read_exact)  sN     	0033DK 4** 	 		s<   A+ )+ A+ AA AA
AAc                 F    |s|S t        fdt        |      D              S )zUnmask WebSocket payload data.c              3   :   K   | ]  \  }}||d z     z    yw)rd   N ).0ibry   s      r   	<genexpr>z,WebSocketProtocol._unmask.<locals>.<genexpr>8  s#     K1QQU++Ks   )r2   	enumerate)r   r^   ry   s     `r   rn   zWebSocketProtocol._unmask3  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   rh   Nr   r1   replace)errorsr   T)	lenrl   rm   r   rH   r   CLOSE_NO_STATUSr   r)   r   r^   s     r   rU   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   rY   z&WebSocketProtocol._handle_continuationI  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).
        r1      rg   i   rh   rf   ri   N)rJ   strr9   r   	bytearrayrI   extendrl   packr   rK   r2   )r   r]   r^   lengthr\   s        r   r7   zWebSocketProtocol._send_frameM  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.rh   r1   N{   T)rl   r   r9   r7   rT   r   )r   r3   r4   r^   s       r   r)   zWebSocketProtocol._send_closej  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#   r$   r6   r"   rS   rj   rn   rU   rY   r7   r)   r   r   r   r	   r	   *   sN    =.8R./6(AT,\P%dLL+:r   r	   )r   r   rB   rD   rl   rX   r8   r:   rT   rV   rW   r;   CLOSE_GOING_AWAYrk   CLOSE_UNSUPPORTEDr   r[   CLOSE_INVALID_DATACLOSE_POLICY_VIOLATIONCLOSE_MESSAGE_TOO_BIGCLOSE_MANDATORY_EXTr*   rF   r	   r   r   r   <module>r      s   
                2F Fr   