
    h"                       d Z ddlZddlZddlmZ ddlZddlmZmZm	Z	m
Z
mZmZ ddlmZmZmZmZmZmZmZmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddl m!Z!  G d dej"                  Z# G d	 d
ej$                  Z% G d de%          Z& G d de%          Z' G d deej(                  Z) G d de)          Z* G d de+          Z, G d de+          Z- G d de.          Z/ G d de)          Z0 G d dej$                  Z1 G d dej2                  Z3 G d  d!ej2                  Z4 G d" d#e4          Z5 G d$ d%e4          Z6 G d& d'e4          Z7 G d( d)e4          Z8 G d* d+ej2                  Z9 G d, d-e9          Z: G d. d/e:          Z; G d0 d1e9          Z< G d2 d3e<          Z= G d4 d5e<          Z> G d6 d7e<          Z? G d8 d9e<          Z@ G d: d;e9          ZA G d< d=e+          ZB G d> d?e9          ZC G d@ dAej2                  ZD G dB dCe9          ZE G dD dEe9          ZF G dF dGeF          ZG G dH dIe9          ZH G dJ dKe9          ZI G dL dMe9          ZJ G dN dOe9          ZKdPdQdRdSdTdUdVdWdXdYdZ
ZL G d[ d\ej2                  ZM G d] d^ej2                  ZN ejO        eMe:d_e:jP        i            ejO        eMe;d_e:jP        i            ejO        eMe=d_e=jP        i            ejO        eMe>d_e=jP        i            ejO        eMe?d_e=jP        i            ejO        eMe@d_e=jP        i            ejO        eMeAd_eAjP        i            ejO        eMeCd_eCjP        i            ejO        eMeEd_eEjP        i            ejO        eMeHd_eHjP        i            ejO        eMeFd_eFjP        i            ejO        eMeGd_eGjP        i            ejO        eMeId_eIjP        i            ejO        eMeJd_eJjP        i            ejO        eMeKd_eKjP        i            e	d`          ZQ G da dbe          ZR G dc dde          ZSdS )ez
http2

HTTP/2 support for Scapy
see RFC7540 and RFC7541 for more information

Implements packets and fields required to encode/decode HTTP/2 Frames
and HPack encoded headers
    N)BytesIO)raw	plain_str	hex_bytesorbchbbytes_encode)OptionalListUnionCallableAnyTupleSizedPattern)Packet_metaclassc                   n     e Zd ZdZdgZ fdZ fdZ fdZ fdZ fdZ	 fdZ
 fd	Z fd
Z xZS )HPackMagicBitFielda,   HPackMagicBitField is a BitField variant that cannot be assigned another
    value than the default one. This field must not be used where there is
    potential for fuzzing. OTOH, this field makes sense (for instance, if the
    magic bits are used by a dispatcher to select the payload class)
    _magicc                     |dk    sJ |dk    sJ || _         t          t          |                               |||           dS )z
        :param str name: this field instance name.
        :param int default: this field only valid value.
        :param int size: this bitfield bitlength.
        :return: None
        :raises: AssertionError
        r   N)r   superr   __init__selfnamedefaultsize	__class__s       W/mounts/lovelace/software/anaconda3/lib/python3.11/site-packages/scapy/contrib/http2.pyr   zHPackMagicBitField.__init__>   sO     !||||qyyyy $''00wEEEEE    c                     || j         k    s#J d                    | j         |                      t          t          |                               ||| j                   S )a%  
        :param packet.Packet|None pkt: the packet instance containing this field instance; probably unused.  # noqa: E501
        :param str|(str, int, long) s: either a str if 0 == size%8 or a tuple with the string to add this field to, the  # noqa: E501
          number of bits already generated and the generated value so far.
        :param int val: unused; must be equal to default value
        :return: str|(str, int, long): the s string extended with this field machine representation  # noqa: E501
        :raises: AssertionError
        z)val parameter must value {}; received: {})r   formatr   r   addfieldr   pktsvalr   s       r   r#   zHPackMagicBitField.addfieldM   s[     dk!!!#N#U#UVZVacf#g#g!!!'..77QLLLr    c                 *   t          t          |                               ||          }t          |t                    r.t          |          dk    rt          |d         t                    s
J d            |d         | j        k    s
J d            |S )ad  
        :param packet.Packet|None pkt: the packet instance containing this field instance; probably unused.  # noqa: E501
        :param str|(str, int) s: either a str if size%8==0 or a tuple with the string to parse from and the number of  # noqa: E501
          bits already consumed by previous bitfield-compatible fields.
        :return: (str|(str, int), int): Returns the remaining string and the parsed value. May return a tuple if there  # noqa: E501
          are remaining bits to parse in the first byte. Returned value is equal to default value  # noqa: E501
        :raises: AssertionError
              zeSecond element of BitField.getfield return value expected to be an int or a long; API change detectedz>Invalid value parsed from s; error in class guessing detected!)r   r   getfield
isinstancetuplelenintr   )r   r%   r&   rr   s       r   r+   zHPackMagicBitField.getfieldZ   s     $d++44S!<<q%  	sFFaKKqtS!! Kr KK tt{"""$d"""r    c                     || j         k    s"J d                    | j                               t          t          |                               || j                   S a  
        :param packet.Packet|None pkt: the packet instance containing this field instance; probably unused  # noqa: E501
        :param int x: unused; must be equal to default value
        :return: int; default value
        :raises: AssertionError
        zOEINVAL: x: This field is magic. Do not attempt to modify it. Expected value: {})r   r"   r   r   h2ir   r%   xr   s      r   r3   zHPackMagicBitField.h2im   X     DK]ddeiepqq  '..223DDDr    c                     || j         k    s"J d                    | j                               t          t          |                               || j                   S r2   )r   r"   r   r   i2hr4   s      r   r8   zHPackMagicBitField.i2hy   r6   r    c                     t          t          |                               ||          }|| j        k    s
J d            |S )a  
        :param packet.Packet|None pkt: the packet instance containing this field instance; probably unused  # noqa: E501
        :param int x: must be the machine representatino of the default value
        :return: int; default value
        :raises: AssertionError
        z@Invalid value parsed from m2i; error in class guessing detected!)r   r   m2ir   )r   r%   r5   r0   r   s       r   r:   zHPackMagicBitField.m2i   sF     $d++//Q77DK!cr    c                     || j         k    s"J d                    | j                               t          t          |                               || j                   S r2   )r   r"   r   r   i2mr4   s      r   r<   zHPackMagicBitField.i2m   r6   r    c                     || j         k    s"J d                    | j                               t          t          |                               || j                   S r2   )r   r"   r   r   any2ir4   s      r   r>   zHPackMagicBitField.any2i   sX     DK]ddeiepqq  '..44S$+FFFr    )__name__
__module____qualname____doc__	__slots__r   r#   r+   r3   r8   r:   r<   r>   __classcell__r   s   @r   r   r   5   s         
IF F F F FM M M M M    &
E 
E 
E 
E 
E
E 
E 
E 
E 
E
 
 
 
 

E 
E 
E 
E 
E
G 
G 
G 
G 
G 
G 
G 
G 
Gr    r   c                        e Zd ZdZg dZ	  fdZd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zd Zed             Zd Zd Zd Z xZS )AbstractUVarIntFieldzEAbstractUVarIntField represents an integer as defined in RFC7541
    )
_max_valuer   revc                     |t          |t                    r|dk    sJ d|cxk     rdk    sn J t          t          |                               ||           || _        d| j        z  dz
  | _        d| _        dS )aS  
        :param str name: the name of this field instance
        :param int|None default: positive, null or None default value for this field instance.  # noqa: E501
        :param int size: the number of bits to consider in the first byte. Valid range is ]0;8]  # noqa: E501
        :return: None
        :raises: AssertionError
        Nr      r*   F)r,   r/   r   rG   r   r   rH   rI   r   s       r   r   zAbstractUVarIntField.__init__   s     :gs#;#;14}}}}1}}}}}}"D))224AAA		>Q. r    c                 @    t          |t                    r|dk    sJ |S )z
        :param packet.Packet|None pkt: unused.
        :param int|None x: the value to convert.
        :return: int|None: the converted value.
        :raises: AssertionError
        r   )r,   r/   r   r%   r5   s      r   r3   zAbstractUVarIntField.h2i   s%     a%%/ar    c                     |S )z
        :param packet.Packet|None pkt: unused.
        :param int|None x: the value to convert.
        :return:: int|None: the converted value.
         rM   s      r   r8   zAbstractUVarIntField.i2h   s	     r    c                     t          |t                    st          |          dk    sJ t          |          | j        z  | j        k    S )a   _detect_multi_byte returns whether the AbstractUVarIntField is represented on  # noqa: E501
          multiple bytes or not.

          A multibyte representation is indicated by all of the first size bits being set  # noqa: E501

        :param str fb: first byte, as a character.
        :return: bool: True if multibyte repr detected, else False.
        :raises: AssertionError
        r*   )r,   r/   r.   r   rH   )r   fbs     r   _detect_multi_bytez'AbstractUVarIntField._detect_multi_byte   s@     "c""2c"ggllllB$/)do==r    c                    t          |          dk    sJ t          |          }d}d}t          ||                   }d}|dz  rm||dz  d|dz
  z  z  z  }||k    r't          j        d                    |                    |dz  }||k     s
J d            t          ||                   }|dz  m||d|dz
  z  z  z  }|| j        z  }|dk    sJ |S )	a   _parse_multi_byte parses x as a multibyte representation to get the
          int value of this AbstractUVarIntField.

        :param str s: the multibyte string to parse.
        :return: int: The parsed int value represented by this AbstractUVarIntField.  # noqa: E501
        :raises:: AssertionError
        :raises:: Scapy_Exception if the input value encodes an integer larger than 1<<64  # noqa: E501
        r)   r   r*   l                  zPout-of-bound value: the string encodes a value that is too large (>2^{{64}}): {}zNEINVAL: x: out-of-bound read: the string ends before the AbstractUVarIntField!)r.   r   errorScapy_Exceptionr"   rH   )r   r&   tmp_lenvalueibyte	max_values          r   _parse_multi_bytez&AbstractUVarIntField._parse_multi_byte   s    1vv{{{{a&&1Q4yy	Tk 	dTkqAE{33Ey  +fmmnstt   FAw;;; p;;;qt99D Tk 	 	!q1u+&& zzzzr    c                    t          |t                    s#t          |t                    r|d         dk    sJ t          |t                    r'd|d         z
  | j        k    s
J d            |d         }n,t          |t                    r| j        dk    s
J d            |}|                     |d                   r|                     |          }nt          |d                   | j        z  }|dk    sJ |S )a  
          A tuple is expected for the "x" param only if "size" is different than 8. If a tuple is received, some bits  # noqa: E501
          were consumed by another field. This field consumes the remaining bits, therefore the int of the tuple must  # noqa: E501
          equal "size".

        :param packet.Packet|None pkt: unused.
        :param str|(str, int) x: the string to convert. If bits were consumed by a previous bitfield-compatible field.  # noqa: E501
        :raises: AssertionError
        r*   r   rK   zGEINVAL: x: not enough bits remaining in current byte to read the prefixz<EINVAL: x: tuple expected when prefix_len is not a full byte)r,   bytesr-   r   rR   r]   r   rH   )r   r%   r5   r'   rets        r   r:   zAbstractUVarIntField.m2i  s     !U##K
1e(<(<K1a 	!H***,u***A$CCa''zDINNN<zNNNC""3q6** 	0((--CCc!f++/Caxxxx
r    c                 d   |dk    sJ || j         k     rt          |          S t          | j                   g}|| j         z  }|dk    r3|                    t          d|dz  z                       |dz  }|dk    3|                    t          |                     d                    |          S )z
        :param packet.Packet|None pkt: unused.
        :param int x: the value to convert.
        :return: str: the converted value.
        :raises: AssertionError
        r   rT      rU   r    )rH   r   appendjoin)r   r%   r5   sls       r   r<   zAbstractUVarIntField.i2m0  s     Avvvvtq66M do&&'B At))		#da$h/00111a t)) IIc!ff88B<<r    c                    t          |t          d                    r|S t          |t                    r=|dk    sJ |                     ||          }t          |t                    r|dk    sJ |S t          |t                    r5|                     ||          }t          |t                    r|dk    sJ |S J d            )a  
          A "x" value as a string is parsed as a binary encoding of a UVarInt. An int is considered an internal value.  # noqa: E501
          None is returned as is.

        :param packet.Packet|None pkt: the packet containing this field; probably unused.  # noqa: E501
        :param str|int|None x: the value to convert.
        :return: int|None: the converted value.
        :raises: AssertionError
        Nr   Fz/EINVAL: x: No idea what the parameter format is)r,   typer/   r3   r_   r:   )r   r%   r5   r`   s       r   r>   zAbstractUVarIntField.any2iG  s     ad$$ 	Ha 	6666((3""Cc3''4C1HHHHJ5!! 	((3""CsC((6SAXXXXJGGGGGr    c                 H    t          |                     ||                    S )z
        :param packet.Packet|None pkt: probably unused.
        :param x: int|None: the positive, null or none value to convert.
        :return: str: the representation of the value.
        reprr8   rM   s      r   i2reprzAbstractUVarIntField.i2repr_  s      DHHS!$$%%%r    c           
         |dk    sJ t          |t                    r.| j        dk    s
J d            ||                     ||          z   S || j        k    rM|d         t          |d         | j        z  | j        z             z   |                     ||          dd         z   S |d         t          |d         | j        z  t          |                     ||                    z             z   S )a  
          An AbstractUVarIntField prefix always consumes the remaining bits
          of a BitField;if no current BitField is in use (no tuple in
          entry) then the prefix length is 8 bits and the whole byte is to
          be consumed

        :param packet.Packet|None pkt: the packet containing this field.
          Probably unused.
        :param str|(str, int, long) s: the string to append this field to.
          A tuple indicates that some bits were already generated by another
          bitfield-compatible field. This MUST be the case if "size" is not 8.
          The int is the number of bits already generated in the first byte of
          the str. The long is the value that was generated by the previous
          bitfield-compatible fields.
        :param int val: the positive or null value to be added.
        :return: str: s concatenated with the machine representation of this
          field.
        :raises: AssertionError
        r   rK   <EINVAL: s: tuple expected when prefix_len is not a full byter)   r*   N)r,   r_   r   r<   rH   r   r   r   r%   r&   r'   s       r   r#   zAbstractUVarIntField.addfieldh  s    * axxxxa 	*9>>>#a>>>txxS)))) $/!!Q4#qtty0DOCDDDtxxPSUXGYGYZ[Z\Z\G]]] tc1Q449,DHHS#4F4F0G0GGHHHHr    c                    t          |           dk    sJ t          |           }d}t          | |                   dz  dk    r1|dz  }||k     s
J d            t          | |                   dz  dk    1|dz   }|dk    sJ |S )a   _detect_bytelen_from_str returns the length of the machine
          representation of an AbstractUVarIntField starting at the beginning
          of s and which is assumed to expand over multiple bytes
          (value > _max_prefix_value).

        :param str s: the string to parse. It is assumed that it is a multibyte int.  # noqa: E501
        :return: The bytelength of the AbstractUVarIntField.
        :raises: AssertionError
        r)   r*   rT   r   zFEINVAL: s: out-of-bound read: unfinished AbstractUVarIntField detectedr.   r   )r&   rX   rZ   r`   s       r   _detect_bytelen_from_strz-AbstractUVarIntField._detect_bytelen_from_str  s     1vv{{{{a&&!A$ii$""FAw;;; h;;; !A$ii$"" !eaxxxx
r    c                     |dk    sJ || j         k     rdS || j         z  }d}|dk    r|dz  }|dk    r|dz  }|dz  }|dk    |}|dk    sJ |S )z
        :param packet.Packet|None pkt: unused.
        :param int x: the positive or null value whose binary size if requested.  # noqa: E501
        :raises: AssertionError
        r   r*   rU   )rH   )r   r%   r5   rZ   r`   s        r   i2lenzAbstractUVarIntField.i2len  s     Avvvvt1 	
T_66FA!ee!GAFA !ee axxxx
r    c                    t          |t                    r?t          |          dk    sJ |}|\  }}|dk    sJ d|z
  | j        k    s
J d            |}n,t          |t                    r| j        dk    s
J d            |}|                     |d                   r|                     |          }nd}||d         |                     ||          f}|d         dk    sJ |S )aI  
        :param packet.Packet|None pkt: the packet instance containing this
          field; probably unused.
        :param str|(str, int) s: the input value to get this field value from.
          If size is 8, s is a string, else it is a tuple containing the value
          and an int indicating the number of bits already consumed in the
          first byte of the str. The number of remaining bits to consume in the
          first byte must be equal to "size".
        :return: (str, int): the remaining bytes of s and the parsed value.
        :raises: AssertionError
        r)   r   rK   zGEINVAL: s: not enough bits remaining in current byte to read the prefixrm   r*   N)r,   r-   r.   r   r_   rR   rq   r:   )	r   r%   r&   temptstir'   rX   r`   s	            r   r+   zAbstractUVarIntField.getfield  s     a 		q66Q;;;;DFB7777r6TY&&&(q&&&CCa''zDINNN<zNNNC""3q6** 	33C88GGG'((mTXXc1---1v{{{{
r    c                 (    t          j                    S )z
        :return: volatile.VolatileValue: a volatile value for this field "long"-compatible internal value.  # noqa: E501
        )volatileRandLongr   s    r   randvalzAbstractUVarIntField.randval  s    
  """r    )r?   r@   rA   rB   rC   r   r3   r8   rR   r]   r:   r<   r>   rk   r#   staticmethodrq   rs   r+   r|   rD   rE   s   @r   rG   rG      s,         .--I
    &	 	 	  > > >" " "H  8     .H H H0& & &#I #I #IJ   \.  0  B# # # # # # #r    rG   c                   F     e Zd Z fdZ fdZ fdZ fdZ fdZ xZS )UVarIntFieldc                     |dk    sJ d|cxk     rdk    sn J t          t          |                               |||           || _        d| j        z  dz
  | _        d| _        dS )z
        :param str name: the name of this field instance.
        :param default: the default value for this field instance. default must be positive or null.  # noqa: E501
        :raises: AssertionError
        r   rK   r*   FN)r   r   r   r   rH   rI   r   s       r   r   zUVarIntField.__init__  su     !||||4}}}}1}}}}}}lD!!**4$???		>Q. r    c                     t          t          |                               ||          }t          |t	          d                    s|dk    sJ |S )a<   h2i is overloaded to restrict the acceptable x values (not None)

        :param packet.Packet|None pkt: the packet instance containing this field instance; probably unused.  # noqa: E501
        :param int x: the value to convert.
        :return: int: the converted value.
        :raises: AssertionError
        Nr   )r   r   r3   r,   rg   r   r%   r5   r`   r   s       r   r3   zUVarIntField.h2i  K     L$''++C33c4::..;3!8888
r    c                     t          t          |                               ||          }t          |t	          d                    s|dk    sJ |S )a<   i2h is overloaded to restrict the acceptable x values (not None)

        :param packet.Packet|None pkt: the packet instance containing this field instance; probably unused.  # noqa: E501
        :param int x: the value to convert.
        :return: int: the converted value.
        :raises: AssertionError
        Nr   )r   r   r8   r,   rg   r   s       r   r8   zUVarIntField.i2h  r   r    c                     t          t          |                               ||          }t          |t	          d                    s|dk    sJ |S )aB   any2i is overloaded to restrict the acceptable x values (not None)

        :param packet.Packet|None pkt: the packet instance containing this field instance; probably unused.  # noqa: E501
        :param str|int x: the value to convert.
        :return: int: the converted value.
        :raises: AssertionError
        Nr   )r   r   r>   r,   rg   r   s       r   r>   zUVarIntField.any2i  sK     L$''--c155c4::..;3!8888
r    c                 V    t          t          |                               ||          S )a   i2repr is overloaded to restrict the acceptable x values (not None)

        :param packet.Packet|None pkt: the packet instance containing this field instance; probably unused.  # noqa: E501
        :param int x: the value to convert.
        :return: str: the converted value.
        )r   r   rk   r4   s      r   rk   zUVarIntField.i2repr   s%     \4((//Q777r    )	r?   r@   rA   r   r3   r8   r>   rk   rD   rE   s   @r   r   r     s            $            8 8 8 8 8 8 8 8 8r    r   c                   F     e Zd ZddgZd f fd	Z fdZ fdZd Z xZS )FieldUVarLenField
_length_of_adjustc                     | S NrO   r5   s    r   <lambda>zFieldUVarLenField.<lambda>.  s     r    c                     ||dk    sJ d|cxk     rdk    sn J t          t          |                               |||           || _        || _        dS )a   Initializes a FieldUVarLenField

        :param str name: The name of this field instance.
        :param int|None default: the default value of this field instance.
        :param int size: the number of bits that are occupied by this field in the first byte of a binary string.  # noqa: E501
          size must be in the range ]0;8].
        :param str length_of: The name of the field this field value is measuring/representing.  # noqa: E501
        :param callable adjust: A function that modifies the value computed from the "length_of" field.  # noqa: E501

        adjust can be used for instance to add a constant to the length_of field  # noqa: E501
         length. For instance, let's say that i2len of the length_of field
         returns 2. If adjust is lambda x: x+1 In that case, this field will
         value 3 at build time.
        :return: None
        :raises: AssertionError
        Nr   rK   )r   r   r   r   r   )r   r   r   r   	length_ofadjustr   s         r   r   zFieldUVarLenField.__init__.  sf    $ 'Q,,,,4}}}}1}}}}}}&&//gtDDD#r    c                    |Yt          |t          j                  s*J d                    t	          |                                |                     |          }t          t          |                               |||          S )aq  
        :param packet.Packet|None pkt: the packet instance containing this field instance. This parameter must not be  # noqa: E501
          None if the val parameter is.
        :param str|(str, int, long) s: the string to append this field to. A tuple indicates that some bits were already  # noqa: E501
          generated by another bitfield-compatible field. This MUST be the case if "size" is not 8. The int is the  # noqa: E501
          number of bits already generated in the first byte of the str. The long is the value that was generated by the  # noqa: E501
          previous bitfield-compatible fields.
        :param int|None val: the positive or null value to be added. If None, the value is computed from pkt.  # noqa: E501
        :return: str: s concatenated with the machine representation of this field.  # noqa: E501
        :raises: AssertionError
        Nz:EINVAL: pkt: Packet expected when val is None; received {})	r,   packetPacketr"   rg   _compute_valuer   r   r#   r$   s       r   r#   zFieldUVarLenField.addfieldG  s     ;c6=11 _ _LSSTXY\T]T]^^_ _ _%%c**C&--66sAsCCCr    c                    |Yt          |t          j                  s*J d                    t	          |                                |                     |          }t          t          |                               ||          S )ab  
        :param packet.Packet|None pkt: the packet instance containing this field instance. This parameter must not be  # noqa: E501
          None if the x parameter is.
        :param int|None x: the positive or null value to be added. If None, the value is computed from pkt.  # noqa: E501
        :return: str
        :raises: AssertionError
        Nz8EINVAL: pkt: Packet expected when x is None; received {})	r,   r   r   r"   rg   r   r   r   r<   r4   s      r   r<   zFieldUVarLenField.i2mZ  s     9c6=11 ] ]JQQRVWZR[R[\\] ] ]##C((A&--11#q999r    c                     |                     | j                  \  }}|                    ||          }|                     |          }|dk    sJ |S )a   Computes the value of this field based on the provided packet and
        the length_of field and the adjust callback

        :param packet.Packet pkt: the packet from which is computed this field value.  # noqa: E501
        :return: int: the computed value for this field.
        :raises: KeyError: the packet nor its payload do not contain an attribute
          with the length_of name.
        :raises: AssertionError
        :raises: KeyError if _length_of is not one of pkt fields
        r   )getfield_and_valr   rs   r   )r   r%   fldfvalr'   r`   s         r   r   z FieldUVarLenField._compute_valuei  sS     ((99	TiiT""ll3axxxx
r    )	r?   r@   rA   rC   r   r#   r<   r   rD   rE   s   @r   r   r   +  s        y)I>Ik      2D D D D D&: : : : :      r    r   c                   t    e Zd Zej        d             Zd Zej        d             Zej        d             ZdS )HPackStringsInterfacec                     d S r   rO   r{   s    r   __str__zHPackStringsInterface.__str__      r    c                 H    |                                  }t          |          S r   )r   r	   )r   r0   s     r   	__bytes__zHPackStringsInterface.__bytes__  s    LLNNAr    c                     d S r   rO   r{   s    r   originzHPackStringsInterface.origin  r   r    c                     d S r   rO   r{   s    r   __len__zHPackStringsInterface.__len__  r   r    N)	r?   r@   rA   abcabstractmethodr   r   r   r   rO   r    r   r   r     s~             	   	    r    r   )	metaclassc                   0    e Zd ZdZdgZd Zd Zd Zd ZdS )HPackLiteralStringz HPackLiteralString is a string. This class is used as a marker and
    implements an interface in common with HPackZString
    _sc                     || _         d S r   r   r   r&   s     r   r   zHPackLiteralString.__init__  s    r    c                     | j         S r   r   r{   s    r   r   zHPackLiteralString.__str__  s	    wr    c                 *    t          | j                  S r   r   r   r{   s    r   r   zHPackLiteralString.origin      !!!r    c                 *    t          | j                  S r   )r.   r   r{   s    r   r   zHPackLiteralString.__len__  s    47||r    N)	r?   r@   rA   rB   rC   r   r   r   r   rO   r    r   r   r     sc          I    " " "    r    r   c                       e Zd ZdZdS )EOSzP Simple "marker" to designate the End Of String symbol in the huffman table
    Nr?   r@   rA   rB   rO   r    r   r   r     s           r    r   c                   :    e Zd ZdZddgZ	 d Zd Zd Zd Zd Z	d	S )
HuffmanNodezo HuffmanNode is an entry of the binary tree used for encoding/decoding
    HPack compressed HTTP/2 headers
    leftrightc                 "    || _         || _        d S r   )r   r   )r   r   r   s      r   r   zHuffmanNode.__init__  s    	


r    c                 "    |r| j         n| j        S r   r   r   )r   bs     r   __getitem__zHuffmanNode.__getitem__  s    -tzzDI-r    c                 *    |r	|| _         d S || _        d S r   r   )r   r   r'   s      r   __setitem__zHuffmanNode.__setitem__  s      	DJJJDIIIr    c                 *    |                                  S r   )__repr__r{   s    r   r   zHuffmanNode.__str__  s    }}r    c                 B    d                     | j        | j                  S )Nz({}, {}))r"   r   r   r{   s    r   r   zHuffmanNode.__repr__  s      DJ777r    N)
r?   r@   rA   rB   rC   r   r   r   r   r   rO   r    r   r   r     sz          !I  
. . .    8 8 8 8 8r    r   c                       e Zd ZdZdS )InvalidEncodingExceptionz} InvalidEncodingException is raised when a supposedly huffman-encoded
     string is decoded and a decoding error arises
    Nr   rO   r    r   r   r                r    r   c                       e Zd ZddgZg dZdZed             Zed             Zed             Z	ed             Z
ed	             Zed
             Zd Zd Zd Zd ZdS )HPackZStringr   _encoded(  )i     )i    )i   )ir   )ir   )ir   )ir   )ir   )ir   )i    )i?   )ir   )ir   )i?r   )ir   )ir   )ir   )ir   )ir   )ir   )ir   )ir   )i?r   )ir   )ir   )ir   )ir   )ir   )ir   )ir   )ir   )ir   )      )i  
   )i  r   )i     )i  r   )   r   )   rK   )i     )i  r   )i  r   )   rK   )i  r   )   rK   )   r   )r   r   )r   r   )r      )r*   r   )r)   r   )   r   )   r   )   r   )r   r   )   r   )r   r   )   r   )\   rU   )   rK   )i     )    r   )i  r   )i  r   )i  r   )!   r   )]   rU   )^   rU   )_   rU   )`   rU   )a   rU   )b   rU   )c   rU   )d   rU   )e   rU   )f   rU   )g   rU   )h   rU   )i   rU   )j   rU   )k   rU   )l   rU   )m   rU   )n   rU   )o   rU   )p   rU   )q   rU   )r   rU   )   rK   )s   rU   )   rK   )i  r   )i    )i  r   )i?     )"   r   )i  r   )   r   )#   r   )   r   )$   r   )r   r   )%   r   )&   r   )'   r   )r   r   )t   rU   )u   rU   )(   r   ))   r   )*   r   )rU   r   )+   r   )v   rU   ),   r   )rK   r   )	   r   )-   r   )w   rU   )x   rU   )y   rU   )z   rU   ){   rU   )i  r   )i  r   )i?  r   )i  r   )ir   )i r   )i? r   )i r   )i r   )i? r   )i? r   )i? r   )i r   )i? r   )i r   )i r   )i r   )i r   )i r   )i r   )i r   )i r   )i r   )i? r   )i r   )i r   )i r   )i r   )i r   )i r   )i r   )i? r   )i r   )i? r   )i r   )i r   )i r   )i? r   )i r   )i r   )i? r   )i? r   )i r   )i r   )i r   )i r   )i? r   )i? r   )i r   )i r   )i? r   )i r   )i r   )i r   )i r   )i? r   )i r   )i r   )i? r   )i r   )i r   )i r   )i? r   )i? r   )i? r   )i r   )i? r   )i? r   )i r   )ir   )ir   )i r   )i r   )i? r   )i r   )i? r   )ir   )ir   )ir   )ir   )ir   )ir   )ir   )i r   )ir   )i r   )i r   )ir   )ir   )ir   )ir   )ir   )i r   )i r   )i r   )ir   )ir   )ir   )ir   )ir   )ir   )i r   )i r   )i r   )i r   )i? r   )i r   )i r   )i r   )i? r   )i? r   )ir   )ir   )i r   )i r   )ir   )i r   )ir   )ir   )ir   )ir   )ir   )ir   )ir   )ir   )ir   )ir   )ir   )ir   )ir   )ir   )ir   )ir   )i?r   Nc                     t          |t                    r| j        d         S t          |t                    st	          |          dk    sJ | j        t          |                   S )z huffman_encode_char assumes that the static_huffman_tree was
        previously initialized

        :param str|EOS c: a symbol to encode
        :return: (int, int): the bitstring of the symbol and its bitlength
        :raises: AssertionError
        r*   )r,   r   static_huffman_coder/   r.   r   )clscs     r   _huffman_encode_charz!HPackZString._huffman_encode_char  sZ     a 	5*2..a%%4Q1&s1vv..r    c                 ,   d}d}|D ]'}|                      |          \  }}||z  |z   }||z  }(d|dz  z
  }|dk    r7|                      t                                \  }}||z  |||z
  z	  z   }||z  }||f}|d         dk    sJ |d         dk    sJ |S )a   huffman_encode returns the bitstring and the bitlength of the
        bitstring representing the string provided as a parameter

        :param str s: the string to encode
        :return: (int, int): the bitstring of s and its bitlength
        :raises: AssertionError
        r   rK   r*   )r  r   )	r  r&   rZ   iblr  r'   blpadlenr`   s	            r   huffman_encodezHPackZString.huffman_encode  s      	 	A..q11GCbCA2ICCcAgQ;;..suu55GCff!56A6MCf1v{{{{A!
r    c                    |dk    sJ |dk    sJ t          | j        t          d                    r|                                  t          | j        t          d                    rJ g }d}d}| j        }d}d}||k     r|||z
  dz
  z	  dz  }	|dz  |	z   }|dz  }||	         }
t          |
t                    r0d}|
}t          |t          d                    rt                      nkt          |
t                    rt          d          t          |
t                    r#d}|	                    |
           | j        }d}d}nt          d          |dz  }||k     |rK|dk    rt          d	          | j
        d
         }|d         |d         |z
  z	  }||k    rt          d          d                    |          S )a   huffman_decode decodes the bitstring provided as parameters.

        :param int i: the bitstring to decode
        :param int ibl: the bitlength of i
        :return: str: the string decoded from the bitstring
        :raises: AssertionError, InvalidEncodingException
        r   NFr*   Tz'Huffman decoder met the full EOS symbolz,Should never happen, so incidentally it willrU   z7Huffman decoder is detecting padding longer than 7 bitsr  z6Huffman decoder is detecting unexpected padding formatr    )r,   static_huffman_treerg   huffman_compute_decode_treer   AssertionErrorr   r   r_   rc   r  rd   )r  rZ   r  r&   jinterruptedcurcur_sym
cur_sym_blr   elmt
eos_symboleos_msbs                r   huffman_decodezHPackZString.huffman_decode  s    Avvvvaxxxxc-tDzz:: 	.++---c5tDzzBBBBB%
#ggsQw{#q(A!|q(G!OJq6D$,, _"c4::.. +(***+D#&& 	_./XYYYD%(( _#-

./]^^^FA+ #gg.  		i A~~./hiii04J m
1
(BCG'!!./ghhhxx{{r    c                    |dk    sJ |dk    sJ |dz  }|dz  }|dk    r|d|z
  z  }|dz  }g }d}||k     r7|                     dt          ||dz  z	  dz                       |dz  }||k     7d                    |          S )a]   huffman_conv2str converts a bitstring of bit_len bitlength into a
        binary string. It DOES NOT compress/decompress the bitstring!

        :param int bit_str: the bitstring to convert.
        :param int bit_len: the bitlength of bit_str.
        :return: str: the converted bitstring as a bytestring.
        :raises: AssertionError
        r   rK   r*      r    )insertr   rd   )r  bit_strbit_lenbyte_lenrem_bitr&   rZ   s          r   huffman_conv2strzHPackZString.huffman_conv2strN  s     !||||!||||a<A+a<<G#GMH (llHHQWQ/4788999FA (ll xx{{r    c                     d}t          |          dz  }|D ]}|dz  t          |          z   }||f}|d         dk    sJ |d         dk    sJ |S )ag   huffman_conv2bitstring converts a string into its bitstring
        representation. It returns a tuple: the bitstring and its bitlength.
        This function DOES NOT compress/decompress the string!

        :param str s: the bytestring to convert.
        :return: (int, int): the bitstring of s, and its bitlength.
        :raises: AssertionError
        r   rK   r*   rp   )r  r&   rZ   r  r  r`   s         r   huffman_conv2bitstringz#HPackZString.huffman_conv2bitstringk  sm     !ffqj 	" 	"Aa3q66!AAf1v{{{{1v{{{{
r    c                    t          dd          | _        d}| j        D ]}| j        }t          |d         dz
  dd          D ]}|d         |z	  dz  }t	          ||         t
                    rt          d          |dk    r'|dk     rt          |          nt                      ||<   n||         t          dd          ||<   ||         }|dz  }dS )z huffman_compute_decode_tree initializes/builds the static_huffman_tree

        :return: None
        :raises: InvalidEncodingException if there is an encoding problem
        Nr   r*   r  z"Huffman unique prefix violation :/   )	r   r#  r  ranger,   r_   r   r   r   )r  rZ   entryparentidxr   s         r   r$  z(HPackZString.huffman_compute_decode_tree  s     #.dD"9"9, 	 	E,FU1X\2r22 # #1X_)fQi// Y23WXXX!88*+c''AsuuF1IIAY& +D$ 7 7F1IFAA	 	r    c                     || _         t          |                               |          \  }}t          |                               ||          | _        d S r   )r   rg   r!  r6  r   )r   r&   rZ   r  s       r   r   zHPackZString.__init__  sG    d**1--3T

33As;;r    c                     | j         S r   )r   r{   s    r   r   zHPackZString.__str__  s
    }r    c                 *    t          | j                  S r   r   r{   s    r   r   zHPackZString.origin  r   r    c                 *    t          | j                  S r   )r.   r   r{   s    r   r   zHPackZString.__len__  s    4=!!!r    )r?   r@   rA   rC   r  r#  classmethodr  r!  r.  r6  r8  r$  r   r   r   r   rO   r    r   r   r     s       z"IB B BH / / [/   [6 7 7 [7r   [8   [(   [,< < <  " " "" " " " "r    r   c                   v     e Zd ZdZddgZ fdZd Zed             Zd Z	d Z
d	 Zd
 Zd Zd Zd Zd Z xZS )HPackStrLenFieldz HPackStrLenField is a StrLenField variant specialized for HTTP/2 HPack

    This variant uses an internal representation that implements HPackStringsInterface.  # noqa: E501
    _length_from
_type_fromc                 v    t          t          |                               ||           || _        || _        d S r   )r   rE  r   rF  rG  )r   r   r   length_from	type_fromr   s        r   r   zHPackStrLenField.__init__  s7    %%..tW==='#r    c                 4    ||                      ||          z   S r   )r<   rn   s       r   r#   zHPackStrLenField.addfield  s    488C%%%%r    c                     | rEt                               |          \  }}t          t                               ||                    S t          |          S )a  
        :param bool t: whether this string is a huffman compressed string.
        :param str s: the string to parse.
        :return: HPackStringsInterface: either a HPackLiteralString or HPackZString, depending on t.  # noqa: E501
        :raises: InvalidEncodingException
        )r   r8  r.  r   )tr&   rZ   r  s       r   _parsezHPackStrLenField._parse  sP      	E!88;;FAs ; ;As C CDDD!!$$$r    c                     |                      |          }|                    | j                  dk    }||d         |                     ||d|                   fS )a  
        :param packet.Packet pkt: the packet instance containing this field instance.  # noqa: E501
        :param str s: the string to parse this field from.
        :return: (str, HPackStringsInterface): the remaining string after this field was carved out & the extracted  # noqa: E501
          value.
        :raises: KeyError if "type_from" is not a field of pkt or its payloads.
        :raises: InvalidEncodingException
        r*   N)rF  getfieldvalrG  rN  )r   r%   r&   rX   rM  s        r   r+   zHPackStrLenField.getfield  sX     ##C((OODO,,1{DKK1XgX;7777r    c                     d}t          |t                    rd}nt          |t                    rd}|                    |                                          S )N zHPackLiteralString({})zHPackZString({}))r,   r   r   r"   r   )r   r%   r5   fmts       r   r8   zHPackStrLenField.i2h  sR    a+,, 	%*CC<(( 	%$Czz!((**%%%r    c                      t          |          S r   )r   rM   s      r   r3   zHPackStrLenField.h2i  s    !!$$$r    c                     |                     | j                  }|                     |          }||
J d            |                     |dk    |d|                   S )a  
        :param packet.Packet pkt: the packet instance containing this field instance.  # noqa: E501
        :param str x: the string to parse.
        :return: HPackStringsInterface: the internal type of the value parsed from x.  # noqa: E501
        :raises: AssertionError
        :raises: InvalidEncodingException
        :raises: KeyError if _type_from is not one of pkt fields.
        Nz>Conversion from string impossible: no type or length specifiedr*   )rP  rG  rF  rN  )r   r%   r5   rM  rX   s        r   r:   zHPackStrLenField.m2i  sc     OODO,,##C((}!4!46v!4!4!4{{161XgX;///r    c                     t          |t                    r2t          |t          j                  sJ |                     ||          S t          |t
                    sJ |S )a=  
        :param packet.Packet|None pkt: the packet instance containing this field instance.  # noqa: E501
        :param str|HPackStringsInterface x: the value to convert
        :return: HPackStringsInterface: the Scapy internal value for this field
        :raises: AssertionError, InvalidEncodingException
        )r,   r_   r   r   r:   r   rM   s      r   r>   zHPackStrLenField.any2i  s^     a 	$c6=1111188C###!233333r    c                      t          |          S r   )r   rM   s      r   r<   zHPackStrLenField.i2m      1vvr    c                      t          |          S r   r.   rM   s      r   rs   zHPackStrLenField.i2len  rX  r    c                 H    t          |                     ||                    S r   ri   rM   s      r   rk   zHPackStrLenField.i2repr  s    DHHS!$$%%%r    )r?   r@   rA   rB   rC   r   r#   r}   rN  r+   r8   r3   r:   r>   r<   rs   rk   rD   rE   s   @r   rE  rE    s           .I$ $ $ $ $& & & % % \%8 8 8& & &% % %0 0 0"      & & & & & & &r    rE  c                        e Zd ZdZdZ ej        dddddd           ed	dd
d           ed e	d          d d          gZ
d Z fdZ xZS )HPackHdrStringzg HPackHdrString is a packet that that is serialized into a RFC7541 par5.2
    string literal repr.
    zHPack Header Stringrg   Nr*   Literal
Compressedr   r*   r.   rU   data)r   rR  c                 ,    |                      d          S )Nr.   rP  r%   s    r   r   zHPackHdrString.<lambda>  s    COOE$:$: r    )rI  rJ  c                 $    t           j        j        S r   configconfpadding_layerr   payloads     r   guess_payload_classz"HPackHdrString.guess_payload_class#  s    
 {((r    c                     |                      d          1t          |                      d          t                    rdnd| _         t	          t
          |           j        di |S )zself_build is overridden because type and len are determined at
        build time, based on the "data" field internal type
        rg   Nra  r*   r   rO   )rP  r,   r   rg   r   r]  
self_build)r   kwargsr   s     r   rn  zHPackHdrString.self_build*  se    
 F##+'(8(8(@(@,OOVUVDI5u^T**5?????r    )r?   r@   rA   rB   r   fieldsBitEnumFieldr   rE  r   fields_descrl  rn  rD   rE   s   @r   r]  r]    s          !DFD!|-L-LMM%qF;;;&&r**::	
 	
 	
K) ) )@ @ @ @ @ @ @ @ @r    r]  c                   0    e Zd ZdZedd            Zd ZdS )HPackHeaderszHPackHeaders uses the "dispatch_hook" trick of Packet_metaclass to select
    the correct HPack header packet type. For this, the first byte of the string  # noqa: E501
    to dissect is snooped on.
    Nc                     |t           j        j        S t          |d                   }|dz  dk    rt          S |dz  dk    rt
          S |dz  dk    rt          S t          S )zldispatch_hook returns the subclass of HPackHeaders that must be used
        to dissect the string.
        Nr   rT   @   r   )rg  rh  	raw_layerr   HPackIndexedHdrHPackLitHdrFldWithIncrIndexingHPackDynamicSizeUpdateHPackLitHdrFldWithoutIndexing)r  r&   _args_kwdsrQ   s        r   dispatch_hookzHPackHeaders.dispatch_hook9  sb     9;((1YY9>>""9>>119>>)),,r    c                 $    t           j        j        S r   rf  rj  s     r   rl  z HPackHeaders.guess_payload_classJ      {((r    r   )r?   r@   rA   rB   rC  r~  rl  rO   r    r   rt  rt  4  sM          - - - [- ) ) ) ) )r    rt  c                   J    e Zd ZdZdZ eddd           eddd          gZdS )	rx  z0 HPackIndexedHdr implements RFC 7541 par6.1
    zHPack Indexed Header Fieldmagicr*   indexr)   rU   Nr?   r@   rA   rB   r   r   r   rr  rO   r    r   rx  rx  O  sG         'D7Aq))Wa##KKKr    rx  c            	           e Zd ZdZdZ eddd           eddd           ej         ej	        d	d
e
          d            ej	        dd
e
          gZd
S )ry  zA HPackLitHdrFldWithIncrIndexing implements RFC 7541 par6.2.1
    z.HPack Literal Header With Incremental Indexingr  r*   r)   r  r   r   hdr_nameNc                 4    |                      d          dk    S Nr  r   rc  rd  s    r   r   z'HPackLitHdrFldWithIncrIndexing.<lambda>b      00A5 r    	hdr_value)r?   r@   rA   rB   r   r   r   rp  ConditionalFieldPacketFieldr]  rr  rO   r    r   ry  ry  Y  s         ;D7Aq))Wa##Fz4@@55	
 	
 	;n==KKKr    ry  c            
           e Zd ZdZdZ eddd           ej        ddddd	d
           eddd           ej	         ej
        dde          d            ej
        dde          gZdS )r{  zR HPackLitHdrFldWithIncrIndexing implements RFC 7541 par6.2.2
    and par6.2.3
    z9HPack Literal Header Without Indexing (or Never Indexing)r  r   r  never_indexr*   zDon't IndexzNever Indexr`  r  r  r  Nc                 4    |                      d          dk    S r  rc  rd  s    r   r   z&HPackLitHdrFldWithoutIndexing.<lambda>v  r  r    r  )r?   r@   rA   rB   r   r   rp  rq  r   r  r  r]  rr  rO   r    r   r{  r{  h  s          GD7Aq))1a-00	
 	
 	Wa##Fz4@@55	
 	
 	;n==KKKr    r{  c                   J    e Zd ZdZdZ eddd           eddd          gZd	S )
rz  z7 HPackDynamicSizeUpdate implements RFC 7541 par6.3
    zHPack Dynamic Size Updater  r*   r  max_sizer   r   Nr  rO   r    r   rz  rz  |  sG         &D7Aq))ZA&&KKKr    rz  c                       e Zd ZdZdS )H2FramePayloadzb H2FramePayload is an empty class that is a super class of all Scapy
    HTTP/2 Frame Packets
    Nr   rO   r    r   r  r    r   r    r  c                       e Zd ZdZdZdZdZe ej        dd          e ej        dd          iZ	dZ
 ej        d	d
          gZdS )H2DataFramezn H2DataFrame implements RFC7540 par6.1
    This packet is the Data Frame to use when there is no padding.
    r   r  ES
End StreamPPaddedzHTTP/2 Data Framera  rR  N)r?   r@   rA   rB   type_idEND_STREAM_FLAGPADDED_FLAGrp  MultiFlagsEntryflagsr   StrFieldrr  rO   r    r   r  r    sy          GOK//lCC+V+C::E
 D##KKKr    r  c                       e Zd ZdZdgZdZ ej        dddd           ej        d	d
d            ej        dd
d           gZ	d Z
d ZdS )H2PaddedDataFramezk H2DataFrame implements RFC7540 par6.1
    This packet is the Data Frame to use when there is padding.
    s_lenzHTTP/2 Padded Data Framer   NpaddingBr   rS  ra  rR  c                 *    |                                  S r   )get_data_lenrd  s    r   r   zH2PaddedDataFrame.<lambda>  s    33C3C3E3E r    rI  c                 ,    |                      d          S Nr   rc  rd  s    r   r   zH2PaddedDataFrame.<lambda>      3??83L3L r    c                     |                      d          }|                     d          \  }}|                    | |          }| j        |z
  |z
  }|dk    sJ |S )a   get_data_len computes the length of the data field

        To do this computation, the length of the padlen field and the actual
        padding is subtracted to the string that was provided to the pre_dissect  # noqa: E501
        fun of the pkt parameter
        :return: int; length of the data part of the HTTP/2 frame packet provided as parameter  # noqa: E501
        :raises: AssertionError
        r   r   rP  r   rs   r  r   padding_lenr   r   padding_len_lenr`   s         r   r  zH2PaddedDataFrame.get_data_len  d     &&x00))(33	T))D$//j?*[8axxxx
r    c                 .    t          |          | _        |S )a  pre_dissect is filling the s_len property of this instance. This
        property is later used during the getfield call of the "data" field when  # noqa: E501
        trying to evaluate the length of the StrLenField! This "trick" works
        because the underlayer packet (H2Frame) is assumed to override the
        "extract_padding" method and to only provide to this packet the data
        necessary for this packet. Tricky, tricky, will break some day probably!  # noqa: E501
        r.   r  r   s     r   pre_dissectzH2PaddedDataFrame.pre_dissect       VV
r    )r?   r@   rA   rB   rC   r   rp  FieldLenFieldStrLenFieldrr  r  r  rO   r    r   r  r    s          	I%DXtycJJJ62'E'E	 	 	 	9b'L'L	 	 	K  $
 
 
 
 
r    r  c                       e Zd ZdZdS )H2AbstractHeadersFramezbSuperclass of all variants of HTTP/2 Header Frame Packets.
    May be used for type checking.
    Nr   rO   r    r   r  r    r   r    r  c                       e Zd ZdZdZdZdZdZdZe e	j
        dd          e e	j
        d	d
          e e	j
        dd          e e	j
        dd          iZdZ e	j        dg e          gZdS )H2HeadersFramea   H2HeadersFrame implements RFC 7540 par6.2 Headers Frame
    when there is no padding and no priority information

    The choice of decomposing into four classes is probably preferable to having  # noqa: E501
    numerous conditional fields based on the underlayer :/
    r*   r   r)   r  r   r  r  EHEnd Headersr  r  +PriorityzHTTP/2 Headers FramehdrsN)r?   r@   rA   rB   r  r  END_HEADERS_FLAGr  PRIORITY_FLAGrp  r  r  r   PacketListFieldrt  rr  rO   r    r   r  r    s          GOKM//lCC0&0}EE+V+C::-v-c:>>	E "Dvr<88KKKr    r  c                       e Zd ZdZdgZdZ ej        dddd           ej        d	g e	d
            ej
        ddd           gZd Zd ZdS )H2PaddedHeadersFramezv H2PaddedHeadersFrame is the variant of H2HeadersFrame where padding flag
    is set and priority flag is cleared
    r  z!HTTP/2 Headers Frame with Paddingr   Nr  r  r  r  c                 *    |                                  S r   get_hdrs_lenrd  s    r   r   zH2PaddedHeadersFrame.<lambda>      s7G7G7I7I r    r  rR  c                 ,    |                      d          S r  rc  rd  s    r   r   zH2PaddedHeadersFrame.<lambda>  r  r    c                     |                      d          }|                     d          \  }}|                    | |          }| j        |z
  |z
  }|dk    sJ |S )a   get_hdrs_len computes the length of the hdrs field

        To do this computation, the length of the padlen field and the actual
        padding is subtracted to the string that was provided to the pre_dissect  # noqa: E501
        fun of the pkt parameter.
        :return: int; length of the data part of the HTTP/2 frame packet provided as parameter  # noqa: E501
        :raises: AssertionError
        r   r   r  r  s         r   r  z!H2PaddedHeadersFrame.get_hdrs_len  r  r    c                 .    t          |          | _        |S a  pre_dissect is filling the s_len property of this instance. This
        property is later used during the parsing of the hdrs PacketListField
        when trying to evaluate the length of the PacketListField! This "trick"
        works because the underlayer packet (H2Frame) is assumed to override the  # noqa: E501
        "extract_padding" method and to only provide to this packet the data
        necessary for this packet. Tricky, tricky, will break some day probably!  # noqa: E501
        r  r   s     r   r  z H2PaddedHeadersFrame.pre_dissect  r  r    )r?   r@   rA   rB   rC   r   rp  r  r  rt  r  rr  r  r  rO   r    r   r  r    s          	I.DXtycJJJvr<+I+I	! 	! 	! 	9b'L'L	 	 	K  $
 
 
 
 
r    r  c                       e Zd ZdZdgZdZ ej        ddd           ej        ddd           ej        d	d           ej	        d
g e
          gZdS )H2PriorityHeadersFramezx H2PriorityHeadersFrame is the variant of H2HeadersFrame where priority flag
    is set and padding flag is cleared
    r  z"HTTP/2 Headers Frame with Priority	exclusiver   r*   stream_dependencyr   weightr  N)r?   r@   rA   rB   rC   r   rp  BitField	ByteFieldr  rt  rr  rO   r    r   r  r  %  s|          	I/DQ**+Q331%% 	vr<88KKKr    r  c            
          e Zd ZdZdgZdZ ej        dddd           ej        d	d
d           ej        dd
d           ej	        dd
           ej
        dg ed            ej        ddd           gZd Zd ZdS )H2PaddedPriorityHeadersFramezu H2PaddedPriorityHeadersFrame is the variant of H2HeadersFrame where
    both priority and padding flags are set
    r  z.HTTP/2 Headers Frame with Padding and Priorityr   Nr  r  r  r  r   r*   r  r   r  r  c                 *    |                                  S r   r  rd  s    r   r   z%H2PaddedPriorityHeadersFrame.<lambda>D  r  r    r  rR  c                 ,    |                      d          S r  rc  rd  s    r   r   z%H2PaddedPriorityHeadersFrame.<lambda>G  r  r    c                    |                      d          }|                     d          \  }}|                    | |          }|                     d          j        }||                     d          j        z  }|                     d          \  }}|                    | |          }t          | j        |z
  |z
  |dz  z
  |z
            }|dk    sJ |S )ar   get_hdrs_len computes the length of the hdrs field

        To do this computation, the length of the padlen field, the priority
        information fields and the actual padding is subtracted to the string
        that was provided to the pre_dissect fun of the pkt parameter.
        :return: int: the length of the hdrs field
        :raises: AssertionError
        r   r  r  r  rK   r   )rP  r   rs   	get_fieldr   r/   r  )r   r  r   r   r  bit_cnt
weight_lenr`   s           r   r  z)H2PaddedPriorityHeadersFrame.get_hdrs_lenK  s     &&x00))(33	T))D$//..--24>>"566;;))(33	TYYtT**
$*!" Q;  	   axxxx
r    c                 .    t          |          | _        |S r  r  r   s     r   r  z(H2PaddedPriorityHeadersFrame.pre_dissectf  r  r    )r?   r@   rA   rB   rC   r   rp  r  r  r  r  rt  r  rr  r  r  rO   r    r   r  r  7  s          	I;DXtycJJJQ**+Q331%%vr<+I+I	! 	! 	! 	9b'L'L	 	 	K  6
 
 
 
 
r    r  c                       e Zd ZdZdZdZ ej        ddd           ej        ddd           ej        d	d          gZ	d
S )H2PriorityFramez0 H2PriorityFrame implements RFC 7540 par6.3
    r)   zHTTP/2 Priority Framer  r   r*   r  r   r  N)
r?   r@   rA   rB   r  r   rp  r  r  rr  rO   r    r   r  r  u  sb         G"DQ**+Q331%%KKKr    r  c                       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ededededede	de
dededededededediZdS )H2ErrorCodesz H2ErrorCodes is an enumeration of the error codes defined in
    RFC7540 par7.
    This enumeration is not part of any frame because the error codes are in
    common with H2ResetFrame and H2GoAwayFrame.
    r   r*   r)   r  r  r   r   rU   rK   r  r   r   r   r   zNo errorzProtocol errorzInternal errorzFlow control errorzSettings timeoutzStream closedzFrame size errorzRefused streamCancelzCompression errorzControl errorzEnhance your calmzInadequate securityzHTTP/1.1 requiredN)r?   r@   rA   rB   NO_ERRORPROTOCOL_ERRORINTERNAL_ERRORFLOW_CONTROL_ERRORSETTINGS_TIMEOUTSTREAM_CLOSEDFRAME_SIZE_ERRORREFUSED_STREAMCANCELCOMPRESSION_ERRORCONNECT_ERRORENHANCE_YOUR_CALMINADEQUATE_SECURITYHTTP_1_1_REQUIREDliteralrO   r    r   r  r    s          HNNMNFM 	*((0,,(..2.GGGr    r  c                   N    e Zd ZdZdZdZ ej        ddej	        d          gZ
dS )	H2ResetFramez- H2ResetFrame implements RFC 7540 par6.4
    r  zHTTP/2 Reset FramerV   r   !IrS  N)r?   r@   rA   rB   r  r   rp  	EnumFieldr  r  rr  rO   r    r   r  r    sE         GD!\%9tDDDKKKr    r  c                       e Zd ZdZdZdZdZdZdZdZ	dZ
 ej        d	d
ededededede	did           ej        dd
          gZd ZdS )	H2SettingzD H2Setting implements a setting, as defined in RFC7540 par6.5.1
    r*   r)   r  r  r   r   zHTTP/2 Settingidr   zHeader table sizezEnable pushzMax concurrent streamszInitial window sizezMax frame sizezMax header list sizez!Hr  rY   c                 $    t           j        j        S r   rf  rj  s     r   rl  zH2Setting.guess_payload_class  r  r    N)r?   r@   rA   rB   SETTINGS_HEADER_TABLE_SIZESETTINGS_ENABLE_PUSHSETTINGS_MAX_CONCURRENT_STREAMSSETTINGS_INITIAL_WINDOW_SIZESETTINGS_MAX_FRAME_SIZESETTINGS_MAX_HEADER_LIST_SIZEr   rp  r  IntFieldrr  rl  rO   r    r   r  r    s         !$&)##& !$'!Dq&(; -+-E(*?#%5)+A#
 	 	 	 	##
K) ) ) ) )r    r  c                   z     e Zd ZdZdZdZe ej        dd          iZdZ	 ej
        dg e          gZ fdZ xZS )	H2SettingsFramez/ H2SettingsFrame implements RFC7540 par6.5
    r  r   AACKzHTTP/2 Settings Framesettingsc                     t          |          dk    sAt          |d         t                    rt          |d                   dz  dk    s
J d             t          t          |           j        |i | dS )a  __init__ initializes this H2SettingsFrame

        If a _pkt arg is provided (by keyword), then this is an initialization
        from a string to dissect and therefore the length of the string to
        dissect have distinctive characteristics that we might want to check.
        This is possible because the underlayer packet (H2Frame) overrides
        extract_padding method to provided only the string that must be parsed
        by this packet!
        :raises: AssertionError
        r   r   z5Invalid settings frame; length is not a multiple of 6N)r.   r,   r_   r   r  r   r   argsro  r   s      r   r   zH2SettingsFrame.__init__  s     IINN47E** DGq A%%%B &%% 	.ot$$-t>v>>>>>r    )r?   r@   rA   rB   r  ACK_FLAGrp  r  r  r   r  r  rr  r   rD   rE   s   @r   r  r    s         GH(&(e44E #Dz2y99K? ? ? ? ? ? ? ? ?r    r  c                       e Zd ZdZdZdZdZe ej        dd          e ej        dd          iZ	d	Z
 ej        d
dd           ej        ddd           ej        dg e          gZdS )H2PushPromiseFramez H2PushPromiseFrame implements RFC7540 par6.6. This packet
    is the variant to use when the underlayer padding flag is cleared
    r   r)   r  r  r  r  r  zHTTP/2 Push Promise Framereservedr   r*   	stream_idr   r  N)r?   r@   rA   rB   r  r  r  rp  r  r  r   r  r  rt  rr  rO   r    r   r  r    s          GK0&0}EE+V+C::E
 'D
Aq))Q++vr<88KKKr    r  c            	           e Zd ZdZdgZdZ ej        dddd           ej        d	d
d           ej        dd
d           ej	        dg e
d            ej        ddd           gZd Zd ZdS )H2PaddedPushPromiseFramez H2PaddedPushPromiseFrame implements RFC7540 par6.6. This
    packet is the variant to use when the underlayer padding flag is set
    r  z HTTP/2 Padded Push Promise Framer   Nr  r  r  r  r   r*   r  r   r  c                 *    |                                  S r   r  rd  s    r   r   z!H2PaddedPushPromiseFrame.<lambda>  r  r    r  rR  c                 ,    |                      d          S r  rc  rd  s    r   r   z!H2PaddedPushPromiseFrame.<lambda>  r  r    c                     |                      d          \  }}|                    | |          }|                     d          j        }||                     d          j        z  }t	          | j        |z
  |z
  |dz  z
            }|dk    sJ |S )af   get_hdrs_len computes the length of the hdrs field

        To do this computation, the length of the padlen field, reserved,
        stream_id and the actual padding is subtracted to the string that was
        provided to the pre_dissect fun of the pkt parameter.
        :return: int: the length of the hdrs field
        :raises: AssertionError
        r   r  r  rK   r   )r   rs   r  r   r/   r  )r   r   r  r  r3  r`   s         r   r  z%H2PaddedPushPromiseFrame.get_hdrs_len"  s      00::[))D+66..,,14>>+..33$*!" Q;   
 axxxx
r    c                 .    t          |          | _        |S r  r  r   s     r   r  z$H2PaddedPushPromiseFrame.pre_dissect9  r  r    )r?   r@   rA   rB   rC   r   rp  r  r  r  rt  r  rr  r  r  rO   r    r   r  r    s          	I-DXtycJJJ
Aq))Q++vr<+I+I	! 	! 	! 	9b'L'L	 	 	
K  .
 
 
 
 
r    r  c                   x     e Zd ZdZdZdZe ej        dd          iZdZ	 ej
        dd          gZ fdZ xZS )	H2PingFramez0 H2PingFrame implements the RFC 7540 par6.7
    r   r   r  r  zHTTP/2 Ping Frameopaquec                     t          |          dk    sEt          |d         t          t          f          rt          |d                   dk    s
J d             t	          t
          |           j        |i | dS ))
        :raises: AssertionError
        r   rK   z#Invalid ping frame; length is not 8N)r.   r,   r_   strr   r  r   r  s      r   r   zH2PingFrame.__init__V  s~     IINN47UCL11 DG!!!0 "!! 	*k4  )4:6:::::r    )r?   r@   rA   rB   r  r
  rp  r  r  r   	LongFieldrr  r   rD   rE   s   @r   r  r  H  s         GH(&(e44E D1%%K; ; ; ; ; ; ; ; ;r    r  c                       e Zd ZdZdZdZ ej        ddd           ej        ddd           ej        d	de	j
        d
           ej        dd          gZdS )H2GoAwayFramez2 H2GoAwayFrame implements the RFC 7540 par6.8
    rU   zHTTP/2 Go Away Framer  r   r*   last_stream_idr   rV   r  r  additional_datarR  N)r?   r@   rA   rB   r  r   rp  r  r  r  r  r  rr  rO   r    r   r  r  f  s~         G!D
Aq))(!R00!\%9tDDD)2..	KKKr    r  c                   r     e Zd ZdZdZdZ ej        ddd           ej        ddd          gZ fd	Z	 xZ
S )
H2WindowUpdateFramez8 H2WindowUpdateFrame implements the RFC 7540 par6.9
    rK   zHTTP/2 Window Update Framer  r   r*   win_size_incrr   c                     t          |          dk    sEt          |d         t          t          f          rt          |d                   dk    s
J d             t	          t
          |           j        |i | dS )r  r   r  z,Invalid window update frame; length is not 4N)r.   r,   r_   r  r   r!  r   r  s      r   r   zH2WindowUpdateFrame.__init__  s     IINN47UCL11 DG!!!9 "!! 	2!4((14B6BBBBBr    )r?   r@   rA   rB   r  r   rp  r  rr  r   rD   rE   s   @r   r!  r!  v  s         G'D
Aq))B//K
C C C C C C C C Cr    r!  c                   j    e Zd ZdZdZdZe ej        dd          iZdZ	 ej
        dg e          gZdS )	H2ContinuationFramez9 H2ContinuationFrame implements the RFC 7540 par6.10
    r  r)   r  r  zHTTP/2 Continuation Framer  N)r?   r@   rA   rB   r  r  rp  r  r  r   r  rt  rr  rO   r    r   r%  r%    sa         G0&0}EEE 'Dvr<88KKKr    r%  DataFrmHdrsFrmPrioFrmRstFrmSetFrmPushFrmPingFrm	GoawayFrmWinFrmContFrm)
r   r*   r)   r  r  r   r   rU   rK   r  c                       e Zd ZdZdZ ej        dd           ej        dded           ej	        d e
            dej        ej        ej        ej        ej        ej        ej        ej        ej        ej        ej        ej        id	 
           ej        ddd           ej        ddd          gZd Zd Z fdZ xZS )H2Framez H2Frame implements the frame structure as defined in RFC 7540 par4.1

    This packet may have a payload (one of the H2FramePayload) or none, in some
    rare cases such as settings acknowledgement)
    zHTTP/2 Framer.   Nrg   r   r  rK   c                 ,    |                      d          S )Nrg   rc  rd  s    r   r   zH2Frame.<lambda>  s    3??6#:#: r    )
depends_onr  r   r*   r  r   c                    t          |          dk    rt          j        S |                     d          }|t          j        k    rDt          j        t          j                 j        |                     d          v rt          S t          S |t          j        k    rt          j        t          j                 j        |                     d          v rDt          j        t          j                 j        |                     d          v rt          S t          S t          j        t          j                 j        |                     d          v rt          S t          S |t          j        k    rt          S |t           j        k    rt           S |t"          j        k    rt"          S |t$          j        k    rDt$          j        t$          j                 j        |                     d          v rt&          S t$          S |t(          j        k    rt(          S |t*          j        k    rt*          S |t,          j        k    rt,          S |t.          j        k    rt.          S t0          j        j        S )a   guess_payload_class returns the Class object to use for parsing a payload
        This function uses the H2Frame.type field value to decide which payload to parse. The implement cannot be  # noqa: E501
        performed using the simple bind_layers helper because sometimes the selection of which Class object to return  # noqa: E501
        also depends on the H2Frame.flags value.

        :param payload:
        :return::
        r   rg   r  )r.   r   	NoPayloadrP  r  r  r  r  shortr  r  r  r  r  r  r  r  r  r  r  r  r  r!  r%  rg  rh  ri  )r   rk  rM  s      r   rl  zH2Frame.guess_payload_class  s    w<<1##V$$### !89?4CSCST[C\C\\\((&&&#N$>?EIYIYZaIbIbbb!'(DEKtO_O_`gOhOhhh77//%n&BCITM]M]^eMfMfff--!!'''""$$$'''"""***!'(:(FGMQUQaQabiQjQjjj//%%###%%%  #+++&&#+++&&{((r    c                     t          | j        t                    r| j        dk    s
J d            t          |          | j        k    s
J d            |d| j                 || j        d         fS )z
        :param str s: the string from which to tell the padding and the payload data apart  # noqa: E501
        :return: (str, str): the padding and the payload data strings
        :raises: AssertionError
        r   zInvalid length: negative len?z0Invalid length: string too short for this lengthN)r,   r.   r/   r   s     r   extract_paddingzH2Frame.extract_padding  sl     $(C(([TX]]]<[]]]1vv!!!#U!!!$(|Qtxyy\))r    c                 $   |                      d          Rt          |          dk     s
J d            t          j        dt          |                    dd         |dd         z   }t	          t
          |                               ||          S )z
        :param str p: the stringified packet
        :param str pay: the stringified payload
        :return: str: the stringified packet and payload, with the packet length field "patched"  # noqa: E501
        :raises: AssertionError
        r.   Ni   z#Invalid length: payload is too longz!Lr*   r  )rP  r.   structpackr   r1  
post_build)r   ppayr   s      r   r<  zH2Frame.post_build  s     E""*s88w''')N'''D#c((++ABB/!ABB%7AWd##..q#666r    )r?   r@   rA   rB   r   rp  X3BytesFieldr  _HTTP2_typesMultiFlagsFieldsetr  r  r  r  r  r  r  r%  r  rr  rl  r8  r<  rD   rE   s   @r   r1  r1    s3        
 DE4((|S99wq!2"N$8&(:(@#_%:!2')<)B3
 ;:		
 		
 		
 	
Aq))Q++K"7) 7) 7)r	* 	* 	*7 7 7 7 7 7 7 7 7r    r1  c                   B    e Zd ZdZdZ ej        dg e          gZd Z	dS )H2Seqz H2Seq is a helper packet that contains several H2Frames and their
    payload. This packet can be used, for instance, while reading manually from
    a TCP socket.
    zHTTP/2 Frame Sequenceframesc                 $    t           j        j        S r   rf  rj  s     r   rl  zH2Seq.guess_payload_class&  r  r    N)
r?   r@   rA   rB   r   rp  r  r1  rr  rl  rO   r    r   rD  rD    sO          #DxW55K) ) ) ) )r    rD  rg   0505249202a20485454502f322e300d0a0d0a534d0d0a0d0ac                   B    e Zd ZdZg dZd Zd Zd Zd ZeZ	d Z
d Zd	S )
HPackHdrEntryz HPackHdrEntry is an entry of the HPackHdrTable helper

    Each HPackHdrEntry instance is a header line (name and value). Names are
    normalized (lowercase), according to RFC 7540 par8.1.2
    )_name_len_valuec                     t          |          dk    sJ |                                | _        || _        dt          | j                  z   t          | j                  z   | _        dS )r  r   r   N)r.   lowerrJ  rL  rK  )r   r   rY   s      r   r   zHPackHdrEntry.__init__M  sV    
 4yy1}}}}ZZ\\
 #dj//)C,<,<<			r    c                     | j         S r   )rJ  r{   s    r   r   zHPackHdrEntry.nameZ  s
    zr    c                     | j         S r   )rL  r{   s    r   rY   zHPackHdrEntry.value^  s
    {r    c                     | j         S )z_ size returns the "length" of the header entry, as defined in
        RFC 7541 par4.1.
        )rK  r{   s    r   r   zHPackHdrEntry.sizeb  s    
 yr    c                     | j                             d          r d                    | j         | j                  S d                    | j         | j                  S )zO __str__ returns the header as it would be formatted in textual format
        :{} {}{}: {})rJ  
startswithr"   rL  r{   s    r   r   zHPackHdrEntry.__str__k  sL     :  %% 	<>>$*dk:::??4:t{;;;r    c                 D    t          |                                           S r   )r	   r   r{   s    r   r   zHPackHdrEntry.__bytes__t  s    DLLNN+++r    N)r?   r@   rA   rB   rC   r   r   rY   r   r   r   r   rO   r    r   rI  rI  E  s         
 ,++I> > >       G< < <, , , , ,r    rI  c                      e Zd ZdZg dZ	 i d edd          d edd          d	 edd
          d edd          d edd          d edd          d edd          d edd          d edd          d edd          d edd          d edd          d  edd!          d" edd#          d$ ed%d          d& ed'd(          d) ed*d          i d+ ed,d          d- ed.d          d/ ed0d          d1 ed2d          d3 ed4d          d5 ed6d          d7 ed8d          d9 ed:d          d; ed<d          d= ed>d          d? ed@d          dA edBd          dC edDd          dE edFd          dG edHd          dI edJd          dK edLd          i dM edNd          dO edPd          dQ edRd          dS edTd          dU edVd          dW edXd          dY edZd          d[ ed\d          d] ed^d          d_ ed`d          da edbd          dc eddd          de edfd          dg edhd          di edjd          dk edld          dm ednd           edod           edpd           edqd           edrd           edsd           edtd           edud           edvd           edwd           edxd          dy
ZdzZed{             Z	dd}Z
d~ Zd Zd ZddZd Zd Zd Zd ZddZed             Zd Zd Zddzd|dd d dfdZdzS )HPackHdrTableaT   HPackHdrTable is a helper class that implements some of the logic
    associated with indexing of headers (read and write operations in this
    "registry". THe HPackHdrTable also implements convenience functions to easily  # noqa: E501
    convert to and from textual representation and binary representation of
    a HTTP/2 requests
    )_dynamic_table_dynamic_table_max_size_dynamic_table_cap_size_regexpr*   z
:authorityrR  r)   z:methodGETr  POSTr  z:path/r   z/index.htmlr   z:schemehttprU   httpsrK   z:status200r  204r   206r   304r   400r   404r   500r   zaccept-charset   zaccept-encodingzgzip, deflate   zaccept-language   zaccept-rangesr   acceptr   zaccess-control-allow-originr   ager   allowr   authorizationr   zcache-controlr   zcontent-dispositionr   zcontent-encodingr   zcontent-languager   zcontent-lengthr   zcontent-locationr   zcontent-ranger   zcontent-typer   cookier   dater   etagr  expectr  expiresr  fromr  hostr  zif-matchr
  zif-modified-sincer  zif-none-matchr  zif-ranger  zif-unmodified-sincer  zlast-modifiedr  link.   location/   zmax-forwards0   zproxy-authenticate1   zproxy-authorization2   r;  3   refererrefreshzretry-afterserverz
set-cookiezstrict-transport-securityztransfer-encodingz
user-agentvaryviazwww-authenticate)
4   5   6   7   8   9   :   ;   <   =   Nc                 8    t          | j                  | _        d S r   )max_static_entries_static_entries_last_idx)r  s    r   init_static_tablezHPackHdrTable.init_static_table  s     (+3+>'?'?$$$r       c                     d| _         t          t          |           j        t          d                    r!t          |                                            ||k    s
J d            g | _        || _        || _        dS )a  
        :param int dynamic_table_max_size: the current maximum size of the dynamic entry table in bytes  # noqa: E501
        :param int dynamic_table_cap_size: the maximum-maximum size of the dynamic entry table in bytes  # noqa: E501
        :raises:s AssertionError
        NzcEINVAL: dynamic_table_max_size too large; expected value is less or equal to dynamic_table_cap_size)r]  r,   rg   r  r  rZ  r[  r\  )r   dynamic_table_max_sizedynamic_table_cap_sizes      r   r   zHPackHdrTable.__init__  s     d4jj94::FF 	+JJ((***%)????q @?? !'=$'=$$$r    c                 ^   |dk    sJ |t          |           j        k    rt|t          |           j        dz   z  }|t          | j                  k    r5t	          d                    |t          | j                                      | j        |         S t          |           j        |         S )a  Gets an element from the header tables (static or dynamic indifferently)

        :param int idx: the index number of the entry to retrieve. If the index
        value is superior to the last index of the static entry table, then the
        dynamic entry type is requested, following the procedure described in
        RFC 7541 par2.3.3
        :return: HPackHdrEntry: the entry defined at this requested index. If the entry does not exist, KeyError is  # noqa: E501
          raised
        :raises: KeyError, AssertionError
        r   r*   z5EINVAL: idx: out-of-bound read: {}; maximum index: {})rg   r  r.   rZ  KeyErrorr"   r  )r   r>  s     r   r   zHPackHdrTable.__getitem__  s     axxxxd4444::6::Cc$-....KRRSVX[\`\oXpXpqq   &s++Dzz)#..r    c                     d|cxk    r| j         k    s$n J d                    | j                               | j        }|| _        || j        k    r|                                  dS dS )a  Resize the dynamic table. If the new size (ns) must be between 0 and
        the cap size. If the new size is lower than the current size of the
        dynamic table, entries are evicted.
        :param int ns: the new size of the dynamic table
        :raises: AssertionError
        r   zEEINVAL: ns: out-of-range value; expected value is in the range [0;{}[N)r\  r"   r[  _reduce_dynamic_table)r   nsold_sizes      r   resizezHPackHdrTable.resize	  s     B6666$666666SZZ[_[wxx 766 /')$d222&&((((( 32r    c                 l    |dk    sJ | j         |k    }|| _         |r|                     |           dS dS )a$  recap changes the maximum size limit of the dynamic table. It also
        proceeds to a resize(), if the new size is lower than the previous one.
        :param int nc: the new cap of the dynamic table (that is the maximum-maximum size)  # noqa: E501
        :raises: AssertionError
        r   N)r\  r  )r   ncrM  s      r   recapzHPackHdrTable.recap	  sM     Qwwww(2-')$ 	 KKOOOOO	 	r    r   c                 2   |dk    sJ t          |           }t          | j                  }|dk    ra||z   | j        k    rWt          | j        d                   }| j                                         |dz  }||z  }|dk    r||z   | j        k    QdS dS dS dS )a  _reduce_dynamic_table evicts entries from the dynamic table until it
        fits in less than the current size limit. The optional parameter,
        new_entry_size, allows the resize to happen so that a new entry of this
        size fits in.
        :param int new_entry_size: if called before adding a new entry, the size of the new entry in bytes (following  # noqa: E501
        the RFC7541 definition of the size of an entry)
        :raises: AssertionError
        r   r  r*   N)r.   rZ  r[  pop)r   new_entry_sizecur_sz
dyn_tbl_szlast_elmt_szs        r   r  z#HPackHdrTable._reduce_dynamic_table"	  s     """"T,--
1nn.!84;W!W!Wt22677L##%%%!OJl"F	 1nn.!84;W!W!W!W!Wnnnn!W!Wr    c                    t          |t                    rd |j        j        D             }n%t          |t                    r|g}nd |D             }|D ]}|j        dk    r-|j                            d                                          }n.t          |j                  }| |         
                                }|j                            d                                          }t          ||          }t          |          }|                     |           || j        k    sJ | j                            d|           dS )a  register adds to this table the instances of
        HPackLitHdrFldWithIncrIndexing provided as parameters.

        A H2Frame with a H2HeadersFrame payload can be provided, as much as a
        python list of HPackHeaders or a single HPackLitHdrFldWithIncrIndexing
        instance.
        :param HPackLitHdrFldWithIncrIndexing|H2Frame|list of HPackHeaders hdrs: the header(s) to register  # noqa: E501
        :raises: AssertionError
        c                 <    g | ]}t          |t                    |S rO   r,   ry  .0hdrs     r   
<listcomp>z*HPackHdrTable.register.<locals>.<listcomp>A	  s(    hhhC
3Hf8g8ghChhhr    c                 <    g | ]}t          |t                    |S rO   r  r  s     r   r  z*HPackHdrTable.register.<locals>.<listcomp>E	  s(    [[[C:c;Y+Z+Z[C[[[r    r   ra  N)r,   r1  rk  r  ry  r  r  rP  r   r/   r   r  rI  r.   r  r[  rZ  r1  )r   r  r  r  r>  r  r<  new_entry_lens           r   registerzHPackHdrTable.register5	  sK    dG$$ 	\hh4<#4hhhDD<== 	\6DD[[4[[[D 	1 	1CyA~~<33F;;BBDD#)nn9>>++11&99@@BBI
 "(I66E  JJM&&}555 D$@@@@@&&q%00005	1 	1r    c                 Z   |                                 }t          |           j                                        D ]!\  }}|                                |k    r|c S "t          | j                  D ]9\  }}|                                |k    rt          |           j        |z   dz   c S :dS )a   get_idx_by_name returns the index of a matching registered header

        This implementation will prefer returning a static entry index whenever
        possible. If multiple matching header name are found in the static
        table, there is insurance that the first entry (lowest index number)
        will be returned.
        If no matching header is found, this method returns None.
        r*   N)rN  rg   r  itemsr   	enumeraterZ  r  )r   r   keyr'   r>  s        r   get_idx_by_namezHPackHdrTable.get_idx_by_namec	  s     zz||T

288:: 	 	HCxxzzT!!


 "!$"566 	E 	EHCxxzzT!!Dzz:S@1DDDD "tr    c                    |                                 }t          |           j                                        D ]9\  }}|                                |k    r|                                |k    r|c S :t          | j                  D ]Q\  }}|                                |k    r4|                                |k    rt          |           j        |z   dz   c S RdS )ad   get_idx_by_name_and_value returns the index of a matching registered
        header

        This implementation will prefer returning a static entry index whenever
        possible. If multiple matching headers are found in the dynamic table,
        the lowest index is returned
        If no matching header is found, this method returns None.
        r*   N)	rN  rg   r  r  r   rY   r  rZ  r  )r   r   rY   r  r'   r>  s         r   get_idx_by_name_and_valuez'HPackHdrTable.get_idx_by_name_and_valuev	  s     zz||T

288:: 	 	HCxxzzT!!ciikkU&:&:


!$"566 	E 	EHCxxzzT!!ciikkU&:&:Dzz:S@1DDDDtr    c                 >    t          d | j        D                       S )zB __len__ returns the summed length of all dynamic entries
        c              3   4   K   | ]}t          |          V  d S r   rZ  )r  r5   s     r   	<genexpr>z(HPackHdrTable.__len__.<locals>.<genexpr>	  s(      77a3q66777777r    )sumrZ  r{   s    r   r   zHPackHdrTable.__len__	  s$     774#6777777r    Tc           	         g }t          |t                    r|j        j        }|D ]}	 t          |t                    r5|                    d                    | |j                                      n0t          |t          t          f          r|j        dk    r | |j                 
                                }n,|j                            d                                          }|                    d          rT|                    d                    ||j                            d                                                               nS|                    d                    ||j                            d                                                               |r*t          |t                    r|                     |           # t"          $ r}t%          |           Y d}~d}~ww xY wd                    |          S )	a%  
        gen_txt_repr returns a "textual" representation of the provided
        headers.
        The output of this function is compatible with the input of
        parse_txt_hdrs.

        :param H2Frame|list of HPackHeaders hdrs: the list of headers to
          convert to textual representation.
        :param bool: whether incremental headers should be added to the dynamic
          table as we generate the text representation
        :return: str: the textual representation of the provided headers
        :raises: AssertionError
        z{}r   ra  rS  rT  rU  N
)r,   r1  rk  r  rx  rc   r"   r  ry  r{  r   r  rP  r   rV  r  r  r  printrd   )r   r  r  lstr  r   es          r   gen_txt_reprzHPackHdrTable.gen_txt_repr	  s    dG$$ 	%<$D 	 	Cc?33 JJt{{4	?;;<<<<21&    yA~~#CI3355"|77??FFHHs++ 

#NN $ # 9 9& A A H H J J     

$OO $ # 9 9& A A H H J J     '
30N O O 'MM#&&&   a yy~~s   F&G
G6G11G6c                     t          |           }t          |          t          |           k    rt          t          |                     S t          |          S )Nra  )r   r.   r]  r   )r&   zss     r   %_optimize_header_length_and_packetifyz3HPackHdrTable._optimize_header_length_and_packetify	  sQ     !__r77c!ff!'9!'<'<====2&&&&r    c           	         |                      ||          }|%t          |          t          | |                   fS |                     |          }|                     |          }|~ |||                    d                                                    rlt          d||          t          t          | |         	                                |                    d                                                              fS  ||          rkt          ||          t          t          | |         	                                |                    d                                                              fS t          ||          t          t          | |         	                                |                    d                                                              fS |                     |          } ||                    d                                          |                    d                                                    rzt          dd||          t          t          |                    d                                          |                    d                                                              fS  ||                    d                                                    ryt          d||	          t          t          |                    d                                          |                    d                                                              fS t          d||	          t          t          |                    d                                          |                    d                                                              fS )
a   _convert_a_header_to_a_h2_header builds a HPackHeaders from a header
        name and a value. It returns a HPackIndexedHdr whenever possible. If not,  # noqa: E501
        it returns a HPackLitHdrFldWithoutIndexing or a
        HPackLitHdrFldWithIncrIndexing, based on the should_index callback.
        HPackLitHdrFldWithoutIndexing is forced if the is_sensitive callback
        returns True and its never_index bit is set.
        N)r  ra  r*   )r  r  r  )r  r  r   )r  r  r  r  )r  r  r  )r  rx  r.   r  r  rP  r   r{  rI  r   ry  )r   r  r  is_sensitiveshould_indexr>  
_hdr_value	_hdr_names           r    _convert_a_header_to_a_h2_headerz.HPackHdrTable._convert_a_header_to_a_h2_header	  s	    ,,XyAA?"---s49~~== ??	JJ
 ""8,,?|&&v..5577   5 !(   !S	(("..v66==??  		 	 |H%% 	5(   !S	(("..v66==??    1$   INN$$**62299;;    >>xHH	<!!&))0022""6**1133
 
 	 1"$	  
 ))&1188::**62299;;  
 
 <	--f55<<>>?? 
	1"$   ))&1188::**62299;;  		 	 - 
 
 
 %%f--4466&&v..5577 
 
		
 		
r    c                    | j         t          j        d          | _         |                                }| j                             |          }|%t          |                                          dk    rdS |                    d          d|                    d          z   }n|                    d          }t          |	                                          t          |                    d                    fS )Ns*   ^(?::([a-z\-0-9]+)|([a-z\-0-9]+):)\s+(.+)$r  )NNr*      :r)   )
r]  recompilerstripmatchr.   groupsgroupr   rN  )r   linehdr_linegrpr  s        r   _parse_header_linez HPackHdrTable._parse_header_line*
  s     <:&TUUDL;;==l  **;#cjjll++q00:99Q<<#ciill*HHyy||H))**Iciill,C,CCCr    c                     dS NFrO   )nvs     r   r   zHPackHdrTable.<lambda>B
  s     r    c                     dS r  rO   r   s    r   r   zHPackHdrTable.<lambda>C
  s    e r    c	                 r   t          t          |t                    r|                                n|          }	t	          t          t                                          }
t                      }t                      }d}|	D ]t}| 	                    |          \  }}|| 
                    ||||          \  }}t	          t          |                    }|r*t          |t                    r|                     |           ||
z   |k    s|dk    r(||k    r"t          d                    |                    |t	          t          |                    |
z   |z   k     s|dk    r|||z   k     rvt                      }t          |t                    r|s|                    d           |j                            t          ||          |z             t'                      }d}|j        }||z  }||z  }vdh}t          |t                    r|s|                    d           |j                            t          ||          |z             |rt	          t          t+                                          }t          |          }	|	                    ||z
  |
z
            }|r|	                    ||z
  |
z
            }t                      }t	          |          dk    r|                    d           |j                            t          ||          t+          |          z             |}||S )a  
        parse_txt_hdrs parses headers expressed in text and converts them
        into a series of H2Frames with the "correct" flags. A body can be
        provided in which case, the data frames are added, bearing the End
        Stream flag, instead of the H2HeadersFrame/H2ContinuationFrame.
        The generated frames may respect max_frm_sz (SETTINGS_MAX_FRAME_SIZE)
        and max_hdr_lst_sz (SETTINGS_MAX_HEADER_LIST_SIZE) if provided.
        The headers are split into multiple headers fragment (and H2Frames)
        to respect these limits. Also, a callback can be provided to tell if
        a header should be never indexed (sensitive headers, such as cookies),
        and another callback say if the header should be registered into the
        index table at all.
        For an header to be registered, the is_sensitive callback must return
        False AND the should_index callback should return True. This is the
        default behavior.

        :param str s: the string to parse for headers
        :param int stream_id: the stream id to use in the generated H2Frames
        :param str/None body: the eventual body of the request, that is added
          to the generated frames
        :param int max_frm_sz: the maximum frame size. This is used to split
          the headers and data frames according to the maximum frame size
          negotiated for this connection.
        :param int max_hdr_lst_sz: the maximum size of a "header fragment" as
          defined in RFC7540
        :param callable is_sensitive: callback that returns True if the
          provided header is sensible and must be stored in a header packet
          requesting this header never to be indexed
        :param callable should_index: callback that returns True if the
          provided header should be stored in a header packet requesting
          indexation in the dynamic header table.
        :param bool register: whether to register new headers with incremental
          indexing as we parse them
        :raises: Exception
        r   NzHeader too long: {}r  )r  r  r  r  )r   r,   r  encoder.   r   r1  rD  r  r  r  ry  r  	Exceptionr"   rB  addrE  rc   r%  r  r  read)r   r&   r  body
max_frm_szmax_hdr_lst_szr  r  r  siobase_frm_lenr`   cur_frm
cur_hdr_szr  r  r  new_hdrnew_hdr_lennew_hdr_bin_lenr  hdr_listbase_data_frm_lenfrgmt	nxt_frgmts                            r   parse_txt_hdrszHPackHdrTable.parse_txt_hdrs<
  s=   ^ Jq#$6$6=ahhjjjA>>3wyy>>**gg ""
  %	& %	&H"&"9"9("C"CHi#'#H#H)\<$ $ G[ "#g,,//O 'Jw0NOO 'g&&&  ,.;;#q(([>-I-I 5 < <X F FGGGSW..=KKK"a''"Z+%=== g~66 $t $IIdOOO
!!'IU"K"K"Kg"UVVV-//
|HH+%JJg~.. 	t 	IIdOOO
'IUCCCgMNNN 	" #C$6$6 7 7$--CHHZ*;;lJKKE "HHZ2C%Cl%RSS	y>>Q&&IIdOOO
!!iu===QV@W@W@WW   "  " 
r    )r  r  )r   )T)r?   r@   rA   rB   rC   rI  r  r  rC  r  r   r   r  r  r  r  r  r  r   r  r}   r  r  r  r  rO   r    r   rY  rY  x  s6          I	>	==r**>	==E**> 	
==F++> 	
==#&&	>
 	
==-00> 	
==F++> 	
==G,,> 	
==E**> 	
==E**> 	MM)U++> 	MM)U++> 	MM)U++> 	MM)U++> 	MM)U++> 	MM*B//>  	MM+_==!>" 	MM+R00#> >$ 	MM/2..%>& 	MM(B'''>( 	MM7<<)>* 	MM%$$+>, 	MM'2&&->. 	MM/2../>0 	MM/2..1>2 	MM/443>4 	MM,b115>6 	MM,b117>8 	MM*B//9>: 	MM,b11;>< 	MM/2..=>> 	MM."--?>@ 	MM(B''A>B 	MM&"%%C>D 	MM&"%%E> > >F 	MM(B''G>H 	MM)R((I>J 	MM&"%%K>L 	MM&"%%M>N 	MM*b))O>P 	MM-r22Q>R 	MM/2..S>T 	MM*b))U>V 	MM/44W>X 	MM/2..Y>Z 	MM&"%%[>\ 	MM*b))]>^ 	MM."--_>` 	MM.33a>b 	MM/44c>d 	MM'2&&e>f 	MM)R((g> >h M)R((M-,,M(B''M,++M5r::M-r22M,++M&"%%M%$$M,b11{> > >OD  $@ @ [@> > > >$/ / /,) ) )    # # # #&,1 ,1 ,1\  &  &8 8 82 2 2 2h ' ' \']
 ]
 ]
~D D D( "# "&&'$6$6$3O $q q q q q qr    rY  )TrB   r   r  ior   r:  scapy.compatr   r   r   r   r   r	   typingr
   r   r   r   r   r   r   r   scapy.base_classesr   scapy.fieldsrp  scapy.packetr   scapy.configrg  scapy.volatilery   scapy.errorrV   r  r   FieldrG   r   r   ABCMetar   r   objectr   r   r  r   r   rE  r   r]  rt  rx  ry  r{  rz  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r!  r%  r@  r1  rD  bind_layersr  H2_CLIENT_CONNECTION_PREFACErI  rY  rO   r    r   <module>r      s
    


 				        J J J J J J J J J J J J J J J J
	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 0 / / / / /                   ! ! ! ! ! !      rG rG rG rG rG rG rG rGjy# y# y# y# y#6< y# y# y#x	B8 B8 B8 B8 B8' B8 B8 B8JN N N N N, N N Nj    ES[    $    .   .    &   
$8 $8 $8 $8 $8& $8 $8 $8N    y   L" L" L" L" L"( L" L" L"^c& c& c& c& c&v| c& c& c&T@ @ @ @ @V] @ @ @@) ) ) ) )6= ) ) )6    l       \       L   (    \       V]       .   $- - - - - - - -d    ^       +   2- - - - -1 - - -`    3   $9 9 9 9 9#9 9 9 9|	 	 	 	 	n 	 	 	% % % % %6 % % %T    >   ) ) ) ) ) ) ) )8!? !? !? !? !?n !? !? !?L       (4 4 4 4 41 4 4 4r; ; ; ; ;. ; ; ;<    N    C C C C C. C C C6    .   $  i7 i7 i7 i7 i7fm i7 i7 i7X) ) ) ) )FM ) ) )  7K&+2E)F G G G  7-8K/L M M M  7NV^5K,L M M M  706>;Q2R S S S  72V^=S4T U U U  786>CY:Z [ [ [  7Ofo6M-N O O O  7L6<3G*H I I I  7Ofo6M-N O O O  7K&+2E)F G G G  7.9K9S0T U U U  74v?W?_6` a a a  7MFM4I+J K K K  7/&:M:U1V W W W  7/&:M:U1V W W W
  )y)[\\ 0, 0, 0, 0, 0,E 0, 0, 0,fu u u u uE u u u u ur    