o
    _7a/3                  
   @   s  d Z 	 ddlZddlZddlZddlZddlT ddlmZ ddlm	Z	 zddl
mZ dd	 ZW n ey?   ejZd
d	 ZY nw g dZdZdZdZdZdZdZdZdZdZdZdZdZdZeeeeeeeeeef
ZG dd dZG dd dZ G dd dZ!dS )z

    N   )*)validate_utf8)Lock)XorMaskerSimplec                 C   s   t | |S N)r   Zprocess)Z_mZ_d r   1/usr/lib/python3/dist-packages/websocket/_abnf.py_mask'   s   r
   c                 C   sH   t |}t|t}t| |d  | d |d   t} || A |tS )N   )lenint
from_bytesnative_byteorderto_bytes)Z
mask_valueZ
data_valueZdatalenr   r   r	   r
   .   s   $)ABNFcontinuous_frameframe_bufferSTATUS_NORMALSTATUS_GOING_AWAYSTATUS_PROTOCOL_ERRORSTATUS_UNSUPPORTED_DATA_TYPESTATUS_STATUS_NOT_AVAILABLESTATUS_ABNORMAL_CLOSEDSTATUS_INVALID_PAYLOADSTATUS_POLICY_VIOLATIONSTATUS_MESSAGE_TOO_BIGSTATUS_INVALID_EXTENSIONSTATUS_UNEXPECTED_CONDITIONSTATUS_BAD_GATEWAYSTATUS_TLS_HANDSHAKE_ERRORi  i  i  i  i  i  i  i  i  i  i  i  i  c                   @   s   e Zd ZdZdZdZdZdZdZdZ	eeeeee	fZ
eded	ed
edede	diZdZdZdZddddeddfddZd$ddZedd Zdd Zed%ddZdd Zdd  Zed!d" Zd#S )&r   z}
    ABNF frame class.
    See http://tools.ietf.org/html/rfc5234
    and http://tools.ietf.org/html/rfc6455#section-5.2
    r   r         	   
   ZconttextbinarycloseZpingZpong~   i   l             c                 C   sB   || _ || _|| _|| _|| _|| _|du rd}|| _tj| _	dS )zG
        Constructor for ABNF. Please check RFC for arguments.
        Nr)   )
finrsv1rsv2rsv3opcodemaskdataosurandomget_mask_key)selfr*   r+   r,   r-   r.   r/   r0   r   r   r	   __init__   s   zABNF.__init__Fc                 C   s   | j s	| js	| jrtd| jtjvrtd| j| jtjkr&| js&td| jtj	krit
| j}|s5dS |dks=|dkrAtd|dkrT|sTt| jdd sTtdd	| jd
  | jd  }| |sktddS dS )z
        Validate the ABNF frame.

        Parameters
        ----------
        skip_utf8_validation: skip utf8 validation.
        zrsv is not implemented, yetzInvalid opcode %rzInvalid ping frame.Nr   r(   zInvalid close frame.r!      r   zInvalid close opcode.)r+   r,   r-   WebSocketProtocolExceptionr.   r   OPCODESOPCODE_PINGr*   OPCODE_CLOSEr   r0   r   _is_valid_close_status)r4   skip_utf8_validationlcoder   r   r	   validate   s&   


zABNF.validatec                 C   s    | t v pd|   kodk S   S )Ni  i  )VALID_CLOSE_STATUS)r>   r   r   r	   r;      s    zABNF._is_valid_close_statusc                 C   s*   dt | j d t | j d t | j S )Nzfin=z opcode=z data=)strr*   r.   r0   r4   r   r   r	   __str__   s   zABNF.__str__c                 C   s2   |t jkrt| tr| d} t |ddd|d| S )a  
        Create frame to send text, binary and other data.

        Parameters
        ----------
        data: <type>
            data to send. This is string value(byte array).
            If opcode is OPCODE_TEXT and this value is unicode,
            data value is converted into unicode string, automatically.
        opcode: <type>
            operation code. please see OPCODE_XXX.
        fin: <type>
            fin flag. if set to 0, create continue fragmentation.
        utf-8r   r   )r   OPCODE_TEXT
isinstancerA   encode)r0   r.   r*   r   r   r	   create_frame   s   
zABNF.create_framec                 C   sF  t dd | j| j| j| jfD rtd| jtjvrtdt	| j
}|tjkr-tdt| jd> | jd> B | jd> B | jd	> B | jB d
}|tjk r]|t| jd> |B d
7 }n2|tjk ry|t| jd> dB d
7 }|td|7 }n|t| jd> dB d
7 }|td|7 }| js|| j
 S | d	}|| | S )zR
        Format this object to string(byte array) to send data to server.
        c                 s   s    | ]}|d vV  qdS ))r   r   Nr   ).0xr   r   r	   	<genexpr>   s    zABNF.format.<locals>.<genexpr>z
not 0 or 1zInvalid OPCODEzdata is too long         r   latin-1r(   !H   !Q)anyr*   r+   r,   r-   
ValueErrorr.   r   r8   r   r0   	LENGTH_63chrrG   LENGTH_7r/   	LENGTH_16structZpackr3   _get_masked)r4   lengthZframe_headermask_keyr   r   r	   format   s:   "






zABNF.formatc                 C   s*   t || j}t|tr|d}|| S )NrD   )r   r/   r0   rF   rA   rG   )r4   r\   sr   r   r	   rZ      s   

zABNF._get_maskedc                 C   sN   |du rd}t | tr| d} t |tr|d}ttd| td|S )z
        Mask or unmask data. Just do xor for each byte

        Parameters
        ----------
        mask_key: <type>
            4 byte string.
        data: <type>
            data to mask/unmask.
        Nr)   rO   B)rF   rA   rG   r
   array)r\   r0   r   r   r	   r/      s   



z	ABNF.maskN)F)r   )__name__
__module____qualname____doc__OPCODE_CONTrE   OPCODE_BINARYr:   r9   ZOPCODE_PONGr8   Z
OPCODE_MAPrW   rX   rU   r5   r?   staticmethodr;   rC   rH   r]   rZ   r/   r   r   r   r	   r   c   sD    



r   c                   @   sl   e Zd ZdZdZdd Zdd Zdd Zd	d
 Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd ZdS )r   rN   rM   c                 C   s&   || _ || _g | _|   t | _d S r   )recvr<   recv_bufferclearr   lock)r4   Zrecv_fnr<   r   r   r	   r5     s
   zframe_buffer.__init__c                 C   s   d | _ d | _d | _d S r   )headerr[   r/   rB   r   r   r	   rj     s   
zframe_buffer.clearc                 C   
   | j d u S r   )rl   rB   r   r   r	   has_received_header!     
z frame_buffer.has_received_headerc                 C   s~   |  d}|d }|d? d@ }|d? d@ }|d? d@ }|d? d@ }|d@ }|d }|d? d@ }	|d	@ }
||||||	|
f| _d S )
Nr!   r   rL   r   rM   rN   r      rQ   )recv_strictrl   )r4   rl   Zb1r*   r+   r,   r-   r.   Zb2has_masklength_bitsr   r   r	   recv_header$  s   
zframe_buffer.recv_headerc                 C   s   | j sdS | j tj S )NF)rl   r   _HEADER_MASK_INDEXrB   r   r   r	   rr   2  s   zframe_buffer.has_maskc                 C   rm   r   )r[   rB   r   r   r	   has_received_length7  ro   z frame_buffer.has_received_lengthc                 C   sn   | j tj }|d@ }|dkr| d}td|d | _d S |dkr2| d}td|d | _d S || _d S )NrQ   r(   r!   rP   r   r"   rR   )rl   r   _HEADER_LENGTH_INDEXrq   rY   unpackr[   )r4   bitsrs   vr   r   r	   recv_length:  s   


zframe_buffer.recv_lengthc                 C   rm   r   )r/   rB   r   r   r	   has_received_maskF  ro   zframe_buffer.has_received_maskc                 C   s"   |   r| d| _d S d| _d S )Nr   r)   )rr   rq   r/   rB   r   r   r	   	recv_maskI  s   "zframe_buffer.recv_maskc              	   C   s   | j R |  r|   | j\}}}}}}}|  r|   | j}|  r)|   | j	}	| 
|}
|r9t	|	|
}
|   t|||||||
}|| j W d    |S 1 sXw   Y  |S r   )rk   rn   rt   rl   rv   r{   r[   r|   r}   r/   rq   r   rj   r?   r<   )r4   r*   r+   r,   r-   r.   rr   _r[   r/   Zpayloadframer   r   r	   
recv_frameL  s(   

zframe_buffer.recv_framec                 C   s   |t tt| j }|dkr&| td|}| j| |t|8 }|dksd| j}|dkr5g | _|S ||d  g| _|d | S )Nr   i @      )summapr   ri   rh   minappendjoin)r4   bufsizeZshortageZbytes_Zunifiedr   r   r	   rq   k  s   zframe_buffer.recv_strictN)ra   rb   rc   ru   rw   r5   rj   rn   rt   rr   rv   r{   r|   r}   r   rq   r   r   r   r	   r     s    	r   c                   @   s4   e Zd Zdd Zdd Zdd Zdd Zd	d
 ZdS )r   c                 C   s   || _ || _d | _d | _d S r   )fire_cont_framer<   	cont_datarecving_frames)r4   r   r<   r   r   r	   r5     s   
zcontinuous_frame.__init__c                 C   sB   | j s|jtjkrtd| j r|jtjtjfv rtdd S d S )NzIllegal frame)r   r.   r   re   r7   rE   rf   r4   r   r   r   r	   r?     s   zcontinuous_frame.validatec                 C   sX   | j r| j d  |j7  < n|jtjtjfv r|j| _|j|jg| _ |jr*d | _d S d S )Nr   )r   r0   r.   r   rE   rf   r   r*   r   r   r   r	   add  s   
zcontinuous_frame.addc                 C   s   |j p| jS r   )r*   r   r   r   r   r	   is_fire  s   zcontinuous_frame.is_firec                 C   sX   | j }d | _ |d |_| js&|d tjkr&| js&t|js&tdt|j |d |gS )Nr   r   zcannot decode: )	r   r0   r   r   rE   r<   r   ZWebSocketPayloadExceptionrepr)r4   r   r0   r   r   r	   extract  s   
$zcontinuous_frame.extractN)ra   rb   rc   r5   r?   r   r   r   r   r   r   r	   r     s    r   )"rd   r`   r1   rY   sys_exceptionsZ_utilsr   Z	threadingr   Zwsaccel.xormaskr   r
   ImportError	byteorderr   __all__r   r   r   r   r   r   r   r   r   r   r   r   r    r@   r   r   r   r   r   r   r	   <module>   sZ     -s