Home | History | Annotate | Download | only in contrib
      1 #############################################################################
      2 ##                                                                         ##
      3 ## http2.py --- HTTP/2 support for Scapy                                   ##
      4 ##              see RFC7540 and RFC7541                                    ##
      5 ##              for more informations                                      ##
      6 ##                                                                         ##
      7 ## Copyright (C) 2016  Florian Maury <florian.maury (at] ssi.gouv.fr>           ##
      8 ##                                                                         ##
      9 ## This file is part of Scapy                                              ##
     10 ## Scapy is free software: you can redistribute it and/or modify it        ##
     11 ## under the terms of the GNU General Public License version 2 as          ##
     12 ## published by the Free Software Foundation.                              ##
     13 ##                                                                         ##
     14 ## This program is distributed in the hope that it will be useful, but     ##
     15 ## WITHOUT ANY WARRANTY; without even the implied warranty of              ##
     16 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU       ##
     17 ## General Public License for more details.                                ##
     18 ##                                                                         ##
     19 #############################################################################
     20 """http2 Module
     21 Implements packets and fields required to encode/decode HTTP/2 Frames
     22 and HPack encoded headers
     23 
     24 scapy.contrib.status=loads
     25 scapy.contrib.description=HTTP/2 (RFC 7540, RFC 7541)
     26 """
     27 
     28 from __future__ import absolute_import
     29 from __future__ import print_function
     30 import abc
     31 import types
     32 import re
     33 from io import BytesIO
     34 import struct
     35 import scapy.modules.six as six
     36 from scapy.compat import *
     37 from scapy.modules.six.moves import range
     38 
     39 # Only required if using mypy-lang for static typing
     40 # Most symbols are used in mypy-interpreted "comments".
     41 # Sized must be one of the superclasses of a class implementing __len__
     42 try:
     43     from typing import Optional, List, Union, Callable, Any, Tuple, Sized
     44 except ImportError:
     45     class Sized(object): pass
     46 
     47 import scapy.fields as fields
     48 import scapy.packet as packet
     49 import scapy.config as config
     50 import scapy.base_classes as base_classes
     51 import scapy.volatile as volatile
     52 import scapy.error as error
     53 
     54 ########################################################################################################################
     55 ################################################ HPACK Integer Fields ##################################################
     56 ########################################################################################################################
     57 
     58 class HPackMagicBitField(fields.BitField):
     59     """ HPackMagicBitField is a BitField variant that cannot be assigned another
     60     value than the default one. This field must not be used where there is
     61     potential for fuzzing. OTOH, this field makes sense (for instance, if the
     62     magic bits are used by a dispatcher to select the payload class)
     63     """
     64 
     65     __slots__ = ['_magic']
     66 
     67     def __init__(self, name, default, size):
     68         # type: (str, int, int) -> None
     69         """
     70         @param str name: this field instance name.
     71         @param int default: this field only valid value.
     72         @param int size: this bitfield bitlength.
     73         @return None
     74         @raise AssertionError
     75         """
     76         assert(default >= 0)
     77         # size can be negative if encoding is little-endian (see rev property of bitfields)
     78         assert(size != 0)
     79         self._magic = default
     80         super(HPackMagicBitField, self).__init__(name, default, size)
     81 
     82     def addfield(self, pkt, s, val):
     83         # type: (Optional[packet.Packet], Union[str, Tuple[str, int, int]], int) -> Union[str, Tuple[str, int, int]]
     84         """
     85         @param packet.Packet|None pkt: the packet instance containing this field instance; probably unused.
     86         @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
     87           number of bits already generated and the generated value so far.
     88         @param int val: unused; must be equal to default value
     89         @return str|(str, int, long): the s string extended with this field machine representation
     90         @raise AssertionError
     91         """
     92         assert val == self._magic, 'val parameter must value {}; received: {}'.format(self._magic, val)
     93         return super(HPackMagicBitField, self).addfield(pkt, s, self._magic)
     94 
     95     def getfield(self, pkt, s):
     96         # type: (Optional[packet.Packet], Union[str, Tuple[str, int]]) -> Tuple[Union[Tuple[str, int], str], int]
     97         """
     98         @param packet.Packet|None pkt: the packet instance containing this field instance; probably unused.
     99         @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
    100           bits already consumed by previous bitfield-compatible fields.
    101         @return (str|(str, int), int): Returns the remaining string and the parsed value. May return a tuple if there
    102           are remaining bits to parse in the first byte. Returned value is equal to default value
    103         @raise AssertionError
    104         """
    105         r = super(HPackMagicBitField, self).getfield(pkt, s)
    106         assert (
    107             isinstance(r, tuple)
    108             and len(r) == 2
    109             and isinstance(r[1], six.integer_types)
    110         ), 'Second element of BitField.getfield return value expected to be an int or a long; API change detected'
    111         assert r[1] == self._magic, 'Invalid value parsed from s; error in class guessing detected!'
    112         return r
    113 
    114     def h2i(self, pkt, x):
    115         # type: (Optional[packet.Packet], int) -> int
    116         """
    117         @param packet.Packet|None pkt: the packet instance containing this field instance; probably unused
    118         @param int x: unused; must be equal to default value
    119         @return int; default value
    120         @raise AssertionError
    121         """
    122         assert x == self._magic, \
    123             'EINVAL: x: This field is magic. Do not attempt to modify it. Expected value: {}'.format(self._magic)
    124         return super(HPackMagicBitField, self).h2i(pkt, self._magic)
    125 
    126     def i2h(self, pkt, x):
    127         # type: (Optional[packet.Packet], int) -> int
    128         """
    129         @param packet.Packet|None pkt: the packet instance containing this field instance; probably unused
    130         @param int x: unused; must be equal to default value
    131         @return int; default value
    132         @raise AssertionError
    133         """
    134         assert x == self._magic, \
    135             'EINVAL: x: This field is magic. Do not attempt to modify it. Expected value: {}'.format(self._magic)
    136         return super(HPackMagicBitField, self).i2h(pkt, self._magic)
    137 
    138     def m2i(self, pkt, x):
    139         # type: (Optional[packet.Packet], int) -> int
    140         """
    141         @param packet.Packet|None pkt: the packet instance containing this field instance; probably unused
    142         @param int x: must be the machine representatino of the default value
    143         @return int; default value
    144         @raise AssertionError
    145         """
    146         r = super(HPackMagicBitField, self).m2i(pkt, x)
    147         assert r == self._magic, 'Invalid value parsed from m2i; error in class guessing detected!'
    148         return r
    149 
    150     def i2m(self, pkt, x):
    151         # type: (Optional[packet.Packet], int) -> int
    152         """
    153         @param packet.Packet|None pkt: the packet instance containing this field instance; probably unused
    154         @param int x: unused; must be equal to default value
    155         @return int; default value
    156         @raise AssertionError
    157         """
    158         assert x == self._magic, \
    159             'EINVAL: x: This field is magic. Do not attempt to modify it. Expected value: {}'.format(self._magic)
    160         return super(HPackMagicBitField, self).i2m(pkt, self._magic)
    161 
    162     def any2i(self, pkt, x):
    163         # type: (Optional[packet.Packet], int) -> int
    164         """
    165         @param packet.Packet|None pkt: the packet instance containing this field instance; probably unused
    166         @param int x: unused; must be equal to default value
    167         @return int; default value
    168         @raise AssertionError
    169         """
    170         assert x == self._magic, \
    171             'EINVAL: x: This field is magic. Do not attempt to modify it. Expected value: {}'.format(self._magic)
    172         return super(HPackMagicBitField, self).any2i(pkt, self._magic)
    173 
    174 
    175 class AbstractUVarIntField(fields.Field):
    176     """AbstractUVarIntField represents an integer as defined in RFC7541
    177     """
    178 
    179     __slots__ = ['_max_value', 'size', 'rev']
    180     """
    181     :var int size: the bit length of the prefix of this AbstractUVarIntField. It
    182       represents the complement of the number of MSB that are used in the
    183       current byte for other purposes by some other BitFields
    184     :var int _max_value: the maximum value that can be stored in the
    185       sole prefix. If the integer equals or exceeds this value, the max prefix
    186       value is assigned to the size first bits and the multibyte representation
    187       is used
    188     :var bool rev: is a fake property, also emulated for the sake of
    189       compatibility with Bitfields
    190     """
    191 
    192     def __init__(self, name, default, size):
    193         # type: (str, Optional[int], int) -> None
    194         """
    195         @param str name: the name of this field instance
    196         @param int|None default: positive, null or None default value for this field instance.
    197         @param int size: the number of bits to consider in the first byte. Valid range is ]0;8]
    198         @return None
    199         @raise AssertionError
    200         """
    201         assert(default is None or (isinstance(default, six.integer_types) and default >= 0))
    202         assert(0 < size <= 8)
    203         super(AbstractUVarIntField, self).__init__(name, default)
    204         self.size = size
    205         self._max_value = (1 << self.size) - 1
    206 
    207         # Configuring the fake property that is useless for this class but that is
    208         # expected from BitFields
    209         self.rev = False
    210 
    211     def h2i(self, pkt, x):
    212         # type: (Optional[packet.Packet], Optional[int]) -> Optional[int]
    213         """
    214         @param packet.Packet|None pkt: unused.
    215         @param int|None x: the value to convert.
    216         @return int|None: the converted value.
    217         @raise AssertionError
    218         """
    219         assert(not isinstance(x, six.integer_types) or x >= 0)
    220         return x
    221 
    222     def i2h(self, pkt, x):
    223         # type: (Optional[packet.Packet], Optional[int]) -> Optional[int]
    224         """
    225         @param packet.Packet|None pkt: unused.
    226         @param int|None x: the value to convert.
    227         @return: int|None: the converted value.
    228         """
    229         return x
    230 
    231     def _detect_multi_byte(self, fb):
    232         # type: (str) -> bool
    233         """ _detect_multi_byte returns whether the AbstractUVarIntField is represented on
    234           multiple bytes or not.
    235 
    236           A multibyte representation is indicated by all of the first size bits being set
    237 
    238         @param str fb: first byte, as a character.
    239         @return bool: True if multibyte repr detected, else False.
    240         @raise AssertionError
    241         """
    242         assert(isinstance(fb, int) or len(fb) == 1)
    243         return (orb(fb) & self._max_value) == self._max_value
    244 
    245     def _parse_multi_byte(self, s):
    246         # type: (str) -> int
    247         """ _parse_multi_byte parses x as a multibyte representation to get the
    248           int value of this AbstractUVarIntField.
    249 
    250         @param str s: the multibyte string to parse.
    251         @return int: The parsed int value represented by this AbstractUVarIntField.
    252         @raise: AssertionError
    253         @raise: Scapy_Exception if the input value encodes an integer larger than 1<<64
    254         """
    255 
    256         assert(len(s) >= 2)
    257 
    258         l = len(s)
    259 
    260         value = 0
    261         i = 1
    262         byte = orb(s[i])
    263         # For CPU sake, stops at an arbitrary large number!
    264         max_value = 1 << 64
    265         # As long as the MSG is set, an another byte must be read
    266         while byte & 0x80:
    267             value += (byte ^ 0x80) << (7 * (i - 1))
    268             if value > max_value:
    269                 raise error.Scapy_Exception(
    270                     'out-of-bound value: the string encodes a value that is too large (>2^{64}): {}'.format(value)
    271                 )
    272             i += 1
    273             assert i < l, 'EINVAL: x: out-of-bound read: the string ends before the AbstractUVarIntField!'
    274             byte = orb(s[i])
    275         value += byte << (7 * (i - 1))
    276         value += self._max_value
    277 
    278         assert(value >= 0)
    279         return value
    280 
    281     def m2i(self, pkt, x):
    282         # type: (Optional[packet.Packet], Union[str, Tuple[str, int]]) -> int
    283         """
    284           A tuple is expected for the "x" param only if "size" is different than 8. If a tuple is received, some bits
    285           were consumed by another field. This field consumes the remaining bits, therefore the int of the tuple must
    286           equal "size".
    287 
    288         @param packet.Packet|None pkt: unused.
    289         @param str|(str, int) x: the string to convert. If bits were consumed by a previous bitfield-compatible field.
    290         @raise AssertionError
    291         """
    292         assert(isinstance(x, bytes) or (isinstance(x, tuple) and x[1] >= 0))
    293 
    294         if isinstance(x, tuple):
    295             assert (8 - x[1]) == self.size, 'EINVAL: x: not enough bits remaining in current byte to read the prefix'
    296             val = x[0]
    297         else:
    298             assert isinstance(x, bytes) and self.size == 8, 'EINVAL: x: tuple expected when prefix_len is not a full byte'
    299             val = x
    300 
    301         if self._detect_multi_byte(val[0]):
    302             ret = self._parse_multi_byte(val)
    303         else:
    304             ret = orb(val[0]) & self._max_value
    305 
    306         assert(ret >= 0)
    307         return ret
    308 
    309     def i2m(self, pkt, x):
    310         # type: (Optional[packet.Packet], int) -> str
    311         """
    312         @param packet.Packet|None pkt: unused.
    313         @param int x: the value to convert.
    314         @return str: the converted value.
    315         @raise AssertionError
    316         """
    317         assert(x >= 0)
    318 
    319         if x < self._max_value:
    320             return chb(x)
    321         else:
    322             # The sl list join is a performance trick, because string
    323             # concatenation is not efficient with Python immutable strings
    324             sl = [chb(self._max_value)]
    325             x -= self._max_value
    326             while x >= 0x80:
    327                 sl.append(chb(0x80 | (x & 0x7F)))
    328                 x >>= 7
    329             sl.append(chb(x))
    330             return b''.join(sl)
    331 
    332     def any2i(self, pkt, x):
    333         # type: (Optional[packet.Packet], Union[None, str, int]) -> Optional[int]
    334         """
    335           A "x" value as a string is parsed as a binary encoding of a UVarInt. An int is considered an internal value.
    336           None is returned as is.
    337 
    338         @param packet.Packet|None pkt: the packet containing this field; probably unused.
    339         @param str|int|None x: the value to convert.
    340         @return int|None: the converted value.
    341         @raise AssertionError
    342         """
    343         if isinstance(x, type(None)):
    344             return x
    345         if isinstance(x, six.integer_types):
    346             assert(x >= 0)
    347             ret = self.h2i(pkt, x)
    348             assert(isinstance(ret, six.integer_types) and ret >= 0)
    349             return ret
    350         elif isinstance(x, bytes):
    351             ret = self.m2i(pkt, x)
    352             assert (isinstance(ret, six.integer_types) and ret >= 0)
    353             return ret
    354         assert False, 'EINVAL: x: No idea what the parameter format is'
    355 
    356     def i2repr(self, pkt, x):
    357         # type: (Optional[packet.Packet], Optional[int]) -> str
    358         """
    359         @param packet.Packet|None pkt: probably unused.
    360         @param x: int|None: the positive, null or none value to convert.
    361         @return str: the representation of the value.
    362         """
    363         return repr(self.i2h(pkt, x))
    364 
    365     def addfield(self, pkt, s, val):
    366         # type: (Optional[packet.Packet], Union[str, Tuple[str, int, int]], int) -> str
    367         """ An AbstractUVarIntField prefix always consumes the remaining bits
    368           of a BitField;if no current BitField is in use (no tuple in
    369           entry) then the prefix length is 8 bits and the whole byte is to
    370           be consumed
    371         @param packet.Packet|None pkt: the packet containing this field. Probably unused.
    372         @param str|(str, int, long) s: the string to append this field to. A tuple indicates that some bits were already
    373           generated by another bitfield-compatible field. This MUST be the case if "size" is not 8. The int is the
    374           number of bits already generated in the first byte of the str. The long is the value that was generated by the
    375           previous bitfield-compatible fields.
    376         @param int val: the positive or null value to be added.
    377         @return str: s concatenated with the machine representation of this field.
    378         @raise AssertionError
    379         """
    380         assert(val >= 0)
    381         if isinstance(s, bytes):
    382             assert self.size == 8, 'EINVAL: s: tuple expected when prefix_len is not a full byte'
    383             return s + self.i2m(pkt, val)
    384 
    385         # s is a tuple
    386         #assert(s[1] >= 0)
    387         #assert(s[2] >= 0)
    388         #assert (8 - s[1]) == self.size, 'EINVAL: s: not enough bits remaining in current byte to read the prefix'
    389 
    390         if val >= self._max_value:
    391             return s[0] + chb((s[2] << self.size) + self._max_value) + self.i2m(pkt, val)[1:]
    392         # This AbstractUVarIntField is only one byte long; setting the prefix value
    393         # and appending the resulting byte to the string
    394         return chb(s[0]) + chb((s[2] << self.size) + orb(self.i2m(pkt, val)))
    395 
    396     @staticmethod
    397     def _detect_bytelen_from_str(s):
    398         # type: (str) -> int
    399         """ _detect_bytelen_from_str returns the length of the machine
    400           representation of an AbstractUVarIntField starting at the beginning
    401           of s and which is assumed to expand over multiple bytes
    402           (value > _max_prefix_value).
    403 
    404         @param str s: the string to parse. It is assumed that it is a multibyte int.
    405         @return The bytelength of the AbstractUVarIntField.
    406         @raise AssertionError
    407         """
    408         assert(len(s) >= 2)
    409         l = len(s)
    410 
    411         i = 1
    412         while orb(s[i]) & 0x80 > 0:
    413             i += 1
    414             assert i < l, 'EINVAL: s: out-of-bound read: unfinished AbstractUVarIntField detected'
    415         ret = i + 1
    416 
    417         assert(ret >= 0)
    418         return ret
    419 
    420     def i2len(self, pkt, x):
    421         # type: (Optional[packet.Packet], int) -> int
    422         """
    423         @param packet.Packet|None pkt: unused.
    424         @param int x: the positive or null value whose binary size if requested.
    425         @raise AssertionError
    426         """
    427         assert(x >= 0)
    428         if x < self._max_value:
    429             return 1
    430 
    431         # x is expressed over multiple bytes
    432         x -= self._max_value
    433         i = 1
    434         if x == 0:
    435             i += 1
    436         while x > 0:
    437             x >>= 7
    438             i += 1
    439 
    440         ret = i
    441         assert(ret >= 0)
    442         return ret
    443 
    444     def getfield(self, pkt, s):
    445         # type: (Optional[packet.Packet], Union[str, Tuple[str, int]]) -> Tuple[str, int]
    446         """
    447         @param packet.Packet|None pkt: the packet instance containing this field; probably unused.
    448         @param str|(str, int) s: the input value to get this field value from. If size is 8, s is a string, else
    449         it is a tuple containing the value and an int indicating the number of bits already consumed in the first byte
    450         of the str. The number of remaining bits to consume in the first byte must be equal to "size".
    451         @return (str, int): the remaining bytes of s and the parsed value.
    452         @raise AssertionError
    453         """
    454         if isinstance(s, tuple):
    455             assert(len(s) == 2)
    456             temp = s  # type: Tuple[str, int]
    457             ts, ti = temp
    458             assert(ti >= 0)
    459             assert 8 - ti == self.size, 'EINVAL: s: not enough bits remaining in current byte to read the prefix'
    460             val = ts
    461         else:
    462             assert isinstance(s, bytes) and self.size == 8, 'EINVAL: s: tuple expected when prefix_len is not a full byte'
    463             val = s
    464 
    465         if self._detect_multi_byte(val[0]):
    466             l = self._detect_bytelen_from_str(val)
    467         else:
    468             l = 1
    469 
    470         ret = val[l:], self.m2i(pkt, s)
    471         assert(ret[1] >= 0)
    472         return ret
    473 
    474     def randval(self):
    475         # type: () -> volatile.VolatileValue
    476         """
    477         @return volatile.VolatileValue: a volatile value for this field "long"-compatible internal value.
    478         """
    479         return volatile.RandLong()
    480 
    481 
    482 class UVarIntField(AbstractUVarIntField):
    483     def __init__(self, name, default, size):
    484         # type: (str, int, int) -> None
    485         """
    486         @param str name: the name of this field instance.
    487         @param default: the default value for this field instance. default must be positive or null.
    488         @raise AssertionError
    489         """
    490         assert(default >= 0)
    491         assert(0 < size <= 8)
    492 
    493         super(UVarIntField, self).__init__(name, default, size)
    494         self.size = size
    495         self._max_value = (1 << self.size) - 1
    496 
    497         # Configuring the fake property that is useless for this class but that is
    498         # expected from BitFields
    499         self.rev = False
    500 
    501     def h2i(self, pkt, x):
    502         # type: (Optional[packet.Packet], int) -> int
    503         """ h2i is overloaded to restrict the acceptable x values (not None)
    504 
    505         @param packet.Packet|None pkt: the packet instance containing this field instance; probably unused.
    506         @param int x: the value to convert.
    507         @return int: the converted value.
    508         @raise AssertionError
    509         """
    510         ret = super(UVarIntField, self).h2i(pkt, x)
    511         assert(not isinstance(ret, type(None)) and ret >= 0)
    512         return ret
    513 
    514     def i2h(self, pkt, x):
    515         # type: (Optional[packet.Packet], int) -> int
    516         """ i2h is overloaded to restrict the acceptable x values (not None)
    517 
    518         @param packet.Packet|None pkt: the packet instance containing this field instance; probably unused.
    519         @param int x: the value to convert.
    520         @return int: the converted value.
    521         @raise AssertionError
    522         """
    523         ret = super(UVarIntField, self).i2h(pkt, x)
    524         assert(not isinstance(ret, type(None)) and ret >= 0)
    525         return ret
    526 
    527     def any2i(self, pkt, x):
    528         # type: (Optional[packet.Packet], Union[str, int]) -> int
    529         """ any2i is overloaded to restrict the acceptable x values (not None)
    530 
    531         @param packet.Packet|None pkt: the packet instance containing this field instance; probably unused.
    532         @param str|int x: the value to convert.
    533         @return int: the converted value.
    534         @raise AssertionError
    535         """
    536         ret = super(UVarIntField, self).any2i(pkt, x)
    537         assert(not isinstance(ret, type(None)) and ret >= 0)
    538         return ret
    539 
    540     def i2repr(self, pkt, x):
    541         # type: (Optional[packet.Packet], int) -> str
    542         """ i2repr is overloaded to restrict the acceptable x values (not None)
    543 
    544         @param packet.Packet|None pkt: the packet instance containing this field instance; probably unused.
    545         @param int x: the value to convert.
    546         @return str: the converted value.
    547         """
    548         return super(UVarIntField, self).i2repr(pkt, x)
    549 
    550 
    551 class FieldUVarLenField(AbstractUVarIntField):
    552     __slots__ = ['_length_of', '_adjust']
    553 
    554     def __init__(self, name, default, size, length_of, adjust=lambda x: x):
    555         # type: (str, Optional[int], int, str, Callable[[int], int]) -> None
    556         """ Initializes a FieldUVarLenField
    557 
    558         @param str name: The name of this field instance.
    559         @param int|None default: the default value of this field instance.
    560         @param int size: the number of bits that are occupied by this field in the first byte of a binary string.
    561           size must be in the range ]0;8].
    562         @param str length_of: The name of the field this field value is measuring/representing.
    563         @param callable adjust: A function that modifies the value computed from the "length_of" field.
    564 
    565         adjust can be used for instance to add a constant to the length_of field
    566          length. For instance, let's say that i2len of the length_of field
    567          returns 2. If adjust is lambda x: x+1 In that case, this field will
    568          value 3 at build time.
    569         @return None
    570         @raise AssertionError
    571         """
    572         assert(default is None or default >= 0)
    573         assert(0 < size <= 8)
    574 
    575         super(FieldUVarLenField, self).__init__(name, default, size)
    576         self._length_of = length_of
    577         self._adjust = adjust
    578 
    579     def addfield(self, pkt, s, val):
    580         # type: (Optional[packet.Packet], Union[str, Tuple[str, int, int]], Optional[int]) -> str
    581         """
    582         @param packet.Packet|None pkt: the packet instance containing this field instance. This parameter must not be
    583           None if the val parameter is.
    584         @param str|(str, int, long) s: the string to append this field to. A tuple indicates that some bits were already
    585           generated by another bitfield-compatible field. This MUST be the case if "size" is not 8. The int is the
    586           number of bits already generated in the first byte of the str. The long is the value that was generated by the
    587           previous bitfield-compatible fields.
    588         @param int|None val: the positive or null value to be added. If None, the value is computed from pkt.
    589         @return str: s concatenated with the machine representation of this field.
    590         @raise AssertionError
    591         """
    592         if val is None:
    593             assert isinstance(pkt, packet.Packet), \
    594                 'EINVAL: pkt: Packet expected when val is None; received {}'.format(type(pkt))
    595             val = self._compute_value(pkt)
    596         return super(FieldUVarLenField, self).addfield(pkt, s, val)
    597 
    598     def i2m(self, pkt, x):
    599         # type: (Optional[packet.Packet], Optional[int]) -> str
    600         """
    601         @param packet.Packet|None pkt: the packet instance containing this field instance. This parameter must not be
    602           None if the x parameter is.
    603         @param int|None x: the positive or null value to be added. If None, the value is computed from pkt.
    604         @return str
    605         @raise AssertionError
    606         """
    607         if x is None:
    608             assert isinstance(pkt, packet.Packet), \
    609                 'EINVAL: pkt: Packet expected when x is None; received {}'.format(type(pkt))
    610             x = self._compute_value(pkt)
    611         return super(FieldUVarLenField, self).i2m(pkt, x)
    612 
    613     def _compute_value(self, pkt):
    614         # type: (packet.Packet) -> int
    615         """ Computes the value of this field based on the provided packet and
    616         the length_of field and the adjust callback
    617 
    618         @param packet.Packet pkt: the packet from which is computed this field value.
    619         @return int: the computed value for this field.
    620         @raise KeyError: the packet nor its payload do not contain an attribute
    621           with the length_of name.
    622         @raise AssertionError
    623         @raise KeyError if _length_of is not one of pkt fields
    624         """
    625         fld, fval = pkt.getfield_and_val(self._length_of)
    626         val = fld.i2len(pkt, fval)
    627         ret = self._adjust(val)
    628         assert(ret >= 0)
    629         return ret
    630 
    631 ########################################################################################################################
    632 ################################################ HPACK String Fields ###################################################
    633 ########################################################################################################################
    634 
    635 class HPackStringsInterface(six.with_metaclass(abc.ABCMeta, Sized)):
    636     @abc.abstractmethod
    637     def __str__(self): pass
    638 
    639     def __bytes__(self):
    640         r = self.__str__()
    641         return r if isinstance(r, bytes) else raw(r)
    642 
    643     @abc.abstractmethod
    644     def origin(self): pass
    645 
    646     @abc.abstractmethod
    647     def __len__(self): pass
    648 
    649 
    650 class HPackLiteralString(HPackStringsInterface):
    651     """ HPackLiteralString is a string. This class is used as a marker and
    652     implements an interface in common with HPackZString
    653     """
    654     __slots__ = ['_s']
    655 
    656     def __init__(self, s):
    657         # type: (str) -> None
    658         self._s = s
    659 
    660     def __str__(self):
    661         # type: () -> str
    662         return self._s
    663 
    664     def origin(self):
    665         # type: () -> str
    666         return plain_str(self._s)
    667 
    668     def __len__(self):
    669         # type: () -> int
    670         return len(self._s)
    671 
    672 
    673 class EOS(object):
    674     """ Simple "marker" to designate the End Of String symbol in the huffman table
    675     """
    676 
    677 
    678 class HuffmanNode(object):
    679     """ HuffmanNode is an entry of the binary tree used for encoding/decoding
    680     HPack compressed HTTP/2 headers
    681     """
    682 
    683     __slots__ = ['l', 'r']
    684     """@var l: the left branch of this node
    685     @var r: the right branch of this Node
    686 
    687     These variables can value None (leaf node), another HuffmanNode, or a
    688      symbol. Symbols are either a character or the End Of String symbol (class
    689      EOS)
    690     """
    691 
    692     def __init__(self, l, r):
    693         # type: (Union[None, HuffmanNode, EOS, str], Union[None, HuffmanNode, EOS, str]) -> None
    694         self.l = l
    695         self.r = r
    696 
    697     def __getitem__(self, b):
    698         # type: (int) -> Union[None, HuffmanNode, EOS, str]
    699         return self.r if b else self.l
    700 
    701     def __setitem__(self, b, val):
    702         # type: (int, Union[None, HuffmanNode, EOS, str]) -> None
    703         if b:
    704             self.r = val
    705         else:
    706             self.l = val
    707 
    708     def __str__(self):
    709         # type: () -> str
    710         return self.__repr__()
    711 
    712     def __repr__(self):
    713         # type: () -> str
    714         return '({}, {})'.format(self.l, self.r)
    715 
    716 
    717 class InvalidEncodingException(Exception):
    718     """ InvalidEncodingException is raised when a supposedly huffman-encoded
    719      string is decoded and a decoding error arises
    720     """
    721 
    722 
    723 class HPackZString(HPackStringsInterface):
    724     __slots__ = ['_s', '_encoded']
    725 
    726     # From RFC 7541
    727     # Tuple is (code,code bitlength)
    728     # The bitlength is required to know how long the left padding
    729     # (implicit 0's) there are
    730     static_huffman_code = [
    731         (0x1ff8, 13),
    732         (0x7fffd8, 23),
    733         (0xfffffe2, 28),
    734         (0xfffffe3, 28),
    735         (0xfffffe4, 28),
    736         (0xfffffe5, 28),
    737         (0xfffffe6, 28),
    738         (0xfffffe7, 28),
    739         (0xfffffe8, 28),
    740         (0xffffea, 24),
    741         (0x3ffffffc, 30),
    742         (0xfffffe9, 28),
    743         (0xfffffea, 28),
    744         (0x3ffffffd, 30),
    745         (0xfffffeb, 28),
    746         (0xfffffec, 28),
    747         (0xfffffed, 28),
    748         (0xfffffee, 28),
    749         (0xfffffef, 28),
    750         (0xffffff0, 28),
    751         (0xffffff1, 28),
    752         (0xffffff2, 28),
    753         (0x3ffffffe, 30),
    754         (0xffffff3, 28),
    755         (0xffffff4, 28),
    756         (0xffffff5, 28),
    757         (0xffffff6, 28),
    758         (0xffffff7, 28),
    759         (0xffffff8, 28),
    760         (0xffffff9, 28),
    761         (0xffffffa, 28),
    762         (0xffffffb, 28),
    763         (0x14, 6),
    764         (0x3f8, 10),
    765         (0x3f9, 10),
    766         (0xffa, 12),
    767         (0x1ff9, 13),
    768         (0x15, 6),
    769         (0xf8, 8),
    770         (0x7fa, 11),
    771         (0x3fa, 10),
    772         (0x3fb, 10),
    773         (0xf9, 8),
    774         (0x7fb, 11),
    775         (0xfa, 8),
    776         (0x16, 6),
    777         (0x17, 6),
    778         (0x18, 6),
    779         (0x0, 5),
    780         (0x1, 5),
    781         (0x2, 5),
    782         (0x19, 6),
    783         (0x1a, 6),
    784         (0x1b, 6),
    785         (0x1c, 6),
    786         (0x1d, 6),
    787         (0x1e, 6),
    788         (0x1f, 6),
    789         (0x5c, 7),
    790         (0xfb, 8),
    791         (0x7ffc, 15),
    792         (0x20, 6),
    793         (0xffb, 12),
    794         (0x3fc, 10),
    795         (0x1ffa, 13),
    796         (0x21, 6),
    797         (0x5d, 7),
    798         (0x5e, 7),
    799         (0x5f, 7),
    800         (0x60, 7),
    801         (0x61, 7),
    802         (0x62, 7),
    803         (0x63, 7),
    804         (0x64, 7),
    805         (0x65, 7),
    806         (0x66, 7),
    807         (0x67, 7),
    808         (0x68, 7),
    809         (0x69, 7),
    810         (0x6a, 7),
    811         (0x6b, 7),
    812         (0x6c, 7),
    813         (0x6d, 7),
    814         (0x6e, 7),
    815         (0x6f, 7),
    816         (0x70, 7),
    817         (0x71, 7),
    818         (0x72, 7),
    819         (0xfc, 8),
    820         (0x73, 7),
    821         (0xfd, 8),
    822         (0x1ffb, 13),
    823         (0x7fff0, 19),
    824         (0x1ffc, 13),
    825         (0x3ffc, 14),
    826         (0x22, 6),
    827         (0x7ffd, 15),
    828         (0x3, 5),
    829         (0x23, 6),
    830         (0x4, 5),
    831         (0x24, 6),
    832         (0x5, 5),
    833         (0x25, 6),
    834         (0x26, 6),
    835         (0x27, 6),
    836         (0x6, 5),
    837         (0x74, 7),
    838         (0x75, 7),
    839         (0x28, 6),
    840         (0x29, 6),
    841         (0x2a, 6),
    842         (0x7, 5),
    843         (0x2b, 6),
    844         (0x76, 7),
    845         (0x2c, 6),
    846         (0x8, 5),
    847         (0x9, 5),
    848         (0x2d, 6),
    849         (0x77, 7),
    850         (0x78, 7),
    851         (0x79, 7),
    852         (0x7a, 7),
    853         (0x7b, 7),
    854         (0x7ffe, 15),
    855         (0x7fc, 11),
    856         (0x3ffd, 14),
    857         (0x1ffd, 13),
    858         (0xffffffc, 28),
    859         (0xfffe6, 20),
    860         (0x3fffd2, 22),
    861         (0xfffe7, 20),
    862         (0xfffe8, 20),
    863         (0x3fffd3, 22),
    864         (0x3fffd4, 22),
    865         (0x3fffd5, 22),
    866         (0x7fffd9, 23),
    867         (0x3fffd6, 22),
    868         (0x7fffda, 23),
    869         (0x7fffdb, 23),
    870         (0x7fffdc, 23),
    871         (0x7fffdd, 23),
    872         (0x7fffde, 23),
    873         (0xffffeb, 24),
    874         (0x7fffdf, 23),
    875         (0xffffec, 24),
    876         (0xffffed, 24),
    877         (0x3fffd7, 22),
    878         (0x7fffe0, 23),
    879         (0xffffee, 24),
    880         (0x7fffe1, 23),
    881         (0x7fffe2, 23),
    882         (0x7fffe3, 23),
    883         (0x7fffe4, 23),
    884         (0x1fffdc, 21),
    885         (0x3fffd8, 22),
    886         (0x7fffe5, 23),
    887         (0x3fffd9, 22),
    888         (0x7fffe6, 23),
    889         (0x7fffe7, 23),
    890         (0xffffef, 24),
    891         (0x3fffda, 22),
    892         (0x1fffdd, 21),
    893         (0xfffe9, 20),
    894         (0x3fffdb, 22),
    895         (0x3fffdc, 22),
    896         (0x7fffe8, 23),
    897         (0x7fffe9, 23),
    898         (0x1fffde, 21),
    899         (0x7fffea, 23),
    900         (0x3fffdd, 22),
    901         (0x3fffde, 22),
    902         (0xfffff0, 24),
    903         (0x1fffdf, 21),
    904         (0x3fffdf, 22),
    905         (0x7fffeb, 23),
    906         (0x7fffec, 23),
    907         (0x1fffe0, 21),
    908         (0x1fffe1, 21),
    909         (0x3fffe0, 22),
    910         (0x1fffe2, 21),
    911         (0x7fffed, 23),
    912         (0x3fffe1, 22),
    913         (0x7fffee, 23),
    914         (0x7fffef, 23),
    915         (0xfffea, 20),
    916         (0x3fffe2, 22),
    917         (0x3fffe3, 22),
    918         (0x3fffe4, 22),
    919         (0x7ffff0, 23),
    920         (0x3fffe5, 22),
    921         (0x3fffe6, 22),
    922         (0x7ffff1, 23),
    923         (0x3ffffe0, 26),
    924         (0x3ffffe1, 26),
    925         (0xfffeb, 20),
    926         (0x7fff1, 19),
    927         (0x3fffe7, 22),
    928         (0x7ffff2, 23),
    929         (0x3fffe8, 22),
    930         (0x1ffffec, 25),
    931         (0x3ffffe2, 26),
    932         (0x3ffffe3, 26),
    933         (0x3ffffe4, 26),
    934         (0x7ffffde, 27),
    935         (0x7ffffdf, 27),
    936         (0x3ffffe5, 26),
    937         (0xfffff1, 24),
    938         (0x1ffffed, 25),
    939         (0x7fff2, 19),
    940         (0x1fffe3, 21),
    941         (0x3ffffe6, 26),
    942         (0x7ffffe0, 27),
    943         (0x7ffffe1, 27),
    944         (0x3ffffe7, 26),
    945         (0x7ffffe2, 27),
    946         (0xfffff2, 24),
    947         (0x1fffe4, 21),
    948         (0x1fffe5, 21),
    949         (0x3ffffe8, 26),
    950         (0x3ffffe9, 26),
    951         (0xffffffd, 28),
    952         (0x7ffffe3, 27),
    953         (0x7ffffe4, 27),
    954         (0x7ffffe5, 27),
    955         (0xfffec, 20),
    956         (0xfffff3, 24),
    957         (0xfffed, 20),
    958         (0x1fffe6, 21),
    959         (0x3fffe9, 22),
    960         (0x1fffe7, 21),
    961         (0x1fffe8, 21),
    962         (0x7ffff3, 23),
    963         (0x3fffea, 22),
    964         (0x3fffeb, 22),
    965         (0x1ffffee, 25),
    966         (0x1ffffef, 25),
    967         (0xfffff4, 24),
    968         (0xfffff5, 24),
    969         (0x3ffffea, 26),
    970         (0x7ffff4, 23),
    971         (0x3ffffeb, 26),
    972         (0x7ffffe6, 27),
    973         (0x3ffffec, 26),
    974         (0x3ffffed, 26),
    975         (0x7ffffe7, 27),
    976         (0x7ffffe8, 27),
    977         (0x7ffffe9, 27),
    978         (0x7ffffea, 27),
    979         (0x7ffffeb, 27),
    980         (0xffffffe, 28),
    981         (0x7ffffec, 27),
    982         (0x7ffffed, 27),
    983         (0x7ffffee, 27),
    984         (0x7ffffef, 27),
    985         (0x7fffff0, 27),
    986         (0x3ffffee, 26),
    987         (0x3fffffff, 30)
    988     ]
    989 
    990     static_huffman_tree = None
    991 
    992     @classmethod
    993     def _huffman_encode_char(cls, c):
    994         # type: (Union[str, EOS]) -> Tuple[int, int]
    995         """ huffman_encode_char assumes that the static_huffman_tree was
    996         previously initialized
    997 
    998         @param str|EOS c: a symbol to encode
    999         @return (int, int): the bitstring of the symbol and its bitlength
   1000         @raise AssertionError
   1001         """
   1002         if isinstance(c, EOS):
   1003             return cls.static_huffman_code[-1]
   1004         else:
   1005             assert(isinstance(c, int) or len(c) == 1)
   1006         return cls.static_huffman_code[orb(c)]
   1007 
   1008     @classmethod
   1009     def huffman_encode(cls, s):
   1010         # type: (str) -> Tuple[int, int]
   1011         """ huffman_encode returns the bitstring and the bitlength of the
   1012         bitstring representing the string provided as a parameter
   1013 
   1014         @param str s: the string to encode
   1015         @return (int, int): the bitstring of s and its bitlength
   1016         @raise AssertionError
   1017         """
   1018         i = 0
   1019         ibl = 0
   1020         for c in s:
   1021             val, bl = cls._huffman_encode_char(c)
   1022             i = (i << bl) + val
   1023             ibl += bl
   1024 
   1025         padlen = 8 - (ibl % 8)
   1026         if padlen != 8:
   1027             val, bl = cls._huffman_encode_char(EOS())
   1028             i = (i << padlen) + (val >> (bl - padlen))
   1029             ibl += padlen
   1030 
   1031         ret = i, ibl
   1032         assert(ret[0] >= 0)
   1033         assert (ret[1] >= 0)
   1034         return ret
   1035 
   1036     @classmethod
   1037     def huffman_decode(cls, i, ibl):
   1038         # type: (int, int) -> str
   1039         """ huffman_decode decodes the bitstring provided as parameters.
   1040 
   1041         @param int i: the bitstring to decode
   1042         @param int ibl: the bitlength of i
   1043         @return str: the string decoded from the bitstring
   1044         @raise AssertionError, InvalidEncodingException
   1045         """
   1046         assert(i >= 0)
   1047         assert(ibl >= 0)
   1048 
   1049         if isinstance(cls.static_huffman_tree, type(None)):
   1050             cls.huffman_compute_decode_tree()
   1051         assert(not isinstance(cls.static_huffman_tree, type(None)))
   1052 
   1053         s = []
   1054         j = 0
   1055         interrupted = False
   1056         cur = cls.static_huffman_tree
   1057         cur_sym = 0
   1058         cur_sym_bl = 0
   1059         while j < ibl:
   1060             b = (i >> (ibl - j - 1)) & 1
   1061             cur_sym = (cur_sym << 1) + b
   1062             cur_sym_bl += 1
   1063             elmt = cur[b]
   1064 
   1065             if isinstance(elmt, HuffmanNode):
   1066                 interrupted = True
   1067                 cur = elmt
   1068                 if isinstance(cur, type(None)):
   1069                     raise AssertionError()
   1070             elif isinstance(elmt, EOS):
   1071                 raise InvalidEncodingException('Huffman decoder met the full EOS symbol')
   1072             elif isinstance(elmt, bytes):
   1073                 interrupted = False
   1074                 s.append(elmt)
   1075                 cur = cls.static_huffman_tree
   1076                 cur_sym = 0
   1077                 cur_sym_bl = 0
   1078             else:
   1079                 raise InvalidEncodingException('Should never happen, so incidentally it will')
   1080             j += 1
   1081 
   1082         if interrupted:
   1083             # Interrupted values true if the bitstring ends in the middle of a
   1084             # symbol; this symbol must be, according to RFC7541 par5.2 the MSB
   1085             # of the EOS symbol
   1086             if cur_sym_bl > 7:
   1087                 raise InvalidEncodingException('Huffman decoder is detecting padding longer than 7 bits')
   1088             eos_symbol = cls.static_huffman_code[-1]
   1089             eos_msb = eos_symbol[0] >> (eos_symbol[1] - cur_sym_bl)
   1090             if eos_msb != cur_sym:
   1091                 raise InvalidEncodingException('Huffman decoder is detecting unexpected padding format')
   1092         return b''.join(s)
   1093 
   1094     @classmethod
   1095     def huffman_conv2str(cls, bit_str, bit_len):
   1096         # type: (int, int) -> str
   1097         """ huffman_conv2str converts a bitstring of bit_len bitlength into a
   1098         binary string. It DOES NOT compress/decompress the bitstring!
   1099 
   1100         @param int bit_str: the bitstring to convert.
   1101         @param int bit_len: the bitlength of bit_str.
   1102         @return str: the converted bitstring as a bytestring.
   1103         @raise AssertionError
   1104         """
   1105         assert(bit_str >= 0)
   1106         assert(bit_len >= 0)
   1107 
   1108         byte_len = bit_len // 8
   1109         rem_bit = bit_len % 8
   1110         if rem_bit != 0:
   1111             bit_str <<= 8 - rem_bit
   1112             byte_len += 1
   1113 
   1114         # As usual the list/join tricks is a performance trick to build
   1115         # efficiently a Python string
   1116         s = []  # type: List[str]
   1117         i = 0
   1118         while i < byte_len:
   1119             s.insert(0, chb((bit_str >> (i*8)) & 0xFF))
   1120             i += 1
   1121         return b''.join(s)
   1122 
   1123     @classmethod
   1124     def huffman_conv2bitstring(cls, s):
   1125         # type: (str) -> Tuple[int, int]
   1126         """ huffman_conv2bitstring converts a string into its bitstring
   1127         representation. It returns a tuple: the bitstring and its bitlength.
   1128         This function DOES NOT compress/decompress the string!
   1129 
   1130         @param str s: the bytestring to convert.
   1131         @return (int, int): the bitstring of s, and its bitlength.
   1132         @raise AssertionError
   1133         """
   1134         i = 0
   1135         ibl = len(s) * 8
   1136         for c in s:
   1137             i = (i << 8) + orb(c)
   1138 
   1139         ret = i, ibl
   1140         assert(ret[0] >= 0)
   1141         assert(ret[1] >= 0)
   1142         return ret
   1143 
   1144     @classmethod
   1145     def huffman_compute_decode_tree(cls):
   1146         # type: () -> None
   1147         """ huffman_compute_decode_tree initializes/builds the static_huffman_tree
   1148 
   1149         @return None
   1150         @raise InvalidEncodingException if there is an encoding problem
   1151         """
   1152         cls.static_huffman_tree = HuffmanNode(None, None)
   1153         i = 0
   1154         for entry in cls.static_huffman_code:
   1155             parent = cls.static_huffman_tree
   1156             for idx in range(entry[1] - 1, -1, -1):
   1157                 b = (entry[0] >> idx) & 1
   1158                 if isinstance(parent[b], bytes):
   1159                     raise InvalidEncodingException('Huffman unique prefix violation :/')
   1160                 if idx == 0:
   1161                     parent[b] = chb(i) if i < 256 else EOS()
   1162                 elif parent[b] is None:
   1163                     parent[b] = HuffmanNode(None, None)
   1164                 parent = parent[b]
   1165             i += 1
   1166 
   1167     def __init__(self, s):
   1168         # type: (str) -> None
   1169         self._s = s
   1170         i, ibl = type(self).huffman_encode(s)
   1171         self._encoded = type(self).huffman_conv2str(i, ibl)
   1172 
   1173     def __str__(self):
   1174         # type: () -> str
   1175         return self._encoded
   1176 
   1177     def origin(self):
   1178         # type: () -> str
   1179         return plain_str(self._s)
   1180 
   1181     def __len__(self):
   1182         # type: () -> int
   1183         return len(self._encoded)
   1184 
   1185 
   1186 class HPackStrLenField(fields.Field):
   1187     """ HPackStrLenField is a StrLenField variant specialized for HTTP/2 HPack
   1188 
   1189     This variant uses an internal representation that implements HPackStringsInterface.
   1190     """
   1191     __slots__ = ['_length_from', '_type_from']
   1192 
   1193     def __init__(self, name, default, length_from, type_from):
   1194         # type: (str, HPackStringsInterface, Callable[[packet.Packet], int], str) -> None
   1195         super(HPackStrLenField, self).__init__(name, default)
   1196         self._length_from = length_from
   1197         self._type_from = type_from
   1198 
   1199     def addfield(self, pkt, s, val):
   1200         # type: (Optional[packet.Packet], str, HPackStringsInterface) -> str
   1201         return s + self.i2m(pkt, val)
   1202 
   1203     @staticmethod
   1204     def _parse(t, s):
   1205         # type: (bool, str) -> HPackStringsInterface
   1206         """
   1207         @param bool t: whether this string is a huffman compressed string.
   1208         @param str s: the string to parse.
   1209         @return HPackStringsInterface: either a HPackLiteralString or HPackZString, depending on t.
   1210         @raise InvalidEncodingException
   1211         """
   1212         if t:
   1213             i, ibl = HPackZString.huffman_conv2bitstring(s)
   1214             return HPackZString(HPackZString.huffman_decode(i, ibl))
   1215         return HPackLiteralString(s)
   1216 
   1217     def getfield(self, pkt, s):
   1218         # type: (packet.Packet, str) -> Tuple[str, HPackStringsInterface]
   1219         """
   1220         @param packet.Packet pkt: the packet instance containing this field instance.
   1221         @param str s: the string to parse this field from.
   1222         @return (str, HPackStringsInterface): the remaining string after this field was carved out & the extracted
   1223           value.
   1224         @raise KeyError if "type_from" is not a field of pkt or its payloads.
   1225         @raise InvalidEncodingException
   1226         """
   1227         l = self._length_from(pkt)
   1228         t = pkt.getfieldval(self._type_from) == 1
   1229         return s[l:], self._parse(t, s[:l])
   1230 
   1231     def i2h(self, pkt, x):
   1232         # type: (Optional[packet.Packet], HPackStringsInterface) -> str
   1233         fmt = ''
   1234         if isinstance(x, HPackLiteralString):
   1235             fmt = "HPackLiteralString({})"
   1236         elif isinstance(x, HPackZString):
   1237             fmt = "HPackZString({})"
   1238         return fmt.format(x.origin())
   1239 
   1240     def h2i(self, pkt, x):
   1241         # type: (packet.Packet, str) -> HPackStringsInterface
   1242         return HPackLiteralString(x)
   1243 
   1244     def m2i(self, pkt, x):
   1245         # type: (packet.Packet, str) -> HPackStringsInterface
   1246         """
   1247         @param packet.Packet pkt: the packet instance containing this field instance.
   1248         @param str x: the string to parse.
   1249         @return HPackStringsInterface: the internal type of the value parsed from x.
   1250         @raise AssertionError
   1251         @raise InvalidEncodingException
   1252         @raise KeyError if _type_from is not one of pkt fields.
   1253         """
   1254         t = pkt.getfieldval(self._type_from)
   1255         l = self._length_from(pkt)
   1256 
   1257         assert t is not None and l is not None, 'Conversion from string impossible: no type or length specified'
   1258 
   1259         return self._parse(t == 1, x[:l])
   1260 
   1261     def any2i(self, pkt, x):
   1262         # type: (Optional[packet.Packet], Union[str, HPackStringsInterface]) -> HPackStringsInterface
   1263         """
   1264         @param packet.Packet|None pkt: the packet instance containing this field instance.
   1265         @param str|HPackStringsInterface x: the value to convert
   1266         @return HPackStringsInterface: the Scapy internal value for this field
   1267         @raise AssertionError, InvalidEncodingException
   1268         """
   1269         if isinstance(x, bytes):
   1270             assert(isinstance(pkt, packet.Packet))
   1271             return self.m2i(pkt, x)
   1272         assert(isinstance(x, HPackStringsInterface))
   1273         return x
   1274 
   1275     def i2m(self, pkt, x):
   1276         # type: (Optional[packet.Packet], HPackStringsInterface) -> str
   1277         return raw(x)
   1278 
   1279     def i2len(self, pkt, x):
   1280         # type: (Optional[packet.Packet], HPackStringsInterface) -> int
   1281         return len(x)
   1282 
   1283     def i2repr(self, pkt, x):
   1284         # type: (Optional[packet.Packet], HPackStringsInterface) -> str
   1285         return repr(self.i2h(pkt, x))
   1286 
   1287 ########################################################################################################################
   1288 ################################################ HPACK Packets #########################################################
   1289 ########################################################################################################################
   1290 
   1291 class HPackHdrString(packet.Packet):
   1292     """ HPackHdrString is a packet that that is serialized into a RFC7541 par5.2
   1293     string literal repr.
   1294     """
   1295     name = 'HPack Header String'
   1296     fields_desc = [
   1297         fields.BitEnumField('type', None, 1, {0: 'Literal', 1: 'Compressed'}),
   1298         FieldUVarLenField('len', None, 7, length_of='data'),
   1299         HPackStrLenField(
   1300             'data', HPackLiteralString(''),
   1301             length_from=lambda pkt: pkt.getfieldval('len'),
   1302             type_from='type'
   1303         )
   1304     ]
   1305 
   1306     def guess_payload_class(self, payload):
   1307         # type: (str) -> base_classes.Packet_metaclass
   1308         # Trick to tell scapy that the remaining bytes of the currently
   1309         # dissected string is not a payload of this packet but of some other
   1310         # underlayer packet
   1311         return config.conf.padding_layer
   1312 
   1313     def self_build(self, field_pos_list=None):
   1314         # type: (Any) -> str
   1315         """self_build is overridden because type and len are determined at
   1316         build time, based on the "data" field internal type
   1317         """
   1318         if self.getfieldval('type') is None:
   1319             self.type = 1 if isinstance(self.getfieldval('data'), HPackZString) else 0
   1320         return super(HPackHdrString, self).self_build(field_pos_list)
   1321 
   1322 
   1323 class HPackHeaders(packet.Packet):
   1324     """HPackHeaders uses the "dispatch_hook" trick of Packet_metaclass to select
   1325     the correct HPack header packet type. For this, the first byte of the string
   1326     to dissect is snooped on.
   1327     """
   1328     @classmethod
   1329     def dispatch_hook(cls, s=None, *_args, **_kwds):
   1330         # type: (Optional[str], *Any, **Any) -> base_classes.Packet_metaclass
   1331         """dispatch_hook returns the subclass of HPackHeaders that must be used
   1332         to dissect the string.
   1333         """
   1334         if s is None:
   1335             return config.conf.raw_layer
   1336         fb = orb(s[0])
   1337         if fb & 0x80 != 0:
   1338             return HPackIndexedHdr
   1339         if fb & 0x40 != 0:
   1340             return HPackLitHdrFldWithIncrIndexing
   1341         if fb & 0x20 != 0:
   1342             return HPackDynamicSizeUpdate
   1343         return HPackLitHdrFldWithoutIndexing
   1344 
   1345     def guess_payload_class(self, payload):
   1346         # type: (str) -> base_classes.Packet_metaclass
   1347         return config.conf.padding_layer
   1348 
   1349 
   1350 class HPackIndexedHdr(HPackHeaders):
   1351     """ HPackIndexedHdr implements RFC 7541 par6.1
   1352     """
   1353     name = 'HPack Indexed Header Field'
   1354     fields_desc = [
   1355         HPackMagicBitField('magic', 1, 1),
   1356         UVarIntField('index', 2, 7)  # Default "2" is ":method GET"
   1357     ]
   1358 
   1359 
   1360 class HPackLitHdrFldWithIncrIndexing(HPackHeaders):
   1361     """ HPackLitHdrFldWithIncrIndexing implements RFC 7541 par6.2.1
   1362     """
   1363     name = 'HPack Literal Header With Incremental Indexing'
   1364     fields_desc = [
   1365         HPackMagicBitField('magic', 1, 2),
   1366         UVarIntField('index', 0, 6),  # Default is New Name
   1367         fields.ConditionalField(
   1368             fields.PacketField('hdr_name', None, HPackHdrString),
   1369             lambda pkt: pkt.getfieldval('index') == 0
   1370         ),
   1371         fields.PacketField('hdr_value', None, HPackHdrString)
   1372     ]
   1373 
   1374 
   1375 class HPackLitHdrFldWithoutIndexing(HPackHeaders):
   1376     """ HPackLitHdrFldWithIncrIndexing implements RFC 7541 par6.2.2
   1377     and par6.2.3
   1378     """
   1379     name = 'HPack Literal Header Without Indexing (or Never Indexing)'
   1380     fields_desc = [
   1381         HPackMagicBitField('magic', 0, 3),
   1382         fields.BitEnumField(
   1383             'never_index', 0, 1,
   1384             {0: "Don't Index", 1: 'Never Index'}
   1385         ),
   1386         UVarIntField('index', 0, 4),  # Default is New Name
   1387         fields.ConditionalField(
   1388             fields.PacketField('hdr_name', None, HPackHdrString),
   1389             lambda pkt: pkt.getfieldval('index') == 0
   1390         ),
   1391         fields.PacketField('hdr_value', None, HPackHdrString)
   1392     ]
   1393 
   1394 
   1395 class HPackDynamicSizeUpdate(HPackHeaders):
   1396     """ HPackDynamicSizeUpdate implements RFC 7541 par6.3
   1397     """
   1398     name = 'HPack Dynamic Size Update'
   1399     fields_desc = [
   1400         HPackMagicBitField('magic', 1, 3),
   1401         UVarIntField('max_size', 0, 5)
   1402     ]
   1403 
   1404 ########################################################################################################################
   1405 ############################################# HTTP/2 Frames ############################################################
   1406 ########################################################################################################################
   1407 
   1408 class H2FramePayload(packet.Packet):
   1409     """ H2FramePayload is an empty class that is a super class of all Scapy
   1410     HTTP/2 Frame Packets
   1411     """
   1412 
   1413 ############################################# HTTP/2 Data Frame Packets ################################################
   1414 
   1415 class H2DataFrame(H2FramePayload):
   1416     """ H2DataFrame implements RFC7540 par6.1
   1417     This packet is the Data Frame to use when there is no padding.
   1418     """
   1419     type_id = 0
   1420     END_STREAM_FLAG = 0  # 0x1
   1421     PADDED_FLAG = 3  # 0x8
   1422     flags = {
   1423         END_STREAM_FLAG: fields.MultiFlagsEntry('ES', 'End Stream'),
   1424         PADDED_FLAG: fields.MultiFlagsEntry('P', 'Padded')
   1425     }
   1426 
   1427     name = 'HTTP/2 Data Frame'
   1428     fields_desc = [
   1429         fields.StrField('data', '')
   1430     ]
   1431 
   1432 
   1433 class H2PaddedDataFrame(H2DataFrame):
   1434     """ H2DataFrame implements RFC7540 par6.1
   1435     This packet is the Data Frame to use when there is padding.
   1436     """
   1437     __slots__ = ['s_len']
   1438 
   1439     name = 'HTTP/2 Padded Data Frame'
   1440     fields_desc = [
   1441         fields.FieldLenField('padlen', None, length_of='padding', fmt="B"),
   1442         fields.StrLenField('data', '',
   1443             length_from=lambda pkt: pkt.get_data_len()
   1444         ),
   1445         fields.StrLenField('padding', '',
   1446             length_from=lambda pkt: pkt.getfieldval('padlen')
   1447         )
   1448     ]
   1449 
   1450     def get_data_len(self):
   1451         # type: () -> int
   1452         """ get_data_len computes the length of the data field
   1453 
   1454         To do this computation, the length of the padlen field and the actual
   1455         padding is subtracted to the string that was provided to the pre_dissect
   1456         fun of the pkt parameter
   1457         @return int; length of the data part of the HTTP/2 frame packet provided as parameter
   1458         @raise AssertionError
   1459         """
   1460         padding_len = self.getfieldval('padlen')
   1461         fld, fval = self.getfield_and_val('padlen')
   1462         padding_len_len = fld.i2len(self, fval)
   1463 
   1464         ret = self.s_len - padding_len_len - padding_len
   1465         assert(ret >= 0)
   1466         return ret
   1467 
   1468     def pre_dissect(self, s):
   1469         # type: (str) -> str
   1470         """pre_dissect is filling the s_len property of this instance. This
   1471         property is later used during the getfield call of the "data" field when
   1472         trying to evaluate the length of the StrLenField! This "trick" works
   1473         because the underlayer packet (H2Frame) is assumed to override the
   1474         "extract_padding" method and to only provide to this packet the data
   1475         necessary for this packet. Tricky, tricky, will break some day probably!
   1476         """
   1477         self.s_len = len(s)
   1478         return s
   1479 
   1480 
   1481 ############################################# HTTP/2 Header Frame Packets ##############################################
   1482 
   1483 class H2AbstractHeadersFrame(H2FramePayload):
   1484     """Superclass of all variants of HTTP/2 Header Frame Packets.
   1485     May be used for type checking.
   1486     """
   1487 
   1488 class H2HeadersFrame(H2AbstractHeadersFrame):
   1489     """ H2HeadersFrame implements RFC 7540 par6.2 Headers Frame
   1490     when there is no padding and no priority informations
   1491 
   1492     The choice of decomposing into four classes is probably preferable to having
   1493     numerous conditional fields based on the underlayer :/
   1494     """
   1495     type_id = 1
   1496     END_STREAM_FLAG = 0  # 0x1
   1497     END_HEADERS_FLAG = 2  # 0x4
   1498     PADDED_FLAG = 3  # 0x8
   1499     PRIORITY_FLAG = 5  # 0x20
   1500     flags = {
   1501         END_STREAM_FLAG: fields.MultiFlagsEntry('ES', 'End Stream'),
   1502         END_HEADERS_FLAG: fields.MultiFlagsEntry('EH', 'End Headers'),
   1503         PADDED_FLAG: fields.MultiFlagsEntry('P', 'Padded'),
   1504         PRIORITY_FLAG: fields.MultiFlagsEntry('+', 'Priority')
   1505     }
   1506 
   1507     name = 'HTTP/2 Headers Frame'
   1508     fields_desc = [
   1509         fields.PacketListField('hdrs', [], HPackHeaders)
   1510     ]
   1511 
   1512 
   1513 class H2PaddedHeadersFrame(H2AbstractHeadersFrame):
   1514     """ H2PaddedHeadersFrame is the variant of H2HeadersFrame where padding flag
   1515     is set and priority flag is cleared
   1516     """
   1517     __slots__ = ['s_len']
   1518 
   1519     name = 'HTTP/2 Headers Frame with Padding'
   1520     fields_desc = [
   1521         fields.FieldLenField('padlen', None, length_of='padding', fmt='B'),
   1522         fields.PacketListField('hdrs', [], HPackHeaders,
   1523             length_from=lambda pkt: pkt.get_hdrs_len()
   1524         ),
   1525         fields.StrLenField('padding', '',
   1526             length_from=lambda pkt: pkt.getfieldval('padlen')
   1527         )
   1528     ]
   1529 
   1530     def get_hdrs_len(self):
   1531         # type: () -> int
   1532         """ get_hdrs_len computes the length of the hdrs field
   1533 
   1534         To do this computation, the length of the padlen field and the actual
   1535         padding is subtracted to the string that was provided to the pre_dissect
   1536         fun of the pkt parameter.
   1537         @return int; length of the data part of the HTTP/2 frame packet provided as parameter
   1538         @raise AssertionError
   1539         """
   1540         padding_len = self.getfieldval('padlen')
   1541         fld, fval = self.getfield_and_val('padlen')
   1542         padding_len_len = fld.i2len(self, fval)
   1543 
   1544         ret = self.s_len - padding_len_len - padding_len
   1545         assert(ret >= 0)
   1546         return ret
   1547 
   1548     def pre_dissect(self, s):
   1549         # type: (str) -> str
   1550         """pre_dissect is filling the s_len property of this instance. This
   1551         property is later used during the parsing of the hdrs PacketListField
   1552         when trying to evaluate the length of the PacketListField! This "trick"
   1553         works because the underlayer packet (H2Frame) is assumed to override the
   1554         "extract_padding" method and to only provide to this packet the data
   1555         necessary for this packet. Tricky, tricky, will break some day probably!
   1556         """
   1557         self.s_len = len(s)
   1558         return s
   1559 
   1560 
   1561 class H2PriorityHeadersFrame(H2AbstractHeadersFrame):
   1562     """ H2PriorityHeadersFrame is the variant of H2HeadersFrame where priority flag
   1563     is set and padding flag is cleared
   1564     """
   1565     __slots__ = ['s_len']
   1566 
   1567     name = 'HTTP/2 Headers Frame with Priority'
   1568     fields_desc = [
   1569         fields.BitField('exclusive', 0, 1),
   1570         fields.BitField('stream_dependency', 0, 31),
   1571         fields.ByteField('weight', 0),
   1572         # This PacketListField will consume all remaining bytes; not a problem
   1573         # because the underlayer (H2Frame) overrides "extract_padding" so that
   1574         # this Packet only get to parser what it needs to
   1575         fields.PacketListField('hdrs', [], HPackHeaders),
   1576     ]
   1577 
   1578 
   1579 class H2PaddedPriorityHeadersFrame(H2AbstractHeadersFrame):
   1580     """ H2PaddedPriorityHeadersFrame is the variant of H2HeadersFrame where
   1581     both priority and padding flags are set
   1582     """
   1583     __slots__ = ['s_len']
   1584 
   1585     name = 'HTTP/2 Headers Frame with Padding and Priority'
   1586     fields_desc = [
   1587         fields.FieldLenField('padlen', None, length_of='padding', fmt='B'),
   1588         fields.BitField('exclusive', 0, 1),
   1589         fields.BitField('stream_dependency', 0, 31),
   1590         fields.ByteField('weight', 0),
   1591         fields.PacketListField('hdrs', [], HPackHeaders,
   1592             length_from=lambda pkt: pkt.get_hdrs_len()
   1593         ),
   1594         fields.StrLenField('padding', '',
   1595             length_from=lambda pkt: pkt.getfieldval('padlen')
   1596         )
   1597     ]
   1598 
   1599     def get_hdrs_len(self):
   1600         # type: () -> int
   1601         """ get_hdrs_len computes the length of the hdrs field
   1602 
   1603         To do this computation, the length of the padlen field, the priority
   1604         information fields and the actual padding is subtracted to the string
   1605         that was provided to the pre_dissect fun of the pkt parameter.
   1606         @return int: the length of the hdrs field
   1607         @raise AssertionError
   1608         """
   1609 
   1610         padding_len = self.getfieldval('padlen')
   1611         fld, fval = self.getfield_and_val('padlen')
   1612         padding_len_len = fld.i2len(self, fval)
   1613         bit_cnt = self.get_field('exclusive').size
   1614         bit_cnt += self.get_field('stream_dependency').size
   1615         fld, fval = self.getfield_and_val('weight')
   1616         weight_len = fld.i2len(self, fval)
   1617         ret = int(self.s_len
   1618             - padding_len_len
   1619             - padding_len
   1620             - (bit_cnt / 8)
   1621             - weight_len
   1622         )
   1623         assert(ret >= 0)
   1624         return ret
   1625 
   1626     def pre_dissect(self, s):
   1627         # type: (str) -> str
   1628         """pre_dissect is filling the s_len property of this instance. This
   1629         property is later used during the parsing of the hdrs PacketListField
   1630         when trying to evaluate the length of the PacketListField! This "trick"
   1631         works because the underlayer packet (H2Frame) is assumed to override the
   1632         "extract_padding" method and to only provide to this packet the data
   1633         necessary for this packet. Tricky, tricky, will break some day probably!
   1634         """
   1635         self.s_len = len(s)
   1636         return s
   1637 
   1638 ########################################### HTTP/2 Priority Frame Packets ##############################################
   1639 
   1640 class H2PriorityFrame(H2FramePayload):
   1641     """ H2PriorityFrame implements RFC 7540 par6.3
   1642     """
   1643     type_id = 2
   1644     name = 'HTTP/2 Priority Frame'
   1645     fields_desc = [
   1646         fields.BitField('exclusive', 0, 1),
   1647         fields.BitField('stream_dependency', 0, 31),
   1648         fields.ByteField('weight', 0)
   1649     ]
   1650 
   1651 ################################################# HTTP/2 Errors ########################################################
   1652 
   1653 class H2ErrorCodes(object):
   1654     """ H2ErrorCodes is an enumeration of the error codes defined in
   1655     RFC7540 par7.
   1656     This enumeration is not part of any frame because the error codes are in
   1657     common with H2ResetFrame and H2GoAwayFrame.
   1658     """
   1659 
   1660     NO_ERROR = 0x0
   1661     PROTOCOL_ERROR = 0x1
   1662     INTERNAL_ERROR = 0x2
   1663     FLOW_CONTROL_ERROR = 0x3
   1664     SETTINGS_TIMEOUT = 0x4
   1665     STREAM_CLOSED = 0x5
   1666     FRAME_SIZE_ERROR = 0x6
   1667     REFUSED_STREAM = 0x7
   1668     CANCEL = 0x8
   1669     COMPRESSION_ERROR = 0x9
   1670     CONNECT_ERROR = 0xa
   1671     ENHANCE_YOUR_CALM = 0xb
   1672     INADEQUATE_SECURITY = 0xc
   1673     HTTP_1_1_REQUIRED = 0xd
   1674 
   1675     literal = {
   1676         NO_ERROR: 'No error',
   1677         PROTOCOL_ERROR: 'Protocol error',
   1678         INTERNAL_ERROR: 'Internal error',
   1679         FLOW_CONTROL_ERROR: 'Flow control error',
   1680         SETTINGS_TIMEOUT: 'Settings timeout',
   1681         STREAM_CLOSED: 'Stream closed',
   1682         FRAME_SIZE_ERROR: 'Frame size error',
   1683         REFUSED_STREAM: 'Refused stream',
   1684         CANCEL: 'Cancel',
   1685         COMPRESSION_ERROR: 'Compression error',
   1686         CONNECT_ERROR: 'Control error',
   1687         ENHANCE_YOUR_CALM: 'Enhance your calm',
   1688         INADEQUATE_SECURITY: 'Inadequate security',
   1689         HTTP_1_1_REQUIRED: 'HTTP/1.1 required'
   1690     }
   1691 
   1692 
   1693 ########################################### HTTP/2 Reset Frame Packets #################################################
   1694 
   1695 class H2ResetFrame(H2FramePayload):
   1696     """ H2ResetFrame implements RFC 7540 par6.4
   1697     """
   1698     type_id = 3
   1699     name = 'HTTP/2 Reset Frame'
   1700     fields_desc = [
   1701         fields.EnumField('error', 0, H2ErrorCodes.literal, fmt='!I')
   1702     ]
   1703 
   1704 
   1705 ########################################### HTTP/2 Settings Frame Packets ##############################################
   1706 
   1707 class H2Setting(packet.Packet):
   1708     """ H2Setting implements a setting, as defined in RFC7540 par6.5.1
   1709     """
   1710     SETTINGS_HEADER_TABLE_SIZE = 0x1
   1711     SETTINGS_ENABLE_PUSH = 0x2
   1712     SETTINGS_MAX_CONCURRENT_STREAMS = 0x3
   1713     SETTINGS_INITIAL_WINDOW_SIZE = 0x4
   1714     SETTINGS_MAX_FRAME_SIZE = 0x5
   1715     SETTINGS_MAX_HEADER_LIST_SIZE = 0x6
   1716 
   1717     name = 'HTTP/2 Setting'
   1718     fields_desc = [
   1719         fields.EnumField('id', 0, {
   1720             SETTINGS_HEADER_TABLE_SIZE: 'Header table size',
   1721             SETTINGS_ENABLE_PUSH: 'Enable push',
   1722             SETTINGS_MAX_CONCURRENT_STREAMS: 'Max concurrent streams',
   1723             SETTINGS_INITIAL_WINDOW_SIZE: 'Initial window size',
   1724             SETTINGS_MAX_FRAME_SIZE: 'Max frame size',
   1725             SETTINGS_MAX_HEADER_LIST_SIZE: 'Max header list size'
   1726         }, fmt='!H'),
   1727         fields.IntField('value', 0)
   1728     ]
   1729 
   1730     def guess_payload_class(self, payload):
   1731         # type: (str) -> base_classes.Packet_metaclass
   1732         return config.conf.padding_layer
   1733 
   1734 
   1735 class H2SettingsFrame(H2FramePayload):
   1736     """ H2SettingsFrame implements RFC7540 par6.5
   1737     """
   1738     type_id = 4
   1739     ACK_FLAG = 0  # 0x1
   1740     flags = {
   1741         ACK_FLAG: fields.MultiFlagsEntry('A', 'ACK')
   1742     }
   1743 
   1744     name = 'HTTP/2 Settings Frame'
   1745     fields_desc = [
   1746         fields.PacketListField('settings', [], H2Setting)
   1747     ]
   1748 
   1749     def __init__(self, *args, **kwargs):
   1750         """__init__ initializes this H2SettingsFrame
   1751 
   1752         If a _pkt arg is provided (by keyword), then this is an initialization
   1753         from a string to dissect and therefore the length of the string to
   1754         dissect have distinctive characteristics that we might want to check.
   1755         This is possible because the underlayer packet (H2Frame) overrides
   1756         extract_padding method to provided only the string that must be parsed
   1757         by this packet!
   1758         @raise AssertionError
   1759         """
   1760 
   1761         # RFC7540 par6.5 p36
   1762         assert(
   1763             len(args) == 0 or (
   1764                 isinstance(args[0], bytes)
   1765                 and len(args[0]) % 6 == 0
   1766             )
   1767         ), 'Invalid settings frame; length is not a multiple of 6'
   1768         super(H2SettingsFrame, self).__init__(*args, **kwargs)
   1769 
   1770 ######################################## HTTP/2 Push Promise Frame Packets #############################################
   1771 
   1772 class H2PushPromiseFrame(H2FramePayload):
   1773     """ H2PushPromiseFrame implements RFC7540 par6.6. This packet
   1774     is the variant to use when the underlayer padding flag is cleared
   1775     """
   1776     type_id = 5
   1777     END_HEADERS_FLAG = 2  # 0x4
   1778     PADDED_FLAG = 3  # 0x8
   1779     flags = {
   1780         END_HEADERS_FLAG: fields.MultiFlagsEntry('EH', 'End Headers'),
   1781         PADDED_FLAG: fields.MultiFlagsEntry('P', 'Padded')
   1782     }
   1783 
   1784     name = 'HTTP/2 Push Promise Frame'
   1785     fields_desc = [
   1786         fields.BitField('reserved', 0, 1),
   1787         fields.BitField('stream_id', 0, 31),
   1788         fields.PacketListField('hdrs', [], HPackHeaders)
   1789     ]
   1790 
   1791 
   1792 class H2PaddedPushPromiseFrame(H2PushPromiseFrame):
   1793     """ H2PaddedPushPromiseFrame implements RFC7540 par6.6. This
   1794     packet is the variant to use when the underlayer padding flag is set
   1795     """
   1796     __slots__ = ['s_len']
   1797 
   1798     name = 'HTTP/2 Padded Push Promise Frame'
   1799     fields_desc = [
   1800         fields.FieldLenField('padlen', None, length_of='padding', fmt='B'),
   1801         fields.BitField('reserved', 0, 1),
   1802         fields.BitField('stream_id', 0, 31),
   1803         fields.PacketListField('hdrs', [], HPackHeaders,
   1804             length_from=lambda pkt: pkt.get_hdrs_len()
   1805         ),
   1806         fields.StrLenField('padding', '',
   1807             length_from=lambda pkt: pkt.getfieldval('padlen')
   1808         )
   1809     ]
   1810 
   1811     def get_hdrs_len(self):
   1812         # type: () -> int
   1813         """ get_hdrs_len computes the length of the hdrs field
   1814 
   1815         To do this computation, the length of the padlen field, reserved,
   1816         stream_id and the actual padding is subtracted to the string that was
   1817         provided to the pre_dissect fun of the pkt parameter.
   1818         @return int: the length of the hdrs field
   1819         @raise AssertionError
   1820         """
   1821         fld, padding_len = self.getfield_and_val('padlen')
   1822         padding_len_len = fld.i2len(self, padding_len)
   1823         bit_len = self.get_field('reserved').size
   1824         bit_len += self.get_field('stream_id').size
   1825 
   1826         ret = int(self.s_len
   1827             - padding_len_len
   1828             - padding_len
   1829             - (bit_len / 8)
   1830         )
   1831         assert(ret >= 0)
   1832         return ret
   1833 
   1834     def pre_dissect(self, s):
   1835         # type: (str) -> str
   1836         """pre_dissect is filling the s_len property of this instance. This
   1837         property is later used during the parsing of the hdrs PacketListField
   1838         when trying to evaluate the length of the PacketListField! This "trick"
   1839         works because the underlayer packet (H2Frame) is assumed to override the
   1840         "extract_padding" method and to only provide to this packet the data
   1841         necessary for this packet. Tricky, tricky, will break some day probably!
   1842         """
   1843         self.s_len = len(s)
   1844         return s
   1845 
   1846 ############################################### HTTP/2 Ping Frame Packets ##############################################
   1847 
   1848 class H2PingFrame(H2FramePayload):
   1849     """ H2PingFrame implements the RFC 7540 par6.7
   1850     """
   1851     type_id = 6
   1852     ACK_FLAG = 0  # 0x1
   1853     flags = {
   1854         ACK_FLAG: fields.MultiFlagsEntry('A', 'ACK')
   1855     }
   1856 
   1857     name = 'HTTP/2 Ping Frame'
   1858     fields_desc = [
   1859         fields.LongField('opaque', 0)
   1860     ]
   1861 
   1862     def __init__(self, *args, **kwargs):
   1863         """
   1864         @raise AssertionError
   1865         """
   1866         # RFC7540 par6.7 p42
   1867         assert(
   1868             len(args) == 0 or (
   1869                 (isinstance(args[0], bytes) or
   1870                 isinstance(args[0], str))
   1871                 and len(args[0]) == 8
   1872             )
   1873         ), 'Invalid ping frame; length is not 8'
   1874         super(H2PingFrame, self).__init__(*args, **kwargs)
   1875 
   1876 
   1877 ############################################# HTTP/2 GoAway Frame Packets ##############################################
   1878 
   1879 class H2GoAwayFrame(H2FramePayload):
   1880     """ H2GoAwayFrame implements the RFC 7540 par6.8
   1881     """
   1882     type_id = 7
   1883 
   1884     name = 'HTTP/2 Go Away Frame'
   1885     fields_desc = [
   1886         fields.BitField('reserved', 0, 1),
   1887         fields.BitField('last_stream_id', 0, 31),
   1888         fields.EnumField('error', 0, H2ErrorCodes.literal, fmt='!I'),
   1889         fields.StrField('additional_data', '')
   1890     ]
   1891 
   1892 ###################################### HTTP/2 Window Update Frame Packets ##############################################
   1893 
   1894 class H2WindowUpdateFrame(H2FramePayload):
   1895     """ H2WindowUpdateFrame implements the RFC 7540 par6.9
   1896     """
   1897     type_id = 8
   1898 
   1899     name = 'HTTP/2 Window Update Frame'
   1900     fields_desc = [
   1901         fields.BitField('reserved', 0, 1),
   1902         fields.BitField('win_size_incr', 0, 31)
   1903     ]
   1904 
   1905     def __init__(self, *args, **kwargs):
   1906         """
   1907         @raise AssertionError
   1908         """
   1909         # RFC7540 par6.9 p46
   1910         assert(
   1911             len(args) == 0 or (
   1912                 (isinstance(args[0], bytes) or
   1913                 isinstance(args[0], str))
   1914                 and len(args[0]) == 4
   1915             )
   1916         ), 'Invalid window update frame; length is not 4'
   1917         super(H2WindowUpdateFrame, self).__init__(*args, **kwargs)
   1918 
   1919 ####################################### HTTP/2 Continuation Frame Packets ##############################################
   1920 
   1921 class H2ContinuationFrame(H2FramePayload):
   1922     """ H2ContinuationFrame implements the RFC 7540 par6.10
   1923     """
   1924     type_id = 9
   1925     END_HEADERS_FLAG = 2  # Ox4
   1926     flags = {
   1927         END_HEADERS_FLAG: fields.MultiFlagsEntry('EH', 'End Headers')
   1928     }
   1929 
   1930     name = 'HTTP/2 Continuation Frame'
   1931     fields_desc = [
   1932         fields.PacketListField('hdrs', [], HPackHeaders)
   1933     ]
   1934 
   1935 ########################################## HTTP/2 Base Frame Packets ###################################################
   1936 
   1937 class H2Frame(packet.Packet):
   1938     """ H2Frame implements the frame structure as defined in RFC 7540 par4.1
   1939 
   1940     This packet may have a payload (one of the H2FramePayload) or none, in some
   1941     rare cases such as settings acknowledgement)
   1942     """
   1943     name = 'HTTP/2 Frame'
   1944     fields_desc = [
   1945         fields.X3BytesField('len', None),
   1946         fields.EnumField('type', None, {
   1947             0: 'DataFrm',
   1948             1: 'HdrsFrm',
   1949             2: 'PrioFrm',
   1950             3: 'RstFrm',
   1951             4: 'SetFrm',
   1952             5: 'PushFrm',
   1953             6: 'PingFrm',
   1954             7: 'GoawayFrm',
   1955             8: 'WinFrm',
   1956             9: 'ContFrm'
   1957         }, "b"),
   1958         fields.MultiFlagsField('flags', set(), 8, {
   1959                 H2DataFrame.type_id: H2DataFrame.flags,
   1960                 H2HeadersFrame.type_id: H2HeadersFrame.flags,
   1961                 H2PushPromiseFrame.type_id: H2PushPromiseFrame.flags,
   1962                 H2SettingsFrame.type_id: H2SettingsFrame.flags,
   1963                 H2PingFrame.type_id: H2PingFrame.flags,
   1964                 H2ContinuationFrame.type_id: H2ContinuationFrame.flags,
   1965             },
   1966             depends_on=lambda pkt: pkt.getfieldval('type')
   1967         ),
   1968         fields.BitField('reserved', 0, 1),
   1969         fields.BitField('stream_id', 0, 31)
   1970     ]
   1971 
   1972     def guess_payload_class(self, payload):
   1973         # type: (str) -> base_classes.Packet_metaclass
   1974         """ guess_payload_class returns the Class object to use for parsing a payload
   1975         This function uses the H2Frame.type field value to decide which payload to parse. The implement cannot be
   1976         performed using the simple bind_layers helper because sometimes the selection of which Class object to return
   1977         also depends on the H2Frame.flags value.
   1978 
   1979         @param payload:
   1980         @return:
   1981         """
   1982         if len(payload) == 0:
   1983             return packet.NoPayload
   1984 
   1985         t = self.getfieldval('type')
   1986         if t == H2DataFrame.type_id:
   1987             if H2DataFrame.flags[H2DataFrame.PADDED_FLAG].short in self.getfieldval('flags'):
   1988                 return H2PaddedDataFrame
   1989             return H2DataFrame
   1990 
   1991         if t == H2HeadersFrame.type_id:
   1992             if H2HeadersFrame.flags[H2HeadersFrame.PADDED_FLAG].short in self.getfieldval('flags'):
   1993                 if H2HeadersFrame.flags[H2HeadersFrame.PRIORITY_FLAG].short in self.getfieldval('flags'):
   1994                     return H2PaddedPriorityHeadersFrame
   1995                 else:
   1996                     return H2PaddedHeadersFrame
   1997             elif H2HeadersFrame.flags[H2HeadersFrame.PRIORITY_FLAG].short in self.getfieldval('flags'):
   1998                     return H2PriorityHeadersFrame
   1999             return H2HeadersFrame
   2000 
   2001         if t == H2PriorityFrame.type_id:
   2002             return H2PriorityFrame
   2003 
   2004         if t == H2ResetFrame.type_id:
   2005             return H2ResetFrame
   2006 
   2007         if t == H2SettingsFrame.type_id:
   2008             return H2SettingsFrame
   2009 
   2010         if t == H2PushPromiseFrame.type_id:
   2011             if H2PushPromiseFrame.flags[H2PushPromiseFrame.PADDED_FLAG].short in self.getfieldval('flags'):
   2012                 return H2PaddedPushPromiseFrame
   2013             return H2PushPromiseFrame
   2014 
   2015         if t == H2PingFrame.type_id:
   2016             return H2PingFrame
   2017 
   2018         if t == H2GoAwayFrame.type_id:
   2019             return H2GoAwayFrame
   2020 
   2021         if t == H2WindowUpdateFrame.type_id:
   2022             return H2WindowUpdateFrame
   2023 
   2024         if t == H2ContinuationFrame.type_id:
   2025             return H2ContinuationFrame
   2026 
   2027         return config.conf.padding_layer
   2028 
   2029     def extract_padding(self, s):
   2030         # type: (str) -> Tuple[str, str]
   2031         """
   2032         @param str s: the string from which to tell the padding and the payload data apart
   2033         @return (str, str): the padding and the payload data strings
   2034         @raise AssertionError
   2035         """
   2036         assert isinstance(self.len, six.integer_types) and self.len >= 0, 'Invalid length: negative len?'
   2037         assert len(s) >= self.len, 'Invalid length: string too short for this length'
   2038         return s[:self.len], s[self.len:]
   2039 
   2040     def post_build(self, p, pay):
   2041         # type: (str, str) -> str
   2042         """
   2043         @param str p: the stringified packet
   2044         @param str pay: the stringified payload
   2045         @return str: the stringified packet and payload, with the packet length field "patched"
   2046         @raise AssertionError
   2047         """
   2048         # This logic, while awkward in the post_build and more reasonable in
   2049         # a self_build is implemented here for performance tricks reason
   2050         if self.getfieldval('len') is None:
   2051             assert(len(pay) < (1 << 24)), 'Invalid length: payload is too long'
   2052             p = struct.pack('!L', len(pay))[1:] + p[3:]
   2053         return super(H2Frame, self).post_build(p, pay)
   2054 
   2055 class H2Seq(packet.Packet):
   2056     """ H2Seq is a helper packet that contains several H2Frames and their
   2057     payload. This packet can be used, for instance, while reading manually from
   2058     a TCP socket.
   2059     """
   2060     name = 'HTTP/2 Frame Sequence'
   2061     fields_desc = [
   2062         fields.PacketListField('frames', [], H2Frame)
   2063     ]
   2064 
   2065     def guess_payload_class(self, payload):
   2066         # type: (str) -> base_classes.Packet_metaclass
   2067         return config.conf.padding_layer
   2068 
   2069 
   2070 packet.bind_layers(H2Frame, H2DataFrame, {'type': H2DataFrame.type_id})
   2071 packet.bind_layers(H2Frame, H2PaddedDataFrame, {'type': H2DataFrame.type_id})
   2072 packet.bind_layers(H2Frame, H2HeadersFrame, {'type': H2HeadersFrame.type_id})
   2073 packet.bind_layers(H2Frame, H2PaddedHeadersFrame, {'type': H2HeadersFrame.type_id})
   2074 packet.bind_layers(H2Frame, H2PriorityHeadersFrame, {'type': H2HeadersFrame.type_id})
   2075 packet.bind_layers(H2Frame, H2PaddedPriorityHeadersFrame, {'type': H2HeadersFrame.type_id})
   2076 packet.bind_layers(H2Frame, H2PriorityFrame, {'type': H2PriorityFrame.type_id})
   2077 packet.bind_layers(H2Frame, H2ResetFrame, {'type': H2ResetFrame.type_id})
   2078 packet.bind_layers(H2Frame, H2SettingsFrame, {'type': H2SettingsFrame.type_id})
   2079 packet.bind_layers(H2Frame, H2PingFrame, {'type': H2PingFrame.type_id})
   2080 packet.bind_layers(H2Frame, H2PushPromiseFrame, {'type': H2PushPromiseFrame.type_id})
   2081 packet.bind_layers(H2Frame, H2PaddedPushPromiseFrame, {'type': H2PaddedPushPromiseFrame.type_id})
   2082 packet.bind_layers(H2Frame, H2GoAwayFrame, {'type': H2GoAwayFrame.type_id})
   2083 packet.bind_layers(H2Frame, H2WindowUpdateFrame, {'type': H2WindowUpdateFrame.type_id})
   2084 packet.bind_layers(H2Frame, H2ContinuationFrame, {'type': H2ContinuationFrame.type_id})
   2085 
   2086 
   2087 ########################################## HTTP/2 Connection Preface ###################################################
   2088 # From RFC 7540 par3.5
   2089 H2_CLIENT_CONNECTION_PREFACE = bytes_hex('505249202a20485454502f322e300d0a0d0a534d0d0a0d0a')
   2090 
   2091 
   2092 ########################################################################################################################
   2093 ################################################### HTTP/2 Helpers #####################################################
   2094 ########################################################################################################################
   2095 
   2096 class HPackHdrEntry(Sized):
   2097     """ HPackHdrEntry is an entry of the HPackHdrTable helper
   2098 
   2099     Each HPackHdrEntry instance is a header line (name and value). Names are
   2100     normalized (lowercased), according to RFC 7540 par8.1.2
   2101     """
   2102     __slots__ = ['_name', '_len', '_value']
   2103 
   2104     def __init__(self, name, value):
   2105         # type: (str, str) -> None
   2106         """
   2107         @raise AssertionError
   2108         """
   2109         assert(len(name) > 0)
   2110 
   2111         self._name = name.lower()
   2112         self._value = value
   2113 
   2114         # 32 bytes is an RFC-hardcoded value: see RFC 7541 par4.1
   2115         self._len = (32 + len(self._name) + len(self._value))
   2116 
   2117     def name(self):
   2118         # type: () -> str
   2119         return self._name
   2120 
   2121     def value(self):
   2122         # type: () -> str
   2123         return self._value
   2124 
   2125     def size(self):
   2126         # type: () -> int
   2127         """ size returns the "length" of the header entry, as defined in
   2128         RFC 7541 par4.1.
   2129         """
   2130         return self._len
   2131 
   2132     __len__ = size
   2133 
   2134     def __str__(self):
   2135         # type: () -> str
   2136         """ __str__ returns the header as it would be formated in textual format
   2137         """
   2138         if self._name.startswith(':'):
   2139             return "{} {}".format(self._name, self._value)
   2140         else:
   2141             return "{}: {}".format(self._name, self._value)
   2142     def __bytes__(self):
   2143         return raw(self.__str__())
   2144 
   2145 
   2146 class HPackHdrTable(Sized):
   2147     """ HPackHdrTable is a helper class that implements some of the logic
   2148     associated with indexing of headers (read and write operations in this
   2149     "registry". THe HPackHdrTable also implements convenience functions to easily
   2150     convert to and from textual representation and binary representation of
   2151     a HTTP/2 requests
   2152     """
   2153     __slots__ = [
   2154         '_dynamic_table',
   2155         '_dynamic_table_max_size',
   2156         '_dynamic_table_cap_size',
   2157         '_regexp'
   2158     ]
   2159     """:var _dynamic_table: the list containing entries requested to be added by
   2160     the peer and registered with a register() call
   2161     :var _dynamic_table_max_size: the current maximum size of the dynamic table
   2162     in bytes. This value is updated with the Dynamic Table Size Update messages
   2163     defined in RFC 7541 par6.3
   2164     :var _dynamic_table_cap_size: the maximum size of the dynamic table in
   2165     bytes. This value is updated with the SETTINGS_HEADER_TABLE_SIZE HTTP/2
   2166     setting.
   2167     """
   2168 
   2169     # Manually imported from RFC 7541 Appendix A
   2170     _static_entries = {
   2171         1: HPackHdrEntry(':authority', ''),
   2172         2: HPackHdrEntry(':method', 'GET'),
   2173         3: HPackHdrEntry(':method', 'POST'),
   2174         4: HPackHdrEntry(':path', '/'),
   2175         5: HPackHdrEntry(':path', '/index.html'),
   2176         6: HPackHdrEntry(':scheme', 'http'),
   2177         7: HPackHdrEntry(':scheme', 'https'),
   2178         8: HPackHdrEntry(':status', '200'),
   2179         9: HPackHdrEntry(':status', '204'),
   2180         10: HPackHdrEntry(':status', '206'),
   2181         11: HPackHdrEntry(':status', '304'),
   2182         12: HPackHdrEntry(':status', '400'),
   2183         13: HPackHdrEntry(':status', '404'),
   2184         14: HPackHdrEntry(':status', '500'),
   2185         15: HPackHdrEntry('accept-charset', ''),
   2186         16: HPackHdrEntry('accept-encoding', 'gzip, deflate'),
   2187         17: HPackHdrEntry('accept-language', ''),
   2188         18: HPackHdrEntry('accept-ranges', ''),
   2189         19: HPackHdrEntry('accept', ''),
   2190         20: HPackHdrEntry('access-control-allow-origin', ''),
   2191         21: HPackHdrEntry('age', ''),
   2192         22: HPackHdrEntry('allow', ''),
   2193         23: HPackHdrEntry('authorization', ''),
   2194         24: HPackHdrEntry('cache-control', ''),
   2195         25: HPackHdrEntry('content-disposition', ''),
   2196         26: HPackHdrEntry('content-encoding', ''),
   2197         27: HPackHdrEntry('content-language', ''),
   2198         28: HPackHdrEntry('content-length', ''),
   2199         29: HPackHdrEntry('content-location', ''),
   2200         30: HPackHdrEntry('content-range', ''),
   2201         31: HPackHdrEntry('content-type', ''),
   2202         32: HPackHdrEntry('cookie', ''),
   2203         33: HPackHdrEntry('date', ''),
   2204         34: HPackHdrEntry('etag', ''),
   2205         35: HPackHdrEntry('expect', ''),
   2206         36: HPackHdrEntry('expires', ''),
   2207         37: HPackHdrEntry('from', ''),
   2208         38: HPackHdrEntry('host', ''),
   2209         39: HPackHdrEntry('if-match', ''),
   2210         40: HPackHdrEntry('if-modified-since', ''),
   2211         41: HPackHdrEntry('if-none-match', ''),
   2212         42: HPackHdrEntry('if-range', ''),
   2213         43: HPackHdrEntry('if-unmodified-since', ''),
   2214         44: HPackHdrEntry('last-modified', ''),
   2215         45: HPackHdrEntry('link', ''),
   2216         46: HPackHdrEntry('location', ''),
   2217         47: HPackHdrEntry('max-forwards', ''),
   2218         48: HPackHdrEntry('proxy-authenticate', ''),
   2219         49: HPackHdrEntry('proxy-authorization', ''),
   2220         50: HPackHdrEntry('range', ''),
   2221         51: HPackHdrEntry('referer', ''),
   2222         52: HPackHdrEntry('refresh', ''),
   2223         53: HPackHdrEntry('retry-after', ''),
   2224         54: HPackHdrEntry('server', ''),
   2225         55: HPackHdrEntry('set-cookie', ''),
   2226         56: HPackHdrEntry('strict-transport-security', ''),
   2227         57: HPackHdrEntry('transfer-encoding', ''),
   2228         58: HPackHdrEntry('user-agent', ''),
   2229         59: HPackHdrEntry('vary', ''),
   2230         60: HPackHdrEntry('via', ''),
   2231         61: HPackHdrEntry('www-authenticate', ''),
   2232     }
   2233 
   2234     # The value of this variable cannot be determined at declaration time. It is
   2235     # initialized by an init_static_table call
   2236     _static_entries_last_idx = None
   2237 
   2238     @classmethod
   2239     def init_static_table(cls):
   2240         # type: () -> None
   2241         cls._static_entries_last_idx = max(cls._static_entries)
   2242 
   2243     def __init__(self, dynamic_table_max_size=4096, dynamic_table_cap_size=4096):
   2244         # type: (int, int) -> None
   2245         """
   2246         @param int dynamic_table_max_size: the current maximum size of the dynamic entry table in bytes
   2247         @param int dynamic_table_cap_size: the maximum-maximum size of the dynamic entry table in bytes
   2248         @raises AssertionError
   2249         """
   2250         self._regexp = None
   2251         if isinstance(type(self)._static_entries_last_idx, type(None)):
   2252             type(self).init_static_table()
   2253 
   2254         assert dynamic_table_max_size <= dynamic_table_cap_size, \
   2255             'EINVAL: dynamic_table_max_size too large; expected value is less or equal to dynamic_table_cap_size'
   2256 
   2257         self._dynamic_table = []  # type: List[HPackHdrEntry]
   2258         self._dynamic_table_max_size = dynamic_table_max_size
   2259         self._dynamic_table_cap_size = dynamic_table_cap_size
   2260 
   2261     def __getitem__(self, idx):
   2262         # type: (int) -> HPackHdrEntry
   2263         """Gets an element from the header tables (static or dynamic indifferently)
   2264 
   2265         @param int idx: the index number of the entry to retrieve. If the index
   2266         value is superior to the last index of the static entry table, then the
   2267         dynamic entry type is requested, following the procedure described in
   2268         RFC 7541 par2.3.3
   2269         @return HPackHdrEntry: the entry defined at this requested index. If the entry does not exist, KeyError is
   2270           raised
   2271         @raise KeyError, AssertionError
   2272         """
   2273         assert(idx >= 0)
   2274         if idx > type(self)._static_entries_last_idx:
   2275             idx -= type(self)._static_entries_last_idx + 1
   2276             if idx >= len(self._dynamic_table):
   2277                 raise KeyError(
   2278                     'EINVAL: idx: out-of-bound read: {}; maximum index: {}'.format(idx, len(self._dynamic_table))
   2279                 )
   2280             return self._dynamic_table[idx]
   2281         return type(self)._static_entries[idx]
   2282 
   2283     def resize(self, ns):
   2284         # type: (int) -> None
   2285         """Resize the dynamic table. If the new size (ns) must be between 0 and
   2286         the cap size. If the new size is lower than the current size of the
   2287         dynamic table, entries are evicted.
   2288         @param int ns: the new size of the dynamic table
   2289         @raise AssertionError
   2290         """
   2291         assert 0 <= ns <= self._dynamic_table_cap_size, \
   2292             'EINVAL: ns: out-of-range value; expected value is in the range [0;{}['.format(self._dynamic_table_cap_size)
   2293 
   2294         old_size = self._dynamic_table_max_size
   2295         self._dynamic_table_max_size = ns
   2296         if old_size > self._dynamic_table_max_size:
   2297             self._reduce_dynamic_table()
   2298 
   2299     def recap(self, nc):
   2300         # type: (int) -> None
   2301         """recap changes the maximum size limit of the dynamic table. It also
   2302         proceeds to a resize(), if the new size is lower than the previous one.
   2303         @param int nc: the new cap of the dynamic table (that is the maximum-maximum size)
   2304         @raise AssertionError
   2305         """
   2306         assert(nc >= 0)
   2307         t = self._dynamic_table_cap_size > nc
   2308         self._dynamic_table_cap_size = nc
   2309 
   2310         if t:
   2311             # The RFC is not clear about whether this resize should happen;
   2312             # we do it anyway
   2313             self.resize(nc)
   2314 
   2315     def _reduce_dynamic_table(self, new_entry_size=0):
   2316         # type: (int) -> None
   2317         """_reduce_dynamic_table evicts entries from the dynamic table until it
   2318         fits in less than the current size limit. The optional parameter,
   2319         new_entry_size, allows the resize to happen so that a new entry of this
   2320         size fits in.
   2321         @param int new_entry_size: if called before adding a new entry, the size of the new entry in bytes (following
   2322         the RFC7541 definition of the size of an entry)
   2323         @raise AssertionError
   2324         """
   2325         assert(new_entry_size >= 0)
   2326         cur_sz = len(self)
   2327         dyn_tbl_sz = len(self._dynamic_table)
   2328         while dyn_tbl_sz > 0 and cur_sz + new_entry_size > self._dynamic_table_max_size:
   2329             last_elmt_sz = len(self._dynamic_table[-1])
   2330             self._dynamic_table.pop()
   2331             dyn_tbl_sz -= 1
   2332             cur_sz -= last_elmt_sz
   2333 
   2334     def register(self, hdrs):
   2335         # type: (Union[HPackLitHdrFldWithIncrIndexing, H2Frame, List[HPackHeaders]]) -> None
   2336         """register adds to this table the instances of
   2337         HPackLitHdrFldWithIncrIndexing provided as parameters.
   2338 
   2339         A H2Frame with a H2HeadersFrame payload can be provided, as much as a
   2340         python list of HPackHeaders or a single HPackLitHdrFldWithIncrIndexing
   2341         instance.
   2342         @param HPackLitHdrFldWithIncrIndexing|H2Frame|list of HPackHeaders hdrs: the header(s) to register
   2343         @raise AssertionError
   2344         """
   2345         if isinstance(hdrs, H2Frame):
   2346             hdrs = [hdr for hdr in hdrs.payload.hdrs if isinstance(hdr, HPackLitHdrFldWithIncrIndexing)]
   2347         elif isinstance(hdrs, HPackLitHdrFldWithIncrIndexing):
   2348             hdrs = [hdrs]
   2349         else:
   2350             hdrs = [hdr for hdr in hdrs if isinstance(hdr, HPackLitHdrFldWithIncrIndexing)]
   2351 
   2352         for hdr in hdrs:
   2353             if hdr.index == 0:
   2354                 hdr_name = hdr.hdr_name.getfieldval('data').origin()
   2355             else:
   2356                 idx = int(hdr.index)
   2357                 hdr_name = self[idx].name()
   2358             hdr_value = hdr.hdr_value.getfieldval('data').origin()
   2359 
   2360             # Note: we do not delete any existing hdrentry with the same names
   2361             # and values, as dictated by RFC 7541 par2.3.2
   2362 
   2363             entry = HPackHdrEntry(hdr_name, hdr_value)
   2364             # According to RFC7541 par4.4, "Before a new entry is added to
   2365             # the dynamic table, entries are evicted
   2366             # from the end of the dynamic table until the size of the dynamic
   2367             # table is less than or equal to (maximum size - new entry size)
   2368             # or until the table is empty"
   2369             # Also, "It is not an error to attempt to add an entry that is
   2370             # larger than the maximum size; an attempt to add an entry larger
   2371             # than the maximum size causes the table to be emptied of all
   2372             # existing entries and results in an empty table"
   2373             # For this reason, we first call the _reduce_dynamic_table and
   2374             # then throw an assertion error if the new entry does not fit in
   2375             new_entry_len = len(entry)
   2376             self._reduce_dynamic_table(new_entry_len)
   2377             assert(new_entry_len <= self._dynamic_table_max_size)
   2378             self._dynamic_table.insert(0, entry)
   2379 
   2380     def get_idx_by_name(self, name):
   2381         # type: (str) -> Optional[int]
   2382         """ get_idx_by_name returns the index of a matching registered header
   2383 
   2384         This implementation will prefer returning a static entry index whenever
   2385         possible. If multiple matching header name are found in the static
   2386         table, there is insurance that the first entry (lowest index number)
   2387         will be returned.
   2388         If no matching header is found, this method returns None.
   2389         """
   2390         name = name.lower()
   2391         for key, val in six.iteritems(type(self)._static_entries):
   2392             if val.name() == name:
   2393                 return key
   2394         for idx, val in enumerate(self._dynamic_table):
   2395             if val.name() == name:
   2396                 return type(self)._static_entries_last_idx + idx + 1
   2397         return None
   2398 
   2399     def get_idx_by_name_and_value(self, name, value):
   2400         # type: (str, str) -> Optional[int]
   2401         """ get_idx_by_name_and_value returns the index of a matching registered
   2402         header
   2403 
   2404         This implementation will prefer returning a static entry index whenever
   2405         possible. If multiple matching headers are found in the dynamic table,
   2406         the lowest index is returned
   2407         If no matching header is found, this method returns None.
   2408         """
   2409         name = name.lower()
   2410         for key, val in six.iteritems(type(self)._static_entries):
   2411             if val.name() == name and val.value() == value:
   2412                 return key
   2413         for idx, val in enumerate(self._dynamic_table):
   2414             if val.name() == name and val.value() == value:
   2415                 return type(self)._static_entries_last_idx + idx + 1
   2416         return None
   2417 
   2418     def __len__(self):
   2419         # type: () -> int
   2420         """ __len__ returns the summed length of all dynamic entries
   2421         """
   2422         return sum(len(x) for x in self._dynamic_table)
   2423 
   2424     def gen_txt_repr(self, hdrs, register=True):
   2425         # type: (Union[H2Frame, List[HPackHeaders]], Optional[bool]) -> str
   2426         """ gen_txt_repr returns a "textual" representation of the provided
   2427         headers.
   2428 
   2429         The output of this function is compatible with the input of
   2430         parse_txt_hdrs.
   2431         @param H2Frame|list of HPackHeaders hdrs: the list of headers to convert to textual representation
   2432         @param bool: whether incremental headers should be added to the dynamic table as we generate the text
   2433             representation
   2434         @return str: the textual representation of the provided headers
   2435         @raise AssertionError
   2436         """
   2437         l = []
   2438         if isinstance(hdrs, H2Frame):
   2439             hdrs = hdrs.payload.hdrs
   2440 
   2441         for hdr in hdrs:
   2442             try:
   2443                 if isinstance(hdr, HPackIndexedHdr):
   2444                     l.append('{}'.format(self[hdr.index]))
   2445                 elif isinstance(hdr, (
   2446                     HPackLitHdrFldWithIncrIndexing,
   2447                     HPackLitHdrFldWithoutIndexing
   2448                 )):
   2449                     if hdr.index != 0:
   2450                         name = self[hdr.index].name()
   2451                     else:
   2452                         name = hdr.hdr_name.getfieldval('data').origin()
   2453                     if name.startswith(':'):
   2454                         l.append(
   2455                             '{} {}'.format(
   2456                                 name,
   2457                                 hdr.hdr_value.getfieldval('data').origin()
   2458                             )
   2459                         )
   2460                     else:
   2461                         l.append(
   2462                             '{}: {}'.format(
   2463                                 name,
   2464                                 hdr.hdr_value.getfieldval('data').origin()
   2465                             )
   2466                         )
   2467                 if register and isinstance(hdr, HPackLitHdrFldWithIncrIndexing):
   2468                     self.register(hdr)
   2469             except KeyError as e:  # raised when an index is out-of-bound
   2470                 print(e)
   2471                 continue
   2472         return '\n'.join(l)
   2473 
   2474     @staticmethod
   2475     def _optimize_header_length_and_packetify(s):
   2476         # type: (str) -> HPackHdrString
   2477         # type: (str) -> HPackHdrString
   2478         zs = HPackZString(s)
   2479         if len(zs) >= len(s):
   2480             return HPackHdrString(data=HPackLiteralString(s))
   2481         return HPackHdrString(data=zs)
   2482 
   2483     def _convert_a_header_to_a_h2_header(self, hdr_name, hdr_value, is_sensitive, should_index):
   2484         # type: (str, str, Callable[[str, str], bool], Callable[[str], bool]) -> Tuple[HPackHeaders, int]
   2485         """ _convert_a_header_to_a_h2_header builds a HPackHeaders from a header
   2486         name and a value. It returns a HPackIndexedHdr whenever possible. If not,
   2487         it returns a HPackLitHdrFldWithoutIndexing or a
   2488         HPackLitHdrFldWithIncrIndexing, based on the should_index callback.
   2489         HPackLitHdrFldWithoutIndexing is forced if the is_sensitive callback
   2490         returns True and its never_index bit is set.
   2491         """
   2492 
   2493         # If both name and value are already indexed
   2494         idx = self.get_idx_by_name_and_value(hdr_name, hdr_value)
   2495         if idx is not None:
   2496             return HPackIndexedHdr(index=idx), len(self[idx])
   2497 
   2498         # The value is not indexed for this headers
   2499 
   2500         hdr_value = self._optimize_header_length_and_packetify(hdr_value)
   2501 
   2502         # Searching if the header name is indexed
   2503         idx = self.get_idx_by_name(hdr_name)
   2504         if idx is not None:
   2505             if is_sensitive(
   2506                 hdr_name,
   2507                 hdr_value.getfieldval('data').origin()
   2508             ):
   2509                 return HPackLitHdrFldWithoutIndexing(
   2510                     never_index=1,
   2511                     index=idx,
   2512                     hdr_value=hdr_value
   2513                 ), len(
   2514                     HPackHdrEntry(
   2515                         self[idx].name(),
   2516                         hdr_value.getfieldval('data').origin()
   2517                     )
   2518                 )
   2519             if should_index(hdr_name):
   2520                 return HPackLitHdrFldWithIncrIndexing(
   2521                     index=idx,
   2522                     hdr_value=hdr_value
   2523                 ), len(
   2524                     HPackHdrEntry(
   2525                         self[idx].name(),
   2526                         hdr_value.getfieldval('data').origin()
   2527                     )
   2528                 )
   2529             return HPackLitHdrFldWithoutIndexing(
   2530                 index=idx,
   2531                 hdr_value=hdr_value
   2532             ), len(
   2533                 HPackHdrEntry(
   2534                     self[idx].name(),
   2535                     hdr_value.getfieldval('data').origin()
   2536                 )
   2537             )
   2538 
   2539         hdr_name = self._optimize_header_length_and_packetify(hdr_name)
   2540 
   2541         if is_sensitive(
   2542             hdr_name.getfieldval('data').origin(),
   2543             hdr_value.getfieldval('data').origin()
   2544         ):
   2545             return HPackLitHdrFldWithoutIndexing(
   2546                 never_index=1,
   2547                 index=0,
   2548                 hdr_name=hdr_name,
   2549                 hdr_value=hdr_value
   2550             ), len(
   2551                 HPackHdrEntry(
   2552                     hdr_name.getfieldval('data').origin(),
   2553                     hdr_value.getfieldval('data').origin()
   2554                 )
   2555             )
   2556         if should_index(hdr_name.getfieldval('data').origin()):
   2557             return HPackLitHdrFldWithIncrIndexing(
   2558                 index=0,
   2559                 hdr_name=hdr_name,
   2560                 hdr_value=hdr_value
   2561             ), len(
   2562                 HPackHdrEntry(
   2563                     hdr_name.getfieldval('data').origin(),
   2564                     hdr_value.getfieldval('data').origin()
   2565                 )
   2566             )
   2567         return HPackLitHdrFldWithoutIndexing(
   2568             index=0,
   2569             hdr_name=hdr_name,
   2570             hdr_value=hdr_value
   2571         ), len(
   2572             HPackHdrEntry(
   2573                 hdr_name.getfieldval('data').origin(),
   2574                 hdr_value.getfieldval('data').origin()
   2575             )
   2576         )
   2577 
   2578     def _parse_header_line(self, l):
   2579         # type: (str) -> Union[Tuple[None, None], Tuple[str, str]]
   2580 
   2581         if self._regexp is None:
   2582             self._regexp = re.compile(b'^(?::([a-z\-0-9]+)|([a-z\-0-9]+):)\s+(.+)$')
   2583 
   2584         hdr_line = l.rstrip()
   2585         grp = self._regexp.match(hdr_line)
   2586 
   2587         if grp is None or len(grp.groups()) != 3:
   2588             return None, None
   2589 
   2590         if grp.group(1) is not None:
   2591             hdr_name = b':'+grp.group(1)
   2592         else:
   2593             hdr_name = grp.group(2)
   2594         return plain_str(hdr_name.lower()), plain_str(grp.group(3))
   2595 
   2596     def parse_txt_hdrs(self,
   2597                        s,  # type: str
   2598                        stream_id=1,  # type: int
   2599                        body=None,  # type: Optional[str]
   2600                        max_frm_sz=4096,  # type: int
   2601                        max_hdr_lst_sz=0,  # type: int
   2602                        is_sensitive=lambda n, v: False,  # type: Callable[[str, str], bool]
   2603                        should_index=lambda x: False,  # type: Callable[[str], bool]
   2604                        register=True,  # type: bool
   2605     ):
   2606         # type: (...) -> H2Seq
   2607         """ parse_txt_hdrs parses headers expressed in text and converts them
   2608         into a series of H2Frames with the "correct" flags. A body can be provided
   2609         in which case, the data frames are added, bearing the End Stream flag,
   2610         instead of the H2HeadersFrame/H2ContinuationFrame. The generated frames
   2611         may respect max_frm_sz (SETTINGS_MAX_FRAME_SIZE) and
   2612         max_hdr_lst_sz (SETTINGS_MAX_HEADER_LIST_SIZE) if provided. The headers
   2613         are split into multiple headers fragment (and H2Frames) to respect these
   2614         limits. Also, a callback can be provided to tell if a header should be
   2615         never indexed (sensitive headers, such as cookies), and another callback
   2616         say if the header should be registered into the index table at all.
   2617         For an header to be registered, the is_sensitive callback must return
   2618         False AND the should_index callback should return True. This is the
   2619         default behavior.
   2620 
   2621         @param str s: the string to parse for headers
   2622         @param int stream_id: the stream id to use in the generated H2Frames
   2623         @param str|None body: the eventual body of the request, that is added to the generated frames
   2624         @param int max_frm_sz: the maximum frame size. This is used to split the headers and data frames according to
   2625         the maximum frame size negociated for this connection
   2626         @param int max_hdr_lst_sz: the maximum size of a "header fragment" as defined in RFC7540
   2627         @param callable is_sensitive: callback that returns True if the provided header is sensible and must be stored
   2628         in a header packet requesting this header never to be indexed
   2629         @param callable should_index: callback that returns True if the provided header should be stored in a header
   2630         packet requesting indexation in the dynamic header table.
   2631         @param bool register: whether to register new headers with incremental indexing as we parse them
   2632         @raise Exception
   2633         """
   2634 
   2635         sio = BytesIO(s)
   2636 
   2637         base_frm_len = len(raw(H2Frame()))
   2638 
   2639         ret = H2Seq()
   2640         cur_frm = H2HeadersFrame()  # type: Union[H2HeadersFrame, H2ContinuationFrame]
   2641         cur_hdr_sz = 0
   2642 
   2643         # For each line in the headers str to parse
   2644         for hdr_line in sio:
   2645             hdr_name, hdr_value = self._parse_header_line(hdr_line)
   2646             if hdr_name is None:
   2647                 continue
   2648 
   2649             new_hdr, new_hdr_len = self._convert_a_header_to_a_h2_header(
   2650                 hdr_name, hdr_value, is_sensitive, should_index
   2651             )
   2652             new_hdr_bin_len = len(raw(new_hdr))
   2653 
   2654             if register and isinstance(new_hdr, HPackLitHdrFldWithIncrIndexing):
   2655                 self.register(new_hdr)
   2656 
   2657             # The new header binary length (+ base frame size) must not exceed
   2658             # the maximum frame size or it will just never fit. Also, the
   2659             # header entry length (as specified in RFC7540 par6.5.2) must not
   2660             # exceed the maximum length of a header fragment or it will just
   2661             # never fit
   2662             if (new_hdr_bin_len + base_frm_len > max_frm_sz
   2663                 or (max_hdr_lst_sz != 0 and new_hdr_len > max_hdr_lst_sz)
   2664             ):
   2665                 raise Exception('Header too long: {}'.format(hdr_name))
   2666 
   2667             if (max_frm_sz < len(raw(cur_frm)) + base_frm_len + new_hdr_len
   2668                 or (
   2669                     max_hdr_lst_sz != 0
   2670                     and max_hdr_lst_sz < cur_hdr_sz + new_hdr_len
   2671                 )
   2672             ):
   2673                 flags = set()
   2674                 if isinstance(cur_frm, H2HeadersFrame) and not body:
   2675                     flags.add('ES')
   2676                 ret.frames.append(H2Frame(stream_id=stream_id, flags=flags)/cur_frm)
   2677                 cur_frm = H2ContinuationFrame()
   2678                 cur_hdr_sz = 0
   2679 
   2680             hdr_list = cur_frm.hdrs
   2681             hdr_list += new_hdr
   2682             cur_hdr_sz += new_hdr_len
   2683 
   2684         flags = {'EH'}
   2685         if isinstance(cur_frm, H2HeadersFrame) and not body:
   2686             flags.add('ES')
   2687         ret.frames.append(H2Frame(stream_id=stream_id, flags=flags)/cur_frm)
   2688 
   2689         if body:
   2690             base_data_frm_len = len(raw(H2DataFrame()))
   2691             sio = BytesIO(body)
   2692             frgmt = sio.read(max_frm_sz - base_data_frm_len - base_frm_len)
   2693             while frgmt:
   2694                 nxt_frgmt = sio.read(max_frm_sz - base_data_frm_len - base_frm_len)
   2695                 flags = set()
   2696                 if len(nxt_frgmt) == 0:
   2697                     flags.add('ES')
   2698                 ret.frames.append(
   2699                     H2Frame(stream_id=stream_id, flags=flags)/H2DataFrame(data=frgmt)
   2700                 )
   2701                 frgmt = nxt_frgmt
   2702         return ret
   2703