
=\•j®6  ã                @   sÒ  d  Z  d d l Z d d l Z d d l Z d d l Z d d l Td d l m Z d d l m	 Z	 y" e j
 r{ d d l Z n d Z Wn e k
 rœ d Z Yn Xy& e sÂ d d l m Z d d	 „  Z Wn e k
 rã d
 d	 „  Z Yn Xd 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 Gd( d „  d e ƒ Z  Gd) d „  d e ƒ Z! Gd* d „  d e ƒ Z" d S)+z

é    Né   )Ú*)Úvalidate_utf8)ÚLock)ÚXorMaskerSimplec             C   s   t  |  ƒ j | ƒ S)N)r   Úprocess)Ú_mÚ_d© r
   ú;/tmp/pip-build-jxowagp5/websocket-client/websocket/_abnf.pyÚ_mask0   s    r   c             C   sT   x0 t  t | ƒ ƒ D] } | | |  | d N<q Wt j rF | j ƒ  S| j ƒ  Sd  S)Né   )ÚrangeÚlenÚsixÚPY3ÚtobytesÚtostring)r   r	   Úir
   r
   r   r   4   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 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é~   é   é?   Ú c             C   sa   | |  _  | |  _ | |  _ | |  _ | |  _ | |  _ | d k rH 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)Úselfr0   r1   r2   r3   r4   r5   r6   r
   r
   r   Ú__init__Ž   s    							zABNF.__init__Fc             C   sT  |  j  s |  j s |  j r' t d ƒ ‚ |  j t j k rK t d |  j ƒ ‚ |  j t j k rs |  j rs t d ƒ ‚ |  j t j	 k rPt
 |  j ƒ } | sž d S| d k s¶ | d k rÂ t d ƒ ‚ | d k rû | rû t |  j d d … ƒ rû t d ƒ ‚ d	 t j |  j d
 d … ƒ t j |  j d d … ƒ } |  j | ƒ sPt 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.)r1   r2   r3   ÚWebSocketProtocolExceptionr4   r   ÚOPCODESÚOPCODE_PINGr0   ÚOPCODE_CLOSEr   r6   r   r   Úbyte2intÚ_is_valid_close_status)r:   Úskip_utf8_validationÚlÚcoder
   r
   r   Úvalidatež   s$    -7zABNF.validatec             C   s$   |  t  k p# d |  k o! d k  SS)Ni¸  iˆ  )ÚVALID_CLOSE_STATUS)rE   r
   r
   r   rB   ½   s    zABNF._is_valid_close_statusc             C   s3   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__c             C   sL   | t  j k r0 t |  t j ƒ r0 |  j 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Ú
isinstancer   Ú	text_typeÚencode)r6   r4   r0   r
   r
   r   Úcreate_frameÆ   s    !zABNF.create_framec             C   sÆ  t  d d „  |  j |  j |  j |  j g Dƒ ƒ r= t d ƒ ‚ |  j t j k 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ƒ } | t j k  rü | t |  j d >| Bƒ 7} t j | ƒ } n’ | t j k  rN| t |  j d >d
 Bƒ 7} t j | ƒ } | t j d | ƒ 7} n@ | t |  j d >d Bƒ 7} t j | ƒ } | t j d | ƒ 7} |  j s¢| |  j
 S|  j d	 ƒ } | |  j | ƒ Sd 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   N)r   r   r
   )Ú.0Úxr
   r
   r   ú	<genexpr>ß   s    zABNF.format.<locals>.<genexpr>z
not 0 or 1zInvalid OPCODEzdata is too longé   é   é   r   r,   z!Hé   z!QN)Úanyr0   r1   r2   r3   Ú
ValueErrorr4   r   r>   r   r6   Ú	LENGTH_63ÚchrÚLENGTH_7r5   r   ÚbÚ	LENGTH_16ÚstructÚpackr9   Ú_get_masked)r:   ÚlengthZframe_headerÚmask_keyr
   r
   r   ÚformatÛ   s0    1+	zABNF.formatc             C   s>   t  j | |  j ƒ } t | t j ƒ r6 | j d ƒ } | | S)Nzutf-8)r   r5   r6   rK   r   rL   rM   )r:   ra   Úsr
   r
   r   r_   ü   s    zABNF._get_maskedc             C   sQ  | d k r d } t  |  t j ƒ r3 t j |  ƒ }  t  | t j ƒ rT t j | ƒ } t rt | ƒ } |  d d >|  d d >B|  d d >B|  d	 B} | t d
 d t | ƒ d d ƒ 7} t j | d d ƒ} t j | | g ƒ j	 d ƒ } t | ƒ | k r| j
 ƒ  d | … S| j
 ƒ  St j d |  ƒ } t j d | ƒ } t | | ƒ Sd S)z×
        Mask or unmask data. Just do xor for each byte

        Parameters
        ----------
        mask_key: <type>
            4 byte string(byte).
        data: <type>
            data to mask/unmask.
        Nr/   é   é   r%   r-   r   r&   r   ú r   zus-asciiZdtypeZuint32ÚB)rK   r   rL   r[   Únumpyr   ÚbytesZ
frombufferZbitwise_xorZastyper   Úarrayr   )ra   r6   ZoriglenZ	_mask_keyÚaZmaskedr   r	   r
   r
   r   r5     s$    .%
z	ABNF.maskNi   l            )Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚOPCODE_CONTrJ   ÚOPCODE_BINARYr@   r?   ZOPCODE_PONGr>   Z
OPCODE_MAPrZ   r\   rX   r;   rF   ÚstaticmethodrB   rI   rN   rb   r_   r5   r
   r
   r
   r   r   l   s8   !c               @   s    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   rT   rS   c             C   s5   | |  _  | |  _ g  |  _ |  j ƒ  t ƒ  |  _ d  S)N)ÚrecvrC   Úrecv_bufferÚclearr   Úlock)r:   Zrecv_fnrC   r
   r
   r   r;   .  s
    			
zframe_buffer.__init__c             C   s   d  |  _  d  |  _ d  |  _ d  S)N)Úheaderr`   r5   )r:   r
   r
   r   ru   7  s    		zframe_buffer.clearc             C   s   |  j  d  k S)N)rw   )r:   r
   r
   r   Úhas_received_header<  s    z frame_buffer.has_received_headerc             C   sÉ   |  j  d ƒ } | d } t j r. t | ƒ } | d ?d @} | d ?d @} | d ?d @} | d ?d @} | d @} | d } t j r� t | ƒ } | d ?d @}	 | d	 @}
 | | | | | |	 |
 f |  _ d  S)
Nr%   r   rR   r   rS   rT   r   é   rU   )Úrecv_strictr   ÚPY2Úordrw   )r:   rw   Zb1r0   r1   r2   r3   r4   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)rw   r   Ú_HEADER_MASK_INDEX)r:   r
   r
   r   r}   U  s    	zframe_buffer.has_maskc             C   s   |  j  d  k S)N)r`   )r:   r
   r
   r   Úhas_received_lengthZ  s    z frame_buffer.has_received_lengthc             C   s•   |  j  t j } | d @} | d k rQ |  j d ƒ } t j d | ƒ d |  _ n@ | d k rˆ |  j d ƒ } t j d | ƒ d |  _ n	 | |  _ d  S)NrU   r,   r%   z!Hr   r&   z!Q)rw   r   Ú_HEADER_LENGTH_INDEXrz   r]   Úunpackr`   )r:   Úbitsr~   Ú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_maski  s    zframe_buffer.has_received_maskc             C   s(   |  j  ƒ  r |  j d ƒ n d |  _ d  S)Nr   r/   )r}   rz   r5   )r:   r
   r
   r   Ú	recv_maskl  s    zframe_buffer.recv_maskc             C   sæ   |  j  �Ö |  j ƒ  r  |  j ƒ  |  j \ } } } } } } } |  j ƒ  rT |  j ƒ  |  j } |  j ƒ  rs |  j ƒ  |  j	 }	 |  j
 | ƒ }
 | r£ t j	 |	 |
 ƒ }
 |  j ƒ  t | | | | | | |
 ƒ } | j |  j ƒ Wd  QRX| S)N)rv   rx   r   rw   r�   r†   r`   r‡   rˆ   r5   rz   r   ru   rF   rC   )r:   r0   r1   r2   r3   r4   r}   Ú_r`   r5   ÚpayloadÚframer
   r
   r   Ú
recv_frameo  s"    


	
	
zframe_buffer.recv_framec             C   sÇ   | t  d d „  |  j Dƒ ƒ } xH | d k rj |  j t d | ƒ ƒ } |  j j | ƒ | t | ƒ 8} q# Wt j d ƒ j |  j ƒ } | d k rŸ g  |  _ | S| | d  … g |  _ | d  | … Sd  S)Nc             s   s   |  ] } t  | ƒ Vq d  S)N)r   )rO   rP   r
   r
   r   rQ   �  s    z+frame_buffer.recv_strict.<locals>.<genexpr>r   i @  r/   )	Úsumrt   rs   ÚminÚappendr   r   r[   Újoin)r:   ÚbufsizeZshortageÚbytes_Zunifiedr
   r
   r   rz   Ž  s     	zframe_buffer.recv_strictN)rl   rm   rn   r€   r‚   r;   ru   rx   r   r}   r�   r†   r‡   rˆ   rŒ   rz   r
   r
   r
   r   r   *  s   	c               @   sL   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)N)Úfire_cont_framerC   Ú	cont_dataÚrecving_frames)r:   r“   rC   r
   r
   r   r;   §  s    			zcontinuous_frame.__init__c             C   s\   |  j  r( | j t j k r( t d ƒ ‚ |  j  rX | j t j t j f k rX t d ƒ ‚ d  S)NzIllegal frame)r•   r4   r   rp   r=   rJ   rq   )r:   r‹   r
   r
   r   rF   ­  s
    	zcontinuous_frame.validatec             C   sr   |  j  r  |  j  d | j 7<n< | j t j t j f k rG | j |  _ | j | j g |  _  | j rn d  |  _ d  S)Nr   )r”   r6   r4   r   rJ   rq   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   s}   |  j  } d  |  _  | d | _ |  j ro | d t j k ro |  j ro t | j ƒ ro t d t | j ƒ ƒ ‚ | d | g S)Nr   r   zcannot decode: )	r”   r6   r“   r   rJ   rC   r   ZWebSocketPayloadExceptionÚrepr)r:   r‹   r6   r
   r
   r   ÚextractÂ  s    		7zcontinuous_frame.extractN)rl   rm   rn   r;   rF   r–   r—   r™   r
   r
   r
   r   r   ¥  s
   )#ro   rj   r7   r]   r   Ú_exceptionsÚ_utilsr   Ú	threadingr   r   rh   ÚImportErrorZwsaccel.xormaskr   r   Ú__all__r   r   r   r   r   r   r   r   r    r!   r"   r#   r$   rG   Úobjectr   r   r   r
   r
   r
   r   Ú<module>   sv   
	
			¾{