| % 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') |
| #Adjustement 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: |
| 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: |
| 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: |
| 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: |
| 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: |
| 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: |
| 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 = raw(''':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) |
| |
| = 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 = raw(''':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)) |
| |
| 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 = raw(''':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)) |
| |
| 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 = raw(''':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)) |
| |
| 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 = raw(''':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)) |
| |
| 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 = raw(''':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))) |
| |
| 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) |