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