U
    g18                     @   s^  d dl Z d dlZd dlZd dlZd dlmZ d dlmZmZm	Z	 ddl
mZmZ ddlmZ z&d dlmZ e j e j edd	d
ZW n0 ek
r   ejZe j e j eddd
ZY nX ddddddddddddddddg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#d)Z$d*Z%ee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 ).    N)Lock)CallableOptionalUnion   )WebSocketPayloadExceptionWebSocketProtocolException)validate_utf8)XorMaskerSimple)
mask_value
data_valuereturnc                 C   s   t | |}|S N)r
   process)r   r   Zmask_result r   3/tmp/pip-unpacked-wheel-0xk_xrpx/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)r   r   ZdatalenZint_data_valueZint_mask_valuer   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  i  i  c                   @   s8  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eeeeeeeeedf ddddZd+eddddZeeedddZedddZed,eeef eed d d!d"Zedd#d$Zeeef ed%d&d'Zeeeef eeef ed(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             N)finrsv1rsv2rsv3opcoder   datar   c                 C   sB   || _ || _|| _|| _|| _|| _|dkr0d}|| _tj| _	dS )zG
        Constructor for ABNF. Please check RFC for arguments.
        Nr1   )
r2   r3   r4   r5   r6   r   r7   osurandomget_mask_key)selfr2   r3   r4   r5   r6   r   r7   r   r   r   __init__   s    zABNF.__init__F)skip_utf8_validationr   c                 C   s   | j s| js| jrtd| jtjkr2td| j| jtjkrL| jsLtd| jtj	krt
| j}|sjdS |dksz|dkrtd|dkr|st| jdd stdd	t| jd
  t| jd  }| |std|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   r0   zInvalid close frame.r)      r   zInvalid close opcode %r)r3   r4   r5   r   r6   r   OPCODESOPCODE_PINGr2   OPCODE_CLOSEr   r7   r	   r   _is_valid_close_status)r;   r=   lcoder   r   r   validate   s"    
 
zABNF.validate)rD   r   c                 C   s    | t kpd|   kodk S   S )Ni  i  )VALID_CLOSE_STATUS)rD   r   r   r   rB      s    zABNF._is_valid_close_statusr   c                 C   s   d| j  d| j d| j S )Nzfin=z opcode=z data=)r2   r6   r7   r;   r   r   r   __str__   s    zABNF.__str__)r7   r6   r2   r   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: str
            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: int
            operation code. please see OPCODE_MAP.
        fin: int
            fin flag. if set to 0, create continue fragmentation.
        utf-8r   r   )r   OPCODE_TEXT
isinstancestrencode)r7   r6   r2   r   r   r   create_frame   s    
zABNF.create_framec                 C   sd  t dd | j| j| j| jfD r*td| jtjkr>tdt	| j
}|tjkrZt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 }nd|tjk r|t| jd> dB d
7 }|td|7 }n,|t| jd> dB d
7 }|td|7 }| jsLt| j
trB| j
d| _
|| j
 S | d	}|| | S )zR
        Format this object to string(byte array) to send data to server.
        c                 s   s   | ]}|d k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-1r0   !H   !QrJ   )anyr2   r3   r4   r5   
ValueErrorr6   r   r?   r   r7   	LENGTH_63chrrN   LENGTH_7r   	LENGTH_16structpackrL   rM   r:   _get_masked)r;   lengthZframe_headermask_keyr   r   r   format   sB    "





zABNF.format)rd   r   c                 C   s*   t || j}t|tr"|d}|| S )NrJ   )r   maskr7   rL   rM   rN   )r;   rd   sr   r   r   rb     s    

zABNF._get_masked)rd   r7   r   c                 C   sN   |dkrd}t | tr | d} t |tr4|d}ttd| td|S )z
        Mask or unmask data. Just do xor for each byte

        Parameters
        ----------
        mask_key: bytes or str
            4 byte mask.
        data: bytes or str
            data to mask/unmask.
        Nr1   rV   B)rL   rM   rN   r   array)rd   r7   r   r   r   rf     s    



z	ABNF.mask)F)r   )__name__
__module____qualname____doc__OPCODE_CONTrK   OPCODE_BINARYrA   r@   ZOPCODE_PONGr?   Z
OPCODE_MAPr^   r_   r\   r   r   rM   bytesr<   boolrE   staticmethodrB   rI   rO   re   rb   rf   r   r   r   r   r   j   sr         
 #c                   @   s   e Zd ZdZdZeegef eddddZdddd	Z	edd
dZ
ddddZeeef dddZedddZddddZedddZddddZedddZeedddZdS )r   rU   rT   N)recv_fnr=   r   c                 C   s&   || _ || _g | _|   t | _d S r   )recvr=   recv_bufferclearr   lock)r;   rs   r=   r   r   r   r<   +  s
    zframe_buffer.__init__rG   c                 C   s   d | _ d | _d | _d S r   )headerrc   r   rH   r   r   r   rv   6  s    zframe_buffer.clearc                 C   s
   | j d kS r   )rx   rH   r   r   r   has_received_header;  s    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   rS   r   rT   rU   r      rX   )recv_strictrx   )r;   rx   Zb1r2   r3   r4   r5   r6   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)rx   r   _HEADER_MASK_INDEX)r;   Z
header_valr   r   r   r|   L  s    zframe_buffer.has_maskc                 C   s
   | j d kS r   )rc   rH   r   r   r   has_received_lengthR  s    z frame_buffer.has_received_lengthc                 C   sj   | j tj }|d@ }|dkr:| d}td|d | _n,|dkr`| d}td|d | _n|| _d S )NrX   r0   r)   rW   r   r*   rY   )rx   r   _HEADER_LENGTH_INDEXr{   r`   unpackrc   )r;   bitsr}   vr   r   r   recv_lengthU  s    

zframe_buffer.recv_lengthc                 C   s
   | j d kS r   )r   rH   r   r   r   has_received_maska  s    zframe_buffer.has_received_maskc                 C   s   |   r| dnd| _d S )Nr   r1   )r|   r{   r   rH   r   r   r   	recv_maskd  s    zframe_buffer.recv_maskc              	   C   s   | j  |  r|   | j\}}}}}}}|  r<|   | j}|  rR|   | j	}	| 
|}
|rrt|	|
}
|   t|||||||
}|| j W 5 Q R X |S r   )rw   ry   r~   rx   r   r   rc   r   r   r   r{   r   rf   rv   rE   r=   )r;   r2   r3   r4   r5   r6   r|   _rc   r   payloadframer   r   r   
recv_frameg  s"    
zframe_buffer.recv_frame)bufsizer   c                 C   s   |t tt| j }|dkrF| td|}| j| |t|8 }qd| j}|dkrdg | _|S ||d  g| _|d | S d S )Nr   i @      )summapr   ru   rt   minappendjoin)r;   r   ZshortageZbytes_Zunifiedr   r   r   r{     s    zframe_buffer.recv_strict)rj   rk   rl   r   r   r   r   rq   r<   rv   ry   r~   r   r|   r   r   r   r   r   r   rp   r{   r   r   r   r   r   '  s     c                   @   sf   e Zd ZeeddddZeddddZedddd	Zeeee	f dd
dZ
eedddZdS )r   N)fire_cont_framer=   r   c                 C   s   || _ || _d | _d | _d S r   )r   r=   	cont_datarecving_frames)r;   r   r=   r   r   r   r<     s    zcontinuous_frame.__init__)r   r   c                 C   s>   | j s|jtjkrtd| j r:|jtjtjfkr:tdd S )NzIllegal frame)r   r6   r   rn   r   rK   ro   r;   r   r   r   r   rE     s    
zcontinuous_frame.validatec                 C   sT   | j r| j d  |j7  < n(|jtjtjfkr6|j| _|j|jg| _ |jrPd | _d S )Nr   )r   r7   r6   r   rK   ro   r   r2   r   r   r   r   add  s    zcontinuous_frame.addc                 C   s   |j p
| jS r   )r2   r   r   r   r   r   is_fire  s    zcontinuous_frame.is_firec                 C   sZ   | j }d | _ |d |_| jsN|d tjkrN| jsNt|jsNtdt|j |d |fS )Nr   r   zcannot decode: )	r   r7   r   r   rK   r=   r	   r   repr)r;   r   r7   r   r   r   extract  s    
zcontinuous_frame.extract)rj   rk   rl   rq   r<   r   rE   r   r   r   r   tupler   r   r   r   r   r     s
   	)*ri   r8   r`   sys	threadingr   typingr   r   r   _exceptionsr   r   _utilsr	   Zwsaccel.xormaskr
   rp   r   ImportError	byteorderr   __all__r   r   r   r   r    r!   r"   r#   r$   r%   r&   ZSTATUS_SERVICE_RESTARTZSTATUS_TRY_AGAIN_LATERr'   r(   rF   r   r   r   r   r   r   r   <module>   s|   
 >u