o
    _c0                     @  sl  d dl mZ d dlZd dlZd dlZd dlZd dlZd dlmZm	Z	m
Z
mZmZ ddlmZmZ ddlmZ zddlmZ W n eyM   ddlmZ Y nw g dZG d	d
 d
ejZejZejZejZejZej Z!ej"Z#eeefZ$ee!e#fZ%ddddddddddddddddZ&h dZ'ddhZ(e)e*e+fZ,ej-G dd dZ.d+d$d%Z/d,d'd(Z0ej-G d)d* d*Z1dS )-    )annotationsN)Callable	GeneratorOptionalSequenceTuple   )
exceptions
extensions)Data)
apply_mask)OpcodeOP_CONTOP_TEXT	OP_BINARYOP_CLOSEOP_PINGOP_PONGDATA_OPCODESCTRL_OPCODESFrameprepare_dataprepare_ctrlClosec                   @  s$   e Zd ZdZd\ZZZd\ZZZ	dS )r   z#Opcode values for WebSocket frames.)r   r      )   	   
   N)
__name__
__module____qualname____doc__CONTTEXTBINARYCLOSEPINGPONG r(   r(   </usr/local/lib/python3.10/dist-packages/websockets/frames.pyr   %   s    
r   OKz
going awayzprotocol errorzunsupported typezno status code [internal]z'connection closed abnormally [internal]zinvalid datazpolicy violationzmessage too bigzextension requiredzunexpected errorzservice restartztry again laterzbad gatewayzTLS failure [internal])          i                  i  >   r+   r,   r-   r.   r0   r1   r2   r3   r4   r5   r6   r7   r+   r,   c                   @  s   e Zd ZU dZded< ded< dZded< d	Zded
< d	Zded< d	Zded< d#ddZ	e
dddd$ddZddd%ddZd&d!d"ZdS )'r   aN  
    WebSocket frame.

    Attributes:
        opcode: Opcode.
        data: Payload data.
        fin: FIN bit.
        rsv1: RSV1 bit.
        rsv2: RSV2 bit.
        rsv3: RSV3 bit.

    Only these fields are needed. The MASK bit, payload length and masking-key
    are handled on the fly when parsing and serializing frames.

    r   opcodebytesdataTboolfinFrsv1rsv2rsv3returnstrc              
   C  s  d}t | j dt | jdkrdnd }| jrdnd}| jtu r)t| j }nx| jtu rR| j}t |dkrGd|dd	 d
|dd g}ddd |D }nO| jt	u r`t
t| j}nA| jrzt| j }d}W n2 ttfy   | j}t |dkrd|dd	 d
|dd g}ddd |D }d}Y nw d}t |dkr|dd d |dd  }dtd|||g}| jj d| d| dS )zC
        Return a human-readable represention of a frame.

        Nz byter    s	continued          s     i c                 s      | ]}|d V  qdS 02xNr(   .0byter(   r(   r)   	<genexpr>       z Frame.__str__.<locals>.<genexpr>textc                 s  rI   rJ   r(   rL   r(   r(   r)   rO      rP   binaryz''K   0   z...iz, z [])lenr:   r<   r8   r   reprdecoder   joinr   rA   r   parseUnicodeDecodeErrorAttributeErrorfiltername)selfZcodinglengthZ	non_finalr:   rR   metadatar(   r(   r)   __str__|   s8   &

 
 zFrame.__str__N)max_sizer
   
read_exact-Callable[[int], Generator[None, None, bytes]]maskrc   Optional[int]r
   (Optional[Sequence[extensions.Extension]]Generator[None, None, Frame]c             
   c  s   |dE dH }t d|\}}|d@ rdnd}|d@ rdnd}	|d@ r&dnd}
|d	@ r.dnd}zt|d
@ }W n tyJ } ztd|d}~ww |d@ rQdnd|krZtd|d@ }|dkrq|dE dH }t d|\}n|dkr|dE dH }t d|\}|dur||krtd| d| d|r|dE dH }||E dH }|rt||}| ||||	|
|}|du rg }t|D ]	}|j	||d}q|
  |S )a&  
        Parse a WebSocket frame.

        This is a generator-based coroutine.

        Args:
            read_exact: generator-based coroutine that reads the requested
                bytes or raises an exception if there isn't enough data.
            mask: whether the frame should be masked i.e. whether the read
                happens on the server side.
            max_size: maximum payload size in bytes.
            extensions: list of extensions, applied in reverse order.

        Raises:
            EOFError: if the connection is closed without a full WebSocket frame.
            UnicodeDecodeError: if the frame contains invalid UTF-8.
            PayloadTooBig: if the frame's payload size exceeds ``max_size``.
            ProtocolError: if the frame contains incorrect values.

        r   N!BB   TF@       rG      zinvalid opcodezincorrect masking   ~   !Hr   z!Qzover size limit (z > z bytes)   )rc   )structunpackr   
ValueErrorr	   ProtocolErrorZPayloadTooBigr   reversedrX   check)clsrd   rf   rc   r
   r:   head1head2r<   r=   r>   r?   r8   excr`   
mask_bytesframe	extensionr(   r(   r)   rZ      sL   

zFrame.parse)r
   c          
      C  s&  |    |du r
g }|D ]}|| } qt }| jrdnd| jr#dndB | jr*dndB | jr1dndB | jB }|r;dnd}t	| j
}|dk rS|td|||B  n|d	k re|td
||dB | n|td||dB | |r~td}|| |rt| j
|}	n| j
}	||	 | S )aH  
        Serialize a WebSocket frame.

        Args:
            mask: whether the frame should be masked i.e. whether the write
                happens on the client side.
            extensions: list of extensions, applied in order.

        Raises:
            ProtocolError: if the frame contains incorrect values.

        Nrk   r   rl   rm   rG   rp   rj   i   z!BBHz!BBQro   rr   )rx   encodeioBytesIOr<   r=   r>   r?   r8   rV   r:   writers   packsecretsZtoken_bytesr   getvalue)
r_   rf   r
   r   outputrz   r{   r`   r}   r:   r(   r(   r)   	serialize   s>   



zFrame.serializeNonec                 C  sV   | j s	| js	| jrtd| jtv r't| jdkrtd| j	s)tddS dS )z
        Check that reserved bits and opcode have acceptable values.

        Raises:
            ProtocolError: if a reserved bit or the opcode is invalid.

        zreserved bits must be 0}   zcontrol frame too longzfragmented control frameN)
r=   r>   r?   r	   rv   r8   r   rV   r:   r<   r_   r(   r(   r)   rx   3  s   



zFrame.checkr@   rA   )
rd   re   rf   r;   rc   rg   r
   rh   r@   ri   )rf   r;   r
   rh   r@   r9   r@   r   )r   r   r    r!   __annotations__r<   r=   r>   r?   rb   classmethodrZ   r   rx   r(   r(   r(   r)   r   c   s    
 
/P;r   r:   r   r@   Tuple[int, bytes]c                 C  s2   t | trt| dfS t | trt| fS td)a  
    Convert a string or byte-like object to an opcode and a bytes-like object.

    This function is designed for data frames.

    If ``data`` is a :class:`str`, return ``OP_TEXT`` and a :class:`bytes`
    object encoding ``data`` in UTF-8.

    If ``data`` is a bytes-like object, return ``OP_BINARY`` and a bytes-like
    object.

    Raises:
        TypeError: if ``data`` doesn't have a supported type.

    utf-8data must be str or bytes-like)
isinstancerA   r   r   	BytesLiker   	TypeErrorr:   r(   r(   r)   r   E  s
   

r   r9   c                 C  s.   t | tr
| dS t | trt| S td)ai  
    Convert a string or byte-like object to bytes.

    This function is designed for ping and pong frames.

    If ``data`` is a :class:`str`, return a :class:`bytes` object encoding
    ``data`` in UTF-8.

    If ``data`` is a bytes-like object, return a :class:`bytes` object.

    Raises:
        TypeError: if ``data`` doesn't have a supported type.

    r   r   )r   rA   r   r   r9   r   r   r(   r(   r)   r   ]  s
   


r   c                   @  sN   e Zd ZU dZded< ded< dddZedddZdddZdddZ	dS )r   z
    Code and reason for WebSocket close frames.

    Attributes:
        code: Close code.
        reason: Close reason.

    intcoderA   reasonr@   c                 C  sz   d| j   krdk rn nd}nd| j   krdk r n nd}nt| j d}| j  d| d}| jr;| d	| j }|S )
zS
        Return a human-readable represention of a close code and reason.

          i  
registered  zprivate useunknownz ()rH   )r   CLOSE_CODESgetr   )r_   Zexplanationresultr(   r(   r)   rb     s   zClose.__str__r:   r9   c                 C  sj   t |dkr%td|dd \}|dd d}| ||}|  |S t |dkr0| ddS td)	z
        Parse the payload of a close frame.

        Args:
            data: payload of the close frame.

        Raises:
            ProtocolError: if data is ill-formed.
            UnicodeDecodeError: if the reason isn't valid UTF-8.

        r   rq   Nr   r   r/   rB   zclose frame too short)rV   rs   rt   rX   rx   r	   rv   )ry   r:   r   r   closer(   r(   r)   rZ     s   


zClose.parsec                 C  s"   |    td| j| jd S )z:
        Serialize the payload of a close frame.

        rq   r   )rx   rs   r   r   r   r   r   r(   r(   r)   r     s   zClose.serializer   c                 C  s4   | j tv sd| j   krdk sn tddS dS )z
        Check that the close code has a valid value for a close frame.

        Raises:
            ProtocolError: if the close code is invalid.

        r   r   zinvalid status codeN)r   EXTERNAL_CLOSE_CODESr	   rv   r   r(   r(   r)   rx     s   "
zClose.checkNr   )r:   r9   r@   r   )r@   r9   r   )
r   r   r    r!   r   rb   r   rZ   r   rx   r(   r(   r(   r)   r   t  s   
 	

r   )r:   r   r@   r   )r:   r   r@   r9   )2
__future__r   dataclassesenumr   r   rs   typingr   r   r   r   r   rB   r	   r
   r   Zspeedupsr   ImportErrorutils__all__IntEnumr   r"   r   r#   r   r$   r   r%   r   r&   r   r'   r   r   r   r   r   ZOK_CLOSE_CODESr9   	bytearray
memoryviewr   	dataclassr   r   r   r   r(   r(   r(   r)   <module>   sd    


 
b
