a
    ñ»jŸj  ã                   @  s<  d dl mZ d dlZd dlZd dlZd dlmZ d dlmZ ddl	m
Z
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mZmZmZmZ dd	lmZmZ dd
l m!Z! ddlm"Z"m#Z#m$Z$ g d¢Z%eeeef Z&G dd„ dej'ƒZ(e(j)Z)e(j*Z*G dd„ dej'ƒZ+e+j,Z,e+j-Z-e+j.Z.e+j/Z/dZ0G dd„ dƒZ1dS )é    )ÚannotationsN)Ú	Generator)ÚUnioné   )ÚConnectionClosedÚConnectionClosedErrorÚConnectionClosedOKÚInvalidStateÚPayloadTooBigÚProtocolError)Ú	Extension)
ÚOK_CLOSE_CODESÚ	OP_BINARYÚOP_CLOSEÚOP_CONTÚOP_PINGÚOP_PONGÚOP_TEXTÚCloseÚ	CloseCodeÚFrame)ÚRequestÚResponse)ÚStreamReader)Ú
LoggerLikeÚOriginÚSubprotocol)ÚProtocolÚSideÚStateÚSEND_EOFc                   @  s   e Zd ZdZedƒ\ZZdS )r   z6A WebSocket connection is either a server or a client.é   N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚrangeÚSERVERÚCLIENT© r)   r)   ú9E:\soccer\ml_env\Lib\site-packages\websockets/protocol.pyr   /   s   r   c                   @  s    e Zd ZdZedƒ\ZZZZdS )r   z6A WebSocket connection is in one of these four states.é   N)	r"   r#   r$   r%   r&   Ú
CONNECTINGÚOPENÚCLOSINGÚCLOSEDr)   r)   r)   r*   r   9   s   r   ó    c                   @  s¢  e Zd ZdZedddœddddd	d
œdd„Zeddœdd„ƒZejdd	dœdd„ƒZeddœdd„ƒZ	eddœdd„ƒZ
eddœdd„ƒZdd	dœdd„Zd	dœdd„Zdd d	d!œd"d#„ZdJdd d	d!œd%d&„ZdKdd d	d!œd'd(„ZdLdd*d	d+œd,d-„Zdd	dœd.d/„Zdd	dœd0d1„ZdMd2d*d	d+œd3d4„Zd5dœd6d7„Zd8dœd9d:„Zd dœd;d<„Zd=dœd>d?„Zd=dœd@dA„ZdBd	dCœdDdE„ZdBd	dCœdFdG„Zd	dœdHdI„ZdS )Nr   a6  
    Sans-I/O implementation of a WebSocket connection.

    Args:
        side: :attr:`~Side.CLIENT` or :attr:`~Side.SERVER`.
        state: Initial state of the WebSocket connection.
        max_size: Maximum size of incoming messages in bytes;
            :obj:`None` disables the limit.
        logger: Logger for this connection; depending on ``side``,
            defaults to ``logging.getLogger("websockets.client")``
            or ``logging.getLogger("websockets.server")``;
            see the :doc:`logging guide <../../topics/logging>` for details.

    i   N)ÚstateÚmax_sizeÚloggerr   r   z
int | NonezLoggerLike | NoneÚNone)Úsider1   r2   r3   Úreturnc                C  s¼   t  ¡ | _|d u r(t d|j ¡ › �¡}|| _| tj	¡| _
|| _|| _|| _d | _d| _d | _g | _d | _d | _d | _d | _d | _d| _tƒ | _g | _g | _|  ¡ | _t| jƒ d | _d S )Nzwebsockets.F) ÚuuidÚuuid4ÚidÚloggingÚ	getLoggerÚnameÚlowerr3   ÚisEnabledForÚDEBUGÚdebugr5   r1   r2   Úcur_sizeÚexpect_continuation_frameÚoriginÚ
extensionsZsubprotocolÚ
close_rcvdÚ
close_sentÚclose_rcvd_then_sentZhandshake_excÚeof_sentr   ÚreaderÚeventsÚwritesÚparseÚparserÚnextÚ
parser_exc)Úselfr5   r1   r2   r3   r)   r)   r*   Ú__init__Y   s0    	
	

zProtocol.__init__)r6   c                 C  s   | j S )a­  
        State of the WebSocket connection.

        Defined in 4.1_, 4.2_, 7.1.3_, and 7.1.4_ of :rfc:`6455`.

        .. _4.1: https://datatracker.ietf.org/doc/html/rfc6455#section-4.1
        .. _4.2: https://datatracker.ietf.org/doc/html/rfc6455#section-4.2
        .. _7.1.3: https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.3
        .. _7.1.4: https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.4

        )Ú_state©rP   r)   r)   r*   r1   �   s    zProtocol.state)r1   r6   c                 C  s    | j r| j  d|j¡ || _d S )Nz= connection is %s)r@   r3   r<   rR   )rP   r1   r)   r)   r*   r1   ¬   s    c                 C  s*   | j turdS | jdu rtjS | jjS dS )zþ
        WebSocket close code received from the remote endpoint.

        Defined in 7.1.5_ of :rfc:`6455`.

        .. _7.1.5: https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.5

        :obj:`None` if the connection isn't closed yet.

        N)r1   r/   rE   r   ÚABNORMAL_CLOSUREÚcoderS   r)   r)   r*   Ú
close_code²   s
    

zProtocol.close_codez
str | Nonec                 C  s(   | j turdS | jdu rdS | jjS dS )a  
        WebSocket close reason  received from the remote endpoint.

        Defined in 7.1.6_ of :rfc:`6455`.

        .. _7.1.6: https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.6

        :obj:`None` if the connection isn't closed yet.

        NÚ )r1   r/   rE   ÚreasonrS   r)   r)   r*   Úclose_reasonÅ   s
    

zProtocol.close_reasonr   c                 C  sf   | j tu sJ dƒ‚| jdurD| jdurD| jjtv rD| jjtv rDt}nt}|| j| j| jƒ}| j	|_
|S )aè  
        Exception to raise when trying to interact with a closed connection.

        Don't raise this exception while the connection :attr:`state`
        is :attr:`~websockets.protocol.State.CLOSING`; wait until
        it's :attr:`~websockets.protocol.State.CLOSED`.

        Indeed, the exception includes the close code and reason, which are
        known only once the connection is closed.

        Raises:
            AssertionError: If the connection isn't closed yet.

        zconnection isn't closed yetN)r1   r/   rE   rF   rU   r   r   r   rG   rO   Ú	__cause__)rP   Úexc_typeÚexcr)   r)   r*   Ú	close_excØ   s$    ÿþ
ý
üýzProtocol.close_excÚbytes)Údatar6   c                 C  s   | j  |¡ t| jƒ dS )aH  
        Receive data from the network.

        After calling this method:

        - You must call :meth:`data_to_send` and send this data to the network.
        - You should call :meth:`events_received` and process resulting events.

        Raises:
            EOFError: If :meth:`receive_eof` was called earlier.

        N)rI   Z	feed_datarN   rM   ©rP   r_   r)   r)   r*   Úreceive_dataþ   s    zProtocol.receive_datac                 C  s$   | j jrdS | j  ¡  t| jƒ dS )a¡  
        Receive the end of the data stream from the network.

        After calling this method:

        - You must call :meth:`data_to_send` and send this data to the network;
          it will return ``[b""]``, signaling the end of the stream, or ``[]``.
        - You aren't expected to call :meth:`events_received`; it won't return
          any new events.

        :meth:`receive_eof` is idempotent.

        N)rI   ÚeofZfeed_eofrN   rM   rS   r)   r)   r*   Úreceive_eof  s    
zProtocol.receive_eofÚbool)r_   Úfinr6   c                 C  sL   | j stdƒ‚| jtur.td| jj ¡ › �ƒ‚| | _ |  t	t
||ƒ¡ dS )aõ  
        Send a `Continuation frame`_.

        .. _Continuation frame:
            https://datatracker.ietf.org/doc/html/rfc6455#section-5.6

        Parameters:
            data: payload containing the same kind of data
                as the initial frame.
            fin: FIN bit; set it to :obj:`True` if this is the last frame
                of a fragmented message and to :obj:`False` otherwise.

        Raises:
            ProtocolError: If a fragmented message isn't in progress.

        úunexpected continuation frameúconnection is N)rB   r   rR   r-   r	   r1   r<   r=   Ú
send_framer   r   ©rP   r_   re   r)   r)   r*   Úsend_continuation#  s    
zProtocol.send_continuationTc                 C  sL   | j rtdƒ‚| jtur.td| jj ¡ › �ƒ‚| | _ |  t	t
||ƒ¡ dS )a£  
        Send a `Text frame`_.

        .. _Text frame:
            https://datatracker.ietf.org/doc/html/rfc6455#section-5.6

        Parameters:
            data: payload containing text encoded with UTF-8.
            fin: FIN bit; set it to :obj:`False` if this is the first frame of
                a fragmented message.

        Raises:
            ProtocolError: If a fragmented message is in progress.

        úexpected a continuation framerg   N)rB   r   rR   r-   r	   r1   r<   r=   rh   r   r   ri   r)   r)   r*   Ú	send_text;  s    
zProtocol.send_textc                 C  sL   | j rtdƒ‚| jtur.td| jj ¡ › �ƒ‚| | _ |  t	t
||ƒ¡ dS )a¥  
        Send a `Binary frame`_.

        .. _Binary frame:
            https://datatracker.ietf.org/doc/html/rfc6455#section-5.6

        Parameters:
            data: payload containing arbitrary binary data.
            fin: FIN bit; set it to :obj:`False` if this is the first frame of
                a fragmented message.

        Raises:
            ProtocolError: If a fragmented message is in progress.

        rk   rg   N)rB   r   rR   r-   r	   r1   r<   r=   rh   r   r   ri   r)   r)   r*   Úsend_binaryR  s    
zProtocol.send_binaryrW   Ústr)rU   rX   r6   c                 C  sŠ   | j tur td| jj ¡ › �ƒ‚|du rJ|dkr8tdƒ‚ttj	dƒ}d}nt||ƒ}| 
¡ }|  tt|ƒ¡ | jdu szJ ‚|| _t| _dS )a_  
        Send a `Close frame`_.

        .. _Close frame:
            https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.1

        Parameters:
            code: close code.
            reason: close reason.

        Raises:
            ProtocolError: If the code isn't valid or if a reason is provided
                without a code.

        rg   NrW   z#cannot send a reason without a coder0   )rR   r-   r	   r1   r<   r=   r   r   r   ZNO_STATUS_RCVDÚ	serializerh   r   r   rE   rF   r.   ©rP   rU   rX   Úcloser_   r)   r)   r*   Ú
send_closei  s    

zProtocol.send_closec                 C  s>   | j tur*| j tur*td| jj ¡ › �ƒ‚|  tt	|ƒ¡ dS )zÚ
        Send a `Ping frame`_.

        .. _Ping frame:
            https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.2

        Parameters:
            data: payload containing arbitrary binary data.

        rg   N)
rR   r-   r.   r	   r1   r<   r=   rh   r   r   r`   r)   r)   r*   Ú	send_ping�  s    zProtocol.send_pingc                 C  s>   | j tur*| j tur*td| jj ¡ › �ƒ‚|  tt	|ƒ¡ dS )zÚ
        Send a `Pong frame`_.

        .. _Pong frame:
            https://datatracker.ietf.org/doc/html/rfc6455#section-5.5.3

        Parameters:
            data: payload containing arbitrary binary data.

        rg   N)
rR   r-   r.   r	   r1   r<   r=   rh   r   r   r`   r)   r)   r*   Ú	send_pong�  s    zProtocol.send_pongÚintc                 C  s‚   | j tu rR|tjkrRt||ƒ}| ¡ }|  tt|ƒ¡ || _	| j
durLd| _t| _ | jtu rj| jsj|  ¡  |  ¡ | _t| jƒ dS )a?  
        `Fail the WebSocket connection`_.

        .. _Fail the WebSocket connection:
            https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.7

        Parameters:
            code: close code
            reason: close reason

        Raises:
            ProtocolError: If the code isn't valid.
        NT)r1   r-   r   rT   r   ro   rh   r   r   rF   rE   rG   r.   r5   r'   rH   Úsend_eofÚdiscardrM   rN   rp   r)   r)   r*   Úfail­  s    




zProtocol.failzlist[Event]c                 C  s   | j g  }| _ |S )a*  
        Fetch events generated from data received from the network.

        Call this method immediately after any of the ``receive_*()`` methods.

        Process resulting events, likely by passing them to the application.

        Returns:
            Events read from the connection.
        )rJ   )rP   rJ   r)   r)   r*   Úevents_receivedÞ  s    zProtocol.events_receivedzlist[bytes]c                 C  s   | j g  }| _ |S )aÉ  
        Obtain data to send to the network.

        Call this method immediately after any of the ``receive_*()``,
        ``send_*()``, or :meth:`fail` methods.

        Write resulting data to the connection.

        The empty bytestring :data:`~websockets.protocol.SEND_EOF` signals
        the end of the data stream. When you receive it, half-close the TCP
        connection.

        Returns:
            Data to write to the connection.

        )rK   )rP   rK   r)   r)   r*   Údata_to_sendî  s    zProtocol.data_to_sendc                 C  s>   | j tu rdS | j tu rdS | j tu r*dS | j tu s8J ‚| jS )a©  
        Tell if the TCP connection is expected to close soon.

        Call this method immediately after any of the ``receive_*()``,
        ``send_close()``, or :meth:`fail` methods.

        If it returns :obj:`True`, schedule closing the TCP connection after a
        short timeout if the other side hasn't already closed it.

        Returns:
            Whether the TCP connection is expected to close soon.

        FT)r1   r-   r.   r/   r,   rH   rS   r)   r)   r*   Úclose_expected  s    "


zProtocol.close_expectedzGenerator[None]c              
   c  s  z¢| j  ¡ E dH r,| jr$| j d¡ tdƒ‚| jdu r<d}n| jdu rN| j}n| j| j }tj| j j	| j
tu || jd�E dH }| jr’| j d|¡ |  |¡ qW �nN tyà } z&|  tjt|ƒ¡ || _W Y d}~�nd}~0  t�y } z$|  tjt|ƒ¡ || _W Y d}~nÞd}~0  t�yb } z.|  tj|j› d|j› �¡ || _W Y d}~n˜d}~0  t�yª } z0| | j¡ |  tjt|ƒ¡ || _W Y d}~nPd}~0  t�yð } z.| jjddd	� |  tj¡ || _W Y d}~n
d}~0 0 dV  td
ƒ‚dS )a-  
        Parse incoming data into frames.

        :meth:`receive_data` and :meth:`receive_eof` run this generator
        coroutine until it needs more data or reaches EOF.

        :meth:`parse` never raises an exception. Instead, it sets the
        :attr:`parser_exc` and yields control.

        Nú< EOFzunexpected end of stream)Úmaskr2   rD   z< %sz at position zparser failedT)Úexc_infoz"parse() shouldn't step after error) rI   Úat_eofr@   r3   ÚEOFErrorr2   rA   r   rL   Z
read_exactr5   r'   rD   Ú
recv_framer   rx   r   ZPROTOCOL_ERRORrn   rO   rT   ÚUnicodeDecodeErrorZINVALID_DATArX   Ústartr
   Zset_current_sizeZMESSAGE_TOO_BIGÚ	ExceptionÚerrorÚINTERNAL_ERRORÚAssertionError)rP   r2   Úframer\   r)   r)   r*   rL   /  sL    

üzProtocol.parsec                 c  s€   | j tu p| jtu | jksJ ‚| j ¡ E dH s:| j ¡  q| jrL| j	 d¡ | j t
u rh| jturh|  ¡  t| _dV  tdƒ‚dS )zí
        Discard incoming data.

        This coroutine replaces :meth:`parse`:

        - after receiving a close frame, during a normal closure (1.4);
        - after sending a close frame, during an abnormal closure (7.1.7).

        Nr|   z"discard() shouldn't step after EOF)r5   r'   r1   r,   rH   rI   r   rw   r@   r3   r(   rv   r/   r‡   rS   r)   r)   r*   rw   w  s    zProtocol.discardr   )rˆ   r6   c                 C  sr  |j tu s|j tu r<| jdur&tdƒ‚|js8t|jƒ| _�n&|j tu r|| jdu rXtdƒ‚|jrfd| _n|  jt|jƒ7  _næ|j t	u ržt
t|jƒ}|  |¡ nÄ|j tu rªn¸|j tu �rPt |j¡| _| jtu râ| jdusÜJ ‚d| _| jdurôtdƒ‚| jtu �r&|  t
t|jƒ¡ | j| _d| _t| _| jtu �r:|  ¡  |  ¡ | _t| jƒ ntd|j d›�ƒ‚| j |¡ dS )	z-
        Process an incoming frame.

        Nrk   rf   Fzincomplete fragmented messageTzunexpected opcode: Ú02x)Úopcoder   r   rA   r   re   Úlenr_   r   r   r   r   rh   r   r   rL   rE   r1   r.   rF   rG   r-   r5   r'   rv   rw   rM   rN   r‡   rJ   Úappend)rP   rˆ   Z
pong_framer)   r)   r*   r�   •  sD    







zProtocol.recv_framec                 C  s6   | j r| j  d|¡ | j |j| jtu | jd�¡ d S )Nz> %s)r}   rD   )r@   r3   rK   rŒ   ro   r5   r(   rD   )rP   rˆ   r)   r)   r*   rh   ç  s    þÿzProtocol.send_framec                 C  s2   | j r
J ‚d| _ | jr"| j d¡ | j t¡ d S )NTz> EOF)rH   r@   r3   rK   rŒ   r    rS   r)   r)   r*   rv   ñ  s
    
zProtocol.send_eof)T)T)NrW   )rW   )r"   r#   r$   r%   r-   rQ   Úpropertyr1   ÚsetterrV   rY   r]   ra   rc   rj   rl   rm   rr   rs   rt   rx   ry   rz   r{   rL   rw   r�   rh   rv   r)   r)   r)   r*   r   I   s@   úD%$1-HR
r   )2Ú
__future__r   Úenumr:   r7   Úcollections.abcr   Útypingr   Ú
exceptionsr   r   r   r	   r
   r   rD   r   Úframesr   r   r   r   r   r   r   r   r   r   Zhttp11r   r   Ústreamsr   r   r   r   Ú__all__ÚEventÚIntEnumr   r'   r(   r   r,   r-   r.   r/   r    r   r)   r)   r)   r*   Ú<module>   s.    0