blob: 11cbcb827b50209bef0b62b7ac56e7c56a0b28e6 [file] [log] [blame]
% HTTP/2 Campaign
# Frames expressed as binary str were generated using the solicit and hpack-rs
# Rust crates (https://github.com/mlalic/solicit, https://github.com/mlalic/hpack-rs)
# except Continuation Frames, Priority Frames and Push Promise Frames that we generated
# using Go x/net/http2 and x/net/http2/hpack modules.
+ Syntax check
= Configuring Scapy
~ http2 frame hpack build dissect data headers priority settings rststream pushpromise ping goaway winupdate continuation hpackhdrtable helpers
import scapy.config
scapy.config.conf.debug_dissector=True
import scapy.packet
import scapy.fields
import scapy.contrib.http2 as h2
import re
flags_bit_pattern = re.compile(r'''^\s+flags\s+=\s+\[.*['"]bit [0-9]+['"].*\]$''', re.M)
def expect_exception(e, c):
try:
eval(c)
return False
except e:
return True
+ HTTP/2 UVarIntField Test Suite
= HTTP/2 UVarIntField.any2i
~ http2 frame field uvarintfield
f = h2.UVarIntField('value', 0, 5)
expect_exception(AssertionError, 'f.any2i(None, None)')
assert f.any2i(None, 0) == 0
assert f.any2i(None, 3) == 3
assert f.any2i(None, 1<<5) == 1<<5
assert f.any2i(None, 1<<16) == 1<<16
f = h2.UVarIntField('value', 0, 8)
assert f.any2i(None, b'\x1E') == 30
= HTTP/2 UVarIntField.m2i on full byte
~ http2 frame field uvarintfield
f = h2.UVarIntField('value', 0, 8)
assert f.m2i(None, b'\x00') == 0
assert f.m2i(None, b'\x03') == 3
assert f.m2i(None, b'\xFE') == 254
assert f.m2i(None, b'\xFF\x00') == 255
assert f.m2i(None, b'\xFF\xFF\x03') == 766 #0xFF + (0xFF ^ 0x80) + (3<<7
= HTTP/2 UVarIntField.m2i on partial byte
~ http2 frame field uvarintfield
f = h2.UVarIntField('value', 0, 5)
assert f.m2i(None, (b'\x00', 3)) == 0
assert f.m2i(None, (b'\x03', 3)) == 3
assert f.m2i(None, (b'\x1e', 3)) == 30
assert f.m2i(None, (b'\x1f\x00', 3)) == 31
assert f.m2i(None, (b'\x1f\xe1\xff\x03', 3)) == 65536
= HTTP/2 UVarIntField.getfield on full byte
~ http2 frame field uvarintfield
f = h2.UVarIntField('value', 0, 8)
r = f.getfield(None, b'\x00\x00')
assert r[0] == b'\x00'
assert r[1] == 0
r = f.getfield(None, b'\x03\x00')
assert r[0] == b'\x00'
assert r[1] == 3
r = f.getfield(None, b'\xFE\x00')
assert r[0] == b'\x00'
assert r[1] == 254
r = f.getfield(None, b'\xFF\x00\x00')
assert r[0] == b'\x00'
assert r[1] == 255
r = f.getfield(None, b'\xFF\xFF\x03\x00')
assert r[0] == b'\x00'
assert r[1] == 766
= HTTP/2 UVarIntField.getfield on partial byte
~ http2 frame field uvarintfield
f = h2.UVarIntField('value', 0, 5)
r = f.getfield(None, (b'\x00\x00', 3))
assert r[0] == b'\x00'
assert r[1] == 0
r = f.getfield(None, (b'\x03\x00', 3))
assert r[0] == b'\x00'
assert r[1] == 3
r = f.getfield(None, (b'\x1e\x00', 3))
assert r[0] == b'\x00'
assert r[1] == 30
r = f.getfield(None, (b'\x1f\x00\x00', 3))
assert r[0] == b'\x00'
assert r[1] == 31
r = f.getfield(None, (b'\x1f\xe1\xff\x03\x00', 3))
assert r[0] == b'\x00'
assert r[1] == 65536
= HTTP/2 UVarIntField.i2m on full byte
~ http2 frame field uvarintfield
f = h2.UVarIntField('value', 0, 8)
assert f.i2m(None, 0) == b'\x00'
assert f.i2m(None, 3) == b'\x03'
assert f.i2m(None, 254).lower() == b'\xfe'
assert f.i2m(None, 255).lower() == b'\xff\x00'
assert f.i2m(None, 766).lower() == b'\xff\xff\x03'
= HTTP/2 UVarIntField.i2m on partial byte
~ http2 frame field uvarintfield
f = h2.UVarIntField('value', 0, 5)
assert f.i2m(None, 0) == b'\x00'
assert f.i2m(None, 3) == b'\x03'
assert f.i2m(None, 30).lower() == b'\x1e'
assert f.i2m(None, 31).lower() == b'\x1f\x00'
assert f.i2m(None, 65536).lower() == b'\x1f\xe1\xff\x03'
= HTTP/2 UVarIntField.addfield on full byte
~ http2 frame field uvarintfield
f = h2.UVarIntField('value', 0, 8)
assert f.addfield(None, b'Toto', 0) == b'Toto\x00'
assert f.addfield(None, b'Toto', 3) == b'Toto\x03'
assert f.addfield(None, b'Toto', 254).lower() == b'toto\xfe'
assert f.addfield(None, b'Toto', 255).lower() == b'toto\xff\x00'
assert f.addfield(None, b'Toto', 766).lower() == b'toto\xff\xff\x03'
= HTTP/2 UVarIntField.addfield on partial byte
~ http2 frame field uvarintfield
f = h2.UVarIntField('value', 0, 5)
assert f.addfield(None, (b'Toto', 3, 4), 0) == b'Toto\x80'
assert f.addfield(None, (b'Toto', 3, 4), 3) == b'Toto\x83'
assert f.addfield(None, (b'Toto', 3, 4), 30).lower() == b'toto\x9e'
assert f.addfield(None, (b'Toto', 3, 4), 31).lower() == b'toto\x9f\x00'
assert f.addfield(None, (b'Toto', 3, 4), 65536).lower() == b'toto\x9f\xe1\xff\x03'
= HTTP/2 UVarIntField.i2len on full byte
~ http2 frame field uvarintfield
f = h2.UVarIntField('value', 0, 8)
assert f.i2len(None, 0) == 1
assert f.i2len(None, 3) == 1
assert f.i2len(None, 254) == 1
assert f.i2len(None, 255) == 2
assert f.i2len(None, 766) == 3
= HTTP/2 UVarIntField.i2len on partial byte
~ http2 frame field uvarintfield
f = h2.UVarIntField('value', 0, 5)
assert f.i2len(None, 0) == 1
assert f.i2len(None, 3) == 1
assert f.i2len(None, 30) == 1
assert f.i2len(None, 31) == 2
assert f.i2len(None, 65536) == 4
+ HTTP/2 FieldUVarLenField Test Suite
= HTTP/2 FieldUVarLenField.i2m without adjustment
~ http2 frame field fielduvarlenfield
f = h2.FieldUVarLenField('len', None, 8, length_of='data')
class TrivialPacket(Packet):
name = 'Trivial Packet'
fields_desc= [
f,
StrField('data', '')
]
assert f.i2m(TrivialPacket(data='a'*5), None) == b'\x05'
assert f.i2m(TrivialPacket(data='a'*255), None).lower() == b'\xff\x00'
assert f.i2m(TrivialPacket(data='a'), 2) == b'\x02'
assert f.i2m(None, 2) == b'\x02'
assert f.i2m(None, 0) == b'\x00'
= HTTP/2 FieldUVarLenField.i2m with adjustment
~ http2 frame field fielduvarlenfield
class TrivialPacket(Packet):
name = 'Trivial Packet'
fields_desc= [
f,
StrField('data', '')
]
f = h2.FieldUVarLenField('value', None, 8, length_of='data', adjust=lambda x: x-1)
assert f.i2m(TrivialPacket(data='a'*5), None) == b'\x04'
assert f.i2m(TrivialPacket(data='a'*255), None).lower() == b'\xfe'
#Adjustment does not affect non-None value!
assert f.i2m(TrivialPacket(data='a'*3), 2) == b'\x02'
+ HTTP/2 HPackZString Test Suite
= HTTP/2 HPackZString Compression
~ http2 hpack huffman
string = 'Test'
s = h2.HPackZString(string)
assert len(s) == 3
assert raw(s) == b"\xdeT'"
assert s.origin() == string
string = 'a'*65535
s = h2.HPackZString(string)
assert len(s) == 40960
assert raw(s) == (b'\x18\xc61\x8cc' * 8191) + b'\x18\xc61\x8c\x7f'
assert s.origin() == string
= HTTP/2 HPackZString Decompression
~ http2 hpack huffman
s = b"\xdeT'"
i, ibl = h2.HPackZString.huffman_conv2bitstring(s)
assert b'Test' == h2.HPackZString.huffman_decode(i, ibl)
s = (b'\x18\xc61\x8cc' * 8191) + b'\x18\xc61\x8c\x7f'
i, ibl = h2.HPackZString.huffman_conv2bitstring(s)
assert b'a'*65535 == h2.HPackZString.huffman_decode(i, ibl)
assert(
expect_exception(h2.InvalidEncodingException,
'h2.HPackZString.huffman_decode(*h2.HPackZString.huffman_conv2bitstring(b"\\xdeT"))')
)
+ HTTP/2 HPackStrLenField Test Suite
= HTTP/2 HPackStrLenField.m2i
~ http2 hpack field hpackstrlenfield
f = h2.HPackStrLenField('data', h2.HPackLiteralString(''), length_from=lambda p: p.len, type_from='type')
class TrivialPacket(Packet):
name = 'Trivial Packet'
fields_desc = [
IntField('type', None),
IntField('len', None),
f
]
s = f.m2i(TrivialPacket(type=0, len=4), b'Test')
assert isinstance(s, h2.HPackLiteralString)
assert s.origin() == 'Test'
s = f.m2i(TrivialPacket(type=1, len=3), b"\xdeT'")
assert isinstance(s, h2.HPackZString)
assert s.origin() == 'Test'
= HTTP/2 HPackStrLenField.any2i
~ http2 hpack field hpackstrlenfield
f = h2.HPackStrLenField('data', h2.HPackLiteralString(''), length_from=lambda p: p.len, type_from='type')
class TrivialPacket(Packet):
name = 'Trivial Packet'
fields_desc = [
IntField('type', None),
IntField('len', None),
f
]
s = f.any2i(TrivialPacket(type=0, len=4), b'Test')
assert isinstance(s, h2.HPackLiteralString)
assert s.origin() == 'Test'
s = f.any2i(TrivialPacket(type=1, len=3), b"\xdeT'")
assert isinstance(s, h2.HPackZString)
assert s.origin() == 'Test'
s = h2.HPackLiteralString('Test')
s2 = f.any2i(TrivialPacket(type=0, len=4), s)
assert s.origin() == s2.origin()
s = h2.HPackZString('Test')
s2 = f.any2i(TrivialPacket(type=1, len=3), s)
assert s.origin() == s2.origin()
s = h2.HPackLiteralString('Test')
s2 = f.any2i(None, s)
assert s.origin() == s2.origin()
s = h2.HPackZString('Test')
s2 = f.any2i(None, s)
assert s.origin() == s2.origin()
# Verifies that one can fuzz
s = h2.HPackLiteralString('Test')
s2 = f.any2i(TrivialPacket(type=1, len=1), s)
assert s.origin() == s2.origin()
= HTTP/2 HPackStrLenField.i2m
~ http2 hpack field hpackstrlenfield
f = h2.HPackStrLenField('data', h2.HPackLiteralString(''), length_from=lambda p: p.len, type_from='type')
s = b'Test'
s2 = f.i2m(None, h2.HPackLiteralString(s))
assert s == s2
s = b'Test'
s2 = f.i2m(None, h2.HPackZString(s))
assert s2 == b"\xdeT'"
= HTTP/2 HPackStrLenField.addfield
~ http2 hpack field hpackstrlenfield
f = h2.HPackStrLenField('data', h2.HPackLiteralString(''), length_from=lambda p: p.len, type_from='type')
s = b'Test'
s2 = f.addfield(None, b'Toto', h2.HPackLiteralString(s))
assert b'Toto' + s == s2
s = b'Test'
s2 = f.addfield(None, b'Toto', h2.HPackZString(s))
assert s2 == b"Toto\xdeT'"
= HTTP/2 HPackStrLenField.getfield
~ http2 hpack field hpackstrlenfield
f = h2.HPackStrLenField('data', h2.HPackLiteralString(''), length_from=lambda p: p.len, type_from='type')
class TrivialPacket(Packet):
name = 'Trivial Packet'
fields_desc = [
IntField('type', None),
IntField('len', None),
f
]
r = f.getfield(TrivialPacket(type=0, len=4), b'TestToto')
assert isinstance(r, tuple)
assert r[0] == b'Toto'
assert isinstance(r[1], h2.HPackLiteralString)
assert r[1].origin() == 'Test'
r = f.getfield(TrivialPacket(type=1, len=3), b"\xdeT'Toto")
assert isinstance(r, tuple)
assert r[0] == b'Toto'
assert isinstance(r[1], h2.HPackZString)
assert r[1].origin() == 'Test'
= HTTP/2 HPackStrLenField.i2h / i2repr
~ http2 hpack field hpackstrlenfield
f = h2.HPackStrLenField('data', h2.HPackLiteralString(''), length_from=lambda p: p.len, type_from='type')
s = b'Test'
assert f.i2h(None, h2.HPackLiteralString(s)) == 'HPackLiteralString(Test)'
assert f.i2repr(None, h2.HPackLiteralString(s)) == repr('HPackLiteralString(Test)')
assert f.i2h(None, h2.HPackZString(s)) == 'HPackZString(Test)'
assert f.i2repr(None, h2.HPackZString(s)) == repr('HPackZString(Test)')
= HTTP/2 HPackStrLenField.i2len
~ http2 hpack field hpackstrlenfield
f = h2.HPackStrLenField('data', h2.HPackLiteralString(''), length_from=lambda p: p.len, type_from='type')
s = b'Test'
assert f.i2len(None, h2.HPackLiteralString(s)) == 4
assert f.i2len(None, h2.HPackZString(s)) == 3
+ HTTP/2 HPackMagicBitField Test Suite
# Magic bits are not supposed to be modified and if they are anyway, they must
# be assigned the magic|default value only...
= HTTP/2 HPackMagicBitField.addfield
~ http2 hpack field hpackmagicbitfield
f = h2.HPackMagicBitField('value', 3, 2)
r = f.addfield(None, b'Toto', 3)
assert isinstance(r, tuple)
assert r[0] == b'Toto'
assert r[1] == 2
assert r[2] == 3
r = f.addfield(None, (b'Toto', 2, 1) , 3)
assert isinstance(r, tuple)
assert r[0] == b'Toto'
assert r[1] == 4
assert r[2] == 7
assert expect_exception(AssertionError, 'f.addfield(None, "toto", 2)')
= HTTP/2 HPackMagicBitField.getfield
~ http2 hpack field hpackmagicbitfield
f = h2.HPackMagicBitField('value', 3, 2)
r = f.getfield(None, b'\xc0')
assert isinstance(r, tuple)
assert len(r) == 2
assert isinstance(r[0], tuple)
assert len(r[0]) == 2
assert r[0][0] == b'\xc0'
assert r[0][1] == 2
assert r[1] == 3
r = f.getfield(None, (b'\x03', 6))
assert isinstance(r, tuple)
assert len(r) == 2
assert isinstance(r[0], bytes)
assert r[0] == b''
assert r[1] == 3
expect_exception(AssertionError, 'f.getfield(None, b"\\x80")')
= HTTP/2 HPackMagicBitField.h2i
~ http2 hpack field hpackmagicbitfield
f = h2.HPackMagicBitField('value', 3, 2)
assert f.h2i(None, 3) == 3
expect_exception(AssertionError, 'f.h2i(None, 2)')
= HTTP/2 HPackMagicBitField.m2i
~ http2 hpack field hpackmagicbitfield
f = h2.HPackMagicBitField('value', 3, 2)
assert f.m2i(None, 3) == 3
expect_exception(AssertionError, 'f.m2i(None, 2)')
= HTTP/2 HPackMagicBitField.i2m
~ http2 hpack field hpackmagicbitfield
f = h2.HPackMagicBitField('value', 3, 2)
assert f.i2m(None, 3) == 3
expect_exception(AssertionError, 'f.i2m(None, 2)')
= HTTP/2 HPackMagicBitField.any2i
~ http2 hpack field hpackmagicbitfield
f = h2.HPackMagicBitField('value', 3, 2)
assert f.any2i(None, 3) == 3
expect_exception(AssertionError, 'f.any2i(None, 2)')
+ HTTP/2 HPackHdrString Test Suite
= HTTP/2 Dissect HPackHdrString
~ http2 pack dissect hpackhdrstring
p = h2.HPackHdrString(b'\x04Test')
assert p.type == 0
assert p.len == 4
assert isinstance(p.getfieldval('data'), h2.HPackLiteralString)
assert p.getfieldval('data').origin() == 'Test'
p = h2.HPackHdrString(b"\x83\xdeT'")
assert p.type == 1
assert p.len == 3
assert isinstance(p.getfieldval('data'), h2.HPackZString)
assert p.getfieldval('data').origin() == 'Test'
= HTTP/2 Build HPackHdrString
~ http2 hpack build hpackhdrstring
p = h2.HPackHdrString(data=h2.HPackLiteralString('Test'))
assert raw(p) == b'\x04Test'
p = h2.HPackHdrString(data=h2.HPackZString('Test'))
assert raw(p) == b"\x83\xdeT'"
#Fuzzing-able tests
p = h2.HPackHdrString(type=1, len=3, data=h2.HPackLiteralString('Test'))
assert raw(p) == b'\x83Test'
+ HTTP/2 HPackIndexedHdr Test Suite
= HTTP/2 Dissect HPackIndexedHdr
~ http2 hpack dissect hpackindexedhdr
p = h2.HPackIndexedHdr(b'\x80')
assert p.magic == 1
assert p.index == 0
p = h2.HPackIndexedHdr(b'\xFF\x00')
assert p.magic == 1
assert p.index == 127
= HTTP/2 Build HPackIndexedHdr
~ http2 hpack build hpackindexedhdr
p = h2.HPackIndexedHdr(index=0)
assert raw(p) == b'\x80'
p = h2.HPackIndexedHdr(index=127)
assert raw(p) == b'\xFF\x00'
+ HTTP/2 HPackLitHdrFldWithIncrIndexing Test Suite
= HTTP/2 Dissect HPackLitHdrFldWithIncrIndexing without indexed name
~ http2 hpack dissect hpacklithdrfldwithincrindexing
p = h2.HPackLitHdrFldWithIncrIndexing(b'\x40\x04Test\x04Toto')
assert p.magic == 1
assert p.index == 0
assert isinstance(p.hdr_name, h2.HPackHdrString)
assert p.hdr_name.type == 0
assert p.hdr_name.len == 4
assert p.hdr_name.getfieldval('data').origin() == 'Test'
assert isinstance(p.hdr_value, h2.HPackHdrString)
assert p.hdr_value.type == 0
assert p.hdr_value.len == 4
assert p.hdr_value.getfieldval('data').origin() == 'Toto'
= HTTP/2 Dissect HPackLitHdrFldWithIncrIndexing with indexed name
~ http2 hpack dissect hpacklithdrfldwithincrindexing
p = h2.HPackLitHdrFldWithIncrIndexing(b'\x41\x04Toto')
assert p.magic == 1
assert p.index == 1
assert p.hdr_name is None
assert isinstance(p.hdr_value, h2.HPackHdrString)
assert p.hdr_value.type == 0
assert p.hdr_value.len == 4
assert p.hdr_value.getfieldval('data').origin() == 'Toto'
= HTTP/2 Build HPackLitHdrFldWithIncrIndexing without indexed name
~ http2 hpack build hpacklithdrfldwithincrindexing
p = h2.HPackLitHdrFldWithIncrIndexing(
hdr_name=h2.HPackHdrString(data=h2.HPackLiteralString('Test')),
hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString(b'Toto'))
)
assert raw(p) == b'\x40\x04Test\x04Toto'
= HTTP/2 Build HPackLitHdrFldWithIncrIndexing with indexed name
~ http2 hpack build hpacklithdrfldwithincrindexing
p = h2.HPackLitHdrFldWithIncrIndexing(
index=1,
hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString(b'Toto'))
)
assert raw(p) == b'\x41\x04Toto'
+ HTTP/2 HPackLitHdrFldWithoutIndexing Test Suite
= HTTP/2 Dissect HPackLitHdrFldWithoutIndexing : don't index and no index
~ http2 hpack dissect hpacklithdrfldwithoutindexing
p = h2.HPackLitHdrFldWithoutIndexing(b'\x00\x04Test\x04Toto')
assert p.magic == 0
assert p.never_index == 0
assert p.index == 0
assert isinstance(p.hdr_name, h2.HPackHdrString)
assert p.hdr_name.type == 0
assert p.hdr_name.len == 4
assert isinstance(p.hdr_name.getfieldval('data'), h2.HPackLiteralString)
assert p.hdr_name.getfieldval('data').origin() == 'Test'
assert isinstance(p.hdr_value, h2.HPackHdrString)
assert p.hdr_value.type == 0
assert p.hdr_value.len == 4
assert isinstance(p.hdr_value.getfieldval('data'), h2.HPackLiteralString)
assert p.hdr_value.getfieldval('data').origin() == 'Toto'
= HTTP/2 Dissect HPackLitHdrFldWithoutIndexing : never index index and no index
~ http2 hpack dissect hpacklithdrfldwithoutindexing
p = h2.HPackLitHdrFldWithoutIndexing(b'\x10\x04Test\x04Toto')
assert p.magic == 0
assert p.never_index == 1
assert p.index == 0
assert isinstance(p.hdr_name, h2.HPackHdrString)
assert p.hdr_name.type == 0
assert p.hdr_name.len == 4
assert isinstance(p.hdr_name.getfieldval('data'), h2.HPackLiteralString)
assert p.hdr_name.getfieldval('data').origin() == 'Test'
assert isinstance(p.hdr_value, h2.HPackHdrString)
assert p.hdr_value.type == 0
assert p.hdr_value.len == 4
assert isinstance(p.hdr_value.getfieldval('data'), h2.HPackLiteralString)
assert p.hdr_value.getfieldval('data').origin() == 'Toto'
= HTTP/2 Dissect HPackLitHdrFldWithoutIndexing : never index and indexed name
~ http2 hpack dissect hpacklithdrfldwithoutindexing
p = h2.HPackLitHdrFldWithoutIndexing(b'\x11\x04Toto')
assert p.magic == 0
assert p.never_index == 1
assert p.index == 1
assert p.hdr_name is None
assert isinstance(p.hdr_value, h2.HPackHdrString)
assert p.hdr_value.type == 0
assert p.hdr_value.len == 4
assert isinstance(p.hdr_value.getfieldval('data'), h2.HPackLiteralString)
assert p.hdr_value.getfieldval('data').origin() == 'Toto'
= HTTP/2 Build HPackLitHdrFldWithoutIndexing : don't index and no index
~ http2 hpack build hpacklithdrfldwithoutindexing
p = h2.HPackLitHdrFldWithoutIndexing(
hdr_name=h2.HPackHdrString(data=h2.HPackLiteralString('Test')),
hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString(b'Toto'))
)
assert raw(p) == b'\x00\x04Test\x04Toto'
= HTTP/2 Build HPackLitHdrFldWithoutIndexing : never index index and no index
~ http2 hpack build hpacklithdrfldwithoutindexing
p = h2.HPackLitHdrFldWithoutIndexing(
never_index=1,
hdr_name=h2.HPackHdrString(data=h2.HPackLiteralString('Test')),
hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString(b'Toto'))
)
assert raw(p) == b'\x10\x04Test\x04Toto'
= HTTP/2 Build HPackLitHdrFldWithoutIndexing : never index and indexed name
~ http2 hpack build hpacklithdrfldwithoutindexing
p = h2.HPackLitHdrFldWithoutIndexing(
never_index=1,
index=1,
hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString(b'Toto'))
)
assert raw(p) == b'\x11\x04Toto'
+ HTTP/2 HPackDynamicSizeUpdate Test Suite
= HTTP/2 Dissect HPackDynamicSizeUpdate
~ http2 hpack dissect hpackdynamicsizeupdate
p = h2.HPackDynamicSizeUpdate(b'\x25')
assert p.magic == 1
assert p.max_size == 5
p = h2.HPackDynamicSizeUpdate(b'\x3F\x00')
assert p.magic == 1
assert p.max_size == 31
= HTTP/2 Build HPackDynamicSizeUpdate
~ http2 hpack build hpackdynamicsizeupdate
p = h2.HPackDynamicSizeUpdate(max_size=5)
assert raw(p) == b'\x25'
p = h2.HPackDynamicSizeUpdate(max_size=31)
assert raw(p) == b'\x3F\x00'
+ HTTP/2 Data Frame Test Suite
= HTTP/2 Dissect Data Frame: Simple data frame
~ http2 frame dissect data
pkt = h2.H2Frame(b'\x00\x00\x04\x00\x00\x00\x00\x00\x01ABCD')
assert pkt.type == 0
assert pkt.len == 4
assert len(pkt.flags) == 0
assert pkt.reserved == 0
assert pkt.stream_id == 1
assert isinstance(pkt.payload, h2.H2DataFrame)
assert pkt[h2.H2DataFrame]
assert pkt.payload.data == b'ABCD'
assert isinstance(pkt.payload.payload, scapy.packet.NoPayload)
= HTTP/2 Build Data Frame: Simple data frame
~ http2 frame build data
pkt = h2.H2Frame(stream_id = 1)/h2.H2DataFrame(data='ABCD')
assert raw(pkt) == b'\x00\x00\x04\x00\x00\x00\x00\x00\x01ABCD'
try:
pkt.show2(dump=True)
assert True
except Exception:
assert False
= HTTP/2 Dissect Data Frame: Simple data frame with padding
~ http2 frame dissect data
pkt = h2.H2Frame(b'\x00\x00\r\x00\x08\x00\x00\x00\x01\x08ABCD\x00\x00\x00\x00\x00\x00\x00\x00') #Padded data frame
assert pkt.type == 0
assert pkt.len == 13
assert len(pkt.flags) == 1
assert 'P' in pkt.flags
assert pkt.reserved == 0
assert pkt.stream_id == 1
assert isinstance(pkt.payload, h2.H2PaddedDataFrame)
assert pkt[h2.H2PaddedDataFrame]
assert pkt.payload.padlen == 8
assert pkt.payload.data == b'ABCD'
assert pkt.payload.padding == b'\x00'*8
assert flags_bit_pattern.search(pkt.show(dump=True)) is None
assert isinstance(pkt.payload.payload, scapy.packet.NoPayload)
= HTTP/2 Build Data Frame: Simple data frame with padding
~ http2 frame build data
pkt = h2.H2Frame(flags = {'P'}, stream_id = 1)/h2.H2PaddedDataFrame(data='ABCD', padding=b'\x00'*8)
assert raw(pkt) == b'\x00\x00\r\x00\x08\x00\x00\x00\x01\x08ABCD\x00\x00\x00\x00\x00\x00\x00\x00'
try:
pkt.show2(dump=True)
assert True
except Exception:
assert False
= HTTP/2 Dissect Data Frame: Simple data frame with padding and end stream flag
~ http2 frame dissect data
pkt = h2.H2Frame(b'\x00\x00\r\x00\t\x00\x00\x00\x01\x08ABCD\x00\x00\x00\x00\x00\x00\x00\x00') #Padded data frame with end stream flag
assert pkt.type == 0
assert pkt.len == 13
assert len(pkt.flags) == 2
assert 'P' in pkt.flags
assert 'ES' in pkt.flags
assert pkt.reserved == 0
assert pkt.stream_id == 1
assert isinstance(pkt.payload, h2.H2PaddedDataFrame)
assert pkt[h2.H2PaddedDataFrame]
assert pkt.payload.padlen == 8
assert pkt.payload.data == b'ABCD'
assert pkt.payload.padding == b'\x00'*8
assert flags_bit_pattern.search(pkt.show(dump=True)) is None
assert isinstance(pkt.payload.payload, scapy.packet.NoPayload)
= HTTP/2 Build Data Frame: Simple data frame with padding and end stream flag
~ http2 frame build data
pkt = h2.H2Frame(flags = {'P', 'ES'}, stream_id=1)/h2.H2PaddedDataFrame(data='ABCD', padding=b'\x00'*8)
assert raw(pkt) == b'\x00\x00\r\x00\t\x00\x00\x00\x01\x08ABCD\x00\x00\x00\x00\x00\x00\x00\x00'
try:
pkt.show2(dump=True)
assert True
except Exception:
assert False
+ HTTP/2 Headers Frame Test Suite
= HTTP/2 Dissect Headers Frame: Simple header frame
~ http2 frame dissect headers
pkt = h2.H2Frame(b'\x00\x00\x0e\x01\x00\x00\x00\x00\x01\x88\x0f\x10\ntext/plain') #Header frame
assert pkt.type == 1
assert pkt.len == 14
assert len(pkt.flags) == 0
assert pkt.reserved == 0
assert pkt.stream_id == 1
assert isinstance(pkt.payload, h2.H2HeadersFrame)
assert pkt[h2.H2HeadersFrame]
hf = pkt[h2.H2HeadersFrame]
assert len(hf.hdrs) == 2
assert isinstance(hf.hdrs[0], h2.HPackIndexedHdr)
assert hf.hdrs[0].magic == 1
assert hf.hdrs[0].index == 8
assert isinstance(hf.hdrs[1], h2.HPackLitHdrFldWithoutIndexing)
assert hf.hdrs[1].magic == 0
assert hf.hdrs[1].never_index == 0
assert hf.hdrs[1].index == 31
assert hf.hdrs[1].hdr_name is None
assert expect_exception(AttributeError, 'hf.hdrs[1].non_existant')
assert isinstance(hf.hdrs[1].hdr_value, h2.HPackHdrString)
s = hf.hdrs[1].hdr_value
assert s.type == 0
assert s.len == 10
assert s.getfieldval('data').origin() == 'text/plain'
assert isinstance(hf.payload, scapy.packet.NoPayload)
= HTTP/2 Build Headers Frame: Simple header frame
~ http2 frame build headers
p = h2.H2Frame(stream_id=1)/h2.H2HeadersFrame(hdrs=[
h2.HPackIndexedHdr(index=8),
h2.HPackLitHdrFldWithoutIndexing(
index=31,
hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('text/plain'))
)
]
)
assert raw(p) == b'\x00\x00\x0e\x01\x00\x00\x00\x00\x01\x88\x0f\x10\ntext/plain'
= HTTP/2 Dissect Headers Frame: Header frame with padding
~ http2 frame dissect headers
pkt = h2.H2Frame(b'\x00\x00\x17\x01\x08\x00\x00\x00\x01\x08\x88\x0f\x10\ntext/plain\x00\x00\x00\x00\x00\x00\x00\x00') #Header frame with padding
assert pkt.type == 1
assert pkt.len == 23
assert len(pkt.flags) == 1
assert 'P' in pkt.flags
assert pkt.reserved == 0
assert pkt.stream_id == 1
assert isinstance(pkt.payload, h2.H2PaddedHeadersFrame)
assert flags_bit_pattern.search(pkt.show(dump=True)) is None
assert pkt[h2.H2PaddedHeadersFrame]
hf = pkt[h2.H2PaddedHeadersFrame]
assert hf.padlen == 8
assert hf.padding == b'\x00' * 8
assert len(hf.hdrs) == 2
assert isinstance(hf.hdrs[0], h2.HPackIndexedHdr)
assert hf.hdrs[0].magic == 1
assert hf.hdrs[0].index == 8
assert isinstance(hf.hdrs[1], h2.HPackLitHdrFldWithoutIndexing)
assert hf.hdrs[1].magic == 0
assert hf.hdrs[1].never_index == 0
assert hf.hdrs[1].index == 31
assert hf.hdrs[1].hdr_name is None
assert expect_exception(AttributeError, 'hf.hdrs[1].non_existant')
assert isinstance(hf.hdrs[1].hdr_value, h2.HPackHdrString)
s = hf.hdrs[1].hdr_value
assert s.type == 0
assert s.len == 10
assert s.getfieldval('data').origin() == 'text/plain'
assert isinstance(hf.payload, scapy.packet.NoPayload)
= HTTP/2 Build Headers Frame: Header frame with padding
~ http2 frame build headers
p = h2.H2Frame(flags={'P'}, stream_id=1)/h2.H2PaddedHeadersFrame(
hdrs=[
h2.HPackIndexedHdr(index=8),
h2.HPackLitHdrFldWithoutIndexing(
index=31,
hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('text/plain'))
)
],
padding=b'\x00'*8,
)
assert raw(p) == b'\x00\x00\x17\x01\x08\x00\x00\x00\x01\x08\x88\x0f\x10\ntext/plain\x00\x00\x00\x00\x00\x00\x00\x00'
= HTTP/2 Dissect Headers Frame: Header frame with priority
~ http2 frame dissect headers
pkt = h2.H2Frame(b'\x00\x00\x13\x01 \x00\x00\x00\x01\x00\x00\x00\x02d\x88\x0f\x10\ntext/plain') #Header frame with priority
assert pkt.type == 1
assert pkt.len == 19
assert len(pkt.flags) == 1
assert '+' in pkt.flags
assert pkt.reserved == 0
assert pkt.stream_id == 1
assert isinstance(pkt.payload, h2.H2PriorityHeadersFrame)
assert flags_bit_pattern.search(pkt.show(dump=True)) is None
assert pkt[h2.H2PriorityHeadersFrame]
hf = pkt[h2.H2PriorityHeadersFrame]
assert hf.exclusive == 0
assert hf.stream_dependency == 2
assert hf.weight == 100
assert len(hf.hdrs) == 2
assert isinstance(hf.hdrs[0], h2.HPackIndexedHdr)
assert hf.hdrs[0].magic == 1
assert hf.hdrs[0].index == 8
assert isinstance(hf.hdrs[1], h2.HPackLitHdrFldWithoutIndexing)
assert hf.hdrs[1].magic == 0
assert hf.hdrs[1].never_index == 0
assert hf.hdrs[1].index == 31
assert hf.hdrs[1].hdr_name is None
assert expect_exception(AttributeError, 'hf.hdrs[1].non_existant')
assert isinstance(hf.hdrs[1].hdr_value, h2.HPackHdrString)
s = hf.hdrs[1].hdr_value
assert s.type == 0
assert s.len == 10
assert s.getfieldval('data').origin() == 'text/plain'
assert isinstance(hf.payload, scapy.packet.NoPayload)
= HTTP/2 Build Headers Frame: Header frame with priority
~ http2 frame build headers
p = h2.H2Frame(flags={'+'}, stream_id=1)/h2.H2PriorityHeadersFrame(
exclusive=0,
stream_dependency=2,
weight=100,
hdrs=[
h2.HPackIndexedHdr(index=8),
h2.HPackLitHdrFldWithoutIndexing(
index=31,
hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('text/plain'))
)
]
)
assert raw(p) == b'\x00\x00\x13\x01 \x00\x00\x00\x01\x00\x00\x00\x02d\x88\x0f\x10\ntext/plain'
= HTTP/2 Dissect Headers Frame: Header frame with priority and padding and flags
~ http2 frame dissect headers
pkt = h2.H2Frame(b'\x00\x00\x1c\x01-\x00\x00\x00\x01\x08\x00\x00\x00\x02d\x88\x0f\x10\ntext/plain\x00\x00\x00\x00\x00\x00\x00\x00') #Header frame with priority and padding and flags ES|EH
assert pkt.type == 1
assert pkt.len == 28
assert len(pkt.flags) == 4
assert '+' in pkt.flags
assert 'P' in pkt.flags
assert 'ES' in pkt.flags
assert 'EH' in pkt.flags
assert pkt.reserved == 0
assert pkt.stream_id == 1
assert isinstance(pkt.payload, h2.H2PaddedPriorityHeadersFrame)
assert flags_bit_pattern.search(pkt.show(dump=True)) is None
assert pkt[h2.H2PaddedPriorityHeadersFrame]
hf = pkt[h2.H2PaddedPriorityHeadersFrame]
assert hf.padlen == 8
assert hf.padding == b'\x00' * 8
assert hf.exclusive == 0
assert hf.stream_dependency == 2
assert hf.weight == 100
assert len(hf.hdrs) == 2
assert isinstance(hf.hdrs[0], h2.HPackIndexedHdr)
assert hf.hdrs[0].magic == 1
assert hf.hdrs[0].index == 8
assert isinstance(hf.hdrs[1], h2.HPackLitHdrFldWithoutIndexing)
assert hf.hdrs[1].magic == 0
assert hf.hdrs[1].never_index == 0
assert hf.hdrs[1].index == 31
assert hf.hdrs[1].hdr_name is None
assert expect_exception(AttributeError, 'hf.hdrs[1].non_existant')
assert isinstance(hf.hdrs[1].hdr_value, h2.HPackHdrString)
s = hf.hdrs[1].hdr_value
assert s.type == 0
assert s.len == 10
assert s.getfieldval('data').origin() == 'text/plain'
assert isinstance(hf.payload, scapy.packet.NoPayload)
= HTTP/2 Build Headers Frame: Header frame with priority and padding and flags
~ http2 frame build headers
p = h2.H2Frame(flags={'P', '+', 'ES', 'EH'}, stream_id=1)/h2.H2PaddedPriorityHeadersFrame(
exclusive=0,
stream_dependency=2,
weight=100,
padding=b'\x00'*8,
hdrs=[
h2.HPackIndexedHdr(index=8),
h2.HPackLitHdrFldWithoutIndexing(
index=31,
hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('text/plain'))
)
]
)
+ HTTP/2 Priority Frame Test Suite
= HTTP/2 Dissect Priority Frame
~ http2 frame dissect priority
pkt = h2.H2Frame(b'\x00\x00\x05\x02\x00\x00\x00\x00\x03\x80\x00\x00\x01d')
assert pkt.type == 2
assert pkt.len == 5
assert len(pkt.flags) == 0
assert pkt.reserved == 0
assert pkt.stream_id == 3
assert isinstance(pkt.payload, h2.H2PriorityFrame)
assert pkt[h2.H2PriorityFrame]
pp = pkt[h2.H2PriorityFrame]
assert pp.stream_dependency == 1
assert pp.exclusive == 1
assert pp.weight == 100
= HTTP/2 Build Priority Frame
~ http2 frame build priority
p = h2.H2Frame(stream_id=3)/h2.H2PriorityFrame(
exclusive=1,
stream_dependency=1,
weight=100
)
assert raw(p) == b'\x00\x00\x05\x02\x00\x00\x00\x00\x03\x80\x00\x00\x01d'
+ HTTP/2 Reset Stream Frame Test Suite
= HTTP/2 Dissect Reset Stream Frame: Protocol Error
~ http2 frame dissect rststream
pkt = h2.H2Frame(b'\x00\x00\x04\x03\x00\x00\x00\x00\x01\x00\x00\x00\x01') #Reset stream with protocol error
assert pkt.type == 3
assert pkt.len == 4
assert len(pkt.flags) == 0
assert pkt.reserved == 0
assert pkt.stream_id == 1
assert isinstance(pkt.payload, h2.H2ResetFrame)
assert pkt[h2.H2ResetFrame]
rf = pkt[h2.H2ResetFrame]
assert rf.error == 1
assert isinstance(rf.payload, scapy.packet.NoPayload)
= HTTP/2 Build Reset Stream Frame: Protocol Error
~ http2 frame build rststream
p = h2.H2Frame(stream_id=1)/h2.H2ResetFrame(error='Protocol error')
assert raw(p) == b'\x00\x00\x04\x03\x00\x00\x00\x00\x01\x00\x00\x00\x01'
p = h2.H2Frame(stream_id=1)/h2.H2ResetFrame(error=1)
assert raw(p) == b'\x00\x00\x04\x03\x00\x00\x00\x00\x01\x00\x00\x00\x01'
= HTTP/2 Dissect Reset Stream Frame: Raw 123456 error
~ http2 frame dissect rststream
pkt = h2.H2Frame(b'\x00\x00\x04\x03\x00\x00\x00\x00\x01\x00\x01\xe2@') #Reset stream with raw error
assert pkt.type == 3
assert pkt.len == 4
assert len(pkt.flags) == 0
assert pkt.reserved == 0
assert pkt.stream_id == 1
assert isinstance(pkt.payload, h2.H2ResetFrame)
assert pkt[h2.H2ResetFrame]
rf = pkt[h2.H2ResetFrame]
assert rf.error == 123456
assert isinstance(rf.payload, scapy.packet.NoPayload)
= HTTP/2 Dissect Reset Stream Frame: Raw 123456 error
~ http2 frame dissect rststream
p = h2.H2Frame(stream_id=1)/h2.H2ResetFrame(error=123456)
assert raw(p) == b'\x00\x00\x04\x03\x00\x00\x00\x00\x01\x00\x01\xe2@'
+ HTTP/2 Settings Frame Test Suite
= HTTP/2 Dissect Settings Frame: Settings Frame
~ http2 frame dissect settings
pkt = h2.H2Frame(b'\x00\x00$\x04\x00\x00\x00\x00\x00\x00\x01\x07[\xcd\x15\x00\x02\x00\x00\x00\x01\x00\x03\x00\x00\x00{\x00\x04\x00\x12\xd6\x87\x00\x05\x00\x01\xe2@\x00\x06\x00\x00\x00{') #Settings frame
assert pkt.type == 4
assert pkt.len == 36
assert len(pkt.flags) == 0
assert pkt.reserved == 0
assert pkt.stream_id == 0
assert isinstance(pkt.payload, h2.H2SettingsFrame)
assert pkt[h2.H2SettingsFrame]
sf = pkt[h2.H2SettingsFrame]
assert len(sf.settings) == 6
assert isinstance(sf.settings[0], h2.H2Setting)
assert sf.settings[0].id == 1
assert sf.settings[0].value == 123456789
assert isinstance(sf.settings[1], h2.H2Setting)
assert sf.settings[1].id == 2
assert sf.settings[1].value == 1
assert isinstance(sf.settings[2], h2.H2Setting)
assert sf.settings[2].id == 3
assert sf.settings[2].value == 123
assert isinstance(sf.settings[3], h2.H2Setting)
assert sf.settings[3].id == 4
assert sf.settings[3].value == 1234567
assert isinstance(sf.settings[4], h2.H2Setting)
assert sf.settings[4].id == 5
assert sf.settings[4].value == 123456
assert isinstance(sf.settings[5], h2.H2Setting)
assert sf.settings[5].id == 6
assert sf.settings[5].value == 123
assert isinstance(sf.payload, scapy.packet.NoPayload)
= HTTP/2 Build Settings Frame: Settings Frame
~ http2 frame build settings
p = h2.H2Frame()/h2.H2SettingsFrame(settings=[
h2.H2Setting(id='Header table size',value=123456789),
h2.H2Setting(id='Enable push', value=1),
h2.H2Setting(id='Max concurrent streams', value=123),
h2.H2Setting(id='Initial window size', value=1234567),
h2.H2Setting(id='Max frame size', value=123456),
h2.H2Setting(id='Max header list size', value=123)
]
)
assert raw(p) == b'\x00\x00$\x04\x00\x00\x00\x00\x00\x00\x01\x07[\xcd\x15\x00\x02\x00\x00\x00\x01\x00\x03\x00\x00\x00{\x00\x04\x00\x12\xd6\x87\x00\x05\x00\x01\xe2@\x00\x06\x00\x00\x00{'
= HTTP/2 Dissect Settings Frame: Incomplete Settings Frame
~ http2 frame dissect settings
#We use here the decode('hex') method because null-bytes are rejected by eval()
assert expect_exception(AssertionError, 'h2.H2Frame(bytes_hex("0000240400000000000001075bcd1500020000000100030000007b00040012d68700050001e2400006000000"))')
= HTTP/2 Dissect Settings Frame: Settings Frame acknowledgement
~ http2 frame dissect settings
pkt = h2.H2Frame(b'\x00\x00\x00\x04\x01\x00\x00\x00\x00') #Settings frame w/ ack flag
assert pkt.type == 4
assert pkt.len == 0
assert len(pkt.flags) == 1
assert 'A' in pkt.flags
assert pkt.reserved == 0
assert pkt.stream_id == 0
assert flags_bit_pattern.search(pkt.show(dump=True)) is None
assert isinstance(pkt.payload, scapy.packet.NoPayload)
= HTTP/2 Build Settings Frame: Settings Frame acknowledgement
~ http2 frame build settings
p = h2.H2Frame(type=h2.H2SettingsFrame.type_id, flags={'A'})
assert raw(p) == b'\x00\x00\x00\x04\x01\x00\x00\x00\x00'
+ HTTP/2 Push Promise Frame Test Suite
= HTTP/2 Dissect Push Promise Frame: no flag & headers with compression and hdr_name
~ http2 frame dissect pushpromise
pkt = h2.H2Frame(b'\x00\x00\x15\x05\x00\x00\x00\x00\x01\x00\x00\x00\x03@\x8c\xfc[i{ZT$\xb2-\xc8\xc9\x9f\x02Me')
assert pkt.type == 5
assert pkt.len == 21
assert len(pkt.flags) == 0
assert pkt.reserved == 0
assert pkt.stream_id == 1
assert isinstance(pkt.payload, h2.H2PushPromiseFrame)
assert pkt[h2.H2PushPromiseFrame]
pf = pkt[h2.H2PushPromiseFrame]
assert pf.reserved == 0
assert pf.stream_id == 3
assert len(pf.hdrs) == 1
assert isinstance(pf.payload, scapy.packet.NoPayload)
hdr = pf.hdrs[0]
assert isinstance(hdr, h2.HPackLitHdrFldWithIncrIndexing)
assert hdr.magic == 1
assert hdr.index == 0
assert isinstance(hdr.hdr_name, h2.HPackHdrString)
assert hdr.hdr_name.type == 1
assert hdr.hdr_name.len == 12
assert hdr.hdr_name.getfieldval('data').origin() == 'X-Requested-With'
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.type == 0
assert hdr.hdr_value.len == 2
assert hdr.hdr_value.getfieldval('data').origin() == 'Me'
= HTTP/2 Build Push Promise Frame: no flag & headers with compression and hdr_name
~ http2 frame build pushpromise
p = h2.H2Frame(stream_id=1)/h2.H2PushPromiseFrame(stream_id=3,hdrs=[
h2.HPackLitHdrFldWithIncrIndexing(
hdr_name=h2.HPackHdrString(data=h2.HPackZString('X-Requested-With')),
hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('Me')),
)
])
assert raw(p) == b'\x00\x00\x15\x05\x00\x00\x00\x00\x01\x00\x00\x00\x03@\x8c\xfc[i{ZT$\xb2-\xc8\xc9\x9f\x02Me'
= HTTP/2 Dissect Push Promise Frame: with padding, the flag END_Header & headers with compression and hdr_name
~ http2 frame dissect pushpromise
pkt = h2.H2Frame(b'\x00\x00\x1e\x05\x0c\x00\x00\x00\x01\x08\x00\x00\x00\x03@\x8c\xfc[i{ZT$\xb2-\xc8\xc9\x9f\x02Me\x00\x00\x00\x00\x00\x00\x00\x00')
assert pkt.type == 5
assert pkt.len == 30
assert len(pkt.flags) == 2
assert 'P' in pkt.flags
assert 'EH' in pkt.flags
assert pkt.reserved == 0
assert pkt.stream_id == 1
assert flags_bit_pattern.search(pkt.show(dump=True)) is None
assert isinstance(pkt.payload, h2.H2PaddedPushPromiseFrame)
assert pkt[h2.H2PaddedPushPromiseFrame]
pf = pkt[h2.H2PaddedPushPromiseFrame]
assert pf.padlen == 8
assert pf.padding == b'\x00'*8
assert pf.stream_id == 3
assert len(pf.hdrs) == 1
hdr = pf.hdrs[0]
assert isinstance(hdr, h2.HPackLitHdrFldWithIncrIndexing)
assert hdr.magic == 1
assert hdr.index == 0
assert isinstance(hdr.hdr_name, h2.HPackHdrString)
assert hdr.hdr_name.type == 1
assert hdr.hdr_name.len == 12
assert hdr.hdr_name.getfieldval('data').origin() == 'X-Requested-With'
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.type == 0
assert hdr.hdr_value.len == 2
assert hdr.hdr_value.getfieldval('data').origin() == 'Me'
= HTTP/2 Build Push Promise Frame: with padding, the flag END_Header & headers with compression and hdr_name
~ http2 frame build pushpromise
p = h2.H2Frame(flags={'P', 'EH'}, stream_id=1)/h2.H2PaddedPushPromiseFrame(
stream_id=3,
hdrs=[
h2.HPackLitHdrFldWithIncrIndexing(
hdr_name=h2.HPackHdrString(data=h2.HPackZString('X-Requested-With')),
hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('Me'))
)
],
padding=b'\x00'*8
)
assert raw(p) == b'\x00\x00\x1e\x05\x0c\x00\x00\x00\x01\x08\x00\x00\x00\x03@\x8c\xfc[i{ZT$\xb2-\xc8\xc9\x9f\x02Me\x00\x00\x00\x00\x00\x00\x00\x00'
+ HTTP/2 Ping Frame Test Suite
= HTTP/2 Dissect Ping Frame: Ping frame
~ http2 frame dissect ping
pkt = h2.H2Frame(b'\x00\x00\x08\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xe2@') #Ping frame with payload
assert pkt.type == 6
assert pkt.len == 8
assert len(pkt.flags) == 0
assert pkt.reserved == 0
assert pkt.stream_id == 0
assert isinstance(pkt.payload, h2.H2PingFrame)
assert pkt[h2.H2PingFrame]
pf = pkt[h2.H2PingFrame]
assert pf.opaque == 123456
assert isinstance(pf.payload, scapy.packet.NoPayload)
= HTTP/2 Build Ping Frame: Ping frame
~ http2 frame build ping
p = h2.H2Frame()/h2.H2PingFrame(opaque=123456)
assert raw(p) == b'\x00\x00\x08\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xe2@'
= HTTP/2 Dissect Ping Frame: Pong frame
~ http2 frame dissect ping
pkt = h2.H2Frame(b'\x00\x00\x08\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xe2@') #Pong frame
assert pkt.type == 6
assert pkt.len == 8
assert len(pkt.flags) == 1
assert 'A' in pkt.flags
assert pkt.reserved == 0
assert pkt.stream_id == 0
assert isinstance(pkt.payload, h2.H2PingFrame)
assert flags_bit_pattern.search(pkt.show(dump=True)) is None
assert pkt[h2.H2PingFrame]
pf = pkt[h2.H2PingFrame]
assert pf.opaque == 123456
assert isinstance(pf.payload, scapy.packet.NoPayload)
= HTTP/2 Dissect Ping Frame: Pong frame
~ http2 frame dissect ping
p = h2.H2Frame(flags={'A'})/h2.H2PingFrame(opaque=123456)
assert raw(p) == b'\x00\x00\x08\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xe2@'
+ HTTP/2 Go Away Frame Test Suite
= HTTP/2 Dissect Go Away Frame: No error
~ http2 frame dissect goaway
pkt = h2.H2Frame(b'\x00\x00\x08\x07\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00') #Go Away for no particular reason :)
assert pkt.type == 7
assert pkt.len == 8
assert len(pkt.flags) == 0
assert pkt.reserved == 0
assert pkt.stream_id == 0
assert isinstance(pkt.payload, h2.H2GoAwayFrame)
assert pkt[h2.H2GoAwayFrame]
gf = pkt[h2.H2GoAwayFrame]
assert gf.reserved == 0
assert gf.last_stream_id == 1
assert gf.error == 0
assert len(gf.additional_data) == 0
assert isinstance(gf.payload, scapy.packet.NoPayload)
= HTTP/2 Build Go Away Frame: No error
~ http2 frame build goaway
p = h2.H2Frame()/h2.H2GoAwayFrame(last_stream_id=1, error='No error')
assert raw(p) == b'\x00\x00\x08\x07\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00'
= HTTP/2 Dissect Go Away Frame: Arbitrary error with additional data
~ http2 frame dissect goaway
pkt = h2.H2Frame(b'\x00\x00\x10\x07\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x01\xe2@\x00\x00\x00\x00\x00\x00\x00\x00') #Go Away with debug data
assert pkt.type == 7
assert pkt.len == 16
assert len(pkt.flags) == 0
assert pkt.reserved == 0
assert pkt.stream_id == 0
assert isinstance(pkt.payload, h2.H2GoAwayFrame)
assert pkt[h2.H2GoAwayFrame]
gf = pkt[h2.H2GoAwayFrame]
assert gf.reserved == 0
assert gf.last_stream_id == 2
assert gf.error == 123456
assert gf.additional_data == 8*b'\x00'
assert isinstance(gf.payload, scapy.packet.NoPayload)
= HTTP/2 Build Go Away Frame: Arbitrary error with additional data
~ http2 frame build goaway
p = h2.H2Frame()/h2.H2GoAwayFrame(
last_stream_id=2,
error=123456,
additional_data=b'\x00'*8
)
assert raw(p) == b'\x00\x00\x10\x07\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x01\xe2@\x00\x00\x00\x00\x00\x00\x00\x00'
+ HTTP/2 Window Update Frame Test Suite
= HTTP/2 Dissect Window Update Frame: global
~ http2 frame dissect winupdate
pkt = h2.H2Frame(b'\x00\x00\x04\x08\x00\x00\x00\x00\x00\x00\x01\xe2@') #Window update with increment for connection
assert pkt.type == 8
assert pkt.len == 4
assert len(pkt.flags) == 0
assert pkt.reserved == 0
assert pkt.stream_id == 0
assert isinstance(pkt.payload, h2.H2WindowUpdateFrame)
assert pkt[h2.H2WindowUpdateFrame]
wf = pkt[h2.H2WindowUpdateFrame]
assert wf.reserved == 0
assert wf.win_size_incr == 123456
assert isinstance(wf.payload, scapy.packet.NoPayload)
= HTTP/2 Build Window Update Frame: global
~ http2 frame build winupdate
p = h2.H2Frame()/h2.H2WindowUpdateFrame(win_size_incr=123456)
assert raw(p) == b'\x00\x00\x04\x08\x00\x00\x00\x00\x00\x00\x01\xe2@'
= HTTP/2 Dissect Window Update Frame: a stream
~ http2 frame dissect winupdate
pkt = h2.H2Frame(b'\x00\x00\x04\x08\x00\x00\x00\x00\x01\x00\x01\xe2@') #Window update with increment for a stream
assert pkt.type == 8
assert pkt.len == 4
assert len(pkt.flags) == 0
assert pkt.reserved == 0
assert pkt.stream_id == 1
assert isinstance(pkt.payload, h2.H2WindowUpdateFrame)
assert pkt[h2.H2WindowUpdateFrame]
wf = pkt[h2.H2WindowUpdateFrame]
assert wf.reserved == 0
assert wf.win_size_incr == 123456
assert isinstance(wf.payload, scapy.packet.NoPayload)
= HTTP/2 Build Window Update Frame: a stream
~ http2 frame build winupdate
p = h2.H2Frame(stream_id=1)/h2.H2WindowUpdateFrame(win_size_incr=123456)
assert raw(p) == b'\x00\x00\x04\x08\x00\x00\x00\x00\x01\x00\x01\xe2@'
+ HTTP/2 Continuation Frame Test Suite
= HTTP/2 Dissect Continuation Frame: no flag & headers with compression and hdr_name
~ http2 frame dissect continuation
pkt = h2.H2Frame(b'\x00\x00\x11\t\x00\x00\x00\x00\x01@\x8c\xfc[i{ZT$\xb2-\xc8\xc9\x9f\x02Me')
assert pkt.type == 9
assert pkt.len == 17
assert len(pkt.flags) == 0
assert pkt.reserved == 0
assert pkt.stream_id == 1
assert isinstance(pkt.payload, h2.H2ContinuationFrame)
assert pkt[h2.H2ContinuationFrame]
hf = pkt[h2.H2ContinuationFrame]
assert len(hf.hdrs) == 1
assert isinstance(hf.payload, scapy.packet.NoPayload)
hdr = hf.hdrs[0]
assert isinstance(hdr, h2.HPackLitHdrFldWithIncrIndexing)
assert hdr.magic == 1
assert hdr.index == 0
assert isinstance(hdr.hdr_name, h2.HPackHdrString)
assert hdr.hdr_name.type == 1
assert hdr.hdr_name.len == 12
assert hdr.hdr_name.getfieldval('data').origin() == 'X-Requested-With'
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.type == 0
assert hdr.hdr_value.len == 2
assert hdr.hdr_value.getfieldval('data').origin() == 'Me'
= HTTP/2 Build Continuation Frame: no flag & headers with compression and hdr_name
~ http2 frame build continuation
p = h2.H2Frame(stream_id=1)/h2.H2ContinuationFrame(
hdrs=[
h2.HPackLitHdrFldWithIncrIndexing(
hdr_name=h2.HPackHdrString(data=h2.HPackZString('X-Requested-With')),
hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('Me'))
)
]
)
assert raw(p) == b'\x00\x00\x11\t\x00\x00\x00\x00\x01@\x8c\xfc[i{ZT$\xb2-\xc8\xc9\x9f\x02Me'
= HTTP/2 Dissect Continuation Frame: flag END_Header & headers with compression, sensitive flag and hdr_name
~ http2 frame dissect continuation
pkt = h2.H2Frame(b'\x00\x00\x11\t\x04\x00\x00\x00\x01\x10\x8c\xfc[i{ZT$\xb2-\xc8\xc9\x9f\x02Me')
assert pkt.type == 9
assert pkt.len == 17
assert len(pkt.flags) == 1
assert 'EH' in pkt.flags
assert pkt.reserved == 0
assert pkt.stream_id == 1
assert flags_bit_pattern.search(pkt.show(dump=True)) is None
assert isinstance(pkt.payload, h2.H2ContinuationFrame)
assert pkt[h2.H2ContinuationFrame]
hf = pkt[h2.H2ContinuationFrame]
assert len(hf.hdrs) == 1
assert isinstance(hf.payload, scapy.packet.NoPayload)
hdr = hf.hdrs[0]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 1
assert hdr.index == 0
assert isinstance(hdr.hdr_name, h2.HPackHdrString)
assert hdr.hdr_name.type == 1
assert hdr.hdr_name.len == 12
assert hdr.hdr_name.getfieldval('data').origin() == 'X-Requested-With'
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.type == 0
assert hdr.hdr_value.len == 2
assert hdr.hdr_value.getfieldval('data').origin() == 'Me'
= HTTP/2 Build Continuation Frame: flag END_Header & headers with compression, sensitive flag and hdr_name
~ http2 frame build continuation
p = h2.H2Frame(flags={'EH'}, stream_id=1)/h2.H2ContinuationFrame(
hdrs=[
h2.HPackLitHdrFldWithoutIndexing(
never_index=1,
hdr_name=h2.HPackHdrString(data=h2.HPackZString('X-Requested-With')),
hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('Me'))
)
]
)
assert raw(p) == b'\x00\x00\x11\t\x04\x00\x00\x00\x01\x10\x8c\xfc[i{ZT$\xb2-\xc8\xc9\x9f\x02Me'
+ HTTP/2 HPackHdrTable Test Suite
= HTTP/2 HPackHdrEntry Tests
~ http2 hpack hpackhdrtable
n = 'X-Requested-With'
v = 'Me'
h = h2.HPackHdrEntry(n, v)
assert len(h) == 32 + len(n) + len(v)
assert h.name() == n.lower()
assert h.value() == v
assert str(h) == '{}: {}'.format(n.lower(), v)
n = ':status'
v = '200'
h = h2.HPackHdrEntry(n, v)
assert len(h) == 32 + len(n) + len(v)
assert h.name() == n.lower()
assert h.value() == v
assert str(h) == '{} {}'.format(n.lower(), v)
= HTTP/2 HPackHdrTable : Querying Static Entries
~ http2 hpack hpackhdrtable
# In RFC7541, the table is 1-based
assert expect_exception(KeyError, 'h2.HPackHdrTable()[0]')
h = h2.HPackHdrTable()
assert h[1].name() == ':authority'
assert h[7].name() == ':scheme'
assert h[7].value() == 'https'
assert str(h[14]) == ':status 500'
assert str(h[16]) == 'accept-encoding: gzip, deflate'
assert expect_exception(KeyError, 'h2.HPackHdrTable()[h2.HPackHdrTable._static_entries_last_idx+1]')
= HTTP/2 HPackHdrTable : Addind Dynamic Entries without overflowing the table
~ http2 hpack hpackhdrtable
tbl = h2.HPackHdrTable(dynamic_table_max_size=1<<32, dynamic_table_cap_size=1<<32)
hdr = h2.HPackLitHdrFldWithIncrIndexing(
index=32,
hdr_value=h2.HPackHdrString(data=h2.HPackZString('PHPSESSID=abcdef0123456789'))
)
tbl.register(hdr)
tbl = h2.HPackHdrTable(dynamic_table_max_size=1<<32, dynamic_table_cap_size=1<<32)
hdr2 = h2.HPackLitHdrFldWithIncrIndexing(
index=32,
hdr_value=h2.HPackHdrString(data=h2.HPackZString('JSESSID=abcdef0123456789'))
)
tbl.register([hdr,hdr2])
tbl = h2.HPackHdrTable(dynamic_table_max_size=1<<32, dynamic_table_cap_size=1<<32)
hdr3 = h2.HPackLitHdrFldWithIncrIndexing(
index=32,
hdr_value=h2.HPackHdrString(data=h2.HPackZString('Test=abcdef0123456789'))
)
frm = h2.H2Frame(stream_id=1)/h2.H2HeadersFrame(hdrs=[hdr, hdr2, hdr3])
tbl.register(frm)
= HTTP/2 HPackHdrTable : Querying Dynamic Entries
~ http2 hpack hpackhdrtable
tbl = h2.HPackHdrTable(dynamic_table_max_size=1<<32, dynamic_table_cap_size=1<<32)
hdrv = 'PHPSESSID=abcdef0123456789'
hdr = h2.HPackLitHdrFldWithIncrIndexing(
index=32,
hdr_value=h2.HPackHdrString(data=h2.HPackZString(hdrv))
)
tbl.register(hdr)
hdrv2 = 'JSESSID=abcdef0123456789'
hdr2 = h2.HPackLitHdrFldWithIncrIndexing(
index=32,
hdr_value=h2.HPackHdrString(data=h2.HPackZString(hdrv2))
)
tbl.register(hdr2)
hdr3 = h2.HPackLitHdrFldWithIncrIndexing(
index=0,
hdr_name=h2.HPackHdrString(data=h2.HPackLiteralString('x-requested-by')),
hdr_value=h2.HPackHdrString(data=h2.HPackZString('me'))
)
tbl.register(hdr3)
assert tbl.get_idx_by_name('x-requested-by') == h2.HPackHdrTable._static_entries_last_idx+1
assert tbl[h2.HPackHdrTable._static_entries_last_idx+2].value() == hdrv2
assert tbl[h2.HPackHdrTable._static_entries_last_idx+3].value() == hdrv
= HTTP/2 HPackHdrTable : Addind already registered Dynamic Entries without overflowing the table
~ http2 hpack hpackhdrtable
tbl = h2.HPackHdrTable(dynamic_table_max_size=1<<32, dynamic_table_cap_size=1<<32)
assert len(tbl) == 0
hdrv = 'PHPSESSID=abcdef0123456789'
hdr = h2.HPackLitHdrFldWithIncrIndexing(
index=32,
hdr_value=h2.HPackHdrString(data=h2.HPackZString(hdrv))
)
tbl.register(hdr)
assert tbl[h2.HPackHdrTable._static_entries_last_idx+1].value() == hdrv
hdr2v = 'JSESSID=abcdef0123456789'
hdr2 = h2.HPackLitHdrFldWithIncrIndexing(
index=32,
hdr_value=h2.HPackHdrString(data=h2.HPackZString(hdr2v))
)
tbl.register(hdr2)
assert tbl[h2.HPackHdrTable._static_entries_last_idx+1].value() == hdr2v
l = len(tbl)
tbl.register(hdr)
assert tbl[h2.HPackHdrTable._static_entries_last_idx+1].value() == hdrv
assert tbl[h2.HPackHdrTable._static_entries_last_idx+2].value() == hdr2v
assert tbl[h2.HPackHdrTable._static_entries_last_idx+3].value() == hdrv
= HTTP/2 HPackHdrTable : Addind Dynamic Entries and overflowing the table
~ http2 hpack hpackhdrtable
tbl = h2.HPackHdrTable(dynamic_table_max_size=80, dynamic_table_cap_size=80)
hdrv = 'PHPSESSID=abcdef0123456789'
hdr = h2.HPackLitHdrFldWithIncrIndexing(
index=32,
hdr_value=h2.HPackHdrString(data=h2.HPackZString(hdrv))
)
tbl.register(hdr)
assert len(tbl) <= 80
assert tbl[h2.HPackHdrTable._static_entries_last_idx+1].value() == hdrv
hdrv2 = 'JSESSID=abcdef0123456789'
hdr2 = h2.HPackLitHdrFldWithIncrIndexing(
index=32,
hdr_value=h2.HPackHdrString(data=h2.HPackZString(hdrv2))
)
tbl.register(hdr2)
assert len(tbl) <= 80
assert tbl[h2.HPackHdrTable._static_entries_last_idx+1].value() == hdrv2
try:
tbl[h2.HPackHdrTable._static_entries_last_idx+2]
ret = False
except Exception:
ret = True
assert ret
= HTTP/2 HPackHdrTable : Resizing
~ http2 hpack hpackhdrtable
tbl = h2.HPackHdrTable()
hdrv = 'PHPSESSID=abcdef0123456789'
hdr = h2.HPackLitHdrFldWithIncrIndexing(
index=32,
hdr_value=h2.HPackHdrString(data=h2.HPackZString(hdrv))
)
tbl.register(hdr)
assert tbl[h2.HPackHdrTable._static_entries_last_idx+1].value() == hdrv
hdrv2 = 'JSESSID=abcdef0123456789'
hdr2 = h2.HPackLitHdrFldWithIncrIndexing(
index=32,
hdr_value=h2.HPackHdrString(data=h2.HPackZString(hdrv2))
)
tbl.register(hdr2)
assert tbl[h2.HPackHdrTable._static_entries_last_idx+1].value() == hdrv2
assert tbl[h2.HPackHdrTable._static_entries_last_idx+2].value() == hdrv
#Resizing to a value higher than cap (default:4096)
try:
tbl.resize(8192)
ret = False
except AssertionError:
ret = True
assert ret
#Resizing to a lower value by that is not small enough to cause eviction
tbl.resize(1024)
assert tbl[h2.HPackHdrTable._static_entries_last_idx+1].value() == hdrv2
assert tbl[h2.HPackHdrTable._static_entries_last_idx+2].value() == hdrv
#Resizing to a higher value but thatt is lower than cap
tbl.resize(2048)
assert tbl[h2.HPackHdrTable._static_entries_last_idx+1].value() == hdrv2
assert tbl[h2.HPackHdrTable._static_entries_last_idx+2].value() == hdrv
#Resizing to a lower value that causes eviction
tbl.resize(80)
assert tbl[h2.HPackHdrTable._static_entries_last_idx+1].value() == hdrv2
try:
tbl[h2.HPackHdrTable._static_entries_last_idx+2]
ret = False
except Exception:
ret = True
assert ret
= HTTP/2 HPackHdrTable : Recapping
~ http2 hpack hpackhdrtable
tbl = h2.HPackHdrTable()
hdrv = 'PHPSESSID=abcdef0123456789'
hdr = h2.HPackLitHdrFldWithIncrIndexing(
index=32,
hdr_value=h2.HPackHdrString(data=h2.HPackZString(hdrv))
)
tbl.register(hdr)
assert tbl[h2.HPackHdrTable._static_entries_last_idx+1].value() == hdrv
hdrv2 = 'JSESSID=abcdef0123456789'
hdr2 = h2.HPackLitHdrFldWithIncrIndexing(
index=32,
hdr_value=h2.HPackHdrString(data=h2.HPackZString(hdrv2))
)
tbl.register(hdr2)
assert tbl[h2.HPackHdrTable._static_entries_last_idx+1].value() == hdrv2
assert tbl[h2.HPackHdrTable._static_entries_last_idx+2].value() == hdrv
#Recapping to a higher value
tbl.recap(8192)
assert tbl[h2.HPackHdrTable._static_entries_last_idx+1].value() == hdrv2
assert tbl[h2.HPackHdrTable._static_entries_last_idx+2].value() == hdrv
#Recapping to a low value but without causing eviction
tbl.recap(1024)
assert tbl[h2.HPackHdrTable._static_entries_last_idx+1].value() == hdrv2
assert tbl[h2.HPackHdrTable._static_entries_last_idx+2].value() == hdrv
#Recapping to a low value that causes evictiontbl.recap(1024)
tbl.recap(80)
assert tbl[h2.HPackHdrTable._static_entries_last_idx+1].value() == hdrv2
try:
tbl[h2.HPackHdrTable._static_entries_last_idx+2]
ret = False
except Exception:
ret = True
assert ret
= HTTP/2 HPackHdrTable : Generating Textual Representation
~ http2 hpack hpackhdrtable helpers
h = h2.HPackHdrTable()
h.register(h2.HPackLitHdrFldWithIncrIndexing(
hdr_name=h2.HPackHdrString(data=h2.HPackZString('X-Generation-Date')),
hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('2016-08-11'))
))
hdrs_lst = [
h2.HPackIndexedHdr(index=2), #Method Get
h2.HPackLitHdrFldWithIncrIndexing(
index=h.get_idx_by_name(':path'),
hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('/index.php'))
),
h2.HPackIndexedHdr(index=7), #Scheme HTTPS
h2.HPackIndexedHdr(index=h2.HPackHdrTable._static_entries_last_idx+2),
h2.HPackLitHdrFldWithIncrIndexing(
index=58,
hdr_value=h2.HPackHdrString(data=h2.HPackZString('Mozilla/5.0 Generated by hand'))
),
h2.HPackLitHdrFldWithoutIndexing(
hdr_name=h2.HPackHdrString(data=h2.HPackZString('X-Generated-By')),
hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('Me'))
)
]
p = h2.H2Frame(stream_id = 1)/h2.H2HeadersFrame(hdrs=hdrs_lst)
expected_output = ''':method GET
:path /index.php
:scheme https
x-generation-date: 2016-08-11
user-agent: Mozilla/5.0 Generated by hand
X-Generated-By: Me'''
assert h.gen_txt_repr(p) == expected_output
= HTTP/2 HPackHdrTable : Parsing Textual Representation
~ http2 hpack hpackhdrtable helpers
body = b'login=titi&passwd=toto'
hdrs = ''':method POST
:path /login.php
:scheme https
content-type: application/x-www-form-urlencoded
content-length: {}
user-agent: Mozilla/5.0 Generated by hand
x-generated-by: Me
x-generation-date: 2016-08-11
x-generation-software: scapy
'''.format(len(body))
h = h2.HPackHdrTable()
h.register(h2.HPackLitHdrFldWithIncrIndexing(
hdr_name=h2.HPackHdrString(data=h2.HPackZString('X-Generation-Date')),
hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('2016-08-11'))
))
seq = h.parse_txt_hdrs(
hdrs,
stream_id=1,
body=body,
should_index=lambda name: name in ['user-agent', 'x-generation-software'],
is_sensitive=lambda name, value: name in ['x-generated-by', ':path']
)
assert isinstance(seq, h2.H2Seq)
assert len(seq.frames) == 2
p = seq.frames[0]
assert isinstance(p, h2.H2Frame)
assert p.type == 1
assert len(p.flags) == 1
assert 'EH' in p.flags
assert p.stream_id == 1
assert isinstance(p.payload, h2.H2HeadersFrame)
hdrs_frm = p[h2.H2HeadersFrame]
assert len(p.hdrs) == 9
hdr = p.hdrs[0]
assert isinstance(hdr, h2.HPackIndexedHdr)
assert hdr.magic == 1
assert hdr.index == 3
hdr = p.hdrs[1]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 1
assert hdr.index in [4, 5]
assert hdr.hdr_name is None
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackZString(/login.php)'
hdr = p.hdrs[2]
assert isinstance(hdr, h2.HPackIndexedHdr)
assert hdr.magic == 1
assert hdr.index == 7
hdr = p.hdrs[3]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 0
assert hdr.index == 31
assert hdr.hdr_name is None
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackZString(application/x-www-form-urlencoded)'
hdr = p.hdrs[4]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 0
assert hdr.index == 28
assert hdr.hdr_name is None
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackLiteralString(22)'
hdr = p.hdrs[5]
assert isinstance(hdr, h2.HPackLitHdrFldWithIncrIndexing)
assert hdr.magic == 1
assert hdr.index == 58
assert hdr.hdr_name is None
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackZString(Mozilla/5.0 Generated by hand)'
hdr = p.hdrs[6]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 1
assert hdr.index == 0
assert isinstance(hdr.hdr_name, h2.HPackHdrString)
assert hdr.hdr_name.data == 'HPackZString(x-generated-by)'
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackLiteralString(Me)'
hdr = p.hdrs[7]
assert isinstance(hdr, h2.HPackIndexedHdr)
assert hdr.magic == 1
assert hdr.index == 63
hdr = p.hdrs[8]
assert isinstance(hdr, h2.HPackLitHdrFldWithIncrIndexing)
assert hdr.magic == 1
assert hdr.index == 0
assert isinstance(hdr.hdr_name, h2.HPackHdrString)
assert hdr.hdr_name.data == 'HPackZString(x-generation-software)'
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackZString(scapy)'
p = seq.frames[1]
assert isinstance(p, h2.H2Frame)
assert p.type == 0
assert len(p.flags) == 1
assert 'ES' in p.flags
assert p.stream_id == 1
assert isinstance(p.payload, h2.H2DataFrame)
pay = p[h2.H2DataFrame]
assert pay.data == body
# now with bytes
h = h2.HPackHdrTable()
h.register(h2.HPackLitHdrFldWithIncrIndexing(
hdr_name=h2.HPackHdrString(data=h2.HPackZString('X-Generation-Date')),
hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('2016-08-11'))
))
seq = h.parse_txt_hdrs(
hdrs.encode(),
stream_id=1,
body=body,
should_index=lambda name: name in ['user-agent', 'x-generation-software'],
is_sensitive=lambda name, value: name in ['x-generated-by', ':path']
)
assert isinstance(seq, h2.H2Seq)
assert len(seq.frames) == 2
p = seq.frames[0]
assert isinstance(p, h2.H2Frame)
assert p.type == 1
assert len(p.flags) == 1
assert 'EH' in p.flags
assert p.stream_id == 1
assert isinstance(p.payload, h2.H2HeadersFrame)
hdrs_frm = p[h2.H2HeadersFrame]
assert len(p.hdrs) == 9
hdr = p.hdrs[0]
assert isinstance(hdr, h2.HPackIndexedHdr)
assert hdr.magic == 1
assert hdr.index == 3
hdr = p.hdrs[1]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 1
assert hdr.index in [4, 5]
assert hdr.hdr_name is None
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackZString(/login.php)'
hdr = p.hdrs[2]
assert isinstance(hdr, h2.HPackIndexedHdr)
assert hdr.magic == 1
assert hdr.index == 7
hdr = p.hdrs[3]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 0
assert hdr.index == 31
assert hdr.hdr_name is None
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackZString(application/x-www-form-urlencoded)'
hdr = p.hdrs[4]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 0
assert hdr.index == 28
assert hdr.hdr_name is None
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackLiteralString(22)'
hdr = p.hdrs[5]
assert isinstance(hdr, h2.HPackLitHdrFldWithIncrIndexing)
assert hdr.magic == 1
assert hdr.index == 58
assert hdr.hdr_name is None
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackZString(Mozilla/5.0 Generated by hand)'
hdr = p.hdrs[6]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 1
assert hdr.index == 0
assert isinstance(hdr.hdr_name, h2.HPackHdrString)
assert hdr.hdr_name.data == 'HPackZString(x-generated-by)'
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackLiteralString(Me)'
hdr = p.hdrs[7]
assert isinstance(hdr, h2.HPackIndexedHdr)
assert hdr.magic == 1
assert hdr.index == 63
hdr = p.hdrs[8]
assert isinstance(hdr, h2.HPackLitHdrFldWithIncrIndexing)
assert hdr.magic == 1
assert hdr.index == 0
assert isinstance(hdr.hdr_name, h2.HPackHdrString)
assert hdr.hdr_name.data == 'HPackZString(x-generation-software)'
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackZString(scapy)'
p = seq.frames[1]
assert isinstance(p, h2.H2Frame)
assert p.type == 0
assert len(p.flags) == 1
assert 'ES' in p.flags
assert p.stream_id == 1
assert isinstance(p.payload, h2.H2DataFrame)
pay = p[h2.H2DataFrame]
assert pay.data == body
= HTTP/2 HPackHdrTable : Parsing Textual Representation without body
~ http2 hpack hpackhdrtable helpers
hdrs = b''':method POST
:path /login.php
:scheme https
user-agent: Mozilla/5.0 Generated by hand
x-generated-by: Me
x-generation-date: 2016-08-11
'''
h = h2.HPackHdrTable()
h.register(h2.HPackLitHdrFldWithIncrIndexing(
hdr_name=h2.HPackHdrString(data=h2.HPackZString('X-Generation-Date')),
hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('2016-08-11'))
))
# Without body
seq = h.parse_txt_hdrs(hdrs, stream_id=1)
assert isinstance(seq, h2.H2Seq)
#This is the first major difference with the first test
assert len(seq.frames) == 1
p = seq.frames[0]
assert isinstance(p, h2.H2Frame)
assert p.type == 1
assert len(p.flags) == 2
assert 'EH' in p.flags
#This is the second major difference with the first test
assert 'ES' in p.flags
assert p.stream_id == 1
assert isinstance(p.payload, h2.H2HeadersFrame)
hdrs_frm = p[h2.H2HeadersFrame]
assert len(p.hdrs) == 6
hdr = p.hdrs[0]
assert isinstance(hdr, h2.HPackIndexedHdr)
assert hdr.magic == 1
assert hdr.index == 3
hdr = p.hdrs[1]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 0
assert hdr.index in [4, 5]
assert hdr.hdr_name is None
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackZString(/login.php)'
hdr = p.hdrs[2]
assert isinstance(hdr, h2.HPackIndexedHdr)
assert hdr.magic == 1
assert hdr.index == 7
hdr = p.hdrs[3]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 0
assert hdr.index == 58
assert hdr.hdr_name is None
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackZString(Mozilla/5.0 Generated by hand)'
hdr = p.hdrs[4]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 0
assert hdr.index == 0
assert isinstance(hdr.hdr_name, h2.HPackHdrString)
assert hdr.hdr_name.data == 'HPackZString(x-generated-by)'
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackLiteralString(Me)'
hdr = p.hdrs[5]
assert isinstance(hdr, h2.HPackIndexedHdr)
assert hdr.magic == 1
assert hdr.index == 62
= HTTP/2 HPackHdrTable : Parsing Textual Representation with too small max frame
~ http2 hpack hpackhdrtable helpers
body = b'login=titi&passwd=toto'
hdrs = ''':method POST
:path /login.php
:scheme https
content-type: application/x-www-form-urlencoded
content-length: {}
user-agent: Mozilla/5.0 Generated by hand
x-generated-by: Me
x-generation-date: 2016-08-11
x-long-header: {}
'''.format(len(body), 'a'*5000).encode()
h = h2.HPackHdrTable()
h.register(h2.HPackLitHdrFldWithIncrIndexing(
hdr_name=h2.HPackHdrString(data=h2.HPackZString('X-Generation-Date')),
hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('2016-08-11'))
))
#x-long-header is too long to fit in any frames (whose default max size is 4096)
expect_exception(Exception, "seq = h.parse_txt_hdrs('''{}''', stream_id=1".format(hdrs))
= HTTP/2 HPackHdrTable : Parsing Textual Representation with very large header and a large authorized frame size
~ http2 hpack hpackhdrtable helpers
body = b'login=titi&passwd=toto'
hdrs = ''':method POST
:path /login.php
:scheme https
content-type: application/x-www-form-urlencoded
content-length: {}
user-agent: Mozilla/5.0 Generated by hand
x-generated-by: Me
x-generation-date: 2016-08-11
x-long-header: {}
'''.format(len(body), 'a'*5000).encode()
h = h2.HPackHdrTable()
h.register(h2.HPackLitHdrFldWithIncrIndexing(
hdr_name=h2.HPackHdrString(data=h2.HPackZString('X-Generation-Date')),
hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('2016-08-11'))
))
# Now trying to parse it with a max frame size large enough for x-long-header to
# fit in a frame
seq = h.parse_txt_hdrs(hdrs, stream_id=1, max_frm_sz=8192)
assert isinstance(seq, h2.H2Seq)
assert len(seq.frames) == 1
p = seq.frames[0]
assert isinstance(p, h2.H2Frame)
assert p.type == 1
assert len(p.flags) == 2
assert 'EH' in p.flags
assert 'ES' in p.flags
assert p.stream_id == 1
assert isinstance(p.payload, h2.H2HeadersFrame)
hdrs_frm = p[h2.H2HeadersFrame]
assert len(p.hdrs) == 9
hdr = p.hdrs[0]
assert isinstance(hdr, h2.HPackIndexedHdr)
assert hdr.magic == 1
assert hdr.index == 3
hdr = p.hdrs[1]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 0
assert hdr.index in [4, 5]
assert hdr.hdr_name is None
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackZString(/login.php)'
hdr = p.hdrs[2]
assert isinstance(hdr, h2.HPackIndexedHdr)
assert hdr.magic == 1
assert hdr.index == 7
hdr = p.hdrs[3]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 0
assert hdr.index == 31
assert hdr.hdr_name is None
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackZString(application/x-www-form-urlencoded)'
hdr = p.hdrs[4]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 0
assert hdr.index == 28
assert hdr.hdr_name is None
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackLiteralString(22)'
hdr = p.hdrs[5]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 0
assert hdr.index == 58
assert hdr.hdr_name is None
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackZString(Mozilla/5.0 Generated by hand)'
hdr = p.hdrs[6]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 0
assert hdr.index == 0
assert isinstance(hdr.hdr_name, h2.HPackHdrString)
assert hdr.hdr_name.data == 'HPackZString(x-generated-by)'
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackLiteralString(Me)'
hdr = p.hdrs[7]
assert isinstance(hdr, h2.HPackIndexedHdr)
assert hdr.magic == 1
assert hdr.index == 62
hdr = p.hdrs[8]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 0
assert hdr.index == 0
assert isinstance(hdr.hdr_name, h2.HPackHdrString)
assert hdr.hdr_name.data == 'HPackZString(x-long-header)'
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackZString({})'.format('a'*5000)
= HTTP/2 HPackHdrTable : Parsing Textual Representation with two very large headers and a large authorized frame size
~ http2 hpack hpackhdrtable helpers
body = b'login=titi&passwd=toto'
hdrs = ''':method POST
:path /login.php
:scheme https
content-type: application/x-www-form-urlencoded
content-length: {}
user-agent: Mozilla/5.0 Generated by hand
x-generated-by: Me
x-generation-date: 2016-08-11
x-long-header: {}
x-long-header: {}
'''.format(len(body), 'a'*5000, 'b'*5000).encode()
h = h2.HPackHdrTable()
h.register(h2.HPackLitHdrFldWithIncrIndexing(
hdr_name=h2.HPackHdrString(data=h2.HPackZString('X-Generation-Date')),
hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('2016-08-11'))
))
# Now trying to parse it with a max frame size large enough for x-long-header to
# fit in a frame but a maximum header fragment size that is not large enough to
# store two x-long-header
seq = h.parse_txt_hdrs(hdrs, stream_id=1, max_frm_sz=8192)
assert isinstance(seq, h2.H2Seq)
assert len(seq.frames) == 2
p = seq.frames[0]
assert isinstance(p, h2.H2Frame)
assert p.type == 1
assert len(p.flags) == 1
assert 'ES' in p.flags
assert p.stream_id == 1
assert isinstance(p.payload, h2.H2HeadersFrame)
hdrs_frm = p[h2.H2HeadersFrame]
assert len(p.hdrs) == 9
hdr = p.hdrs[0]
assert isinstance(hdr, h2.HPackIndexedHdr)
assert hdr.magic == 1
assert hdr.index == 3
hdr = p.hdrs[1]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 0
assert hdr.index in [4, 5]
assert hdr.hdr_name is None
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackZString(/login.php)'
hdr = p.hdrs[2]
assert isinstance(hdr, h2.HPackIndexedHdr)
assert hdr.magic == 1
assert hdr.index == 7
hdr = p.hdrs[3]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 0
assert hdr.index == 31
assert hdr.hdr_name is None
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackZString(application/x-www-form-urlencoded)'
hdr = p.hdrs[4]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 0
assert hdr.index == 28
assert hdr.hdr_name is None
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackLiteralString(22)'
hdr = p.hdrs[5]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 0
assert hdr.index == 58
assert hdr.hdr_name is None
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackZString(Mozilla/5.0 Generated by hand)'
hdr = p.hdrs[6]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 0
assert hdr.index == 0
assert isinstance(hdr.hdr_name, h2.HPackHdrString)
assert hdr.hdr_name.data == 'HPackZString(x-generated-by)'
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackLiteralString(Me)'
hdr = p.hdrs[7]
assert isinstance(hdr, h2.HPackIndexedHdr)
assert hdr.magic == 1
assert hdr.index == 62
hdr = p.hdrs[8]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 0
assert hdr.index == 0
assert isinstance(hdr.hdr_name, h2.HPackHdrString)
assert hdr.hdr_name.data == 'HPackZString(x-long-header)'
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackZString({})'.format('a'*5000)
p = seq.frames[1]
assert isinstance(p, h2.H2Frame)
assert p.type == 9
assert len(p.flags) == 1
assert 'EH' in p.flags
assert p.stream_id == 1
assert isinstance(p.payload, h2.H2ContinuationFrame)
hdrs_frm = p[h2.H2ContinuationFrame]
assert len(p.hdrs) == 1
hdr = p.hdrs[0]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 0
assert hdr.index == 0
assert isinstance(hdr.hdr_name, h2.HPackHdrString)
assert hdr.hdr_name.data == 'HPackZString(x-long-header)'
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackZString({})'.format('b'*5000)
= HTTP/2 HPackHdrTable : Parsing Textual Representation with two very large headers, a large authorized frame size and a "small" max header list size
~ http2 hpack hpackhdrtable helpers
body = b'login=titi&passwd=toto'
hdrs = ''':method POST
:path /login.php
:scheme https
content-type: application/x-www-form-urlencoded
content-length: {}
user-agent: Mozilla/5.0 Generated by hand
x-generated-by: Me
x-generation-date: 2016-08-11
x-long-header: {}
x-long-header: {}
'''.format(len(body), 'a'*5000, 'b'*5000).encode()
h = h2.HPackHdrTable()
h.register(h2.HPackLitHdrFldWithIncrIndexing(
hdr_name=h2.HPackHdrString(data=h2.HPackZString('X-Generation-Date')),
hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('2016-08-11'))
))
# Now trying to parse it with a max frame size large enough for x-long-header to
# fit in a frame but and a max header list size that is large enough to fit one
# but not two
seq = h.parse_txt_hdrs(hdrs, stream_id=1, max_frm_sz=8192, max_hdr_lst_sz=5050)
assert isinstance(seq, h2.H2Seq)
assert len(seq.frames) == 3
p = seq.frames[0]
assert isinstance(p, h2.H2Frame)
assert p.type == 1
assert len(p.flags) == 1
assert 'ES' in p.flags
assert p.stream_id == 1
assert isinstance(p.payload, h2.H2HeadersFrame)
hdrs_frm = p[h2.H2HeadersFrame]
assert len(p.hdrs) == 8
hdr = p.hdrs[0]
assert isinstance(hdr, h2.HPackIndexedHdr)
assert hdr.magic == 1
assert hdr.index == 3
hdr = p.hdrs[1]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 0
assert hdr.index in [4, 5]
assert hdr.hdr_name is None
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackZString(/login.php)'
hdr = p.hdrs[2]
assert isinstance(hdr, h2.HPackIndexedHdr)
assert hdr.magic == 1
assert hdr.index == 7
hdr = p.hdrs[3]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 0
assert hdr.index == 31
assert hdr.hdr_name is None
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackZString(application/x-www-form-urlencoded)'
hdr = p.hdrs[4]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 0
assert hdr.index == 28
assert hdr.hdr_name is None
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackLiteralString(22)'
hdr = p.hdrs[5]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 0
assert hdr.index == 58
assert hdr.hdr_name is None
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackZString(Mozilla/5.0 Generated by hand)'
hdr = p.hdrs[6]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 0
assert hdr.index == 0
assert isinstance(hdr.hdr_name, h2.HPackHdrString)
assert hdr.hdr_name.data == 'HPackZString(x-generated-by)'
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackLiteralString(Me)'
hdr = p.hdrs[7]
assert isinstance(hdr, h2.HPackIndexedHdr)
assert hdr.magic == 1
assert hdr.index == 62
p = seq.frames[1]
assert isinstance(p, h2.H2Frame)
assert p.type == 9
assert len(p.flags) == 0
assert p.stream_id == 1
assert isinstance(p.payload, h2.H2ContinuationFrame)
hdrs_frm = p[h2.H2ContinuationFrame]
assert len(p.hdrs) == 1
hdr = p.hdrs[0]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 0
assert hdr.index == 0
assert isinstance(hdr.hdr_name, h2.HPackHdrString)
assert hdr.hdr_name.data == 'HPackZString(x-long-header)'
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackZString({})'.format('a'*5000)
p = seq.frames[2]
assert isinstance(p, h2.H2Frame)
assert p.type == 9
assert len(p.flags) == 1
assert 'EH' in p.flags
assert p.stream_id == 1
assert isinstance(p.payload, h2.H2ContinuationFrame)
hdrs_frm = p[h2.H2ContinuationFrame]
assert len(p.hdrs) == 1
hdr = p.hdrs[0]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 0
assert hdr.index == 0
assert isinstance(hdr.hdr_name, h2.HPackHdrString)
assert hdr.hdr_name.data == 'HPackZString(x-long-header)'
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackZString({})'.format('b'*5000)
= HTTP/2 HPackHdrTable : Parsing Textual Representation with sensitive headers and non-indexable ones
~ http2 hpack hpackhdrtable helpers
hdrs = ''':method POST
:path /login.php
:scheme https
content-type: application/x-www-form-urlencoded
content-length: {}
user-agent: Mozilla/5.0 Generated by hand
x-generated-by: Me
x-generation-date: 2016-08-11
'''.format(len(body)).encode()
h = h2.HPackHdrTable()
seq = h.parse_txt_hdrs(hdrs, stream_id=1, body=body, is_sensitive=lambda n,v: n in ['x-generation-date'], should_index=lambda x: x != 'x-generated-by')
assert isinstance(seq, h2.H2Seq)
assert len(seq.frames) == 2
p = seq.frames[0]
assert isinstance(p, h2.H2Frame)
assert p.type == 1
assert len(p.flags) == 1
assert 'EH' in p.flags
assert p.stream_id == 1
assert isinstance(p.payload, h2.H2HeadersFrame)
hdrs_frm = p[h2.H2HeadersFrame]
assert len(p.hdrs) == 8
hdr = p.hdrs[0]
assert isinstance(hdr, h2.HPackIndexedHdr)
assert hdr.magic == 1
assert hdr.index == 3
hdr = p.hdrs[1]
assert isinstance(hdr, h2.HPackLitHdrFldWithIncrIndexing)
assert hdr.magic == 1
assert hdr.index in [4, 5]
assert hdr.hdr_name is None
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackZString(/login.php)'
hdr = p.hdrs[2]
assert isinstance(hdr, h2.HPackIndexedHdr)
assert hdr.magic == 1
assert hdr.index == 7
hdr = p.hdrs[3]
assert isinstance(hdr, h2.HPackLitHdrFldWithIncrIndexing)
assert hdr.magic == 1
assert hdr.index == 31
assert hdr.hdr_name is None
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackZString(application/x-www-form-urlencoded)'
hdr = p.hdrs[4]
assert isinstance(hdr, h2.HPackLitHdrFldWithIncrIndexing)
assert hdr.magic == 1
assert hdr.index == 28
assert hdr.hdr_name is None
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackLiteralString(22)'
hdr = p.hdrs[5]
assert isinstance(hdr, h2.HPackLitHdrFldWithIncrIndexing)
assert hdr.magic == 1
assert hdr.index == 58
assert hdr.hdr_name is None
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackZString(Mozilla/5.0 Generated by hand)'
hdr = p.hdrs[6]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 0
assert hdr.index == 0
assert isinstance(hdr.hdr_name, h2.HPackHdrString)
assert hdr.hdr_name.data == 'HPackZString(x-generated-by)'
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackLiteralString(Me)'
hdr = p.hdrs[7]
assert isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)
assert hdr.magic == 0
assert hdr.never_index == 1
assert hdr.index == 0
assert isinstance(hdr.hdr_name, h2.HPackHdrString)
assert hdr.hdr_name.data == 'HPackZString(x-generation-date)'
assert isinstance(hdr.hdr_value, h2.HPackHdrString)
assert hdr.hdr_value.data == 'HPackZString(2016-08-11)'
p = seq.frames[1]
assert isinstance(p, h2.H2Frame)
assert p.type == 0
assert len(p.flags) == 1
assert 'ES' in p.flags
assert p.stream_id == 1
assert isinstance(p.payload, h2.H2DataFrame)
pay = p[h2.H2DataFrame]
assert pay.data == body