U
    *eZ5                     @   sT  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ej
rVddlZndZW n ek
rt   dZY nX zesddlmZ dd	 ZW n ek
r   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eeeeeeeeeef
ZG d(d deZ G d)d deZ!G d*d deZ"dS )+aL  
websocket - WebSocket client library for Python

Copyright (C) 2010 Hiroki Ohtani(liris)

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA  02110-1335  USA

    N   )*)validate_utf8)Lock)XorMaskerSimplec                 C   s   t | |S N)r   Zprocess)_m_d r
   1/usr/lib/python3/dist-packages/websocket/_abnf.py_mask-   s    r   c                 C   sD   t t|D ]}||  | |d  N  < qtjr8| S | S d S )N   )rangelensixPY3tobytesZtostring)r   r	   ir
   r
   r   r   1   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kr0d}|| _tj| _	dS )zO
        Constructor for ABNF.
        please check RFC for arguments.
        Nr,   )
finrsv1rsv2rsv3opcodemaskdataosurandomget_mask_key)selfr-   r.   r/   r0   r1   r2   r3   r
   r
   r   __init__   s    zABNF.__init__Fc                 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
d  t| jdd  }| |stddS )z^
        validate the ABNF frame.
        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/   r0   WebSocketProtocolExceptionr1   r   OPCODESOPCODE_PINGr-   OPCODE_CLOSEr   r3   r   r   Zbyte2int_is_valid_close_status)r7   skip_utf8_validationlcoder
   r
   r   validate   s*    

zABNF.validatec                 C   s    | t kpd|   kodk S   S )Ni  i  )VALID_CLOSE_STATUS)rA   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-   r1   r3   r7   r
   r
   r   __str__   s    zABNF.__str__c                 C   s4   |t jkr t| tjr | d} t |ddd|d| S )a  
        create frame to send text, binary and other data.

        data: 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: operation code. please see OPCODE_XXX.

        fin: fin flag. if set to 0, create continue fragmentation.
        utf-8r   r   )r   OPCODE_TEXT
isinstancer   	text_typeencode)r3   r1   r-   r
   r
   r   create_frame   s    
zABNF.create_framec                 C   sR  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 }|tjk r|t| jd> |B 7 }t|}nl|tjk r|t| jd> d
B 7 }t|}|td|7 }n0|t| jd> dB 7 }t|}|td|7 }| js6|| 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   r+   !H   !QN)anyr-   r.   r/   r0   
ValueErrorr1   r   r;   r   r3   	LENGTH_63chrLENGTH_7r2   r   b	LENGTH_16structZpackr6   _get_masked)r7   lengthZframe_headermask_keyr
   r
   r   format   s<    "








zABNF.formatc                 C   s,   t || j}t|tjr$|d}|| S )NrG   )r   r2   r3   rI   r   rJ   rK   )r7   ra   sr
   r
   r   r_      s    
zABNF._get_maskedc                 C   s   |dkrd}t | tjr"t| } t |tjr8t|}trt|}| d d> | d d> B | d d> B | d	 B }|td
dt|d   d7 }tj|dd}t||g	d}t||kr|
 d| S |
 S td| }td|}t||S dS )z
        mask or unmask data. Just do xor for each byte

        mask_key: 4 byte string(byte).

        data: data to mask/unmask.
        Nr,         r$      r   r%   r    r   zus-asciiZuint32)ZdtypeB)rI   r   rJ   r\   numpyr   bytesZ
frombufferZbitwise_xorZastyper   arrayr   )ra   r3   ZoriglenZ	_mask_keyaZmaskedr   r	   r
   r
   r   r2      s$    	

,z	ABNF.maskN)F)r   )__name__
__module____qualname____doc__OPCODE_CONTrH   OPCODE_BINARYr=   r<   ZOPCODE_PONGr;   Z
OPCODE_MAPr[   r]   rY   r8   rB   staticmethodr>   rF   rL   rb   r_   r2   r
   r
   r
   r   r   i   sT          
  


!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   rS   rR   c                 C   s&   || _ || _g | _|   t | _d S r   )recvr?   recv_bufferclearr   lock)r7   Zrecv_fnr?   r
   r
   r   r8   #  s
    zframe_buffer.__init__c                 C   s   d | _ d | _d | _d S r   )headerr`   r2   rE   r
   r
   r   rv   ,  s    zframe_buffer.clearc                 C   s
   | j d kS r   )rx   rE   r
   r
   r   has_received_header1  s    z frame_buffer.has_received_headerc                 C   s   |  d}|d }tjr t|}|d? d@ }|d? d@ }|d? d@ }|d? d@ }|d@ }|d }tjrnt|}|d? d@ }	|d	@ }
||||||	|
f| _d S )
Nr$   r   rQ   r   rR   rS   r      rU   )recv_strictr   ZPY2ordrx   )r7   rx   Zb1r-   r.   r/   r0   r1   Zb2has_masklength_bitsr
   r
   r   recv_header4  s    
zframe_buffer.recv_headerc                 C   s   | j s
dS | j tj S )NF)rx   r   _HEADER_MASK_INDEXrE   r
   r
   r   r}   J  s    zframe_buffer.has_maskc                 C   s
   | j d kS r   )r`   rE   r
   r
   r   has_received_lengthO  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 )NrU   r+   r$   rT   r   r%   rV   )rx   r   _HEADER_LENGTH_INDEXr{   r^   Zunpackr`   )r7   bitsr~   vr
   r
   r   recv_lengthR  s    

zframe_buffer.recv_lengthc                 C   s
   | j d kS r   )r2   rE   r
   r
   r   has_received_mask^  s    zframe_buffer.has_received_maskc                 C   s   |   r| dnd| _d S )Nr   r,   )r}   r{   r2   rE   r
   r
   r   	recv_maska  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   r`   r   r   r2   r{   r   rv   rB   r?   )r7   r-   r.   r/   r0   r1   r}   _r`   r2   Zpayloadframer
   r
   r   
recv_framed  s"    
zframe_buffer.recv_framec                 C   s   |t dd | jD  }|dkrJ| td|}| j| |t|8 }qtd| j}|dkrng | _|S ||d  g| _|d | S d S )Nc                 s   s   | ]}t |V  qd S r   )r   rM   r
   r
   r   rP     s     z+frame_buffer.recv_strict.<locals>.<genexpr>r   i @  r,   )	sumru   rt   minappendr   r   r\   join)r7   bufsizeZshortageZbytes_Zunifiedr
   r
   r   r{     s    zframe_buffer.recv_strictN)rm   rn   ro   r   r   r8   rv   ry   r   r}   r   r   r   r   r   r{   r
   r
   r
   r   r     s   	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)r7   r   r?   r
   r
   r   r8     s    zcontinuous_frame.__init__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   r1   r   rq   r:   rH   rr   r7   r   r
   r
   r   rB     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   r3   r1   r   rH   rr   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sL|d tjkrL| jsLt|jsLtdt|j |d |gS )Nr   r   zcannot decode: )	r   r3   r   r   rH   r?   r   ZWebSocketPayloadExceptionrepr)r7   r   r3   r
   r
   r   extract  s    
$zcontinuous_frame.extractN)rm   rn   ro   r8   rB   r   r   r   r
   r
   r
   r   r     s
   )#rp   rk   r4   r^   r   _exceptionsZ_utilsr   Z	threadingr   r   ri   ImportErrorZwsaccel.xormaskr   r   __all__r   r   r   r   r   r   r   r   r   r    r!   r"   r#   rC   objectr   r   r   r
   r
   r
   r   <module>   s   

   7{