B
    &d35                 @   s6  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 yd dl	m
Z
 eddd	ZW n, ek
r   ejZee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   )*)validate_utf8)Lock)XorMaskerSimple)returnc             C   s   t | |S )N)r   process)_mZ_d r
   \/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/websocket/_abnf.py_mask$   s    r   )
mask_value
data_valuer   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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  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eeeeeee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d d d!d"Zedd#d$Zeed%d&d'Zeee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         	   
   conttextbinarycloseZpingpong~   i   l             N)finrsv1rsv2rsv3opcodemaskdatar   c             C   sB   || _ || _|| _|| _|| _|| _|dkr0d}|| _tj| _	dS )zG
        Constructor for ABNF. Please check RFC for arguments.
        Nr/   )
r0   r1   r2   r3   r4   r5   r6   osurandomget_mask_key)selfr0   r1   r2   r3   r4   r5   r6   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	| jd
  | 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   r.   zInvalid close frame.r%      r   zInvalid close opcode %r)r1   r2   r3   WebSocketProtocolExceptionr4   r   OPCODESOPCODE_PINGr0   OPCODE_CLOSEr   r6   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t | j d t | j d t | j S )Nzfin=z opcode=z data=)strr0   r4   r6   )r:   r
   r
   r   __str__   s    zABNF.__str__)r6   r4   r0   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: <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.
        zutf-8r   r   )r   OPCODE_TEXT
isinstancerG   encode)r6   r4   r0   r
   r
   r   create_frame   s    
zABNF.create_framec             C   sL  t dd | j| j| j| jg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s0|| j
 S | d	}|| | 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   zlatin-1r.   z!H   z!QN)anyr0   r1   r2   r3   
ValueErrorr4   r   r?   r   r6   	LENGTH_63chrrK   LENGTH_7r5   	LENGTH_16structpackr9   _get_masked)r:   lengthZframe_headermask_keyr
   r
   r   format   s*    "

&



zABNF.format)r^   r   c             C   s*   t || j}t|tr"|d}|| S )Nzutf-8)r   r5   r6   rJ   rG   rK   )r:   r^   sr
   r
   r   r\      s    

zABNF._get_masked)r^   r6   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.
        Nr/   zlatin-1B)rJ   rG   rK   r   array)r^   r6   r
   r
   r   r5      s    



z	ABNF.mask)F)r   )__name__
__module____qualname____doc__OPCODE_CONTrI   OPCODE_BINARYrA   r@   ZOPCODE_PONGr?   Z
OPCODE_MAPrX   rY   rV   r   rG   r;   boolrE   staticmethodrB   rH   rL   bytesr_   r\   r5   r
   r
   r
   r   r   d   s<   $c               @   s   e Zd ZdZdZeeddddZdddd	Zedd
dZ	ddddZ
epRe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   rR   rQ   N)recv_fnr<   r   c             C   s&   || _ || _g | _|   t | _d S )N)recvr<   recv_bufferclearr   lock)r:   rl   r<   r
   r
   r   r;     s
    zframe_buffer.__init__)r   c             C   s   d | _ d | _d | _d S )N)headerr]   r5   )r:   r
   r
   r   ro     s    zframe_buffer.clearc             C   s
   | j d kS )N)rq   )r:   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   rP   r   rQ   rR   r      rS   )recv_strictrq   )r:   rq   b1r0   r1   r2   r3   r4   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)rq   r   _HEADER_MASK_INDEX)r:   r
   r
   r   rw   3  s    zframe_buffer.has_maskc             C   s
   | j d kS )N)r]   )r:   r
   r
   r   has_received_length8  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 )NrS   r.   r%   z!Hr   r&   z!Q)rq   r   _HEADER_LENGTH_INDEXrt   rZ   unpackr]   )r:   bitsrx   vr
   r
   r   recv_length;  s    

zframe_buffer.recv_lengthc             C   s
   | j d kS )N)r5   )r:   r
   r
   r   has_received_maskG  s    zframe_buffer.has_received_maskc             C   s   |   r| dnd| _d S )Nr   r/   )rw   rt   r5   )r:   r
   r
   r   	recv_maskJ  s    zframe_buffer.recv_maskc          	   C   s   | j  |  r|   | j\}}}}}}}|  r<|   | j}|  rR|   | j	}	| 
|}
|rrt	|	|
}
|   t|||||||
}|| j W d Q R X |S )N)rp   rr   ry   rq   r{   r   r]   r   r   r5   rt   r   ro   rE   r<   )r:   r0   r1   r2   r3   r4   rw   _r]   r5   payloadframer
   r
   r   
recv_frameM  s"    
zframe_buffer.recv_frame)bufsizer   c             C   s   |t tt| j }x4|dkrH| td|}| j| |t|8 }qW d| j}|dkrhg | _|S ||d  g| _|d | S d S )Nr   i @      )summapr   rn   rm   minappendjoin)r:   r   Zshortagebytes_Zunifiedr
   r
   r   rt   l  s    
zframe_buffer.recv_strict)rc   rd   re   rz   r|   r   ri   r;   ro   rr   ry   rw   r{   r   r   r   r   r   rk   rt   r
   r
   r
   r   r     s   	c               @   sb   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pBe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 )N)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   r4   r   rg   r>   rI   rh   )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   r6   r4   r   rI   rh   r   r0   )r:   r   r
   r
   r   add  s    zcontinuous_frame.addc             C   s   |j p
| jS )N)r0   r   )r:   r   r
   r
   r   is_fire  s    zcontinuous_frame.is_firec             C   sX   | j }d | _ |d |_| jsL|d tjkrL| jsLt|jsLtdt|j |d |gS )Nr   r   zcannot decode: )	r   r6   r   r   rI   r<   r   ZWebSocketPayloadExceptionrepr)r:   r   r6   r
   r
   r   extract  s    
$zcontinuous_frame.extract)rc   rd   re   ri   r;   r   rE   r   r   r   listr   r
   r
   r
   r   r     s
   )%rb   r7   rZ   sys_exceptions_utilsr   	threadingr   Zwsaccel.xormaskr   rk   r   ImportError	byteorderr   r   __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>   sr    -s