a
   9yqӉE                
   @   s4  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yr   dZY n0 zesddlmZ dd	 ZW n ey   d
d	 ZY n0 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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
   3/usr/lib/python3.9/site-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textZbinarycloseZpingZpong~   i   l             c                 C   sB   || _ || _|| _|| _|| _|| _|du 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.   r/   r0   r1   r2   r
   r
   r   __init__   s    zABNF.__init__Fc                 C   s   | j s| js| jrtd| jtjv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.   r/   WebSocketProtocolExceptionr0   r   OPCODESOPCODE_PINGr,   OPCODE_CLOSEr   r2   r   r   Zbyte2int_is_valid_close_status)r6   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,   r0   r2   r6   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)r2   r0   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v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 vV  qdS ))r   r   Nr
   .0xr
   r
   r   	<genexpr>       zABNF.format.<locals>.<genexpr>z
not 0 or 1zInvalid OPCODEzdata is too long         r   r*   !H   !QN)anyr,   r-   r.   r/   
ValueErrorr0   r   r:   r   r2   	LENGTH_63chrLENGTH_7r1   r   b	LENGTH_16structpackr5   _get_masked)r6   lengthZframe_headermask_keyr
   r
   r   format   s<    "








zABNF.formatc                 C   s,   t || j}t|tjr$|d}|| S )NrF   )r   r1   r2   rH   r   rI   rJ   )r6   rb   sr
   r
   r   r`      s    
zABNF._get_maskedc                 C   s   |du 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)rH   r   rI   r\   numpyr   bytesZ
frombufferZbitwise_xorZastyper   arrayr   )rb   r2   ZoriglenZ	_mask_keyaZmaskedr   r	   r
   r
   r   r1      s$    	

,z	ABNF.maskN)F)r   )__name__
__module____qualname____doc__OPCODE_CONTrG   OPCODE_BINARYr<   r;   ZOPCODE_PONGr:   Z
OPCODE_MAPr[   r]   rY   r7   rA   staticmethodr=   rE   rK   rc   r`   r1   r
   r
   r
   r   r   i   sB   



!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   rS   rR   c                 C   s&   || _ || _g | _|   t | _d S r   )recvr>   recv_bufferclearr   lock)r6   Zrecv_fnr>   r
   r
   r   r7   #  s
    zframe_buffer.__init__c                 C   s   d | _ d | _d | _d S r   )headerra   r1   rD   r
   r
   r   rw   ,  s    zframe_buffer.clearc                 C   s
   | j d u S r   )ry   rD   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ordry   )r6   ry   b1r,   r-   r.   r/   r0   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)ry   r   _HEADER_MASK_INDEXrD   r
   r
   r   r   J  s    zframe_buffer.has_maskc                 C   s
   | j d u S r   )ra   rD   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   )ry   r   _HEADER_LENGTH_INDEXr|   r^   unpackra   )r6   bitsr   vr
   r
   r   recv_lengthR  s    

zframe_buffer.recv_lengthc                 C   s
   | j d u S r   )r1   rD   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|   r1   rD   r
   r
   r   	recv_maska  s    zframe_buffer.recv_maskc              	   C   s   | j  |  r|   | j\}}}}}}}|  r<|   | j}|  rR|   | j	}	| 
|}
|rrt	|	|
}
|   t|||||||
}|| j W d    n1 s0    Y  |S r   )rx   rz   r   ry   r   r   ra   r   r   r1   r|   r   rw   rA   r>   )r6   r,   r-   r.   r/   r0   r   _ra   r1   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   rL   r
   r
   r   rO     rP   z+frame_buffer.recv_strict.<locals>.<genexpr>r   i @  r+   )	sumrv   ru   minappendr   r   r\   join)r6   bufsizeZshortageZbytes_Zunifiedr
   r
   r   r|     s    zframe_buffer.recv_strictN)rn   ro   rp   r   r   r7   rw   rz   r   r   r   r   r   r   r   r|   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)r6   r   r>   r
   r
   r   r7     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v r:tdd S )NzIllegal frame)r   r0   r   rr   r9   rG   rs   r6   r   r
   r
   r   rA     s    zcontinuous_frame.validatec                 C   sT   | j r| j d  |j7  < n(|jtjtjfv r6|j| _|j|jg| _ |jrPd | _d S )Nr   )r   r2   r0   r   rG   rs   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   r2   r   r   rG   r>   r   ZWebSocketPayloadExceptionrepr)r6   r   r2   r
   r
   r   extract  s    
$zcontinuous_frame.extractN)rn   ro   rp   r7   rA   r   r   r   r
   r
   r
   r   r     s
   r   )#rq   rl   r3   r^   r   _exceptionsZ_utilsr   	threadingr   r   rj   ImportErrorZwsaccel.xormaskr   r   __all__r   r   r   r   r   r   r   r   r   r    r!   r"   r#   rB   objectr   r   r   r
   r
   r
   r   <module>   s`   


 7{