
    aDgB                         d Z ddlmZ ddlZddlmZmZmZ ddlm	Z	m
Z
mZmZ ddlmZmZmZmZmZmZ dZ G d	 d
e      Zd Zd Zy)zR
wsproto/handshake
~~~~~~~~~~~~~~~~~~

An implementation of WebSocket handshakes.
    )dequeN   )
ConnectionConnectionStateConnectionType)AcceptConnectionRejectConnection
RejectDataRequest)generate_accept_tokengenerate_nonceLocalProtocolErrornormed_header_dictRemoteProtocolErrorsplit_comma_headers   13c                   x    e Zd ZdZd Zed        Zed        Zd Zd Z	d Z
d Zd	 Zd
 Zd Zd Zd Zd Zd Zy)H11Handshakez4A Handshake implementation for HTTP/1.1 connections.c                 ^   |t         j                  u | _        t        j                  | _        | j                  r)t        j                  t        j                        | _        n(t        j                  t        j                        | _        d | _
        t               | _        d | _        d | _        y N)r   CLIENTclientr   
CONNECTING_stateh11r   _h11_connectionSERVER_connectionr   _events_initiating_request_nonce)selfconnection_types     Q/var/www/highfloat_scraper/venv/lib/python3.12/site-packages/wsproto/handshake.py__init__zH11Handshake.__init__   sr    %)>)>>%00;;#&>>#**#=D #&>>#**#=D w#'     c                     | j                   S r   )r   r!   s    r#   statezH11Handshake.state-   s     {{r%   c                     | j                   S )zReturn the established connection.

        This will either return the connection or raise a
        LocalProtocolError if the connection has not yet been
        established.
        )r   r'   s    r#   
connectionzH11Handshake.connection2   s     r%   c                     | j                   rt        d      t        j                  d||      }t        j                  t        j
                        }| j                  |j                  |             y)zInitiate an upgrade connection.

        This should be used if the request has already be received and
        parsed.

        z?Cannot initiate an upgrade connection when acting as the client   GETmethodtargetheadersN)r   r   r   r   r   r   receive_datasend)r!   r0   pathupgrade_request
h11_clients        r#   initiate_upgrade_connectionz(H11Handshake.initiate_upgrade_connection=   sX     ;;$Q  ++VD'R^^CJJ/
*///:;r%   c                 j   d}t        |t              r|| j                  |      z  }|S t        |t              r|| j	                  |      z  }|S t        |t
              r|| j                  |      z  }|S t        |t              r|| j                  |      z  }|S t        dj                  |            )zSend an event to the remote.

        This will return the bytes to send based on the event or raise
        a LocalProtocolError if the event is not valid given the
        state.

        r%   z,Event {} cannot be sent during the handshake)
isinstancer   _initiate_connectionr   _acceptr	   _rejectr
   _send_reject_datar   formatr!   eventdatas      r#   r2   zH11Handshake.sendM   s     eW%D--e44D  /0DLL''D  /0DLL''D  z*D**511D
  %>EEeL r%   c                 R   | j                   j                  |       	 	 | j                   j                         }t        |t        j                        s$|t        j                  u s|t        j                  u ry	| j                  rt        |t        j                        r|j                  dk(  r,| j                  j                  | j                  |             n| j                  j                  t        |j                   |j                  d             t"        j$                  | _        nPt        |t        j(                        rQt"        j*                  | _        | j                  j                  t        |j                   |j                  d             nt        |t        j,                        r1| j                  j                  t/        |j0                  d             nt        |t        j2                        r| j                  j                  t/        dd             t"        j$                  | _        nDt        |t        j4                        r*| j                  j                  | j7                  |             `# t        j                  $ r t	        dt                     w xY w)
zReceive data from the remote.

        A list of events that the remote peer triggered by sending
        this data can be retrieved with :meth:`events`.

        TzBad HTTP message
event_hinte   F)r0   status_codehas_body)r@   body_finishedr%   N)r   r1   
next_eventr   r   r	   r8   ConnectionClosed	NEED_DATAPAUSEDr   InformationalResponserE   r   append_establish_client_connectionr0   r   CLOSEDr   Response	REJECTINGDatar
   r@   EndOfMessager   _process_connection_request)r!   r@   r?   s      r#   r1   zH11Handshake.receive_datae   s    	))$/,,779 5#"6"67CMM)CJJ&{{eS%>%>?((C/++D,M,Me,TU++,(-,1,=,=). '6&<&<s||4"1";";DKLL''($)MM(-(9(9%)  sxx0LL''"

%H  s'7'78LL''
4(PQ"1"8"8DKeS[[1LL''(H(H(OP[  ** )&3C3E s   I= =)J&c              #   x   K   | j                   r*| j                   j                          | j                   r)y y wr   )r   popleftr'   s    r#   eventszH11Handshake.events   s)     ll,,&&(( lls   5::c           	      \   |j                   dk7  rt        dt                     d }g }d }d }g }d}d }g }	|j                  D ]  \  }
}|
j	                         }
|
dk(  rt        |      }nP|
dk(  r|j                  d      }>|
dk(  rt        |      }O|
d	k(  r|}n |
d
k(  rt        |      }h|
dk(  r|}n|
dk(  r|}|	j                  |
|f        |t        d |D              st        dt                     |t        k7  rt        dt        dt        fgd            |t        dt                     |j	                         dk7  rt        dt                     |t        dt                     t        ||	|||j                  j                  d            | _        | j                  S )Nr,   zRequest method must be GETrB   r%   
   connections   hostascii   sec-websocket-extensions   sec-websocket-key   sec-websocket-protocols   sec-websocket-version   upgradec              3   B   K   | ]  }|j                         d k(    ywupgradeNlower.0tokens     r#   	<genexpr>z;H11Handshake._process_connection_request.<locals>.<genexpr>          0
+0EKKMY&0
   %Missing header, 'Connection: Upgrade'z'Missing header, 'Sec-WebSocket-Version'   Sec-WebSocket-Versioni  )r0   rE   z#Missing header, 'Sec-WebSocket-Key'	   websocket$Missing header, 'Upgrade: WebSocket')
extensionsextra_headershostsubprotocolsr/   )r.   r   r	   r0   rc   r   decoderM   anyWEBSOCKET_VERSIONr   r/   r   )r!   r?   connection_tokensrn   rp   keyrq   ra   versionr0   namevalues               r#   rT   z(H11Handshake._process_connection_request   s   <<6!%,9I9K  !
 == 	*KD%::<D}$$6u$=!||G,44/6
--221%811#NND%=)'	*( $C 0
4E0
 -
 &7DTDV  ''%9+68IJK #  ;%5BRBT  ==?l*%6CSCU  ?%9FVFX  $+!!%<<&&w/$
  '''r%   c                 2   t        | j                  j                        }|d   }t        |      }ddd|fg}|j                  r|j                  | j                  j
                  vr$t        dj                  |j                              |j                  d|j                  j                  d      f       |j                  r?t        | j                  j                  |j                        }|r|j                  d|f       t        j                  d	||j                  z   
      }t        | j                  rt         j"                  nt         j$                  |j                        | _        t(        j*                  | _        | j.                  j1                  |      S )Nr\      Upgrades	   WebSockets
   Connectionr|   s   Sec-WebSocket-Acceptzunexpected subprotocol {}   Sec-WebSocket-ProtocolrZ      Sec-WebSocket-ExtensionsrD   rE   r0   )r   r   ro   r   subprotocolrq   r   r=   rM   encodern   server_extensions_handshaker   rL   r   r   r   r   r   r   r   OPENr   r   r2   )r!   r?   request_headersnonceaccept_tokenr0   acceptsresponses           r#   r:   zH11Handshake._accept   sl   ,T-E-E-S-ST 45,U3 ''$l3
 (  (@(@(M(MM(/66u7H7HI  NN*E,=,=,D,DW,MN 1((33U5E5EG  ;WEF,,Wu/B/B%B
 &%)[[N!!n6K6K
 &**##((22r%   c                    | j                   t        j                  k7  rt        d| j                   z        |j                  }|j
                  s|j                  d       t        j                  |j                  |      }| j                  j                  |      }t        j                  | _        |j
                  sE|| j                  j                  t        j                               z  }t        j                  | _        |S )Nz)Connection cannot be rejected in state %s)s   content-length   0r   )r(   r   r   r   r0   rF   rM   r   rP   rE   r   r2   rQ   r   rS   rO   )r!   r?   r0   r   r@   s        r#   r;   zH11Handshake._reject  s    ::333$;djjH  --~~NN45<<E,=,=wO##((2%//~~D((--c.>.>.@AAD)00DKr%   c                    | j                   t        j                  k7  r$t        dj	                  | j                               | j
                  j                  t        j                  |j                              }|j                  rE|| j
                  j                  t        j                               z  }t        j                  | _        |S )Nz&Cannot send rejection data in state {})r@   )r(   r   rQ   r   r=   r   r2   r   rR   r@   rG   rS   rO   r   r>   s      r#   r<   zH11Handshake._send_reject_data"  s    ::222$8??

K  ##((uzz)BCD((--c.>.>.@AAD)00DKr%   c                 r   || _         t               | _        d|j                  j	                  d      fddd| j                  fdt
        fg}|j                  r;|j                  ddj                  |j                        j	                  d      f       |j                  r|j                  D ci c]  }|j                  |j                          }}g }|j                         D ]R  \  }}|d	u r!|j                  |j	                  d             +|s.|j                  |d
|j	                  d             T |r"|j                  ddj                  |      f       t        j                  d|j                  j	                  d      ||j                   z         }| j"                  j%                  |      S c c}w )Ns   HostrZ   r{   r}   s   Sec-WebSocket-Keyrk   r~   z, T; r      , r,   r-   )r   r   r    rp   r   rt   rq   rM   joinrn   rx   offeritemsr   r   r/   ro   r   r2   )	r!   requestr0   eoffersrn   rx   paramsra   s	            r#   r9   z!H11Handshake._initiate_connection1  s   #* $& gll))'23&'!4;;/%'89
 NN-YYw334<<WE 181C1CDAaffaggi'DFDJ & SfT>%%dkk'&:;%%4'@&H&H&QRS  ;UZZ
=STU++>>((1g333

 ##((11! Es   ,"F4c                    d }d }g }d }d}g }|j                   D ]b  \  }}	|j                         }|dk(  rt        |	      }'|dk(  rt        |	      }8|dk(  r|	}@|dk(  r|	}H|dk(  r|	}P|j                  ||	f       d |t	        d |D              st        dt               	      |j                         d
k7  rt        dt               	      t        | j                        }
||
k7  rt        dt               	      |M|j                  d      }|| j                  j                  vr$t        dj                  |      t               	      t        || j                  j                        }t        | j                   rt"        j$                  nt"        j&                  || j(                  j*                  d         | _        t.        j0                  | _        t5        |||      S )Nr%   rY   r[   s   sec-websocket-acceptr]   r^   c              3   B   K   | ]  }|j                         d k(    ywr`   rb   rd   s     r#   rg   z<H11Handshake._establish_client_connection.<locals>.<genexpr>s  rh   ri   rj   rB   rl   rm   zBad accept tokenrZ   zunrecognized subprotocol {}r   )rn   ro   r   )r0   rc   r   rM   rs   r   r	   r   r    rr   r   rq   r=   client_extensions_handshakern   r   r   r   r   r   r   trailing_datar   r   r   r   r   )r!   r?   acceptru   r   r   ra   r0   rx   ry   r   rn   s               r#   rN   z)H11Handshake._establish_client_connectionY  s     == 	*KD%::<D}$$6u$=!44,U30022##NND%=)#	*& $C 0
4E0
 -
 &7DTDV  ==?l*%6CSCU  -T[[9\!%&8EUEWXX"%,,W5K$":":"G"GG)188E/1  1T--88

 &%)[[N!!n6K6K  ..q1

 &**!k
 	
r%   c                 x    dj                  | j                  j                  | j                  | j                        S )Nz{}(client={}, state={}))r=   	__class____name__r   r(   r'   s    r#   __repr__zH11Handshake.__repr__  s.    (//NN##T[[$**
 	
r%   N)r   
__module____qualname____doc__r$   propertyr(   r*   r6   r2   r1   rW   rT   r:   r;   r<   r9   rN   r    r%   r#   r   r      sp    >      < 06Qp)C(J%3N$&2P:
x
r%   r   c                    i }| D ]  }|j                  dd      d   j                         }|D ]]  }|j                  |k(  s|j                  |      }|du rd||j                  <   8|dus=|@|j	                  d      ||j                  <   _  |rg }|j                         D ]  \  }}|du r!|j                  |j	                  d             +|j                  d      }|dk(  r$|j                  d	|z  j	                  d             e|j                  |d
|j	                  d              dj                  |      S y)zAgree on the extensions to use returning an appropriate header value.

    This returns None if there are no agreed extensions
    ;r   r   TFNrZ    z%sr   r   )	splitstriprx   r   r   r   rM   rr   r   )		requested	supportedr   r   rx   	extensionr   rn   r   s	            r#   r   r     sG    G E{{3"1%++-" 	EI~~%"))%0T>.2GINN+5(V-?.4mmG.DGINN+	EE 
#MMO 		SLD&~!!$++g"67  w/R<%%tt}&<&<W&EF%%4'@&H&H&QR		S zz*%%r%   c                    g }| D ]  }|j                  dd      d   j                         }|D ]5  }|j                  |k(  s|j                  |       |j	                  |        _ t        dj                  |      t                      |S )Nr   r   r   zunrecognized extension {}rB   )r   r   rx   finalizerM   r   r=   r	   )acceptedr   rn   r   rx   r   s         r#   r   r     s     J 
||C#A&,,." 	I~~%""6*!!),		 &+2248EUEW 
 r%   )r   collectionsr   r   r*   r   r   r   rW   r   r	   r
   r   	utilitiesr   r   r   r   r   r   rt   objectr   r   r   r   r%   r#   <module>r      sJ     
 C C K K   }
6 }
@Dr%   