U
    gU`                     @  s  d dl m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 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Sequence   )frames)DuplicateParameterInvalidParameterNameInvalidParameterValueNegotiationErrorPayloadTooBigProtocolError)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-dx_q7dq3/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dict[Any, Any] | None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__S   s    $zPerMessageDeflate.__repr__)max_sizezframes.Frame
int | None)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 n. 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   unconsumed_tailr   )r4   r<   r:   r@   
max_lengthexcr   r   r   decode\   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   rM   rS   r   r   r   r   r   !   s    *:r!   r;   int | bool | None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    


ra   Sequence[ExtensionParameter]z0tuple[bool, bool, int | None, int | bool | None])r`   	is_serverr)   c                C  s  d}d}d}d}| D ]\}}|dkrJ|r0t ||dkr>d}qt||q|dkrx|r^t ||dkrld}qt||q|dkr|dk	rt ||tkrt|}qt||q|dkr|dk	rt ||r|dkrd}q|tkrt|}qt||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   r	   _MAX_WINDOW_BITS_VALUESr"   r   )r`   rc   r[   r\   r]   r^   rX   valuer   r   r   _extract_parameters   sJ    



rf   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://datatracker.ietf.org/doc/html/rfc7692#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;   rY   dict[str, Any] | Noner#   )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__rZ   r6   c                 C  s   t | j| j| j| jS )z,
        Build request parameters.

        )ra   r[   r\   r]   r^   r8   r   r   r   get_request_paramsG  s    z1ClientPerMessageDeflateFactory.get_request_paramsrb   Sequence[Extension]r   r`   accepted_extensionsr)   c                   s   t  fdd|D r&td j t|dd\}}}} jrL|sLtd jrZ|sZd} jdkrfn$|dkrxtd	n| jkrtd
 jdkr|dk	rtdn. 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rX   r   otherr8   r   r   	<genexpr>^  s     zIClientPerMessageDeflateFactory.process_response_params.<locals>.<genexpr>zreceived duplicate Frc   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
   rX   rf   r[   r\   r]   r^   r   r(   r4   r`   ro   r[   r\   r]   r^   r   r8   r   process_response_paramsS  sH    








z6ClientPerMessageDeflateFactory.process_response_params)FFNTN)	rT   rU   rV   rW   r   rX   r5   rl   rx   r   r   r   r   r     s         z'Sequence[ClientExtensionFactory] | Nonez 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 rp   )rX   r   )r   Zextension_factoryr   r   r   rt     s   z3enable_client_permessage_deflate.<locals>.<genexpr>memLevel   )r(   )rv   listr   ry   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://datatracker.ietf.org/doc/html/rfc7692#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;   rg   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 )	rh   Nr   r*   ri   rj   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)rk   r[   r\   r]   r^   r(   r~   )r4   r[   r\   r]   r^   r(   r~   r   r   r   r5     s$    z'ServerPerMessageDeflateFactory.__init__rb   rm   z2tuple[list[ExtensionParameter], PerMessageDeflate]rn   c                   s   t  fdd|D r&td j t|dd\}}}} jrH|sHd} jrV|sVd} jdkrbn |dkrr j}n| jkr j} jdkr|dkrԈ j}n8|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 rp   rq   rr   r8   r   r   rt      s     zHServerPerMessageDeflateFactory.process_request_params.<locals>.<genexpr>zskipped duplicate Tru   Nzrequired client_max_window_bitsr*   )rv   r
   rX   rf   r[   r\   r]   r^   r~   ra   r   r(   rw   r   r8   r   process_request_params  sX    





z5ServerPerMessageDeflateFactory.process_request_params)FFNNNF)rT   rU   rV   rW   r   rX   r5   r   r   r   r   r   r     s         #z'Sequence[ServerExtensionFactory] | Nonez 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 rp   )rX   r   )r   Zext_factoryr   r   r   rt     s   z3enable_server_permessage_deflate.<locals>.<genexpr>   rz   r{   )r]   r^   r(   )rv   r|   r   r}   r   r   r   r     s    
)!
__future__r   rE   r.   typingr   r    r   
exceptionsr   r   r	   r
   r   r   r   r   baser   r   r   __all__rG   rangerd   r   ra   rf   r   r   r   r   r   r   r   r   <module>   s2     = 1 3