U
    Mf`                     @  s  d dl mZ d dlZd dlZd dlmZmZmZmZm	Z	m
Z
mZ ddlmZmZ ddlmZmZ ddlmZmZmZ d	d
dddgZdZdd eddD ZG dd	 d	eZddddddddZddddddZG d d
 d
eZd!d"d#d$dZG d%d deZd&d'd#d(dZdS ))    )annotationsN)AnyDictListOptionalSequenceTupleUnion   )
exceptionsframes)ExtensionNameExtensionParameter   )ClientExtensionFactory	ExtensionServerExtensionFactoryPerMessageDeflateClientPerMessageDeflateFactory enable_client_permessage_deflateServerPerMessageDeflateFactory enable_server_permessage_deflates     c                 C  s   g | ]}t |qS  )str).0bitsr   r   L/tmp/pip-unpacked-wheel-yzabpfcc/websockets/extensions/permessage_deflate.py
<listcomp>   s     r         c                   @  sh   e Zd ZdZedZddddddddd	d
ZddddZddddddddZdddddZ	dS )r   z)
    Per-Message Deflate extension.

    permessage-deflateNboolintzOptional[Dict[Any, Any]]None)remote_no_context_takeoverlocal_no_context_takeoverremote_max_window_bitslocal_max_window_bitscompress_settingsreturnc                 C  s   |dkri }|dkst |dks$t d|  kr8dks>n t d|  krRdksXn t d|ksdt || _|| _|| _|| _|| _| jstj| j d| _| jstj	f d| j i| j| _
d| _dS )z?
        Configure the Per-Message Deflate extension.

        N)FTr      wbitsr+   F)AssertionErrorr$   r%   r&   r'   r(   zlibdecompressobjdecodercompressobjencoderdecode_cont_data)selfr$   r%   r&   r'   r(   r   r   r   __init__!   s*    zPerMessageDeflate.__init__r   r)   c              	   C  s&   d| j  d| j d| j d| j d	S )Nz-PerMessageDeflate(remote_no_context_takeover=z, local_no_context_takeover=z, remote_max_window_bits=z, local_max_window_bits=))r$   r%   r&   r'   r4   r   r   r   __repr__J   s    $zPerMessageDeflate.__repr__)max_sizezframes.FrameOptional[int])framer:   r)   c             
   C  s  |j tjkr|S |j tjkr4| js&|S |jrpd| _n<|js>|S tj|dd}|jsXd| _| j	rpt
j| j d| _|j}|jr|t7 }|dkrdn|}z| j||}W n0 t
jk
r } ztd|W 5 d}~X Y nX | jjrtd| d	|jr| j	r| `tj||d
S )z,
        Decode an incoming frame.

        Frsv1Tr,   Nr   zdecompression failedzover size limit (? > z bytes)data)opcoder   CTRL_OPCODESOP_CONTr3   finr>   dataclassesreplacer$   r.   r/   r&   r0   r@   _EMPTY_UNCOMPRESSED_BLOCK
decompresserrorr   ProtocolErrorunconsumed_tailZPayloadTooBig)r4   r<   r:   r@   
max_lengthexcr   r   r   decodeS   s6    zPerMessageDeflate.decode)r<   r)   c                 C  s   |j tjkr|S |j tjk	rLtj|dd}| jrLtjf d| j	 i| j
| _| j|j| jtj }|jr|tr|dd }|jr| jr| `tj||dS )z,
        Encode an outgoing frame.

        Tr=   r+   Nr?   )rA   r   rB   rC   rE   rF   r%   r.   r1   r'   r(   r2   compressr@   flushZ_SYNC_FLUSHrD   endswithrG   )r4   r<   r@   r   r   r   encode   s     zPerMessageDeflate.encode)N)
__name__
__module____qualname____doc__r   namer5   r9   rN   rT   r   r   r   r   r      s    ):r!   r;   Optional[Union[int, bool]]List[ExtensionParameter])server_no_context_takeoverclient_no_context_takeoverserver_max_window_bitsclient_max_window_bitsr)   c                 C  sd   g }| r| d |r | d |r6| dt|f |dkrJ| d n|r`| dt|f |S )zS
    Build a list of ``(name, value)`` pairs for some compression parameters.

    )r\   N)r]   Nr^   T)r_   Nr_   )appendr   )r\   r]   r^   r_   paramsr   r   r   _build_parameters   s    


rb   Sequence[ExtensionParameter]z<Tuple[bool, bool, Optional[int], Optional[Union[int, bool]]])ra   	is_serverr)   c                C  s   d}d}d}d}| D ]\}}|dkrN|r2t ||dkr@d}nt ||q|dkr|rdt ||dkrrd}nt ||q|dkr|dk	rt ||tkrt|}nt ||q|dkr|dk	rt ||r|dkrd}n|tkrt|}nt ||qt |q||||fS )z
    Extract compression parameters from a list of ``(name, value)`` pairs.

    If ``is_server`` is :obj:`True`, ``client_max_window_bits`` may be
    provided without a value. This is only allowed in handshake requests.

    FNr\   Tr]   r^   r_   )r   ZDuplicateParameterZInvalidParameterValue_MAX_WINDOW_BITS_VALUESr"   ZInvalidParameterName)ra   rd   r\   r]   r^   r_   rY   valuer   r   r   _extract_parameters   sJ    







rg   c                   @  sR   e Zd ZdZedZdddddd	d
dddZddddZddddddZdS )r   a  
    Client-side extension factory for the Per-Message Deflate extension.

    Parameters behave as described in `section 7.1 of RFC 7692`_.

    .. _section 7.1 of RFC 7692: https://www.rfc-editor.org/rfc/rfc7692.html#section-7.1

    Set them to :obj:`True` to include them in the negotiation offer without a
    value or to an integer value to include them with this value.

    Args:
        server_no_context_takeover: prevent server from using context takeover.
        client_no_context_takeover: prevent client from using context takeover.
        server_max_window_bits: maximum size of the server's LZ77 sliding window
            in bits, between 8 and 15.
        client_max_window_bits: maximum size of the client's LZ77 sliding window
            in bits, between 8 and 15, or :obj:`True` to indicate support without
            setting a limit.
        compress_settings: additional keyword arguments for :func:`zlib.compressobj`,
            excluding ``wbits``.

    r    FNTr!   r;   rZ   Optional[Dict[str, Any]]r#   )r\   r]   r^   r_   r(   r)   c                 C  s   |dks&d|  krdks&n t d|dksT|dksTd|  krJdksTn t d|dk	rld|krlt d|| _|| _|| _|| _|| _dS )	G
        Configure the Per-Message Deflate extension factory.

        Nr   r*   /server_max_window_bits must be between 8 and 15T/client_max_window_bits must be between 8 and 15r+   zLcompress_settings must not include wbits, set client_max_window_bits instead)
ValueErrorr\   r]   r^   r_   r(   )r4   r\   r]   r^   r_   r(   r   r   r   r5     s*     z'ClientPerMessageDeflateFactory.__init__r[   r6   c                 C  s   t | j| j| j| jS )z,
        Build request parameters.

        )rb   r\   r]   r^   r_   r8   r   r   r   get_request_params=  s    z1ClientPerMessageDeflateFactory.get_request_paramsrc   Sequence[Extension]r   ra   accepted_extensionsr)   c                   s   t  fdd|D r(td j t|dd\}}}} jrP|sPtd jr^|s^d} jdkrjn(|dkr~td	n| jkrtd
 jdkr|dk	rtdn0 jdkrn$|dkr̈ j}n| jkrtdt	|||pd|pd j
S )zV
        Process response parameters.

        Return an extension instance.

        c                 3  s   | ]}|j  j kV  qd S NrY   r   otherr8   r   r   	<genexpr>T  s     zIClientPerMessageDeflateFactory.process_response_params.<locals>.<genexpr>zreceived duplicate Frd   z#expected server_no_context_takeoverTNzexpected server_max_window_bitsz"unsupported server_max_window_bitsz!unexpected client_max_window_bitsz"unsupported client_max_window_bitsr*   )anyr   NegotiationErrorrY   rg   r\   r]   r^   r_   r   r(   r4   ra   rp   r\   r]   r^   r_   r   r8   r   process_response_paramsI  sH    









z6ClientPerMessageDeflateFactory.process_response_params)FFNTN)	rU   rV   rW   rX   r   rY   r5   rm   rz   r   r   r   r   r     s         z*Optional[Sequence[ClientExtensionFactory]]z Sequence[ClientExtensionFactory])
extensionsr)   c                 C  s:   | dkrg } t dd | D s6t| tddidg } | S )z
    Enable Per-Message Deflate with default settings in client extensions.

    If the extension is already present, perhaps with non-default settings,
    the configuration isn't changed.

    Nc                 s  s   | ]}|j tj kV  qd S rq   )rY   r   )r   Zextension_factoryr   r   r   ru     s   z3enable_client_permessage_deflate.<locals>.<genexpr>memLevel   )r(   )rw   listr   r{   r   r   r   r     s    
c                	   @  sF   e Zd ZdZedZddddddddd	d
dZddddddZdS )r   a  
    Server-side extension factory for the Per-Message Deflate extension.

    Parameters behave as described in `section 7.1 of RFC 7692`_.

    .. _section 7.1 of RFC 7692: https://www.rfc-editor.org/rfc/rfc7692.html#section-7.1

    Set them to :obj:`True` to include them in the negotiation offer without a
    value or to an integer value to include them with this value.

    Args:
        server_no_context_takeover: prevent server from using context takeover.
        client_no_context_takeover: prevent client from using context takeover.
        server_max_window_bits: maximum size of the server's LZ77 sliding window
            in bits, between 8 and 15.
        client_max_window_bits: maximum size of the client's LZ77 sliding window
            in bits, between 8 and 15.
        compress_settings: additional keyword arguments for :func:`zlib.compressobj`,
            excluding ``wbits``.
        require_client_max_window_bits: do not enable compression at all if
            client doesn't advertise support for ``client_max_window_bits``;
            the default behavior is to enable compression without enforcing
            ``client_max_window_bits``.

    r    FNr!   r;   rh   r#   )r\   r]   r^   r_   r(   require_client_max_window_bitsr)   c                 C  s   |dks&d|  krdks&n t d|dksLd|  krBdksLn t d|dk	rdd|krdt d|dkrx|rxt d|| _|| _|| _|| _|| _|| _dS )	ri   Nr   r*   rj   rk   r+   zLcompress_settings must not include wbits, set server_max_window_bits insteadzVrequire_client_max_window_bits is enabled, but client_max_window_bits isn't configured)rl   r\   r]   r^   r_   r(   r   )r4   r\   r]   r^   r_   r(   r   r   r   r   r5     s$    z'ServerPerMessageDeflateFactory.__init__rc   rn   z2Tuple[List[ExtensionParameter], PerMessageDeflate]ro   c                   s   t  fdd|D r(td j t|dd\}}}} jrJ|sJd} jrX|sXd} jdkrdn |dkrt j}n| jkr j} jdkr|dkr؈ j}n:|dkr j	rtdn |dkrȈ j}n j|k r؈ j}t
||||t|||pd|pd jfS )	zi
        Process request parameters.

        Return response params and an extension instance.

        c                 3  s   | ]}|j  j kV  qd S rq   rr   rs   r8   r   r   ru     s     zHServerPerMessageDeflateFactory.process_request_params.<locals>.<genexpr>zskipped duplicate Trv   Nzrequired client_max_window_bitsr*   )rw   r   rx   rY   rg   r\   r]   r^   r_   r   rb   r   r(   ry   r   r8   r   process_request_params  sX    




z5ServerPerMessageDeflateFactory.process_request_params)FFNNNF)rU   rV   rW   rX   r   rY   r5   r   r   r   r   r   r     s         #z*Optional[Sequence[ServerExtensionFactory]]z Sequence[ServerExtensionFactory]c                 C  s>   | dkrg } t dd | D s:t| tddddidg } | S )z
    Enable Per-Message Deflate with default settings in server extensions.

    If the extension is already present, perhaps with non-default settings,
    the configuration isn't changed.

    Nc                 s  s   | ]}|j tj kV  qd S rq   )rY   r   )r   Zext_factoryr   r   r   ru     s   z3enable_server_permessage_deflate.<locals>.<genexpr>   r|   r}   )r^   r_   r(   )rw   r~   r   r   r   r   r   r   }  s    
) 
__future__r   rE   r.   typingr   r   r   r   r   r   r	    r   r   r   r   baser   r   r   __all__rG   rangere   r   rb   rg   r   r   r   r   r   r   r   r   <module>   s0   $ = 1 3