o
    ]iH                     @  s   d Z ddlmZ ddlmZ ddlmZ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mZ dd	lmZ dd
lmZmZmZmZmZmZ erZddlmZmZmZ ddlm Z  dZ!dZ"G dd dZ#dddZ$dddZ%dS )zR
wsproto/handshake
~~~~~~~~~~~~~~~~~~

An implementation of WebSocket handshakes.
    )annotations)deque)TYPE_CHECKINGcastN   )
ConnectionConnectionStateConnectionType)AcceptConnectionEventRejectConnection
RejectDataRequest)	Extension)LocalProtocolErrorRemoteProtocolErrorgenerate_accept_tokengenerate_noncenormed_header_dictsplit_comma_header)	GeneratorIterableSequence)Headerss   13s	   websocketc                   @  s   e Zd ZdZd7ddZed8d	d
Zed9ddZd:ddZd;ddZ	d<ddZ
d=ddZd>d"d#Zd?d%d&Zd@d(d)ZdAd+d,ZdBd.d/ZdCd1d2ZdDd4d5Zd6S )EH11Handshakez4A Handshake implementation for HTTP/1.1 connections.connection_typer	   returnNonec                 C  sV   |t ju | _tj| _| jrttj| _nttj	| _d | _
t | _d | _d | _d S N)r	   CLIENTclientr   
CONNECTING_stateh11r   _h11_connectionSERVER_connectionr   _events_initiating_request_nonce)selfr    r+   V/var/www/html/stock_analysis/be/venv/lib/python3.10/site-packages/wsproto/handshake.py__init__,   s   
zH11Handshake.__init__r   c                 C     | j S r   )r"   r*   r+   r+   r,   state:   s   zH11Handshake.stateConnection | Nonec                 C  r.   )z
        Return the established connection.

        This will either return the connection or raise a
        LocalProtocolError if the connection has not yet been
        established.

        :rtype: h11.Connection
        )r&   r/   r+   r+   r,   
connection>   s   zH11Handshake.connectionheadersr   pathbytes | strc                 C  sB   | j r	d}t|tjd||d}ttj}| || dS )z
        Initiate an upgrade connection.

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

        :param list headers: HTTP headers represented as a list of 2-tuples.
        :param str path: A URL path.
        z?Cannot initiate an upgrade connection when acting as the client   GETmethodtargetr3   N)r    r   r#   r   r   r   receive_datasend)r*   r3   r4   msgupgrade_request
h11_clientr+   r+   r,   initiate_upgrade_connectionK   s   z(H11Handshake.initiate_upgrade_connectioneventr   bytesc                 C  s   d}t |tr|| |7 }|S t |tr|| |7 }|S t |tr,|| |7 }|S t |tr:|| |7 }|S d| d}t	|)a  
        Send 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.

        :returns: Data to send to the WebSocket peer.
        :rtype: bytes
            zEvent z$ cannot be sent during the handshake)

isinstancer   _initiate_connectionr
   _acceptr   _rejectr   _send_reject_datar   )r*   r@   datar<   r+   r+   r,   r;   `   s"   




zH11Handshake.sendrH   bytes | Nonec                 C  sb  | j |pd 	 z| j  }W n tjy!   d}t|t dw t|tjs2|tju s2|tj	u r4d	S | j
rt|tjr`|jdkrL| j| | nd| jtt|j|jdd tj| _nPt|tjrztj| _| jtt|j|jdd n6t|tjr| jt|jdd n$t|tjr| jtddd tj| _nt|tjr| j| | q	)
z
        Receive data from the remote.

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

        :param bytes data: Data received from the WebSocket peer.
        rB   TzBad HTTP message
event_hinte   F)r3   status_codehas_body)rH   body_finishedN)r$   r:   
next_eventr#   r   r   rC   ConnectionClosed	NEED_DATAPAUSEDr    InformationalResponserM   r'   append_establish_client_connectionlistr3   r   CLOSEDr"   Response	REJECTINGDatar   rH   EndOfMessager   _process_connection_request)r*   rH   r@   r<   r+   r+   r,   r:   {   sb   	


zH11Handshake.receive_dataGenerator[Event, None, None]c                 c  s"    | j r| j  V  | j sdS dS )z
        Return a generator that provides any events that have been generated
        by protocol activity.

        :returns: a generator that yields H11 events.
        N)r'   popleftr/   r+   r+   r,   events   s   zH11Handshake.eventsh11.Requestr   c                 C  s  |j dkrd}t|t dd }g }d }d }g }d}d }	g }
|jD ]N\}}| }|dkr2t|}n6|dkr<|d}q!|dkrH|t| q!|d	krO|}n|d
kr[|t| q!|dkrb|}	n|dkrh|}|
||f q!|d u s}t	dd |D sd}t|t d|	t
krd}t|tdt
fg|	rdnddd|d u rd}t|t d| tkrdt  d}t|t d|d u rd}t|t dt||
|||jdd| _| jS )Nr6   zRequest method must be GETrJ   rB   
   connections   hostidna   sec-websocket-extensions   sec-websocket-key   sec-websocket-protocols   sec-websocket-version   upgradec                 s      | ]	}|  d kV  qdS upgradeNlower.0tokenr+   r+   r,   	<genexpr>       
z;H11Handshake._process_connection_request.<locals>.<genexpr>%Missing header, 'Connection: Upgrade'z'Missing header, 'Sec-WebSocket-Version'   Sec-WebSocket-Versioni  i  )r3   rM   z#Missing header, 'Sec-WebSocket-Key'Missing header, 'Upgrade: 'zMissing header, 'Host'ascii)
extensionsextra_headershostsubprotocolsr9   )r8   r   r   r3   rl   r   decodeextendrU   anyWEBSOCKET_VERSIONWEBSOCKET_UPGRADEr   r9   r(   )r*   r@   r<   connection_tokensrw   ry   keyrz   rj   versionr3   namevaluer+   r+   r,   r]      s   




z(H11Handshake._process_connection_requestr
   c           	      C  s   | j d usJ t| j j}|d }t|}dtfdd|fg}|jd ur?|j| j jvr4d|j }t||d|j	df |j
rVttd| j j
|j
}|rV|d	|f tjd
||j dd}t| jrhtjntj|j
| _tj| _| j|pzdS )Nre      Upgrades
   Connectionr   s   Sec-WebSocket-Acceptzunexpected subprotocol    Sec-WebSocket-Protocolrv   zSequence[str]   Sec-WebSocket-ExtensionsrL   s   Switching Protocols)rM   r3   reasonrB   )r(   r   rx   r   r   subprotocolrz   r   rU   encoderw   server_extensions_handshaker   r#   rT   r   r    r	   r   r%   r&   r   OPENr"   r$   r;   )	r*   r@   request_headersnonceaccept_tokenr3   r<   acceptsresponser+   r+   r,   rE     sB   
zH11Handshake._acceptr   c                 C  s   | j tjkrd| j  }t|t|j}|js|d tj	|j
|d}| j|p,d}tj| _|jsD|| jt p>d7 }tj| _|S )Nz'Connection cannot be rejected in state )s   content-length   0)rM   r3   rB   )r0   r   r!   r   rW   r3   rN   rU   r#   rY   rM   r$   r;   rZ   r"   r\   rX   )r*   r@   r<   r3   r   rH   r+   r+   r,   rF   8  s   

zH11Handshake._rejectr   c                 C  sd   | j tjkrd| j  }t|| jtj|jdpd}|j	r0|| jt
 p*d7 }tj| _|S )Nz$Cannot send rejection data in state )rH   rB   )r0   r   rZ   r   r$   r;   r#   r[   rH   rO   r\   rX   r"   )r*   r@   r<   rH   r+   r+   r,   rG   J  s   zH11Handshake._send_reject_datarequestc           
      C  s"  || _ t | _d|jdfdtfdd| jfdtfg}|jr,|dd	|jd	f |j
rzi }|j
D ]}t|ts=J | ||j< q4g }| D ]"\}}|d	}t|tra|r`|| qK|d
||d	f  qK|rz|dd	|f tjd|jd	||j d}	| j|	pdS )Ns   Hostrc   r   r   s   Sec-WebSocket-Keyrs   r   z, rv      %s; %sr      , r6   r7   rB   )r(   r   r)   ry   r   r   r~   rz   rU   joinrw   rC   r   offerr   itemsboolr#   r   r9   rx   r$   r;   )
r*   r   r3   offerserw   r   paramsbnamerj   r+   r+   r,   rD   Y  sF   




z!H11Handshake._initiate_connectionh11.InformationalResponsec                 C  s  | j d usJ | jd usJ d }d }g }d }d}g }|jD ]9\}}	| }|dkr.t|	}q|dkr7t|	}q|dkr>|	}q|dkrH|	d}q|dkrO|	}q|||	f q|d u sdtdd	 |D smd
}
t|
t	 d| t
krdt
  d}
t|
t	 dt| j}||krd}
t|
t	 d|d ur|| j jvrd| }
t|
t	 dt|td| j j}t| jrtjntj|| jjd | _tj| _t|||dS )NrB   rb   rd   s   sec-websocket-acceptrf   rv   rg   c                 s  rh   ri   rk   rm   r+   r+   r,   rp     rq   z<H11Handshake._establish_client_connection.<locals>.<genexpr>rr   rJ   rt   ru   zBad accept tokenzunrecognized subprotocol Sequence[Extension]r   )rw   rx   r   )r(   r)   r3   rl   r   r{   rU   r}   r   r   r   r   rz   client_extensions_handshaker   rw   r   r    r	   r   r%   r$   trailing_datar&   r   r   r"   r
   )r*   r@   acceptr   r   r   rj   r3   r   r   r<   r   rw   r+   r+   r,   rV     sz   



z)H11Handshake._establish_client_connectionstrc                 C  s   | j j d| j d| j dS )Nz(client=z, state=))	__class____name__r    r0   r/   r+   r+   r,   __repr__  s   zH11Handshake.__repr__N)r   r	   r   r   )r   r   )r   r1   )r3   r   r4   r5   r   r   )r@   r   r   rA   )rH   rI   r   r   )r   r^   )r@   ra   r   r   )r@   r
   r   rA   )r@   r   r   rA   )r@   r   r   rA   )r   r   r   rA   )r@   r   r   r
   )r   r   )r   
__module____qualname____doc__r-   propertyr0   r2   r?   r;   r:   r`   r]   rE   rF   rG   rD   rV   r   r+   r+   r+   r,   r   )   s$    




9

N
*


+Er   	requestedIterable[str]	supportedlist[Extension]r   rI   c           
      C  s   i }| D ]4}| ddd  }|D ]%}|j|kr7||}t|tr+|r*d||j< q|dur7|d||j< qq|rtg }| D ]-\}}|d}	t|trY|sSJ ||	 qA|dkre|d|	  qA|d	|	|f  qAd
	|S dS )z
    Agree on the extensions to use returning an appropriate header value.

    This returns None if there are no agreed extensions
    ;r   r   TNrv   rB   s   %sr   r   )
splitstripr   r   rC   r   r   r   rU   r   )
r   r   r   r   r   	extensionr   rw   r   
name_bytesr+   r+   r,   r     s4   



	


r   acceptedr   c                 C  sj   g }| D ].}| ddd  }|D ]}|j|kr%|| ||  nqd| }t|t dq|S )Nr   r   r   zunrecognized extension rJ   )r   r   r   finalizerU   r   r   )r   r   rw   r   r   r   r<   r+   r+   r,   r     s   



r   )r   r   r   r   r   rI   )r   r   r   r   r   r   )&r   
__future__r   collectionsr   typingr   r   r#   r2   r   r   r	   r`   r
   r   r   r   r   rw   r   	utilitiesr   r   r   r   r   r   collections.abcr   r   r   r   r~   r   r   r   r   r+   r+   r+   r,   <module>   s(     	   
'$