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