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