U
    gi[                     @   s  d Z ddlZddlZddlmZmZ ddlmZ ddlm	Z	m
Z
mZmZmZmZmZ erdddlmZ dd	 ed
D ZG dd dZG dd dZdZdZdZdZdZeZdZdZdZdZdZ dZ!dZ"G dd deZ#G dd deZ$e$j%e$j&e$j'fZ(dZ)dZ*dZ+dZ,d Z-d!Z.d"Z/d"Z0e1d#dZ2G d$d% d%e3Z4G d&d' d'eZ5G d(d) d)eZ6G d*d+ d+eZ7e8e9e8d,d-d.Z:G d/d0 d0Z;G d1d2 d2Z<G d3d4 d4Z=G d5d6 d6Z>dS )7zY
wsproto/frame_protocol
~~~~~~~~~~~~~~~~~~~~~~

WebSocket frame protocol implementation.
    N)getincrementaldecoderIncrementalDecoder)IntEnum)	GeneratorList
NamedTupleOptionalTupleTYPE_CHECKINGUnion   )	Extensionc                    s&   g | ] t  fd dtdD qS )c                 3   s   | ]}| A V  qd S N ).0abr   :/tmp/pip-unpacked-wheel-u83us8q9/wsproto/frame_protocol.py	<genexpr>   s     z<listcomp>.<genexpr>   )bytesrange)r   r   r   r   
<listcomp>   s     r   r   c                   @   s,   e Zd ZeddddZeedddZdS )XorMaskerSimpleN)masking_keyreturnc                 C   s
   || _ d S r   )_masking_key)selfr   r   r   r   __init__   s    zXorMaskerSimple.__init__datar   c                 C   s   |rt |}dd | jD \}}}}|d d d ||d d d< |dd d ||dd d< |dd d ||dd d< |dd d ||dd d< t|d }| j|d  | jd |  | _t|S |S )Nc                 s   s   | ]}t | V  qd S r   )
_XOR_TABLE)r   nr   r   r   r      s     z*XorMaskerSimple.process.<locals>.<genexpr>   r         )	bytearrayr   	translatelenr   )r   r!   Z
data_arrayr   r   cdZkey_rotationr   r   r   process   s    zXorMaskerSimple.process)__name__
__module____qualname__r   r   r,   r   r   r   r   r      s   r   c                   @   s   e Zd ZeedddZdS )XorMaskerNullr    c                 C   s   |S r   r   r   r!   r   r   r   r,   .   s    zXorMaskerNull.processN)r-   r.   r/   r   r,   r   r   r   r   r0   -   s   r0   ~      }   i  l       @             c                   @   s6   e Zd ZdZdZdZdZdZdZdZ	e
dd	d
ZdS )Opcodez7
    RFC 6455, Section 5.2 - Base Framing Protocol
    r   r   r%      	   
   r   c                 C   s   t | d@ S )Nr;   )boolr   r   r   r   	iscontrol_   s    zOpcode.iscontrolN)r-   r.   r/   __doc__CONTINUATIONTEXTBINARYCLOSEPINGPONGr?   rA   r   r   r   r   r:   H   s   r:   c                   @   sH   e 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dZdS )CloseReasonz8
    RFC 6455, Section 7.4.1 - Defined Status Codes
      i  i  i  i  i  i  i  i  i  i  i  i  i  N)r-   r.   r/   rB   NORMAL_CLOSUREZ
GOING_AWAYPROTOCOL_ERRORZUNSUPPORTED_DATANO_STATUS_RCVDABNORMAL_CLOSUREINVALID_FRAME_PAYLOAD_DATAZPOLICY_VIOLATIONZMESSAGE_TOO_BIGZMANDATORY_EXTINTERNAL_ERRORZSERVICE_RESTARTZTRY_AGAIN_LATERTLS_HANDSHAKE_FAILEDr   r   r   r   rI   c   s   		rI   rJ   i  i  i  i  i  z!Ic                       s,   e Zd Zejfeedd fddZ  ZS )ParseFailedN)msgcoder   c                    s   t  | || _d S r   )superr   rT   )r   rS   rT   	__class__r   r   r      s    zParseFailed.__init__)r-   r.   r/   rI   rL   strr   __classcell__r   r   rV   r   rR      s    rR   c                   @   s&   e Zd ZU eed< eed< eed< dS )RsvBitsrsv1rsv2rsv3N)r-   r.   r/   r?   __annotations__r   r   r   r   rZ      s   
rZ   c                   @   s:   e Zd ZU eed< eed< eed< eed< ee	 ed< dS )Headerfinrsvopcodepayload_lenr   N)
r-   r.   r/   r?   r^   rZ   r:   intr   r   r   r   r   r   r_      s
   
r_   c                   @   s@   e Zd ZU eed< eeeee	ef f ed< e
ed< e
ed< dS )Framerb   payloadframe_finishedmessage_finishedN)r-   r.   r/   r:   r^   r   r   rX   r	   rd   r?   r   r   r   r   re      s   
re   )r!   nbytesr   c                 C   s4   t | |kr| S | d | } | jdddd} | S )Nutf-8ignore)errors)r)   decodeencode)r!   ri   r   r   r   _truncate_utf8   s
    ro   c                   @   s   e Zd Zdee ddddZeddddZeedd	d
Zeee dddZ	ddddZ
ddddZedddZdS )BufferN)initial_bytesr   c                 C   s    t  | _d| _|r| | d S Nr   )r'   buffer
bytes_usedfeed)r   rq   r   r   r   r      s    zBuffer.__init__)	new_bytesr   c                 C   s   |  j |7  _ d S r   )rs   )r   rv   r   r   r   ru     s    zBuffer.feed)ri   r   c                 C   s6   |s
t  S | j| j| j|  }|  jt|7  _|S r   )r'   rs   rt   r)   )r   ri   r!   r   r   r   consume_at_most  s
    zBuffer.consume_at_mostc                 C   s"   t | j| j |k rd S | |S r   )r)   rs   rt   rw   )r   ri   r   r   r   consume_exactly  s    zBuffer.consume_exactlyr>   c                 C   s   | j d | j= d| _d S rr   )rs   rt   r@   r   r   r   commit  s    zBuffer.commitc                 C   s
   d| _ d S rr   )rt   r@   r   r   r   rollback  s    zBuffer.rollbackc                 C   s
   t | jS r   )r)   rs   r@   r   r   r   __len__  s    zBuffer.__len__)N)r-   r.   r/   r   r   r   ru   rd   rw   rx   ry   rz   r{   r   r   r   r   rp      s   rp   c                   @   s*   e Zd ZddddZeedddZdS )MessageDecoderNr>   c                 C   s   d | _ d | _d S r   )rb   decoderr@   r   r   r   r   "  s    zMessageDecoder.__init__framer   c              
   C   s
  |j  rt| j d kr6|j tjkr,td|j | _ n|j tjk	rPtd|j  |j tjkrhtd | _|j	or|j
}| jd kr|j}n\t|jttfstz| j|j|}W n2 tk
r } ztt|tjW 5 d }~X Y nX t| j ||j	|}|rd | _ d | _|S )Nzunexpected CONTINUATIONzexpected CONTINUATION, got %rrj   )rb   rA   AssertionErrorr:   rC   rR   rD   r   r}   rg   rh   rf   
isinstancer   r'   rm   UnicodeDecodeErrorrX   rI   rO   re   )r   r   finishedr!   excr   r   r   process_frame&  s,    


"zMessageDecoder.process_frame)r-   r.   r/   r   re   r   r   r   r   r   r|   !  s   r|   c                   @   s   e Zd Zdeeed  ddddZeddddZee	 d	d
dZ
ed	ddZeeee dddZeeeddddZdS )FrameDecoderNr   client
extensionsr   c                 C   s:   || _ |pg | _t | _d | _d | _d | _d| _d| _d S rr   )	r   r   rp   rs   headereffective_opcodemaskerpayload_requiredpayload_consumedr   r   r   r   r   r   r   H  s    
zFrameDecoder.__init__r    c                 C   s   | j | d S r   )rs   ru   r1   r   r   r   receive_bytesV  s    zFrameDecoder.receive_bytesr>   c           	      C   st  | j s|  sd S | j d k	s t| jd k	s.t| jd k	s<tt| j| jk rPd S | j j| j	 }| j
|}|s~| j jdkr~d S | j  |  j	t|7  _	| j	| j jk}| j|}| jD ](}|| |}t|trtd||}q|r:t }| jD ]:}|| | j j}t|tr td||d k	r||7 }q||7 }t| j||| j j}|rhd | _ d | _d | _ntj| _|S )Nr   error in extension)r   parse_headerr   r   r   r)   rs   r   rc   r   rw   ry   r,   r   Zframe_inbound_payload_datar   rI   rR   r'   Zframe_inbound_completer`   re   r:   rC   )	r   Zpayload_remainingrf   r   	extensionZpayload_finalresultr   r   r   r   process_bufferY  sJ    






zFrameDecoder.process_bufferc           	      C   s  | j d}|d kr"| j   dS t|d t@ }tt|d t@ t|d t@ t|d t@ }|d t	@ }zt
|}W n$ tk
r   td|dY nX | r|stdt|d t@ }|d t@ }| ||}|d kr| j   dS | ||| |r| jrtd|s,| js,td	|rb| j d
}|d krV| j   dS t|| _nt | _| j   t||||d | _| jj| _| jj r|| _nd| _d| _dS )Nr%   Fr   zInvalid opcode z#xz)Invalid attempt to fragment control framer   z'client received unexpected masked framez)server received unexpected unmasked framer$   T)rs   rx   rz   r?   FIN_MASKrZ   	RSV1_MASK	RSV2_MASK	RSV3_MASKOPCODE_MASKr:   
ValueErrorrR   rA   	MASK_MASKPAYLOAD_LEN_MASKparse_extended_payload_lengthextension_processingr   r   r   r0   ry   r_   r   rb   r   r   r   )	r   r!   r`   ra   rb   Zhas_maskZpayload_len_shortrc   r   r   r   r   r     sV    





zFrameDecoder.parse_header)rb   rc   r   c                 C   s   |  r|tkrtd|tkrX| jd}|d kr8d S td|\}|tkrtdnN|tkr| jd}|d krxd S td|\}|t	krtd|d? rtd	|S )
Nz$Control frame with payload len > 125r%   !Hz6Payload length used 2 bytes when 1 would have sufficedr;   !Qz6Payload length used 8 bytes when 2 would have sufficed?   z'8-byte payload length with non-zero MSB)
rA   MAX_PAYLOAD_NORMALrR   PAYLOAD_LENGTH_TWO_BYTErs   rx   structunpackPAYLOAD_LENGTH_EIGHT_BYTEMAX_PAYLOAD_TWO_BYTE)r   rb   rc   r!   r   r   r   r     s.    z*FrameDecoder.parse_extended_payload_length)rb   ra   rc   r   c                 C   s   dddg}| j D ]F}|| |||}t|tr8td|t|D ]\}}|r@d||< q@qt||D ]\}	}
|
rb|	sbtdqbd S )NFr   TzReserved bit set unexpectedly)r   Zframe_inbound_headerr   rI   rR   	enumeratezip)r   rb   ra   rc   Zrsv_usedr   r   bitusedexpectedfoundr   r   r   r     s    



z!FrameDecoder.extension_processing)N)r-   r.   r/   r?   r   r   r   r   r   re   r   r   r:   rd   r   rZ   r   r   r   r   r   r   G  s$     
26   r   c                   @   s   e Zd Zeed ddddZeedddZee	e ddf d	d
dZ
eddddZeeddf d	ddZd$e	e e	e edddZd%eedddZd&eedddZd'eeeef eedddZeeeeddd Zd(eeeed!d"d#ZdS ))FrameProtocolr   Nr   c                 C   sB   || _ dd |D | _t| j | j| _t | _|  | _d | _d S )Nc                 S   s   g | ]}|  r|qS r   Zenabledr   extr   r   r   r     s      z*FrameProtocol.__init__.<locals>.<listcomp>)	r   r   r   _frame_decoderr|   _message_decoder_parse_more_gen_parse_more_outbound_opcoder   r   r   r   r     s    
zFrameProtocol.__init__r~   c              
   C   s$  |j }t|ttfst|s(tjdf}nt|dkr>tdnt	
d|d d \}|tk sd|tkrltdzt|}W n tk
r   Y nX |tkrtdt|ts|tkrtdz|dd  d	}W n8 tk
r } ztd
t| tjW 5 d }~X Y nX ||f}t|j||j|jS )N r   zCLOSE with 1 byte payloadr   r%   zCLOSE with invalid codez#remote CLOSE with local-only reasonz CLOSE with unknown reserved coderj   zError decoding CLOSE reason: )rf   r   r   r'   r   rI   rM   r)   rR   r   r   MIN_CLOSE_REASONMAX_CLOSE_REASONr   LOCAL_ONLY_CLOSE_REASONSMAX_PROTOCOL_CLOSE_REASONrm   r   rX   rO   re   rb   rg   rh   )r   r   r!   rT   reasonr   r   r   r   _process_close  s4    

zFrameProtocol._process_closer>   c                 c   sj   dd | j D | _ d}|sf| j }|d k	r^|j sD| j|}n|jtjkr^| 	|}d}|V  qd S )Nc                 S   s   g | ]}|  r|qS r   r   r   r   r   r   r   !  s      z1FrameProtocol._parse_more_gen.<locals>.<listcomp>FT)
r   r   r   rb   rA   r   r   r:   rF   r   )r   closedr   r   r   r   r     s    


zFrameProtocol._parse_more_genr    c                 C   s   | j | d S r   )r   r   r1   r   r   r   r   0  s    zFrameProtocol.receive_bytesc                 c   s$   | j D ]}|d kr q q|V  qd S r   )r   )r   eventr   r   r   received_frames3  s    
zFrameProtocol.received_frames)rT   r   r   c                 C   s   t  }|tjkrd }|d kr(|r(td|tkr6tj}|d k	rr|t td|7 }|d k	rr|t|	dt
d 7 }| tj|S )Nz&cannot specify a reason without a coder   rj   r%   )r'   rI   rM   	TypeErrorr   rK   r   packro   rn   r   _serialize_framer:   rF   )r   rT   r   rf   r   r   r   close:  s    
 zFrameProtocol.close    )rf   r   c                 C   s   |  tj|S r   )r   r:   rG   r   rf   r   r   r   pingK  s    zFrameProtocol.pingc                 C   s   |  tj|S r   )r   r:   rH   r   r   r   r   pongN  s    zFrameProtocol.pongT)rf   r`   r   c                 C   s   t |tttfrtj}n$t |tr4tj}|d}nt	d| j
d krN|| _
n| j
|k	rbtdntj}|rrd | _
| |||S )Nrj   zMust provide bytes or textz!Data type mismatch inside message)r   r   r'   
memoryviewr:   rE   rX   rD   rn   r   r   r   rC   r   )r   rf   r`   rb   r   r   r   	send_dataQ  s    



zFrameProtocol.send_data)r`   ra   rb   r   c                 C   sJ   t |d> }t |jd> t |jd>  t |jd>  }t |}||B |B S )N         r$   )rd   r[   r\   r]   )r   r`   ra   rb   Zfin_bitsZrsv_bitsZopcode_bitsr   r   r   _make_fin_rsv_opcodeh  s    *z"FrameProtocol._make_fin_rsv_opcode)rb   rf   r`   r   c                 C   s  t ddd}t| jD ]}|| ||||\}}q| |||}t|}d}|tkr^|}	d }
n|tkrpt}	|}
nt	}	|}
d}| j
r|	dO }	t||	g}|
d k	r| rtd|r|ttd|
7 }n|ttd|
7 }| j
rtd}t|}|| || S || S )NFTr5   z"payload too long for control framer   r   r$   )rZ   reversedr   Zframe_outboundr   r)   r   r   r   r   r   r'   rA   r   r   r   osurandomr   r,   )r   rb   rf   r`   ra   r   Zfin_rsv_opcodeZpayload_lengthZquad_payloadZfirst_payloadZsecond_payloadr   r   r   r   r   r   r   o  s:    
zFrameProtocol._serialize_frame)NN)r   )r   )r   T)r   T)r-   r.   r/   r?   r   r   re   r   r   r   r   r   r   r   rd   rX   r   r   r   r   r'   r   rZ   r:   r   r   r   r   r   r   r     s0   !         r   )?rB   r   r   codecsr   r   enumr   typingr   r   r   r   r	   r
   r   r   r   r   r"   r   r0   r   r   r   r   ZMAX_PAYLOAD_EIGHT_BYTEZMAX_FRAME_PAYLOADr   r   r   r   r   r   r   r:   rI   rM   rN   rQ   r   r   ZMIN_PROTOCOL_CLOSE_REASONr   ZMIN_LIBRARY_CLOSE_REASONZMAX_LIBRARY_CLOSE_REASONZMIN_PRIVATE_CLOSE_REASONZMAX_PRIVATE_CLOSE_REASONr   r   Z	NULL_MASK	ExceptionrR   rZ   r_   re   r   rd   ro   rp   r|   r   r   r   r   r   r   <module>   s`   $Y$& (