U
    ÕCdª-  ã                   @   sˆ   d Z ddlZddlmZ ddlZddlmZ ddlmZ ddl	m
Z
 G dd„ dejƒZd	d
„ ZG dd„ dƒZG dd„ deƒZdd„ ZdS )a  
h2/settings
~~~~~~~~~~~

This module contains a HTTP/2 settings object. This object provides a simple
API for manipulating HTTP/2 settings, keeping track of both the current active
state of the settings and the unacknowledged future values of the settings.
é    N)ÚMutableMapping)ÚSettingsFrame)Ú
ErrorCodes)ÚInvalidSettingsValueErrorc                   @   s:   e Zd ZdZejZejZejZejZej	Z	ej
Z
ejZdS )ÚSettingCodeszF
    All known HTTP/2 setting codes.

    .. versionadded:: 2.6.0
    N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   ÚHEADER_TABLE_SIZEÚENABLE_PUSHÚMAX_CONCURRENT_STREAMSÚINITIAL_WINDOW_SIZEÚMAX_FRAME_SIZEÚMAX_HEADER_LIST_SIZEÚENABLE_CONNECT_PROTOCOL© r   r   ú//tmp/pip-unpacked-wheel-eftilyz8/h2/settings.pyr      s   r   c                 C   s(   z
t | ƒW S  tk
r"   |  Y S X dS )zÃ
    Given an integer setting code, returns either one of :class:`SettingCodes
    <h2.settings.SettingCodes>` or, if not present in the known set of codes,
    returns the integer directly.
    N)r   Ú
ValueError)Úcoder   r   r   Ú_setting_code_from_int:   s    
r   c                   @   s   e Zd Zdd„ Zdd„ ZdS )ÚChangedSettingc                 C   s   || _ || _|| _d S ©N©ÚsettingÚoriginal_valueÚ	new_value)Úselfr   r   r   r   r   r   Ú__init__H   s    zChangedSetting.__init__c                 C   s   d| j | j| jf S )Nz;ChangedSetting(setting=%s, original_value=%s, new_value=%s)r   ©r   r   r   r   Ú__repr__U   s    ýýzChangedSetting.__repr__N)r   r   r	   r   r    r   r   r   r   r   F   s   r   c                   @   s  e Zd ZdZd+dd„Zdd„ Zedd	„ ƒZejd
d	„ ƒZedd„ ƒZ	e	jdd„ ƒZ	edd„ ƒZ
e
jdd„ ƒZ
edd„ ƒZejdd„ ƒZedd„ ƒZejdd„ ƒZedd„ ƒZejdd„ ƒZedd„ ƒZej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 ),ÚSettingsam  
    An object that encapsulates HTTP/2 settings state.

    HTTP/2 Settings are a complex beast. Each party, remote and local, has its
    own settings and a view of the other party's settings. When a settings
    frame is emitted by a peer it cannot assume that the new settings values
    are in place until the remote peer acknowledges the setting. In principle,
    multiple settings changes can be "in flight" at the same time, all with
    different values.

    This object encapsulates this mess. It provides a dict-like interface to
    settings, which return the *current* values of the settings in question.
    Additionally, it keeps track of the stack of proposed values: each time an
    acknowledgement is sent/received, it updates the current values with the
    stack of proposed values. On top of all that, it validates the values to
    make sure they're allowed, and raises :class:`InvalidSettingsValueError
    <h2.exceptions.InvalidSettingsValueError>` if they are not.

    Finally, this object understands what the default values of the HTTP/2
    settings are, and sets those defaults appropriately.

    .. versionchanged:: 2.2.0
       Added the ``initial_values`` parameter.

    .. versionchanged:: 2.5.0
       Added the ``max_header_list_size`` property.

    :param client: (optional) Whether these settings should be defaulted for a
        client implementation or a server implementation. Defaults to ``True``.
    :type client: ``bool``
    :param initial_values: (optional) Any initial values the user would like
        set, rather than RFC 7540's defaults.
    :type initial_vales: ``MutableMapping``
    TNc                 C   s¢   t jt dg¡t jt t|ƒg¡t jt dg¡t jt dg¡t jt dg¡i| _	|d k	rž| 
¡ D ]<\}}t||ƒ}|rŠtd||f |d‚t |g¡| j	|< q`d S )Ni   iÿÿ  é @  r   úSetting %d has invalid value %d©Z
error_code)r   r   ÚcollectionsÚdequer   Úintr   r   r   Ú	_settingsÚitemsÚ_validate_settingr   )r   ÚclientZinitial_valuesÚkeyÚvalueÚinvalidr   r   r   r   ƒ   s(     
  
 
 
û

þzSettings.__init__c                 C   sH   i }| j  ¡ D ]4\}}t|ƒdkr| ¡ }|d }t|||ƒ||< q|S )zÕ
        The settings have been acknowledged, either by the user (remote
        settings) or by the remote peer (local settings).

        :returns: A dict of {setting: ChangedSetting} that were applied.
        é   r   )r(   r)   ÚlenÚpopleftr   )r   Zchanged_settingsÚkÚvZold_settingZnew_settingr   r   r   Úacknowledge›   s      ÿ
zSettings.acknowledgec                 C   s
   | t j S )z‚
        The current value of the :data:`HEADER_TABLE_SIZE
        <h2.settings.SettingCodes.HEADER_TABLE_SIZE>` setting.
        ©r   r   r   r   r   r   Úheader_table_size±   s    zSettings.header_table_sizec                 C   s   || t j< d S r   r5   ©r   r-   r   r   r   r6   ¹   s    c                 C   s
   | t j S )zv
        The current value of the :data:`ENABLE_PUSH
        <h2.settings.SettingCodes.ENABLE_PUSH>` setting.
        ©r   r   r   r   r   r   Úenable_push½   s    zSettings.enable_pushc                 C   s   || t j< d S r   r8   r7   r   r   r   r9   Å   s    c                 C   s
   | t j S )z†
        The current value of the :data:`INITIAL_WINDOW_SIZE
        <h2.settings.SettingCodes.INITIAL_WINDOW_SIZE>` setting.
        ©r   r   r   r   r   r   Úinitial_window_sizeÉ   s    zSettings.initial_window_sizec                 C   s   || t j< d S r   r:   r7   r   r   r   r;   Ñ   s    c                 C   s
   | t j S )z|
        The current value of the :data:`MAX_FRAME_SIZE
        <h2.settings.SettingCodes.MAX_FRAME_SIZE>` setting.
        ©r   r   r   r   r   r   Úmax_frame_sizeÕ   s    zSettings.max_frame_sizec                 C   s   || t j< d S r   r<   r7   r   r   r   r=   Ý   s    c                 C   s   |   tjd¡S )zŒ
        The current value of the :data:`MAX_CONCURRENT_STREAMS
        <h2.settings.SettingCodes.MAX_CONCURRENT_STREAMS>` setting.
        l       )Úgetr   r   r   r   r   r   Úmax_concurrent_streamsá   s    zSettings.max_concurrent_streamsc                 C   s   || t j< d S r   )r   r   r7   r   r   r   r?   é   s    c                 C   s   |   tjd¡S )zæ
        The current value of the :data:`MAX_HEADER_LIST_SIZE
        <h2.settings.SettingCodes.MAX_HEADER_LIST_SIZE>` setting. If not set,
        returns ``None``, which means unlimited.

        .. versionadded:: 2.5.0
        N)r>   r   r   r   r   r   r   Úmax_header_list_sizeí   s    	zSettings.max_header_list_sizec                 C   s   || t j< d S r   )r   r   r7   r   r   r   r@   ø   s    c                 C   s
   | t j S )zŽ
        The current value of the :data:`ENABLE_CONNECT_PROTOCOL
        <h2.settings.SettingCodes.ENABLE_CONNECT_PROTOCOL>` setting.
        ©r   r   r   r   r   r   Úenable_connect_protocolü   s    z Settings.enable_connect_protocolc                 C   s   || t j< d S r   rA   r7   r   r   r   rB     s    c                 C   s   | j | d }|d krt‚|S )Nr   )r(   ÚKeyError)r   r,   Úvalr   r   r   Ú__getitem__	  s    zSettings.__getitem__c                 C   sj   t ||ƒ}|r"td||f |d‚z| j| }W n* tk
rZ   t d g¡}|| j|< Y nX | |¡ d S )Nr#   r$   )r*   r   r(   rC   r%   r&   Úappend)r   r,   r-   r.   r)   r   r   r   Ú__setitem__  s    

þzSettings.__setitem__c                 C   s   | j |= d S r   )r(   )r   r,   r   r   r   Ú__delitem__#  s    zSettings.__delitem__c                 C   s
   | j  ¡ S r   )r(   Ú__iter__r   r   r   r   rI   &  s    zSettings.__iter__c                 C   s
   t | jƒS r   )r0   r(   r   r   r   r   Ú__len__)  s    zSettings.__len__c                 C   s   t |tƒr| j|jkS tS d S r   )Ú
isinstancer!   r(   ÚNotImplemented©r   Úotherr   r   r   Ú__eq__,  s    
zSettings.__eq__c                 C   s   t |tƒr| |k S tS d S r   )rK   r!   rL   rM   r   r   r   Ú__ne__2  s    

zSettings.__ne__)TN)r   r   r	   r
   r   r4   Úpropertyr6   Úsetterr9   r;   r=   r?   r@   rB   rE   rG   rH   rI   rJ   rO   rP   r   r   r   r   r!   `   sL   "
















r!   c                 C   s    | t jkr|dkrœtjS n‚| t jkrBd|  kr8dksœn tjS nZ| t jkrjd|  kr`dksœn tjS n2| t jkr„|dk rœtjS n| t jkrœ|dkrœtjS dS )zš
    Confirms that a specific setting has a well-formed value. If the setting is
    invalid, returns an error code. Otherwise, returns 0 (NO_ERROR).
    )r   r/   r   iÿÿÿr"   iÿÿÿ )	r   r   r   ZPROTOCOL_ERRORr   ZFLOW_CONTROL_ERRORr   r   r   )r   r-   r   r   r   r*   9  s     




r*   )r
   r%   Úcollections.abcr   ÚenumZhyperframe.framer   Z	h2.errorsr   Zh2.exceptionsr   ÚIntEnumr   r   r   r!   r*   r   r   r   r   Ú<module>   s   & Z