
    Gi1/                         S r SSKrSSKrSSKrSSKrSrSrSrSrSr	Sr
SrS	rS
rSrSrSrSrSrSrSrSrSr " S S5      rg)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                   j    \ rS rSrSrS rS rS rS rS r	S r
S	 rS
 rS rS rS rS rSS jrSrg)WebSocketProtocol*   z3WebSocket connection handler for ASGI applications.c                     Xl         X l        X0l        X@l        XPl        SU l        SU l        SU l        SU l        / U l	        SU l
        [        R                  " 5       U l        g)zInitialize 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         a/var/www/fortnox.synktek.com/backend/venv/lib/python3.13/site-packages/gunicorn/asgi/websocket.py__init__WebSocketProtocol.__init__-   s[     #
  $ &mmo    c                 d  #    U R                   R                  SS05      I Sh  vN   [        R                  " U R	                  5       5      n U R                  U R                  U R                  U R                  5      I Sh  vN   UR                  5          UI Sh  vN   U R                  (       d1  U R                  (       a  U R!                  ["        S5      I Sh  vN   ggg N Nd! [         a    U R                  R                  S5         Nf = f Nv! [        R                   a     Nf = f NR! UR                  5          UI Sh  vN    O! [        R                   a     Of = fU R                  (       d2  U R                  (       a   U R!                  ["        S5      I Sh  vN    f f f = f7f)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   runWebSocketProtocol.runI   sf     !!%%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   !F0C$(F04C( C&C( F0D DD !;F0D/F0&C( (%DD1 DD1 D D,)F0+D,,F01F-EE	EF-E&#F-%E&&>F-$F'%F--F0c                 R   #    U R                   R                  5       I Sh  vN $  N7f)zASGI receive callable.N)r   get)r   s    r   r%   WebSocketProtocol._receive`   s      ((,,....s   '%'c                   #    US   nUS:X  a=  U R                   (       a  [        S5      eU R                  U5      I Sh  vN   SU l         gUS:X  a  U R                   (       d  [        S5      eU R                  (       a  [        S5      eS	U;   a1  U R	                  [
        US	   R                  S
5      5      I Sh  vN   gSU;   a"  U R	                  [        US   5      I Sh  vN   ggUS:X  aI  UR                  S[        5      nUR                  SS5      nU R                  X45      I Sh  vN   SU l        gg N N NZ N7f)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_BINARYr1   CLOSE_NORMALr+   )r   messagemsg_typer7   r8   s        r   r&   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   <ED9A;E:D;;'E"D=#AE+D?,E;E=E?Ec                   #    SnU R                   S    H  u  p4US:X  d  M  Un  O   U(       d  [        S5      e[        R                  " [        R
                  " U[        -   5      R                  5       5      R                  S5      nSSSS	U S
3/nUR                  S5      nU(       a  UR                  SU S
35        UR                  S/ 5      nU Hh  u  p4[        U[        5      (       a  UR                  S5      n[        U[        5      (       a  UR                  S5      nUR                  U SU S
35        Mj     UR                  S
5        U R                  R                  SR                  U5      R!                  S5      5        g7f)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   r9   base64	b64encodehashlibsha1WS_GUIDdigestdecoder1   append
isinstancer6   r   writejoinr=   )	r   r@   ws_keynamevalue
accept_keyrD   rF   extra_headerss	            r   r:   WebSocketProtocol._send_accept   sc     ::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   F	E(F	c                   #     U R                   (       Gd!  U R                  5       I Sh  vN nUc  GOUu  p#U[        :X  a  U R                  U5      I Sh  vN   OU[        :X  a  U R                  [        U5      I Sh  vN   OU[        :X  a  OU[        :X  a6  U R                  R                  SUR                  S5      S.5      I Sh  vN   OTU[        :X  a'  U R                  R                  SUS.5      I Sh  vN   O#U[        :X  a  U R                  U5      I Sh  vN   U R                   (       d  GM!  U R                   (       dE  SU l         U R                  R                  SU R&                  =(       d    [(        S	.5      I Sh  vN   gg GNe GN< GN N N N|! [        R                   a    e [          a&  nU R"                  R%                  SU5         SnANSnAff = f N\! U R                   (       dF  SU l         U R                  R                  SU R&                  =(       d    [(        S	.5      I Sh  vN    f f = f7f)
z+Read and process incoming WebSocket frames.Nzwebsocket.receiver5   )r!   r4   )r!   r6   zWebSocket read error: %sTzwebsocket.disconnect)r!   r7   )r   _read_frameOPCODE_CLOSE_handle_closeOPCODE_PINGr;   OPCODE_PONGr<   r   r"   rM   r>   OPCODE_CONTINUATION_handle_continuationr   r*   r'   r   debugr   CLOSE_ABNORMAL)r   frameopcodepayloades        r   r$   WebSocketProtocol._read_frames   s    *	kkk"..00="'\),,W555[(**;@@@{*{*--11 3 'w 73    },--11 3!(3    2233G<<<9 kkkH ;;"))--2 OO=~/    G 1 6 A

 =%% 	 	:HHNN5q99	: ;;"))--2 OO=~/    s   I%F FF G& "F FF G& #F >F?A
F 	F
0F :F;#F FF 7AIG$IF F F F F F G!;GG& G!!G& $I&AH?7H:8H??Ic                   #    U R                  S5      I Sh  vN nU(       d  gUS   US   p2US-	  S-  nUS-	  S-  nUS-	  S-  nUS-	  S-  nUS	-  nU(       d  U(       d  U(       a  U R                  [        S
5      I Sh  vN   gUS-	  S-  n	US-  n
U	(       d  U R                  [        S5      I Sh  vN   gU
S:X  a<  U R                  S5      I Sh  vN nU(       d  g[        R                  " SU5      S   n
OAU
S:X  a;  U R                  S5      I Sh  vN nU(       d  g[        R                  " SU5      S   n
U R                  S5      I Sh  vN nU(       d  gU R                  U
5      I Sh  vN nUc  gU R                  X5      nU[        :X  a  U R                  c  U R                  [        S5      I Sh  vN   gU R                  R                  U5        U(       a8  SR                  U R                  5      nU R                  n/ U l        SU l        X4$ [        S4$ U[        [        4;   a   U(       d  Xl        U/U l        [        S4$ X4$ X4$  GN? GN GN GN GNM GN N N7f)zcRead 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_unmaskr^   r   r   rN   rQ   r<   r>   )r   header
first_bytesecond_bytefinrsv1rsv2rsv3rc   maskedpayload_lenext_lenmasking_keyrd   full_payloadfinal_opcodes                   r   rY   WebSocketProtocol._read_frame   st     ''**"()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"$(,%$33'--]33(.%#*)+S11$$ $$S + I M
 0
 0 0
 6 Xs   I,IA(I, I2I,3I4I,IAI,I":I,I% I,1I(2A	I,;I*<BI,I,I,I,"I,%I,(I,*I,c                    #     U R                   R                  U5      I Sh  vN nU$  N! [        R                   a     g[         a     gf = f7f)z%Read exactly n bytes from the reader.N)r   readexactlyr   IncompleteReadErrorr'   )r   ndatas      r   rq   WebSocketProtocol._read_exact)  sM     	0033DK 4** 	 		s<   A+ )+ A+ AA	A
AAAc                 R   ^ U(       d  U$ [        U4S j[        U5       5       5      $ )zUnmask WebSocket payload data.c              3   >   >#    U  H  u  pUTUS -     -  v   M     g7f)rk   N ).0ibr   s      r   	<genexpr>,WebSocketProtocol._unmask.<locals>.<genexpr>8  s#     K8JQQU++8Js   )r6   	enumerate)r   rd   r   s     `r   ru   WebSocketProtocol._unmask3  s!    NK	'8JKKKr   c                 T  #    [        U5      S:  a;  [        R                  " SUSS 5      S   U l        USS R	                  SSS9U l        O[        U l        SU l        U R                  (       d.  U R                  U R                  U R
                  5      I Sh  vN   S	U l        g N7f)
zHandle incoming close frame.r   ro   Nr   r5   replace)errorsr   T)	lenrs   rt   r   rM   r   CLOSE_NO_STATUSr   r+   r   rd   s     r   r[   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                    #    g7f)z=Handle continuation frame (already processed in _read_frame).Nr   r   s     r   r_   &WebSocketProtocol._handle_continuationI  s     s   c                 .  #    [        U[        5      (       a  UR                  S5      n[        U5      n[	        5       nUR                  SU-  5        US:  a  UR                  U5        OuUS:  a8  UR                  S5        UR                  [        R                  " SU5      5        O7UR                  S5        UR                  [        R                  " SU5      5        UR                  U5        U R                  R                  [        U5      5        g7f)	zBSend a WebSocket frame.

Server frames are not masked (RFC 6455).
r5      rn   i   ro   rm   rp   N)rO   strr=   r   	bytearrayrN   extendrs   packr   rP   r6   )r   rc   rd   lengthrb   s        r   r;   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                    #    [         R                  " SU5      nU(       a  X2R                  S5      SS -  nU R                  [        U5      I Sh  vN   SU l        g N7f)zSend a close frame.ro   r5   N{   T)rs   r   r=   r;   rZ   r   )r   r7   r8   rd   s       r   r+   WebSocketProtocol._send_closej  sR     ++dD)}}W-ds33G|W555 	6s   AAAA)r   r   r   r   r   r   r   r   r   r   r   r   N)r   )__name__
__module____qualname____firstlineno____doc__r   r.   r%   r&   r:   r$   rY   rq   ru   r[   r_   r;   r+   __static_attributes__r   r   r   r	   r	   *   sN    =.8R./6(AT,\P%dLL+:r   r	   )r   r   rG   rI   rs   r^   r<   r>   rZ   r\   r]   r?   CLOSE_GOING_AWAYrr   CLOSE_UNSUPPORTEDr   ra   CLOSE_INVALID_DATACLOSE_POLICY_VIOLATIONCLOSE_MESSAGE_TOO_BIGCLOSE_MANDATORY_EXTr,   rK   r	   r   r   r   <module>r      s   
                2F Fr   