B
    ]b]0                 @  s  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 yddlmZ W n  ek
r   ddlmZ Y nX dd	d
ddddddddddg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&d&d'd(d)d*d+d,d-d.d/d0d1hZ'd&d'hZ(e)e*e+fZ,ej-G d2d dZ.d3d4d5d6dZ/d3d7d5d8dZ0ej-G d9d 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(   0lib/python3.7/site-packages/websockets/frames.pyr   %   s   
Z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  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  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dZ	e
dddddddddddZddddddddZd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str)returnc          
   C  s  d}t | j dt | jdkr"dnd }| jr4dnd}| jtkrRt| j }n| jtkr| j}t |dkrd|dd	 d
|dd g}ddd |D }n| jt	krt
t| j}n| jrHyt| j }d}W nf ttfk
rD   | j}t |dkr(d|dd	 d
|dd g}ddd |D }d}Y nX nd}t |dkrv|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  s   | ]}|d V  qdS )02xNr(   ).0byter(   r(   r)   	<genexpr>   s    z Frame.__str__.<locals>.<genexpr>textc             s  s   | ]}|d V  qdS )r;   Nr(   )r<   r=   r(   r(   r)   r>      s    binaryz''K   0   z...iz, z [])lenr,   r.   r*   r   reprdecoder   joinr   r2   r   parseUnicodeDecodeErrorAttributeErrorfiltername)selfZcodinglengthZ	non_finalr,   r@   Zmetadatar(   r(   r)   __str__|   s6    &

 
 zFrame.__str__N)max_sizer
   z-Callable[[int], Generator[None, None, bytes]]zOptional[int]z(Optional[Sequence[extensions.Extension]]zGenerator[None, None, Frame])
read_exactmaskrP   r
   r3   c         
   c  s  |dE dH }t d|\}}|d@ r*dnd}|d@ r:dnd}	|d@ rJdnd}
|d	@ rZdnd}yt|d
@ }W n. tk
r } ztd|W dd}~X Y nX |d@ rdnd|krtd|d@ }|dkr|dE dH }t d|\}n&|dkr|dE dH }t d|\}|dk	r<||kr<td| d| d|rP|dE dH }||E dH }|rnt||}| ||||	|
|}|dkrg }x t|D ]}|j	||d}qW |
  |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:
            PayloadTooBig: if the frame's payload size exceeds ``max_size``.
            ProtocolError: if the frame contains incorrect values.

        r   Nz!BB   TF@       r9      zinvalid opcodezincorrect masking   ~   z!Hr   z!Qzover size limit (z > z bytes)   )rP   )structunpackr   
ValueErrorr	   ProtocolErrorZPayloadTooBigr   reversedrF   check)clsrQ   rR   rP   r
   r,   head1head2r.   r/   r0   r1   r*   excrN   
mask_bytesframe	extensionr(   r(   r)   rH      sD    



zFrame.parse)r
   )rR   r
   r3   c      
      C  s.  |    |dkrg }x|D ]}|| } qW t }| jr>dnd| jrJdndB | jrXdndB | jrfdndB | jB }|rzdnd}t	| j
}|dk r|td|||B  n>|d	k r|td
||dB | n|td||dB | |rtd}|| |rt| 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.

        NrS   r   rT   rU   r9   rX   z!BBi   z!BBHz!BBQrW   rY   )r_   encodeioBytesIOr.   r/   r0   r1   r*   rD   r,   writerZ   packsecretsZtoken_bytesr   getvalue)
rM   rR   r
   rf   outputra   rb   rN   rd   r,   r(   r(   r)   	serialize   s,    
>



zFrame.serializeNonec             C  sR   | j s| js| jrtd| jtkrNt| jdkr>td| j	sNtd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/   r0   r1   r	   r]   r*   r   rD   r,   r.   )rM   r(   r(   r)   r_   1  s    


zFrame.check)r   r   r    r!   __annotations__r.   r/   r0   r1   rO   classmethodrH   ro   r_   r(   r(   r(   r)   r   c   s   
/H7r   zTuple[int, bytes])r,   r3   c             C  s6   t | trt| dfS t | tr*t| fS tddS )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.

    zutf-8zdata must be str or bytes-likeN)
isinstancer2   r   rg   	BytesLiker   	TypeError)r,   r(   r(   r)   r   C  s
    

r+   c             C  s2   t | tr| dS t | tr&t| S tddS )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.

    zutf-8zdata must be str or bytes-likeN)rt   r2   rg   ru   r+   rv   )r,   r(   r(   r)   r   [  s
    


c               @  s`   e Zd ZU dZded< ded< ddddZed	d d
ddZd	dddZddddZ	dS )r   z
    Code and reason for WebSocket close frames.

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

    intcoder2   reason)r3   c             C  sz   d| j   krdk r n nd}n.d| j   kr6dk r@n nd}nt| j d}| j  d| d}| jrv| d	| j }|S )
zS
        Return a human-readable represention of a close code and reason.

        i  i  Z
registeredi  zprivate useunknownz ()r:   )rx   CLOSE_CODESgetry   )rM   Zexplanationresultr(   r(   r)   rO     s    zClose.__str__r+   )r,   r3   c             C  sn   t |dkrJtd|dd \}|dd d}| ||}|  |S t |dkr`| ddS tddS )	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   z!HNzutf-8r   i  r4   zclose frame too short)rD   rZ   r[   rF   r_   r	   r]   )r`   r,   rx   ry   closer(   r(   r)   rH     s    

zClose.parsec             C  s"   |    td| j| jd S )z:
        Serialize the payload of a close frame.

        z!Hzutf-8)r_   rZ   rk   rx   ry   rg   )rM   r(   r(   r)   ro     s    zClose.serializerp   c             C  s0   | j tks,d| j   kr dk s,n tddS )z
        Check that the close code has a valid value for a close frame.

        Raises:
            ProtocolError: if the close code is invalid.

        i  i  zinvalid status codeN)rx   EXTERNAL_CLOSE_CODESr	   r]   )rM   r(   r(   r)   r_     s    "zClose.checkN)
r   r   r    r!   rr   rO   rs   rH   ro   r_   r(   r(   r(   r)   r   r  s   
	)2Z
__future__r   Zdataclassesenumrh   rl   rZ   typingr   r   r   r   r   r4   r	   r
   r   Zspeedupsr   ImportErrorZutils__all__IntEnumr   r"   r   r#   r   r$   r   r%   r   r&   r   r'   r   r   r   r|   r   ZOK_CLOSE_CODESr+   	bytearray
memoryviewru   Z	dataclassr   r   r   r   r(   r(   r(   r)   <module>   s   


 a