1% HTTP/2 Campaign 2# Frames expressed as binary str were generated using the solicit and hpack-rs 3# Rust crates (https://github.com/mlalic/solicit, https://github.com/mlalic/hpack-rs) 4# except Continuation Frames, Priority Frames and Push Promise Frames that we generated 5# using Go x/net/http2 and x/net/http2/hpack modules. 6 7+ Syntax check 8= Configuring Scapy 9~ http2 frame hpack build dissect data headers priority settings rststream pushpromise ping goaway winupdate continuation hpackhdrtable helpers 10 11import scapy.config 12scapy.config.conf.debug_dissector=True 13import scapy.packet 14import scapy.fields 15import scapy.contrib.http2 as h2 16import re 17flags_bit_pattern = re.compile(r'''^\s+flags\s+=\s+\[.*['"]bit [0-9]+['"].*\]$''', re.M) 18def expect_exception(e, c): 19 try: 20 eval(c) 21 return False 22 except e: 23 return True 24 25+ HTTP/2 UVarIntField Test Suite 26 27= HTTP/2 UVarIntField.any2i 28~ http2 frame field uvarintfield 29 30f = h2.UVarIntField('value', 0, 5) 31expect_exception(AssertionError, 'f.any2i(None, None)') 32assert(f.any2i(None, 0) == 0) 33assert(f.any2i(None, 3) == 3) 34assert(f.any2i(None, 1<<5) == 1<<5) 35assert(f.any2i(None, 1<<16) == 1<<16) 36f = h2.UVarIntField('value', 0, 8) 37assert(f.any2i(None, b'\x1E') == 30) 38 39= HTTP/2 UVarIntField.m2i on full byte 40~ http2 frame field uvarintfield 41 42f = h2.UVarIntField('value', 0, 8) 43assert(f.m2i(None, b'\x00') == 0) 44assert(f.m2i(None, b'\x03') == 3) 45assert(f.m2i(None, b'\xFE') == 254) 46assert(f.m2i(None, b'\xFF\x00') == 255) 47assert(f.m2i(None, b'\xFF\xFF\x03') == 766) #0xFF + (0xFF ^ 0x80) + (3<<7) 48 49= HTTP/2 UVarIntField.m2i on partial byte 50~ http2 frame field uvarintfield 51 52f = h2.UVarIntField('value', 0, 5) 53assert(f.m2i(None, (b'\x00', 3)) == 0) 54assert(f.m2i(None, (b'\x03', 3)) == 3) 55assert(f.m2i(None, (b'\x1e', 3)) == 30) 56assert(f.m2i(None, (b'\x1f\x00', 3)) == 31) 57assert(f.m2i(None, (b'\x1f\xe1\xff\x03', 3)) == 65536) 58 59= HTTP/2 UVarIntField.getfield on full byte 60~ http2 frame field uvarintfield 61 62f = h2.UVarIntField('value', 0, 8) 63 64r = f.getfield(None, b'\x00\x00') 65assert(r[0] == b'\x00') 66assert(r[1] == 0) 67 68r = f.getfield(None, b'\x03\x00') 69assert(r[0] == b'\x00') 70assert(r[1] == 3) 71 72r = f.getfield(None, b'\xFE\x00') 73assert(r[0] == b'\x00') 74assert(r[1] == 254) 75 76r = f.getfield(None, b'\xFF\x00\x00') 77assert(r[0] == b'\x00') 78assert(r[1] == 255) 79 80r = f.getfield(None, b'\xFF\xFF\x03\x00') 81assert(r[0] == b'\x00') 82assert(r[1] == 766) 83 84= HTTP/2 UVarIntField.getfield on partial byte 85~ http2 frame field uvarintfield 86 87f = h2.UVarIntField('value', 0, 5) 88 89r = f.getfield(None, (b'\x00\x00', 3)) 90assert(r[0] == b'\x00') 91assert(r[1] == 0) 92 93r = f.getfield(None, (b'\x03\x00', 3)) 94assert(r[0] == b'\x00') 95assert(r[1] == 3) 96 97r = f.getfield(None, (b'\x1e\x00', 3)) 98assert(r[0] == b'\x00') 99assert(r[1] == 30) 100 101r = f.getfield(None, (b'\x1f\x00\x00', 3)) 102assert(r[0] == b'\x00') 103assert(r[1] == 31) 104 105r = f.getfield(None, (b'\x1f\xe1\xff\x03\x00', 3)) 106assert(r[0] == b'\x00') 107assert(r[1] == 65536) 108 109= HTTP/2 UVarIntField.i2m on full byte 110~ http2 frame field uvarintfield 111 112f = h2.UVarIntField('value', 0, 8) 113assert(f.i2m(None, 0) == b'\x00') 114assert(f.i2m(None, 3) == b'\x03') 115assert(f.i2m(None, 254).lower() == b'\xfe') 116assert(f.i2m(None, 255).lower() == b'\xff\x00') 117assert(f.i2m(None, 766).lower() == b'\xff\xff\x03') 118 119= HTTP/2 UVarIntField.i2m on partial byte 120~ http2 frame field uvarintfield 121 122f = h2.UVarIntField('value', 0, 5) 123assert(f.i2m(None, 0) == b'\x00') 124assert(f.i2m(None, 3) == b'\x03') 125assert(f.i2m(None, 30).lower() == b'\x1e') 126assert(f.i2m(None, 31).lower() == b'\x1f\x00') 127assert(f.i2m(None, 65536).lower() == b'\x1f\xe1\xff\x03') 128 129= HTTP/2 UVarIntField.addfield on full byte 130~ http2 frame field uvarintfield 131 132f = h2.UVarIntField('value', 0, 8) 133 134assert(f.addfield(None, b'Toto', 0) == b'Toto\x00') 135assert(f.addfield(None, b'Toto', 3) == b'Toto\x03') 136assert(f.addfield(None, b'Toto', 254).lower() == b'toto\xfe') 137assert(f.addfield(None, b'Toto', 255).lower() == b'toto\xff\x00') 138assert(f.addfield(None, b'Toto', 766).lower() == b'toto\xff\xff\x03') 139 140= HTTP/2 UVarIntField.addfield on partial byte 141~ http2 frame field uvarintfield 142 143f = h2.UVarIntField('value', 0, 5) 144 145assert(f.addfield(None, (b'Toto', 3, 4), 0) == b'Toto\x80') 146assert(f.addfield(None, (b'Toto', 3, 4), 3) == b'Toto\x83') 147assert(f.addfield(None, (b'Toto', 3, 4), 30).lower() == b'toto\x9e') 148assert(f.addfield(None, (b'Toto', 3, 4), 31).lower() == b'toto\x9f\x00') 149assert(f.addfield(None, (b'Toto', 3, 4), 65536).lower() == b'toto\x9f\xe1\xff\x03') 150 151= HTTP/2 UVarIntField.i2len on full byte 152~ http2 frame field uvarintfield 153 154f = h2.UVarIntField('value', 0, 8) 155 156assert(f.i2len(None, 0) == 1) 157assert(f.i2len(None, 3) == 1) 158assert(f.i2len(None, 254) == 1) 159assert(f.i2len(None, 255) == 2) 160assert(f.i2len(None, 766) == 3) 161 162= HTTP/2 UVarIntField.i2len on partial byte 163~ http2 frame field uvarintfield 164 165f = h2.UVarIntField('value', 0, 5) 166 167assert(f.i2len(None, 0) == 1) 168assert(f.i2len(None, 3) == 1) 169assert(f.i2len(None, 30) == 1) 170assert(f.i2len(None, 31) == 2) 171assert(f.i2len(None, 65536) == 4) 172 173+ HTTP/2 FieldUVarLenField Test Suite 174 175= HTTP/2 FieldUVarLenField.i2m without adjustment 176~ http2 frame field fielduvarlenfield 177 178 179f = h2.FieldUVarLenField('len', None, 8, length_of='data') 180class TrivialPacket(Packet): 181 name = 'Trivial Packet' 182 fields_desc= [ 183 f, 184 StrField('data', '') 185 ] 186 187assert(f.i2m(TrivialPacket(data='a'*5), None) == b'\x05') 188assert(f.i2m(TrivialPacket(data='a'*255), None).lower() == b'\xff\x00') 189assert(f.i2m(TrivialPacket(data='a'), 2) == b'\x02') 190assert(f.i2m(None, 2) == b'\x02') 191assert(f.i2m(None, 0) == b'\x00') 192 193= HTTP/2 FieldUVarLenField.i2m with adjustment 194~ http2 frame field fielduvarlenfield 195 196class TrivialPacket(Packet): 197 name = 'Trivial Packet' 198 fields_desc= [ 199 f, 200 StrField('data', '') 201 ] 202 203f = h2.FieldUVarLenField('value', None, 8, length_of='data', adjust=lambda x: x-1) 204assert(f.i2m(TrivialPacket(data='a'*5), None) == b'\x04') 205assert(f.i2m(TrivialPacket(data='a'*255), None).lower() == b'\xfe') 206#Adjustement does not affect non-None value! 207assert(f.i2m(TrivialPacket(data='a'*3), 2) == b'\x02') 208 209+ HTTP/2 HPackZString Test Suite 210 211= HTTP/2 HPackZString Compression 212~ http2 hpack huffman 213 214string = 'Test' 215s = h2.HPackZString(string) 216assert(len(s) == 3) 217assert(raw(s) == b"\xdeT'") 218assert(s.origin() == string) 219 220string = 'a'*65535 221s = h2.HPackZString(string) 222assert(len(s) == 40960) 223assert(raw(s) == (b'\x18\xc61\x8cc' * 8191) + b'\x18\xc61\x8c\x7f') 224assert(s.origin() == string) 225 226= HTTP/2 HPackZString Decompression 227~ http2 hpack huffman 228 229s = b"\xdeT'" 230i, ibl = h2.HPackZString.huffman_conv2bitstring(s) 231assert(b'Test' == h2.HPackZString.huffman_decode(i, ibl)) 232 233s = (b'\x18\xc61\x8cc' * 8191) + b'\x18\xc61\x8c\x7f' 234i, ibl = h2.HPackZString.huffman_conv2bitstring(s) 235assert(b'a'*65535 == h2.HPackZString.huffman_decode(i, ibl)) 236 237assert( 238 expect_exception(h2.InvalidEncodingException, 239 'h2.HPackZString.huffman_decode(*h2.HPackZString.huffman_conv2bitstring(b"\\xdeT"))') 240) 241 242+ HTTP/2 HPackStrLenField Test Suite 243 244= HTTP/2 HPackStrLenField.m2i 245~ http2 hpack field hpackstrlenfield 246 247f = h2.HPackStrLenField('data', h2.HPackLiteralString(''), length_from=lambda p: p.len, type_from='type') 248class TrivialPacket(Packet): 249 name = 'Trivial Packet' 250 fields_desc = [ 251 IntField('type', None), 252 IntField('len', None), 253 f 254 ] 255 256s = f.m2i(TrivialPacket(type=0, len=4), b'Test') 257assert(isinstance(s, h2.HPackLiteralString)) 258assert(s.origin() == 'Test') 259 260s = f.m2i(TrivialPacket(type=1, len=3), b"\xdeT'") 261assert(isinstance(s, h2.HPackZString)) 262assert(s.origin() == 'Test') 263 264= HTTP/2 HPackStrLenField.any2i 265~ http2 hpack field hpackstrlenfield 266 267f = h2.HPackStrLenField('data', h2.HPackLiteralString(''), length_from=lambda p: p.len, type_from='type') 268class TrivialPacket(Packet): 269 name = 'Trivial Packet' 270 fields_desc = [ 271 IntField('type', None), 272 IntField('len', None), 273 f 274 ] 275 276s = f.any2i(TrivialPacket(type=0, len=4), b'Test') 277assert(isinstance(s, h2.HPackLiteralString)) 278assert(s.origin() == 'Test') 279 280s = f.any2i(TrivialPacket(type=1, len=3), b"\xdeT'") 281assert(isinstance(s, h2.HPackZString)) 282assert(s.origin() == 'Test') 283 284s = h2.HPackLiteralString('Test') 285s2 = f.any2i(TrivialPacket(type=0, len=4), s) 286assert(s.origin() == s2.origin()) 287 288s = h2.HPackZString('Test') 289s2 = f.any2i(TrivialPacket(type=1, len=3), s) 290assert(s.origin() == s2.origin()) 291 292s = h2.HPackLiteralString('Test') 293s2 = f.any2i(None, s) 294assert(s.origin() == s2.origin()) 295 296s = h2.HPackZString('Test') 297s2 = f.any2i(None, s) 298assert(s.origin() == s2.origin()) 299 300# Verifies that one can fuzz 301s = h2.HPackLiteralString('Test') 302s2 = f.any2i(TrivialPacket(type=1, len=1), s) 303assert(s.origin() == s2.origin()) 304 305= HTTP/2 HPackStrLenField.i2m 306~ http2 hpack field hpackstrlenfield 307 308f = h2.HPackStrLenField('data', h2.HPackLiteralString(''), length_from=lambda p: p.len, type_from='type') 309 310s = b'Test' 311s2 = f.i2m(None, h2.HPackLiteralString(s)) 312assert(s == s2) 313 314s = b'Test' 315s2 = f.i2m(None, h2.HPackZString(s)) 316assert(s2 == b"\xdeT'") 317 318= HTTP/2 HPackStrLenField.addfield 319~ http2 hpack field hpackstrlenfield 320 321f = h2.HPackStrLenField('data', h2.HPackLiteralString(''), length_from=lambda p: p.len, type_from='type') 322 323s = b'Test' 324s2 = f.addfield(None, b'Toto', h2.HPackLiteralString(s)) 325assert(b'Toto' + s == s2) 326 327s = b'Test' 328s2 = f.addfield(None, b'Toto', h2.HPackZString(s)) 329assert(s2 == b"Toto\xdeT'") 330 331= HTTP/2 HPackStrLenField.getfield 332~ http2 hpack field hpackstrlenfield 333 334f = h2.HPackStrLenField('data', h2.HPackLiteralString(''), length_from=lambda p: p.len, type_from='type') 335class TrivialPacket(Packet): 336 name = 'Trivial Packet' 337 fields_desc = [ 338 IntField('type', None), 339 IntField('len', None), 340 f 341 ] 342 343r = f.getfield(TrivialPacket(type=0, len=4), b'TestToto') 344assert(isinstance(r, tuple)) 345assert(r[0] == b'Toto') 346assert(isinstance(r[1], h2.HPackLiteralString)) 347assert(r[1].origin() == 'Test') 348 349r = f.getfield(TrivialPacket(type=1, len=3), b"\xdeT'Toto") 350assert(isinstance(r, tuple)) 351assert(r[0] == b'Toto') 352assert(isinstance(r[1], h2.HPackZString)) 353assert(r[1].origin() == 'Test') 354 355= HTTP/2 HPackStrLenField.i2h / i2repr 356~ http2 hpack field hpackstrlenfield 357 358f = h2.HPackStrLenField('data', h2.HPackLiteralString(''), length_from=lambda p: p.len, type_from='type') 359 360s = b'Test' 361assert(f.i2h(None, h2.HPackLiteralString(s)) == 'HPackLiteralString(Test)') 362assert(f.i2repr(None, h2.HPackLiteralString(s)) == repr('HPackLiteralString(Test)')) 363 364assert(f.i2h(None, h2.HPackZString(s)) == 'HPackZString(Test)') 365assert(f.i2repr(None, h2.HPackZString(s)) == repr('HPackZString(Test)')) 366 367= HTTP/2 HPackStrLenField.i2len 368~ http2 hpack field hpackstrlenfield 369 370f = h2.HPackStrLenField('data', h2.HPackLiteralString(''), length_from=lambda p: p.len, type_from='type') 371 372s = b'Test' 373assert(f.i2len(None, h2.HPackLiteralString(s)) == 4) 374assert(f.i2len(None, h2.HPackZString(s)) == 3) 375 376+ HTTP/2 HPackMagicBitField Test Suite 377# Magic bits are not supposed to be modified and if they are anyway, they must 378# be assigned the magic|default value only... 379 380= HTTP/2 HPackMagicBitField.addfield 381~ http2 hpack field hpackmagicbitfield 382 383f = h2.HPackMagicBitField('value', 3, 2) 384r = f.addfield(None, b'Toto', 3) 385assert(isinstance(r, tuple)) 386assert(r[0] == b'Toto') 387assert(r[1] == 2) 388assert(r[2] == 3) 389 390r = f.addfield(None, (b'Toto', 2, 1) , 3) 391assert(isinstance(r, tuple)) 392assert(r[0] == b'Toto') 393assert(r[1] == 4) 394assert(r[2] == 7) 395 396assert(expect_exception(AssertionError, 'f.addfield(None, "toto", 2)')) 397 398= HTTP/2 HPackMagicBitField.getfield 399~ http2 hpack field hpackmagicbitfield 400 401f = h2.HPackMagicBitField('value', 3, 2) 402 403r = f.getfield(None, b'\xc0') 404assert(isinstance(r, tuple)) 405assert(len(r) == 2) 406assert(isinstance(r[0], tuple)) 407assert(len(r[0]) == 2) 408assert(r[0][0] == b'\xc0') 409assert(r[0][1] == 2) 410assert(r[1] == 3) 411 412r = f.getfield(None, (b'\x03', 6)) 413assert(isinstance(r, tuple)) 414assert(len(r) == 2) 415assert(isinstance(r[0], bytes)) 416assert(r[0] == b'') 417assert(r[1] == 3) 418 419expect_exception(AssertionError, 'f.getfield(None, b"\\x80")') 420 421= HTTP/2 HPackMagicBitField.h2i 422~ http2 hpack field hpackmagicbitfield 423 424f = h2.HPackMagicBitField('value', 3, 2) 425assert(f.h2i(None, 3) == 3) 426expect_exception(AssertionError, 'f.h2i(None, 2)') 427 428= HTTP/2 HPackMagicBitField.m2i 429~ http2 hpack field hpackmagicbitfield 430 431f = h2.HPackMagicBitField('value', 3, 2) 432assert(f.m2i(None, 3) == 3) 433expect_exception(AssertionError, 'f.m2i(None, 2)') 434 435= HTTP/2 HPackMagicBitField.i2m 436~ http2 hpack field hpackmagicbitfield 437 438f = h2.HPackMagicBitField('value', 3, 2) 439assert(f.i2m(None, 3) == 3) 440expect_exception(AssertionError, 'f.i2m(None, 2)') 441 442= HTTP/2 HPackMagicBitField.any2i 443~ http2 hpack field hpackmagicbitfield 444 445f = h2.HPackMagicBitField('value', 3, 2) 446assert(f.any2i(None, 3) == 3) 447expect_exception(AssertionError, 'f.any2i(None, 2)') 448 449+ HTTP/2 HPackHdrString Test Suite 450 451= HTTP/2 Dissect HPackHdrString 452~ http2 pack dissect hpackhdrstring 453 454p = h2.HPackHdrString(b'\x04Test') 455assert(p.type == 0) 456assert(p.len == 4) 457assert(isinstance(p.getfieldval('data'), h2.HPackLiteralString)) 458assert(p.getfieldval('data').origin() == 'Test') 459 460p = h2.HPackHdrString(b"\x83\xdeT'") 461assert(p.type == 1) 462assert(p.len == 3) 463assert(isinstance(p.getfieldval('data'), h2.HPackZString)) 464assert(p.getfieldval('data').origin() == 'Test') 465 466= HTTP/2 Build HPackHdrString 467~ http2 hpack build hpackhdrstring 468 469p = h2.HPackHdrString(data=h2.HPackLiteralString('Test')) 470assert(raw(p) == b'\x04Test') 471 472p = h2.HPackHdrString(data=h2.HPackZString('Test')) 473assert(raw(p) == b"\x83\xdeT'") 474 475#Fuzzing-able tests 476p = h2.HPackHdrString(type=1, len=3, data=h2.HPackLiteralString('Test')) 477assert(raw(p) == b'\x83Test') 478 479+ HTTP/2 HPackIndexedHdr Test Suite 480 481= HTTP/2 Dissect HPackIndexedHdr 482~ http2 hpack dissect hpackindexedhdr 483 484p = h2.HPackIndexedHdr(b'\x80') 485assert(p.magic == 1) 486assert(p.index == 0) 487 488p = h2.HPackIndexedHdr(b'\xFF\x00') 489assert(p.magic == 1) 490assert(p.index == 127) 491 492= HTTP/2 Build HPackIndexedHdr 493~ http2 hpack build hpackindexedhdr 494 495p = h2.HPackIndexedHdr(index=0) 496assert(raw(p) == b'\x80') 497 498p = h2.HPackIndexedHdr(index=127) 499assert(raw(p) == b'\xFF\x00') 500 501+ HTTP/2 HPackLitHdrFldWithIncrIndexing Test Suite 502 503= HTTP/2 Dissect HPackLitHdrFldWithIncrIndexing without indexed name 504~ http2 hpack dissect hpacklithdrfldwithincrindexing 505 506p = h2.HPackLitHdrFldWithIncrIndexing(b'\x40\x04Test\x04Toto') 507assert(p.magic == 1) 508assert(p.index == 0) 509assert(isinstance(p.hdr_name, h2.HPackHdrString)) 510assert(p.hdr_name.type == 0) 511assert(p.hdr_name.len == 4) 512assert(p.hdr_name.getfieldval('data').origin() == 'Test') 513assert(isinstance(p.hdr_value, h2.HPackHdrString)) 514assert(p.hdr_value.type == 0) 515assert(p.hdr_value.len == 4) 516assert(p.hdr_value.getfieldval('data').origin() == 'Toto') 517 518= HTTP/2 Dissect HPackLitHdrFldWithIncrIndexing with indexed name 519~ http2 hpack dissect hpacklithdrfldwithincrindexing 520 521p = h2.HPackLitHdrFldWithIncrIndexing(b'\x41\x04Toto') 522assert(p.magic == 1) 523assert(p.index == 1) 524assert(p.hdr_name is None) 525assert(isinstance(p.hdr_value, h2.HPackHdrString)) 526assert(p.hdr_value.type == 0) 527assert(p.hdr_value.len == 4) 528assert(p.hdr_value.getfieldval('data').origin() == 'Toto') 529 530 531= HTTP/2 Build HPackLitHdrFldWithIncrIndexing without indexed name 532~ http2 hpack build hpacklithdrfldwithincrindexing 533 534p = h2.HPackLitHdrFldWithIncrIndexing( 535 hdr_name=h2.HPackHdrString(data=h2.HPackLiteralString('Test')), 536 hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString(b'Toto')) 537) 538assert(raw(p) == b'\x40\x04Test\x04Toto') 539 540= HTTP/2 Build HPackLitHdrFldWithIncrIndexing with indexed name 541~ http2 hpack build hpacklithdrfldwithincrindexing 542 543p = h2.HPackLitHdrFldWithIncrIndexing( 544 index=1, 545 hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString(b'Toto')) 546) 547assert(raw(p) == b'\x41\x04Toto') 548 549+ HTTP/2 HPackLitHdrFldWithoutIndexing Test Suite 550 551= HTTP/2 Dissect HPackLitHdrFldWithoutIndexing : don't index and no index 552~ http2 hpack dissect hpacklithdrfldwithoutindexing 553 554p = h2.HPackLitHdrFldWithoutIndexing(b'\x00\x04Test\x04Toto') 555assert(p.magic == 0) 556assert(p.never_index == 0) 557assert(p.index == 0) 558assert(isinstance(p.hdr_name, h2.HPackHdrString)) 559assert(p.hdr_name.type == 0) 560assert(p.hdr_name.len == 4) 561assert(isinstance(p.hdr_name.getfieldval('data'), h2.HPackLiteralString)) 562assert(p.hdr_name.getfieldval('data').origin() == 'Test') 563assert(isinstance(p.hdr_value, h2.HPackHdrString)) 564assert(p.hdr_value.type == 0) 565assert(p.hdr_value.len == 4) 566assert(isinstance(p.hdr_value.getfieldval('data'), h2.HPackLiteralString)) 567assert(p.hdr_value.getfieldval('data').origin() == 'Toto') 568 569= HTTP/2 Dissect HPackLitHdrFldWithoutIndexing : never index index and no index 570~ http2 hpack dissect hpacklithdrfldwithoutindexing 571 572p = h2.HPackLitHdrFldWithoutIndexing(b'\x10\x04Test\x04Toto') 573assert(p.magic == 0) 574assert(p.never_index == 1) 575assert(p.index == 0) 576assert(isinstance(p.hdr_name, h2.HPackHdrString)) 577assert(p.hdr_name.type == 0) 578assert(p.hdr_name.len == 4) 579assert(isinstance(p.hdr_name.getfieldval('data'), h2.HPackLiteralString)) 580assert(p.hdr_name.getfieldval('data').origin() == 'Test') 581assert(isinstance(p.hdr_value, h2.HPackHdrString)) 582assert(p.hdr_value.type == 0) 583assert(p.hdr_value.len == 4) 584assert(isinstance(p.hdr_value.getfieldval('data'), h2.HPackLiteralString)) 585assert(p.hdr_value.getfieldval('data').origin() == 'Toto') 586 587= HTTP/2 Dissect HPackLitHdrFldWithoutIndexing : never index and indexed name 588~ http2 hpack dissect hpacklithdrfldwithoutindexing 589 590p = h2.HPackLitHdrFldWithoutIndexing(b'\x11\x04Toto') 591assert(p.magic == 0) 592assert(p.never_index == 1) 593assert(p.index == 1) 594assert(p.hdr_name is None) 595assert(isinstance(p.hdr_value, h2.HPackHdrString)) 596assert(p.hdr_value.type == 0) 597assert(p.hdr_value.len == 4) 598assert(isinstance(p.hdr_value.getfieldval('data'), h2.HPackLiteralString)) 599assert(p.hdr_value.getfieldval('data').origin() == 'Toto') 600 601= HTTP/2 Build HPackLitHdrFldWithoutIndexing : don't index and no index 602~ http2 hpack build hpacklithdrfldwithoutindexing 603 604p = h2.HPackLitHdrFldWithoutIndexing( 605 hdr_name=h2.HPackHdrString(data=h2.HPackLiteralString('Test')), 606 hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString(b'Toto')) 607) 608assert(raw(p) == b'\x00\x04Test\x04Toto') 609 610= HTTP/2 Build HPackLitHdrFldWithoutIndexing : never index index and no index 611~ http2 hpack build hpacklithdrfldwithoutindexing 612 613p = h2.HPackLitHdrFldWithoutIndexing( 614 never_index=1, 615 hdr_name=h2.HPackHdrString(data=h2.HPackLiteralString('Test')), 616 hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString(b'Toto')) 617) 618assert(raw(p) == b'\x10\x04Test\x04Toto') 619 620= HTTP/2 Build HPackLitHdrFldWithoutIndexing : never index and indexed name 621~ http2 hpack build hpacklithdrfldwithoutindexing 622 623p = h2.HPackLitHdrFldWithoutIndexing( 624 never_index=1, 625 index=1, 626 hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString(b'Toto')) 627) 628assert(raw(p) == b'\x11\x04Toto') 629 630+ HTTP/2 HPackDynamicSizeUpdate Test Suite 631 632= HTTP/2 Dissect HPackDynamicSizeUpdate 633~ http2 hpack dissect hpackdynamicsizeupdate 634 635p = h2.HPackDynamicSizeUpdate(b'\x25') 636assert(p.magic == 1) 637assert(p.max_size == 5) 638p = h2.HPackDynamicSizeUpdate(b'\x3F\x00') 639assert(p.magic == 1) 640assert(p.max_size == 31) 641 642= HTTP/2 Build HPackDynamicSizeUpdate 643~ http2 hpack build hpackdynamicsizeupdate 644 645p = h2.HPackDynamicSizeUpdate(max_size=5) 646assert(raw(p) == b'\x25') 647p = h2.HPackDynamicSizeUpdate(max_size=31) 648assert(raw(p) == b'\x3F\x00') 649 650+ HTTP/2 Data Frame Test Suite 651 652= HTTP/2 Dissect Data Frame: Simple data frame 653~ http2 frame dissect data 654 655pkt = h2.H2Frame(b'\x00\x00\x04\x00\x00\x00\x00\x00\x01ABCD') 656assert(pkt.type == 0) 657assert(pkt.len == 4) 658assert(len(pkt.flags) == 0) 659assert(pkt.reserved == 0) 660assert(pkt.stream_id == 1) 661assert(isinstance(pkt.payload, h2.H2DataFrame)) 662assert(pkt[h2.H2DataFrame]) 663assert(pkt.payload.data == b'ABCD') 664assert(isinstance(pkt.payload.payload, scapy.packet.NoPayload)) 665 666= HTTP/2 Build Data Frame: Simple data frame 667~ http2 frame build data 668 669pkt = h2.H2Frame(stream_id = 1)/h2.H2DataFrame(data='ABCD') 670assert(raw(pkt) == b'\x00\x00\x04\x00\x00\x00\x00\x00\x01ABCD') 671try: 672 pkt.show2(dump=True) 673 assert(True) 674except: 675 assert(False) 676 677= HTTP/2 Dissect Data Frame: Simple data frame with padding 678~ http2 frame dissect data 679 680pkt = h2.H2Frame(b'\x00\x00\r\x00\x08\x00\x00\x00\x01\x08ABCD\x00\x00\x00\x00\x00\x00\x00\x00') #Padded data frame 681assert(pkt.type == 0) 682assert(pkt.len == 13) 683assert(len(pkt.flags) == 1) 684assert('P' in pkt.flags) 685assert(pkt.reserved == 0) 686assert(pkt.stream_id == 1) 687assert(isinstance(pkt.payload, h2.H2PaddedDataFrame)) 688assert(pkt[h2.H2PaddedDataFrame]) 689assert(pkt.payload.padlen == 8) 690assert(pkt.payload.data == b'ABCD') 691assert(pkt.payload.padding == b'\x00'*8) 692assert(flags_bit_pattern.search(pkt.show(dump=True)) is None) 693assert(isinstance(pkt.payload.payload, scapy.packet.NoPayload)) 694 695= HTTP/2 Build Data Frame: Simple data frame with padding 696~ http2 frame build data 697 698pkt = h2.H2Frame(flags = {'P'}, stream_id = 1)/h2.H2PaddedDataFrame(data='ABCD', padding=b'\x00'*8) 699assert(raw(pkt) == b'\x00\x00\r\x00\x08\x00\x00\x00\x01\x08ABCD\x00\x00\x00\x00\x00\x00\x00\x00') 700try: 701 pkt.show2(dump=True) 702 assert(True) 703except: 704 assert(False) 705 706= HTTP/2 Dissect Data Frame: Simple data frame with padding and end stream flag 707~ http2 frame dissect data 708 709pkt = 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 710assert(pkt.type == 0) 711assert(pkt.len == 13) 712assert(len(pkt.flags) == 2) 713assert('P' in pkt.flags) 714assert('ES' in pkt.flags) 715assert(pkt.reserved == 0) 716assert(pkt.stream_id == 1) 717assert(isinstance(pkt.payload, h2.H2PaddedDataFrame)) 718assert(pkt[h2.H2PaddedDataFrame]) 719assert(pkt.payload.padlen == 8) 720assert(pkt.payload.data == b'ABCD') 721assert(pkt.payload.padding == b'\x00'*8) 722assert(flags_bit_pattern.search(pkt.show(dump=True)) is None) 723assert(isinstance(pkt.payload.payload, scapy.packet.NoPayload)) 724 725= HTTP/2 Build Data Frame: Simple data frame with padding and end stream flag 726~ http2 frame build data 727 728pkt = h2.H2Frame(flags = {'P', 'ES'}, stream_id=1)/h2.H2PaddedDataFrame(data='ABCD', padding=b'\x00'*8) 729assert(raw(pkt) == b'\x00\x00\r\x00\t\x00\x00\x00\x01\x08ABCD\x00\x00\x00\x00\x00\x00\x00\x00') 730try: 731 pkt.show2(dump=True) 732 assert(True) 733except: 734 assert(False) 735 736+ HTTP/2 Headers Frame Test Suite 737 738= HTTP/2 Dissect Headers Frame: Simple header frame 739~ http2 frame dissect headers 740 741pkt = h2.H2Frame(b'\x00\x00\x0e\x01\x00\x00\x00\x00\x01\x88\x0f\x10\ntext/plain') #Header frame 742assert(pkt.type == 1) 743assert(pkt.len == 14) 744assert(len(pkt.flags) == 0) 745assert(pkt.reserved == 0) 746assert(pkt.stream_id == 1) 747assert(isinstance(pkt.payload, h2.H2HeadersFrame)) 748assert(pkt[h2.H2HeadersFrame]) 749hf = pkt[h2.H2HeadersFrame] 750assert(len(hf.hdrs) == 2) 751assert(isinstance(hf.hdrs[0], h2.HPackIndexedHdr)) 752assert(hf.hdrs[0].magic == 1) 753assert(hf.hdrs[0].index == 8) 754assert(isinstance(hf.hdrs[1], h2.HPackLitHdrFldWithoutIndexing)) 755assert(hf.hdrs[1].magic == 0) 756assert(hf.hdrs[1].never_index == 0) 757assert(hf.hdrs[1].index == 31) 758assert(hf.hdrs[1].hdr_name is None) 759assert(expect_exception(AttributeError, 'hf.hdrs[1].non_existant')) 760assert(isinstance(hf.hdrs[1].hdr_value, h2.HPackHdrString)) 761s = hf.hdrs[1].hdr_value 762assert(s.type == 0) 763assert(s.len == 10) 764assert(s.getfieldval('data').origin() == 'text/plain') 765assert(isinstance(hf.payload, scapy.packet.NoPayload)) 766 767= HTTP/2 Build Headers Frame: Simple header frame 768~ http2 frame build headers 769 770p = h2.H2Frame(stream_id=1)/h2.H2HeadersFrame(hdrs=[ 771 h2.HPackIndexedHdr(index=8), 772 h2.HPackLitHdrFldWithoutIndexing( 773 index=31, 774 hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('text/plain')) 775 ) 776 ] 777) 778assert(raw(p) == b'\x00\x00\x0e\x01\x00\x00\x00\x00\x01\x88\x0f\x10\ntext/plain') 779 780= HTTP/2 Dissect Headers Frame: Header frame with padding 781~ http2 frame dissect headers 782 783pkt = 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 784assert(pkt.type == 1) 785assert(pkt.len == 23) 786assert(len(pkt.flags) == 1) 787assert('P' in pkt.flags) 788assert(pkt.reserved == 0) 789assert(pkt.stream_id == 1) 790assert(isinstance(pkt.payload, h2.H2PaddedHeadersFrame)) 791assert(flags_bit_pattern.search(pkt.show(dump=True)) is None) 792assert(pkt[h2.H2PaddedHeadersFrame]) 793hf = pkt[h2.H2PaddedHeadersFrame] 794assert(hf.padlen == 8) 795assert(hf.padding == b'\x00' * 8) 796assert(len(hf.hdrs) == 2) 797assert(isinstance(hf.hdrs[0], h2.HPackIndexedHdr)) 798assert(hf.hdrs[0].magic == 1) 799assert(hf.hdrs[0].index == 8) 800assert(isinstance(hf.hdrs[1], h2.HPackLitHdrFldWithoutIndexing)) 801assert(hf.hdrs[1].magic == 0) 802assert(hf.hdrs[1].never_index == 0) 803assert(hf.hdrs[1].index == 31) 804assert(hf.hdrs[1].hdr_name is None) 805assert(expect_exception(AttributeError, 'hf.hdrs[1].non_existant')) 806assert(isinstance(hf.hdrs[1].hdr_value, h2.HPackHdrString)) 807s = hf.hdrs[1].hdr_value 808assert(s.type == 0) 809assert(s.len == 10) 810assert(s.getfieldval('data').origin() == 'text/plain') 811assert(isinstance(hf.payload, scapy.packet.NoPayload)) 812 813= HTTP/2 Build Headers Frame: Header frame with padding 814~ http2 frame build headers 815 816p = h2.H2Frame(flags={'P'}, stream_id=1)/h2.H2PaddedHeadersFrame( 817 hdrs=[ 818 h2.HPackIndexedHdr(index=8), 819 h2.HPackLitHdrFldWithoutIndexing( 820 index=31, 821 hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('text/plain')) 822 ) 823 ], 824 padding=b'\x00'*8, 825) 826assert(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') 827 828= HTTP/2 Dissect Headers Frame: Header frame with priority 829~ http2 frame dissect headers 830 831pkt = h2.H2Frame(b'\x00\x00\x13\x01 \x00\x00\x00\x01\x00\x00\x00\x02d\x88\x0f\x10\ntext/plain') #Header frame with priority 832assert(pkt.type == 1) 833assert(pkt.len == 19) 834assert(len(pkt.flags) == 1) 835assert('+' in pkt.flags) 836assert(pkt.reserved == 0) 837assert(pkt.stream_id == 1) 838assert(isinstance(pkt.payload, h2.H2PriorityHeadersFrame)) 839assert(flags_bit_pattern.search(pkt.show(dump=True)) is None) 840assert(pkt[h2.H2PriorityHeadersFrame]) 841hf = pkt[h2.H2PriorityHeadersFrame] 842assert(hf.exclusive == 0) 843assert(hf.stream_dependency == 2) 844assert(hf.weight == 100) 845assert(len(hf.hdrs) == 2) 846assert(isinstance(hf.hdrs[0], h2.HPackIndexedHdr)) 847assert(hf.hdrs[0].magic == 1) 848assert(hf.hdrs[0].index == 8) 849assert(isinstance(hf.hdrs[1], h2.HPackLitHdrFldWithoutIndexing)) 850assert(hf.hdrs[1].magic == 0) 851assert(hf.hdrs[1].never_index == 0) 852assert(hf.hdrs[1].index == 31) 853assert(hf.hdrs[1].hdr_name is None) 854assert(expect_exception(AttributeError, 'hf.hdrs[1].non_existant')) 855assert(isinstance(hf.hdrs[1].hdr_value, h2.HPackHdrString)) 856s = hf.hdrs[1].hdr_value 857assert(s.type == 0) 858assert(s.len == 10) 859assert(s.getfieldval('data').origin() == 'text/plain') 860assert(isinstance(hf.payload, scapy.packet.NoPayload)) 861 862= HTTP/2 Build Headers Frame: Header frame with priority 863~ http2 frame build headers 864 865p = h2.H2Frame(flags={'+'}, stream_id=1)/h2.H2PriorityHeadersFrame( 866 exclusive=0, 867 stream_dependency=2, 868 weight=100, 869 hdrs=[ 870 h2.HPackIndexedHdr(index=8), 871 h2.HPackLitHdrFldWithoutIndexing( 872 index=31, 873 hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('text/plain')) 874 ) 875 ] 876) 877assert(raw(p) == b'\x00\x00\x13\x01 \x00\x00\x00\x01\x00\x00\x00\x02d\x88\x0f\x10\ntext/plain') 878 879= HTTP/2 Dissect Headers Frame: Header frame with priority and padding and flags 880~ http2 frame dissect headers 881 882pkt = 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 883assert(pkt.type == 1) 884assert(pkt.len == 28) 885assert(len(pkt.flags) == 4) 886assert('+' in pkt.flags) 887assert('P' in pkt.flags) 888assert('ES' in pkt.flags) 889assert('EH' in pkt.flags) 890assert(pkt.reserved == 0) 891assert(pkt.stream_id == 1) 892assert(isinstance(pkt.payload, h2.H2PaddedPriorityHeadersFrame)) 893assert(flags_bit_pattern.search(pkt.show(dump=True)) is None) 894assert(pkt[h2.H2PaddedPriorityHeadersFrame]) 895hf = pkt[h2.H2PaddedPriorityHeadersFrame] 896assert(hf.padlen == 8) 897assert(hf.padding == b'\x00' * 8) 898assert(hf.exclusive == 0) 899assert(hf.stream_dependency == 2) 900assert(hf.weight == 100) 901assert(len(hf.hdrs) == 2) 902assert(isinstance(hf.hdrs[0], h2.HPackIndexedHdr)) 903assert(hf.hdrs[0].magic == 1) 904assert(hf.hdrs[0].index == 8) 905assert(isinstance(hf.hdrs[1], h2.HPackLitHdrFldWithoutIndexing)) 906assert(hf.hdrs[1].magic == 0) 907assert(hf.hdrs[1].never_index == 0) 908assert(hf.hdrs[1].index == 31) 909assert(hf.hdrs[1].hdr_name is None) 910assert(expect_exception(AttributeError, 'hf.hdrs[1].non_existant')) 911assert(isinstance(hf.hdrs[1].hdr_value, h2.HPackHdrString)) 912s = hf.hdrs[1].hdr_value 913assert(s.type == 0) 914assert(s.len == 10) 915assert(s.getfieldval('data').origin() == 'text/plain') 916assert(isinstance(hf.payload, scapy.packet.NoPayload)) 917 918= HTTP/2 Build Headers Frame: Header frame with priority and padding and flags 919~ http2 frame build headers 920 921p = h2.H2Frame(flags={'P', '+', 'ES', 'EH'}, stream_id=1)/h2.H2PaddedPriorityHeadersFrame( 922 exclusive=0, 923 stream_dependency=2, 924 weight=100, 925 padding=b'\x00'*8, 926 hdrs=[ 927 h2.HPackIndexedHdr(index=8), 928 h2.HPackLitHdrFldWithoutIndexing( 929 index=31, 930 hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('text/plain')) 931 ) 932 ] 933) 934 935+ HTTP/2 Priority Frame Test Suite 936 937= HTTP/2 Dissect Priority Frame 938~ http2 frame dissect priority 939 940pkt = h2.H2Frame(b'\x00\x00\x05\x02\x00\x00\x00\x00\x03\x80\x00\x00\x01d') 941assert(pkt.type == 2) 942assert(pkt.len == 5) 943assert(len(pkt.flags) == 0) 944assert(pkt.reserved == 0) 945assert(pkt.stream_id == 3) 946assert(isinstance(pkt.payload, h2.H2PriorityFrame)) 947assert(pkt[h2.H2PriorityFrame]) 948pp = pkt[h2.H2PriorityFrame] 949assert(pp.stream_dependency == 1) 950assert(pp.exclusive == 1) 951assert(pp.weight == 100) 952 953= HTTP/2 Build Priority Frame 954~ http2 frame build priority 955 956p = h2.H2Frame(stream_id=3)/h2.H2PriorityFrame( 957 exclusive=1, 958 stream_dependency=1, 959 weight=100 960) 961assert(raw(p) == b'\x00\x00\x05\x02\x00\x00\x00\x00\x03\x80\x00\x00\x01d') 962 963+ HTTP/2 Reset Stream Frame Test Suite 964 965= HTTP/2 Dissect Reset Stream Frame: Protocol Error 966~ http2 frame dissect rststream 967 968pkt = h2.H2Frame(b'\x00\x00\x04\x03\x00\x00\x00\x00\x01\x00\x00\x00\x01') #Reset stream with protocol error 969assert(pkt.type == 3) 970assert(pkt.len == 4) 971assert(len(pkt.flags) == 0) 972assert(pkt.reserved == 0) 973assert(pkt.stream_id == 1) 974assert(isinstance(pkt.payload, h2.H2ResetFrame)) 975assert(pkt[h2.H2ResetFrame]) 976rf = pkt[h2.H2ResetFrame] 977assert(rf.error == 1) 978assert(isinstance(rf.payload, scapy.packet.NoPayload)) 979 980= HTTP/2 Build Reset Stream Frame: Protocol Error 981~ http2 frame build rststream 982 983p = h2.H2Frame(stream_id=1)/h2.H2ResetFrame(error='Protocol error') 984assert(raw(p) == b'\x00\x00\x04\x03\x00\x00\x00\x00\x01\x00\x00\x00\x01') 985 986p = h2.H2Frame(stream_id=1)/h2.H2ResetFrame(error=1) 987assert(raw(p) == b'\x00\x00\x04\x03\x00\x00\x00\x00\x01\x00\x00\x00\x01') 988 989= HTTP/2 Dissect Reset Stream Frame: Raw 123456 error 990~ http2 frame dissect rststream 991 992pkt = h2.H2Frame(b'\x00\x00\x04\x03\x00\x00\x00\x00\x01\x00\x01\xe2@') #Reset stream with raw error 993assert(pkt.type == 3) 994assert(pkt.len == 4) 995assert(len(pkt.flags) == 0) 996assert(pkt.reserved == 0) 997assert(pkt.stream_id == 1) 998assert(isinstance(pkt.payload, h2.H2ResetFrame)) 999assert(pkt[h2.H2ResetFrame]) 1000rf = pkt[h2.H2ResetFrame] 1001assert(rf.error == 123456) 1002assert(isinstance(rf.payload, scapy.packet.NoPayload)) 1003 1004= HTTP/2 Dissect Reset Stream Frame: Raw 123456 error 1005~ http2 frame dissect rststream 1006 1007p = h2.H2Frame(stream_id=1)/h2.H2ResetFrame(error=123456) 1008assert(raw(p) == b'\x00\x00\x04\x03\x00\x00\x00\x00\x01\x00\x01\xe2@') 1009 1010+ HTTP/2 Settings Frame Test Suite 1011 1012= HTTP/2 Dissect Settings Frame: Settings Frame 1013~ http2 frame dissect settings 1014 1015pkt = 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 1016assert(pkt.type == 4) 1017assert(pkt.len == 36) 1018assert(len(pkt.flags) == 0) 1019assert(pkt.reserved == 0) 1020assert(pkt.stream_id == 0) 1021assert(isinstance(pkt.payload, h2.H2SettingsFrame)) 1022assert(pkt[h2.H2SettingsFrame]) 1023sf = pkt[h2.H2SettingsFrame] 1024assert(len(sf.settings) == 6) 1025assert(isinstance(sf.settings[0], h2.H2Setting)) 1026assert(sf.settings[0].id == 1) 1027assert(sf.settings[0].value == 123456789) 1028assert(isinstance(sf.settings[1], h2.H2Setting)) 1029assert(sf.settings[1].id == 2) 1030assert(sf.settings[1].value == 1) 1031assert(isinstance(sf.settings[2], h2.H2Setting)) 1032assert(sf.settings[2].id == 3) 1033assert(sf.settings[2].value == 123) 1034assert(isinstance(sf.settings[3], h2.H2Setting)) 1035assert(sf.settings[3].id == 4) 1036assert(sf.settings[3].value == 1234567) 1037assert(isinstance(sf.settings[4], h2.H2Setting)) 1038assert(sf.settings[4].id == 5) 1039assert(sf.settings[4].value == 123456) 1040assert(isinstance(sf.settings[5], h2.H2Setting)) 1041assert(sf.settings[5].id == 6) 1042assert(sf.settings[5].value == 123) 1043assert(isinstance(sf.payload, scapy.packet.NoPayload)) 1044 1045= HTTP/2 Build Settings Frame: Settings Frame 1046~ http2 frame build settings 1047 1048p = h2.H2Frame()/h2.H2SettingsFrame(settings=[ 1049 h2.H2Setting(id='Header table size',value=123456789), 1050 h2.H2Setting(id='Enable push', value=1), 1051 h2.H2Setting(id='Max concurrent streams', value=123), 1052 h2.H2Setting(id='Initial window size', value=1234567), 1053 h2.H2Setting(id='Max frame size', value=123456), 1054 h2.H2Setting(id='Max header list size', value=123) 1055 ] 1056) 1057assert(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{') 1058 1059= HTTP/2 Dissect Settings Frame: Incomplete Settings Frame 1060~ http2 frame dissect settings 1061 1062#We use here the decode('hex') method because null-bytes are rejected by eval() 1063assert(expect_exception(AssertionError, 'h2.H2Frame(bytes_hex("0000240400000000000001075bcd1500020000000100030000007b00040012d68700050001e2400006000000"))')) 1064 1065= HTTP/2 Dissect Settings Frame: Settings Frame acknowledgement 1066~ http2 frame dissect settings 1067 1068pkt = h2.H2Frame(b'\x00\x00\x00\x04\x01\x00\x00\x00\x00') #Settings frame w/ ack flag 1069assert(pkt.type == 4) 1070assert(pkt.len == 0) 1071assert(len(pkt.flags) == 1) 1072assert('A' in pkt.flags) 1073assert(pkt.reserved == 0) 1074assert(pkt.stream_id == 0) 1075assert(flags_bit_pattern.search(pkt.show(dump=True)) is None) 1076assert(isinstance(pkt.payload, scapy.packet.NoPayload)) 1077 1078= HTTP/2 Build Settings Frame: Settings Frame acknowledgement 1079~ http2 frame build settings 1080 1081p = h2.H2Frame(type=h2.H2SettingsFrame.type_id, flags={'A'}) 1082assert(raw(p) == b'\x00\x00\x00\x04\x01\x00\x00\x00\x00') 1083 1084+ HTTP/2 Push Promise Frame Test Suite 1085 1086= HTTP/2 Dissect Push Promise Frame: no flag & headers with compression and hdr_name 1087~ http2 frame dissect pushpromise 1088 1089pkt = 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') 1090assert(pkt.type == 5) 1091assert(pkt.len == 21) 1092assert(len(pkt.flags) == 0) 1093assert(pkt.reserved == 0) 1094assert(pkt.stream_id == 1) 1095assert(isinstance(pkt.payload, h2.H2PushPromiseFrame)) 1096assert(pkt[h2.H2PushPromiseFrame]) 1097pf = pkt[h2.H2PushPromiseFrame] 1098assert(pf.reserved == 0) 1099assert(pf.stream_id == 3) 1100assert(len(pf.hdrs) == 1) 1101assert(isinstance(pf.payload, scapy.packet.NoPayload)) 1102hdr = pf.hdrs[0] 1103assert(isinstance(hdr, h2.HPackLitHdrFldWithIncrIndexing)) 1104assert(hdr.magic == 1) 1105assert(hdr.index == 0) 1106assert(isinstance(hdr.hdr_name, h2.HPackHdrString)) 1107assert(hdr.hdr_name.type == 1) 1108assert(hdr.hdr_name.len == 12) 1109assert(hdr.hdr_name.getfieldval('data').origin() == 'X-Requested-With') 1110assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 1111assert(hdr.hdr_value.type == 0) 1112assert(hdr.hdr_value.len == 2) 1113assert(hdr.hdr_value.getfieldval('data').origin() == 'Me') 1114 1115= HTTP/2 Build Push Promise Frame: no flag & headers with compression and hdr_name 1116~ http2 frame build pushpromise 1117 1118p = h2.H2Frame(stream_id=1)/h2.H2PushPromiseFrame(stream_id=3,hdrs=[ 1119 h2.HPackLitHdrFldWithIncrIndexing( 1120 hdr_name=h2.HPackHdrString(data=h2.HPackZString('X-Requested-With')), 1121 hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('Me')), 1122 ) 1123]) 1124assert(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') 1125 1126= HTTP/2 Dissect Push Promise Frame: with padding, the flag END_Header & headers with compression and hdr_name 1127~ http2 frame dissect pushpromise 1128 1129pkt = 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') 1130assert(pkt.type == 5) 1131assert(pkt.len == 30) 1132assert(len(pkt.flags) == 2) 1133assert('P' in pkt.flags) 1134assert('EH' in pkt.flags) 1135assert(pkt.reserved == 0) 1136assert(pkt.stream_id == 1) 1137assert(flags_bit_pattern.search(pkt.show(dump=True)) is None) 1138assert(isinstance(pkt.payload, h2.H2PaddedPushPromiseFrame)) 1139assert(pkt[h2.H2PaddedPushPromiseFrame]) 1140pf = pkt[h2.H2PaddedPushPromiseFrame] 1141assert(pf.padlen == 8) 1142assert(pf.padding == b'\x00'*8) 1143assert(pf.stream_id == 3) 1144assert(len(pf.hdrs) == 1) 1145hdr = pf.hdrs[0] 1146assert(isinstance(hdr, h2.HPackLitHdrFldWithIncrIndexing)) 1147assert(hdr.magic == 1) 1148assert(hdr.index == 0) 1149assert(isinstance(hdr.hdr_name, h2.HPackHdrString)) 1150assert(hdr.hdr_name.type == 1) 1151assert(hdr.hdr_name.len == 12) 1152assert(hdr.hdr_name.getfieldval('data').origin() == 'X-Requested-With') 1153assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 1154assert(hdr.hdr_value.type == 0) 1155assert(hdr.hdr_value.len == 2) 1156assert(hdr.hdr_value.getfieldval('data').origin() == 'Me') 1157 1158= HTTP/2 Build Push Promise Frame: with padding, the flag END_Header & headers with compression and hdr_name 1159~ http2 frame build pushpromise 1160 1161p = h2.H2Frame(flags={'P', 'EH'}, stream_id=1)/h2.H2PaddedPushPromiseFrame( 1162 stream_id=3, 1163 hdrs=[ 1164 h2.HPackLitHdrFldWithIncrIndexing( 1165 hdr_name=h2.HPackHdrString(data=h2.HPackZString('X-Requested-With')), 1166 hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('Me')) 1167 ) 1168 ], 1169 padding=b'\x00'*8 1170) 1171assert(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') 1172 1173+ HTTP/2 Ping Frame Test Suite 1174 1175= HTTP/2 Dissect Ping Frame: Ping frame 1176~ http2 frame dissect ping 1177 1178pkt = h2.H2Frame(b'\x00\x00\x08\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xe2@') #Ping frame with payload 1179assert(pkt.type == 6) 1180assert(pkt.len == 8) 1181assert(len(pkt.flags) == 0) 1182assert(pkt.reserved == 0) 1183assert(pkt.stream_id == 0) 1184assert(isinstance(pkt.payload, h2.H2PingFrame)) 1185assert(pkt[h2.H2PingFrame]) 1186pf = pkt[h2.H2PingFrame] 1187assert(pf.opaque == 123456) 1188assert(isinstance(pf.payload, scapy.packet.NoPayload)) 1189 1190= HTTP/2 Build Ping Frame: Ping frame 1191~ http2 frame build ping 1192 1193p = h2.H2Frame()/h2.H2PingFrame(opaque=123456) 1194assert(raw(p) == b'\x00\x00\x08\x06\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xe2@') 1195 1196= HTTP/2 Dissect Ping Frame: Pong frame 1197~ http2 frame dissect ping 1198 1199pkt = h2.H2Frame(b'\x00\x00\x08\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xe2@') #Pong frame 1200assert(pkt.type == 6) 1201assert(pkt.len == 8) 1202assert(len(pkt.flags) == 1) 1203assert('A' in pkt.flags) 1204assert(pkt.reserved == 0) 1205assert(pkt.stream_id == 0) 1206assert(isinstance(pkt.payload, h2.H2PingFrame)) 1207assert(flags_bit_pattern.search(pkt.show(dump=True)) is None) 1208assert(pkt[h2.H2PingFrame]) 1209pf = pkt[h2.H2PingFrame] 1210assert(pf.opaque == 123456) 1211assert(isinstance(pf.payload, scapy.packet.NoPayload)) 1212 1213= HTTP/2 Dissect Ping Frame: Pong frame 1214~ http2 frame dissect ping 1215 1216p = h2.H2Frame(flags={'A'})/h2.H2PingFrame(opaque=123456) 1217assert(raw(p) == b'\x00\x00\x08\x06\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xe2@') 1218 1219+ HTTP/2 Go Away Frame Test Suite 1220 1221= HTTP/2 Dissect Go Away Frame: No error 1222~ http2 frame dissect goaway 1223 1224pkt = 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 :) 1225assert(pkt.type == 7) 1226assert(pkt.len == 8) 1227assert(len(pkt.flags) == 0) 1228assert(pkt.reserved == 0) 1229assert(pkt.stream_id == 0) 1230assert(isinstance(pkt.payload, h2.H2GoAwayFrame)) 1231assert(pkt[h2.H2GoAwayFrame]) 1232gf = pkt[h2.H2GoAwayFrame] 1233assert(gf.reserved == 0) 1234assert(gf.last_stream_id == 1) 1235assert(gf.error == 0) 1236assert(len(gf.additional_data) == 0) 1237assert(isinstance(gf.payload, scapy.packet.NoPayload)) 1238 1239= HTTP/2 Build Go Away Frame: No error 1240~ http2 frame build goaway 1241 1242p = h2.H2Frame()/h2.H2GoAwayFrame(last_stream_id=1, error='No error') 1243assert(raw(p) == b'\x00\x00\x08\x07\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00') 1244 1245= HTTP/2 Dissect Go Away Frame: Arbitrary error with additional data 1246~ http2 frame dissect goaway 1247 1248pkt = 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 1249assert(pkt.type == 7) 1250assert(pkt.len == 16) 1251assert(len(pkt.flags) == 0) 1252assert(pkt.reserved == 0) 1253assert(pkt.stream_id == 0) 1254assert(isinstance(pkt.payload, h2.H2GoAwayFrame)) 1255assert(pkt[h2.H2GoAwayFrame]) 1256gf = pkt[h2.H2GoAwayFrame] 1257assert(gf.reserved == 0) 1258assert(gf.last_stream_id == 2) 1259assert(gf.error == 123456) 1260assert(gf.additional_data == 8*b'\x00') 1261assert(isinstance(gf.payload, scapy.packet.NoPayload)) 1262 1263= HTTP/2 Build Go Away Frame: Arbitrary error with additional data 1264~ http2 frame build goaway 1265 1266p = h2.H2Frame()/h2.H2GoAwayFrame( 1267 last_stream_id=2, 1268 error=123456, 1269 additional_data=b'\x00'*8 1270) 1271assert(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') 1272 1273+ HTTP/2 Window Update Frame Test Suite 1274 1275= HTTP/2 Dissect Window Update Frame: global 1276~ http2 frame dissect winupdate 1277 1278pkt = h2.H2Frame(b'\x00\x00\x04\x08\x00\x00\x00\x00\x00\x00\x01\xe2@') #Window update with increment for connection 1279assert(pkt.type == 8) 1280assert(pkt.len == 4) 1281assert(len(pkt.flags) == 0) 1282assert(pkt.reserved == 0) 1283assert(pkt.stream_id == 0) 1284assert(isinstance(pkt.payload, h2.H2WindowUpdateFrame)) 1285assert(pkt[h2.H2WindowUpdateFrame]) 1286wf = pkt[h2.H2WindowUpdateFrame] 1287assert(wf.reserved == 0) 1288assert(wf.win_size_incr == 123456) 1289assert(isinstance(wf.payload, scapy.packet.NoPayload)) 1290 1291= HTTP/2 Build Window Update Frame: global 1292~ http2 frame build winupdate 1293 1294p = h2.H2Frame()/h2.H2WindowUpdateFrame(win_size_incr=123456) 1295assert(raw(p) == b'\x00\x00\x04\x08\x00\x00\x00\x00\x00\x00\x01\xe2@') 1296 1297= HTTP/2 Dissect Window Update Frame: a stream 1298~ http2 frame dissect winupdate 1299 1300pkt = h2.H2Frame(b'\x00\x00\x04\x08\x00\x00\x00\x00\x01\x00\x01\xe2@') #Window update with increment for a stream 1301assert(pkt.type == 8) 1302assert(pkt.len == 4) 1303assert(len(pkt.flags) == 0) 1304assert(pkt.reserved == 0) 1305assert(pkt.stream_id == 1) 1306assert(isinstance(pkt.payload, h2.H2WindowUpdateFrame)) 1307assert(pkt[h2.H2WindowUpdateFrame]) 1308wf = pkt[h2.H2WindowUpdateFrame] 1309assert(wf.reserved == 0) 1310assert(wf.win_size_incr == 123456) 1311assert(isinstance(wf.payload, scapy.packet.NoPayload)) 1312 1313= HTTP/2 Build Window Update Frame: a stream 1314~ http2 frame build winupdate 1315 1316p = h2.H2Frame(stream_id=1)/h2.H2WindowUpdateFrame(win_size_incr=123456) 1317assert(raw(p) == b'\x00\x00\x04\x08\x00\x00\x00\x00\x01\x00\x01\xe2@') 1318 1319+ HTTP/2 Continuation Frame Test Suite 1320 1321= HTTP/2 Dissect Continuation Frame: no flag & headers with compression and hdr_name 1322~ http2 frame dissect continuation 1323 1324pkt = h2.H2Frame(b'\x00\x00\x11\t\x00\x00\x00\x00\x01@\x8c\xfc[i{ZT$\xb2-\xc8\xc9\x9f\x02Me') 1325assert(pkt.type == 9) 1326assert(pkt.len == 17) 1327assert(len(pkt.flags) == 0) 1328assert(pkt.reserved == 0) 1329assert(pkt.stream_id == 1) 1330assert(isinstance(pkt.payload, h2.H2ContinuationFrame)) 1331assert(pkt[h2.H2ContinuationFrame]) 1332hf = pkt[h2.H2ContinuationFrame] 1333assert(len(hf.hdrs) == 1) 1334assert(isinstance(hf.payload, scapy.packet.NoPayload)) 1335hdr = hf.hdrs[0] 1336assert(isinstance(hdr, h2.HPackLitHdrFldWithIncrIndexing)) 1337assert(hdr.magic == 1) 1338assert(hdr.index == 0) 1339assert(isinstance(hdr.hdr_name, h2.HPackHdrString)) 1340assert(hdr.hdr_name.type == 1) 1341assert(hdr.hdr_name.len == 12) 1342assert(hdr.hdr_name.getfieldval('data').origin() == 'X-Requested-With') 1343assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 1344assert(hdr.hdr_value.type == 0) 1345assert(hdr.hdr_value.len == 2) 1346assert(hdr.hdr_value.getfieldval('data').origin() == 'Me') 1347 1348= HTTP/2 Build Continuation Frame: no flag & headers with compression and hdr_name 1349~ http2 frame build continuation 1350 1351p = h2.H2Frame(stream_id=1)/h2.H2ContinuationFrame( 1352 hdrs=[ 1353 h2.HPackLitHdrFldWithIncrIndexing( 1354 hdr_name=h2.HPackHdrString(data=h2.HPackZString('X-Requested-With')), 1355 hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('Me')) 1356 ) 1357 ] 1358) 1359assert(raw(p) == b'\x00\x00\x11\t\x00\x00\x00\x00\x01@\x8c\xfc[i{ZT$\xb2-\xc8\xc9\x9f\x02Me') 1360 1361= HTTP/2 Dissect Continuation Frame: flag END_Header & headers with compression, sensitive flag and hdr_name 1362~ http2 frame dissect continuation 1363 1364pkt = h2.H2Frame(b'\x00\x00\x11\t\x04\x00\x00\x00\x01\x10\x8c\xfc[i{ZT$\xb2-\xc8\xc9\x9f\x02Me') 1365assert(pkt.type == 9) 1366assert(pkt.len == 17) 1367assert(len(pkt.flags) == 1) 1368assert('EH' in pkt.flags) 1369assert(pkt.reserved == 0) 1370assert(pkt.stream_id == 1) 1371assert(flags_bit_pattern.search(pkt.show(dump=True)) is None) 1372assert(isinstance(pkt.payload, h2.H2ContinuationFrame)) 1373assert(pkt[h2.H2ContinuationFrame]) 1374hf = pkt[h2.H2ContinuationFrame] 1375assert(len(hf.hdrs) == 1) 1376assert(isinstance(hf.payload, scapy.packet.NoPayload)) 1377hdr = hf.hdrs[0] 1378assert(isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)) 1379assert(hdr.magic == 0) 1380assert(hdr.never_index == 1) 1381assert(hdr.index == 0) 1382assert(isinstance(hdr.hdr_name, h2.HPackHdrString)) 1383assert(hdr.hdr_name.type == 1) 1384assert(hdr.hdr_name.len == 12) 1385assert(hdr.hdr_name.getfieldval('data').origin() == 'X-Requested-With') 1386assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 1387assert(hdr.hdr_value.type == 0) 1388assert(hdr.hdr_value.len == 2) 1389assert(hdr.hdr_value.getfieldval('data').origin() == 'Me') 1390 1391= HTTP/2 Build Continuation Frame: flag END_Header & headers with compression, sensitive flag and hdr_name 1392~ http2 frame build continuation 1393 1394p = h2.H2Frame(flags={'EH'}, stream_id=1)/h2.H2ContinuationFrame( 1395 hdrs=[ 1396 h2.HPackLitHdrFldWithoutIndexing( 1397 never_index=1, 1398 hdr_name=h2.HPackHdrString(data=h2.HPackZString('X-Requested-With')), 1399 hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('Me')) 1400 ) 1401 ] 1402) 1403assert(raw(p) == b'\x00\x00\x11\t\x04\x00\x00\x00\x01\x10\x8c\xfc[i{ZT$\xb2-\xc8\xc9\x9f\x02Me') 1404 1405+ HTTP/2 HPackHdrTable Test Suite 1406 1407= HTTP/2 HPackHdrEntry Tests 1408~ http2 hpack hpackhdrtable 1409 1410n = 'X-Requested-With' 1411v = 'Me' 1412h = h2.HPackHdrEntry(n, v) 1413assert(len(h) == 32 + len(n) + len(v)) 1414assert(h.name() == n.lower()) 1415assert(h.value() == v) 1416assert(str(h) == '{}: {}'.format(n.lower(), v)) 1417 1418n = ':status' 1419v = '200' 1420h = h2.HPackHdrEntry(n, v) 1421assert(len(h) == 32 + len(n) + len(v)) 1422assert(h.name() == n.lower()) 1423assert(h.value() == v) 1424assert(str(h) == '{} {}'.format(n.lower(), v)) 1425 1426= HTTP/2 HPackHdrTable : Querying Static Entries 1427~ http2 hpack hpackhdrtable 1428 1429# In RFC7541, the table is 1-based 1430assert(expect_exception(KeyError, 'h2.HPackHdrTable()[0]')) 1431 1432h = h2.HPackHdrTable() 1433assert(h[1].name() == ':authority') 1434assert(h[7].name() == ':scheme') 1435assert(h[7].value() == 'https') 1436assert(str(h[14]) == ':status 500') 1437assert(str(h[16]) == 'accept-encoding: gzip, deflate') 1438 1439assert(expect_exception(KeyError, 'h2.HPackHdrTable()[h2.HPackHdrTable._static_entries_last_idx+1]')) 1440 1441= HTTP/2 HPackHdrTable : Addind Dynamic Entries without overflowing the table 1442~ http2 hpack hpackhdrtable 1443 1444tbl = h2.HPackHdrTable(dynamic_table_max_size=1<<32, dynamic_table_cap_size=1<<32) 1445hdr = h2.HPackLitHdrFldWithIncrIndexing( 1446 index=32, 1447 hdr_value=h2.HPackHdrString(data=h2.HPackZString('PHPSESSID=abcdef0123456789')) 1448) 1449tbl.register(hdr) 1450 1451tbl = h2.HPackHdrTable(dynamic_table_max_size=1<<32, dynamic_table_cap_size=1<<32) 1452hdr2 = h2.HPackLitHdrFldWithIncrIndexing( 1453 index=32, 1454 hdr_value=h2.HPackHdrString(data=h2.HPackZString('JSESSID=abcdef0123456789')) 1455) 1456tbl.register([hdr,hdr2]) 1457 1458tbl = h2.HPackHdrTable(dynamic_table_max_size=1<<32, dynamic_table_cap_size=1<<32) 1459hdr3 = h2.HPackLitHdrFldWithIncrIndexing( 1460 index=32, 1461 hdr_value=h2.HPackHdrString(data=h2.HPackZString('Test=abcdef0123456789')) 1462) 1463frm = h2.H2Frame(stream_id=1)/h2.H2HeadersFrame(hdrs=[hdr, hdr2, hdr3]) 1464tbl.register(frm) 1465 1466 1467= HTTP/2 HPackHdrTable : Querying Dynamic Entries 1468~ http2 hpack hpackhdrtable 1469 1470tbl = h2.HPackHdrTable(dynamic_table_max_size=1<<32, dynamic_table_cap_size=1<<32) 1471hdrv = 'PHPSESSID=abcdef0123456789' 1472hdr = h2.HPackLitHdrFldWithIncrIndexing( 1473 index=32, 1474 hdr_value=h2.HPackHdrString(data=h2.HPackZString(hdrv)) 1475) 1476tbl.register(hdr) 1477 1478hdrv2 = 'JSESSID=abcdef0123456789' 1479hdr2 = h2.HPackLitHdrFldWithIncrIndexing( 1480 index=32, 1481 hdr_value=h2.HPackHdrString(data=h2.HPackZString(hdrv2)) 1482) 1483tbl.register(hdr2) 1484 1485hdr3 = h2.HPackLitHdrFldWithIncrIndexing( 1486 index=0, 1487 hdr_name=h2.HPackHdrString(data=h2.HPackLiteralString('x-requested-by')), 1488 hdr_value=h2.HPackHdrString(data=h2.HPackZString('me')) 1489) 1490tbl.register(hdr3) 1491 1492assert(tbl.get_idx_by_name('x-requested-by') == h2.HPackHdrTable._static_entries_last_idx+1) 1493assert(tbl[h2.HPackHdrTable._static_entries_last_idx+2].value() == hdrv2) 1494assert(tbl[h2.HPackHdrTable._static_entries_last_idx+3].value() == hdrv) 1495 1496= HTTP/2 HPackHdrTable : Addind already registered Dynamic Entries without overflowing the table 1497~ http2 hpack hpackhdrtable 1498 1499tbl = h2.HPackHdrTable(dynamic_table_max_size=1<<32, dynamic_table_cap_size=1<<32) 1500 1501assert(len(tbl) == 0) 1502 1503hdrv = 'PHPSESSID=abcdef0123456789' 1504hdr = h2.HPackLitHdrFldWithIncrIndexing( 1505 index=32, 1506 hdr_value=h2.HPackHdrString(data=h2.HPackZString(hdrv)) 1507) 1508tbl.register(hdr) 1509assert(tbl[h2.HPackHdrTable._static_entries_last_idx+1].value() == hdrv) 1510 1511hdr2v = 'JSESSID=abcdef0123456789' 1512hdr2 = h2.HPackLitHdrFldWithIncrIndexing( 1513 index=32, 1514 hdr_value=h2.HPackHdrString(data=h2.HPackZString(hdr2v)) 1515) 1516tbl.register(hdr2) 1517assert(tbl[h2.HPackHdrTable._static_entries_last_idx+1].value() == hdr2v) 1518 1519l = len(tbl) 1520tbl.register(hdr) 1521assert(tbl[h2.HPackHdrTable._static_entries_last_idx+1].value() == hdrv) 1522assert(tbl[h2.HPackHdrTable._static_entries_last_idx+2].value() == hdr2v) 1523assert(tbl[h2.HPackHdrTable._static_entries_last_idx+3].value() == hdrv) 1524 1525= HTTP/2 HPackHdrTable : Addind Dynamic Entries and overflowing the table 1526~ http2 hpack hpackhdrtable 1527 1528tbl = h2.HPackHdrTable(dynamic_table_max_size=80, dynamic_table_cap_size=80) 1529hdrv = 'PHPSESSID=abcdef0123456789' 1530hdr = h2.HPackLitHdrFldWithIncrIndexing( 1531 index=32, 1532 hdr_value=h2.HPackHdrString(data=h2.HPackZString(hdrv)) 1533) 1534tbl.register(hdr) 1535assert(len(tbl) <= 80) 1536assert(tbl[h2.HPackHdrTable._static_entries_last_idx+1].value() == hdrv) 1537 1538hdrv2 = 'JSESSID=abcdef0123456789' 1539hdr2 = h2.HPackLitHdrFldWithIncrIndexing( 1540 index=32, 1541 hdr_value=h2.HPackHdrString(data=h2.HPackZString(hdrv2)) 1542) 1543tbl.register(hdr2) 1544assert(len(tbl) <= 80) 1545assert(tbl[h2.HPackHdrTable._static_entries_last_idx+1].value() == hdrv2) 1546try: 1547 tbl[h2.HPackHdrTable._static_entries_last_idx+2] 1548 ret = False 1549except: 1550 ret = True 1551 1552assert(ret) 1553 1554 1555= HTTP/2 HPackHdrTable : Resizing 1556~ http2 hpack hpackhdrtable 1557 1558tbl = h2.HPackHdrTable() 1559hdrv = 'PHPSESSID=abcdef0123456789' 1560hdr = h2.HPackLitHdrFldWithIncrIndexing( 1561 index=32, 1562 hdr_value=h2.HPackHdrString(data=h2.HPackZString(hdrv)) 1563) 1564tbl.register(hdr) 1565assert(tbl[h2.HPackHdrTable._static_entries_last_idx+1].value() == hdrv) 1566 1567hdrv2 = 'JSESSID=abcdef0123456789' 1568hdr2 = h2.HPackLitHdrFldWithIncrIndexing( 1569 index=32, 1570 hdr_value=h2.HPackHdrString(data=h2.HPackZString(hdrv2)) 1571) 1572tbl.register(hdr2) 1573assert(tbl[h2.HPackHdrTable._static_entries_last_idx+1].value() == hdrv2) 1574assert(tbl[h2.HPackHdrTable._static_entries_last_idx+2].value() == hdrv) 1575 1576#Resizing to a value higher than cap (default:4096) 1577try: 1578 tbl.resize(8192) 1579 ret = False 1580except AssertionError: 1581 ret = True 1582 1583assert(ret) 1584#Resizing to a lower value by that is not small enough to cause eviction 1585tbl.resize(1024) 1586assert(tbl[h2.HPackHdrTable._static_entries_last_idx+1].value() == hdrv2) 1587assert(tbl[h2.HPackHdrTable._static_entries_last_idx+2].value() == hdrv) 1588#Resizing to a higher value but thatt is lower than cap 1589tbl.resize(2048) 1590assert(tbl[h2.HPackHdrTable._static_entries_last_idx+1].value() == hdrv2) 1591assert(tbl[h2.HPackHdrTable._static_entries_last_idx+2].value() == hdrv) 1592#Resizing to a lower value that causes eviction 1593tbl.resize(80) 1594assert(tbl[h2.HPackHdrTable._static_entries_last_idx+1].value() == hdrv2) 1595try: 1596 tbl[h2.HPackHdrTable._static_entries_last_idx+2] 1597 ret = False 1598except: 1599 ret = True 1600 1601assert(ret) 1602 1603= HTTP/2 HPackHdrTable : Recapping 1604~ http2 hpack hpackhdrtable 1605 1606tbl = h2.HPackHdrTable() 1607hdrv = 'PHPSESSID=abcdef0123456789' 1608hdr = h2.HPackLitHdrFldWithIncrIndexing( 1609 index=32, 1610 hdr_value=h2.HPackHdrString(data=h2.HPackZString(hdrv)) 1611) 1612tbl.register(hdr) 1613assert(tbl[h2.HPackHdrTable._static_entries_last_idx+1].value() == hdrv) 1614 1615hdrv2 = 'JSESSID=abcdef0123456789' 1616hdr2 = h2.HPackLitHdrFldWithIncrIndexing( 1617 index=32, 1618 hdr_value=h2.HPackHdrString(data=h2.HPackZString(hdrv2)) 1619) 1620tbl.register(hdr2) 1621assert(tbl[h2.HPackHdrTable._static_entries_last_idx+1].value() == hdrv2) 1622assert(tbl[h2.HPackHdrTable._static_entries_last_idx+2].value() == hdrv) 1623 1624#Recapping to a higher value 1625tbl.recap(8192) 1626assert(tbl[h2.HPackHdrTable._static_entries_last_idx+1].value() == hdrv2) 1627assert(tbl[h2.HPackHdrTable._static_entries_last_idx+2].value() == hdrv) 1628 1629#Recapping to a low value but without causing eviction 1630tbl.recap(1024) 1631assert(tbl[h2.HPackHdrTable._static_entries_last_idx+1].value() == hdrv2) 1632assert(tbl[h2.HPackHdrTable._static_entries_last_idx+2].value() == hdrv) 1633 1634#Recapping to a low value that causes evictiontbl.recap(1024) 1635tbl.recap(80) 1636assert(tbl[h2.HPackHdrTable._static_entries_last_idx+1].value() == hdrv2) 1637try: 1638 tbl[h2.HPackHdrTable._static_entries_last_idx+2] 1639 ret = False 1640except: 1641 ret = True 1642 1643assert(ret) 1644 1645= HTTP/2 HPackHdrTable : Generating Textual Representation 1646~ http2 hpack hpackhdrtable helpers 1647 1648h = h2.HPackHdrTable() 1649h.register(h2.HPackLitHdrFldWithIncrIndexing( 1650 hdr_name=h2.HPackHdrString(data=h2.HPackZString('X-Generation-Date')), 1651 hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('2016-08-11')) 1652)) 1653 1654hdrs_lst = [ 1655 h2.HPackIndexedHdr(index=2), #Method Get 1656 h2.HPackLitHdrFldWithIncrIndexing( 1657 index=h.get_idx_by_name(':path'), 1658 hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('/index.php')) 1659 ), 1660 h2.HPackIndexedHdr(index=7), #Scheme HTTPS 1661 h2.HPackIndexedHdr(index=h2.HPackHdrTable._static_entries_last_idx+2), 1662 h2.HPackLitHdrFldWithIncrIndexing( 1663 index=58, 1664 hdr_value=h2.HPackHdrString(data=h2.HPackZString('Mozilla/5.0 Generated by hand')) 1665 ), 1666 h2.HPackLitHdrFldWithoutIndexing( 1667 hdr_name=h2.HPackHdrString(data=h2.HPackZString('X-Generated-By')), 1668 hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('Me')) 1669 ) 1670] 1671 1672p = h2.H2Frame(stream_id = 1)/h2.H2HeadersFrame(hdrs=hdrs_lst) 1673 1674expected_output = ''':method GET 1675:path /index.php 1676:scheme https 1677x-generation-date: 2016-08-11 1678user-agent: Mozilla/5.0 Generated by hand 1679X-Generated-By: Me''' 1680 1681assert(h.gen_txt_repr(p) == expected_output) 1682 1683= HTTP/2 HPackHdrTable : Parsing Textual Representation 1684~ http2 hpack hpackhdrtable helpers 1685 1686body = b'login=titi&passwd=toto' 1687hdrs = raw(''':method POST 1688:path /login.php 1689:scheme https 1690content-type: application/x-www-form-urlencoded 1691content-length: {} 1692user-agent: Mozilla/5.0 Generated by hand 1693x-generated-by: Me 1694x-generation-date: 2016-08-11 1695x-generation-software: scapy 1696'''.format(len(body))) 1697 1698h = h2.HPackHdrTable() 1699h.register(h2.HPackLitHdrFldWithIncrIndexing( 1700 hdr_name=h2.HPackHdrString(data=h2.HPackZString('X-Generation-Date')), 1701 hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('2016-08-11')) 1702)) 1703seq = h.parse_txt_hdrs( 1704 hdrs, 1705 stream_id=1, 1706 body=body, 1707 should_index=lambda name: name in ['user-agent', 'x-generation-software'], 1708 is_sensitive=lambda name, value: name in ['x-generated-by', ':path'] 1709) 1710assert(isinstance(seq, h2.H2Seq)) 1711assert(len(seq.frames) == 2) 1712p = seq.frames[0] 1713assert(isinstance(p, h2.H2Frame)) 1714assert(p.type == 1) 1715assert(len(p.flags) == 1) 1716assert('EH' in p.flags) 1717assert(p.stream_id == 1) 1718assert(isinstance(p.payload, h2.H2HeadersFrame)) 1719hdrs_frm = p[h2.H2HeadersFrame] 1720assert(len(p.hdrs) == 9) 1721hdr = p.hdrs[0] 1722assert(isinstance(hdr, h2.HPackIndexedHdr)) 1723assert(hdr.magic == 1) 1724assert(hdr.index == 3) 1725hdr = p.hdrs[1] 1726assert(isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)) 1727assert(hdr.magic == 0) 1728assert(hdr.never_index == 1) 1729assert(hdr.index in [4, 5]) 1730assert(hdr.hdr_name is None) 1731assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 1732assert(hdr.hdr_value.data == 'HPackZString(/login.php)') 1733hdr = p.hdrs[2] 1734assert(isinstance(hdr, h2.HPackIndexedHdr)) 1735assert(hdr.magic == 1) 1736assert(hdr.index == 7) 1737hdr = p.hdrs[3] 1738assert(isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)) 1739assert(hdr.magic == 0) 1740assert(hdr.never_index == 0) 1741assert(hdr.index == 31) 1742assert(hdr.hdr_name is None) 1743assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 1744assert(hdr.hdr_value.data == 'HPackZString(application/x-www-form-urlencoded)') 1745hdr = p.hdrs[4] 1746assert(isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)) 1747assert(hdr.magic == 0) 1748assert(hdr.never_index == 0) 1749assert(hdr.index == 28) 1750assert(hdr.hdr_name is None) 1751assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 1752assert(hdr.hdr_value.data == 'HPackLiteralString(22)') 1753hdr = p.hdrs[5] 1754assert(isinstance(hdr, h2.HPackLitHdrFldWithIncrIndexing)) 1755assert(hdr.magic == 1) 1756assert(hdr.index == 58) 1757assert(hdr.hdr_name is None) 1758assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 1759assert(hdr.hdr_value.data == 'HPackZString(Mozilla/5.0 Generated by hand)') 1760hdr = p.hdrs[6] 1761assert(isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)) 1762assert(hdr.magic == 0) 1763assert(hdr.never_index == 1) 1764assert(hdr.index == 0) 1765assert(isinstance(hdr.hdr_name, h2.HPackHdrString)) 1766assert(hdr.hdr_name.data == 'HPackZString(x-generated-by)') 1767assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 1768assert(hdr.hdr_value.data == 'HPackLiteralString(Me)') 1769hdr = p.hdrs[7] 1770assert(isinstance(hdr, h2.HPackIndexedHdr)) 1771assert(hdr.magic == 1) 1772assert(hdr.index == 63) 1773hdr = p.hdrs[8] 1774assert(isinstance(hdr, h2.HPackLitHdrFldWithIncrIndexing)) 1775assert(hdr.magic == 1) 1776assert(hdr.index == 0) 1777assert(isinstance(hdr.hdr_name, h2.HPackHdrString)) 1778assert(hdr.hdr_name.data == 'HPackZString(x-generation-software)') 1779assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 1780assert(hdr.hdr_value.data == 'HPackZString(scapy)') 1781 1782p = seq.frames[1] 1783assert(isinstance(p, h2.H2Frame)) 1784assert(p.type == 0) 1785assert(len(p.flags) == 1) 1786assert('ES' in p.flags) 1787assert(p.stream_id == 1) 1788assert(isinstance(p.payload, h2.H2DataFrame)) 1789pay = p[h2.H2DataFrame] 1790assert(pay.data == body) 1791 1792= HTTP/2 HPackHdrTable : Parsing Textual Representation without body 1793~ http2 hpack hpackhdrtable helpers 1794 1795hdrs = b''':method POST 1796:path /login.php 1797:scheme https 1798user-agent: Mozilla/5.0 Generated by hand 1799x-generated-by: Me 1800x-generation-date: 2016-08-11 1801''' 1802 1803h = h2.HPackHdrTable() 1804h.register(h2.HPackLitHdrFldWithIncrIndexing( 1805 hdr_name=h2.HPackHdrString(data=h2.HPackZString('X-Generation-Date')), 1806 hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('2016-08-11')) 1807)) 1808 1809# Without body 1810seq = h.parse_txt_hdrs(hdrs, stream_id=1) 1811assert(isinstance(seq, h2.H2Seq)) 1812#This is the first major difference with the first test 1813assert(len(seq.frames) == 1) 1814p = seq.frames[0] 1815assert(isinstance(p, h2.H2Frame)) 1816assert(p.type == 1) 1817assert(len(p.flags) == 2) 1818assert('EH' in p.flags) 1819#This is the second major difference with the first test 1820assert('ES' in p.flags) 1821assert(p.stream_id == 1) 1822assert(isinstance(p.payload, h2.H2HeadersFrame)) 1823hdrs_frm = p[h2.H2HeadersFrame] 1824assert(len(p.hdrs) == 6) 1825hdr = p.hdrs[0] 1826assert(isinstance(hdr, h2.HPackIndexedHdr)) 1827assert(hdr.magic == 1) 1828assert(hdr.index == 3) 1829hdr = p.hdrs[1] 1830assert(isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)) 1831assert(hdr.magic == 0) 1832assert(hdr.never_index == 0) 1833assert(hdr.index in [4, 5]) 1834assert(hdr.hdr_name is None) 1835assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 1836assert(hdr.hdr_value.data == 'HPackZString(/login.php)') 1837hdr = p.hdrs[2] 1838assert(isinstance(hdr, h2.HPackIndexedHdr)) 1839assert(hdr.magic == 1) 1840assert(hdr.index == 7) 1841hdr = p.hdrs[3] 1842assert(isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)) 1843assert(hdr.magic == 0) 1844assert(hdr.never_index == 0) 1845assert(hdr.index == 58) 1846assert(hdr.hdr_name is None) 1847assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 1848assert(hdr.hdr_value.data == 'HPackZString(Mozilla/5.0 Generated by hand)') 1849hdr = p.hdrs[4] 1850assert(isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)) 1851assert(hdr.magic == 0) 1852assert(hdr.never_index == 0) 1853assert(hdr.index == 0) 1854assert(isinstance(hdr.hdr_name, h2.HPackHdrString)) 1855assert(hdr.hdr_name.data == 'HPackZString(x-generated-by)') 1856assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 1857assert(hdr.hdr_value.data == 'HPackLiteralString(Me)') 1858hdr = p.hdrs[5] 1859assert(isinstance(hdr, h2.HPackIndexedHdr)) 1860assert(hdr.magic == 1) 1861assert(hdr.index == 62) 1862 1863 1864= HTTP/2 HPackHdrTable : Parsing Textual Representation with too small max frame 1865~ http2 hpack hpackhdrtable helpers 1866 1867body = b'login=titi&passwd=toto' 1868hdrs = raw(''':method POST 1869:path /login.php 1870:scheme https 1871content-type: application/x-www-form-urlencoded 1872content-length: {} 1873user-agent: Mozilla/5.0 Generated by hand 1874x-generated-by: Me 1875x-generation-date: 2016-08-11 1876x-long-header: {} 1877'''.format(len(body), 'a'*5000)) 1878 1879h = h2.HPackHdrTable() 1880h.register(h2.HPackLitHdrFldWithIncrIndexing( 1881 hdr_name=h2.HPackHdrString(data=h2.HPackZString('X-Generation-Date')), 1882 hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('2016-08-11')) 1883)) 1884 1885#x-long-header is too long to fit in any frames (whose default max size is 4096) 1886expect_exception(Exception, "seq = h.parse_txt_hdrs('''{}''', stream_id=1".format(hdrs)) 1887 1888= HTTP/2 HPackHdrTable : Parsing Textual Representation with very large header and a large authorized frame size 1889~ http2 hpack hpackhdrtable helpers 1890 1891body = b'login=titi&passwd=toto' 1892hdrs = raw(''':method POST 1893:path /login.php 1894:scheme https 1895content-type: application/x-www-form-urlencoded 1896content-length: {} 1897user-agent: Mozilla/5.0 Generated by hand 1898x-generated-by: Me 1899x-generation-date: 2016-08-11 1900x-long-header: {} 1901'''.format(len(body), 'a'*5000)) 1902 1903h = h2.HPackHdrTable() 1904h.register(h2.HPackLitHdrFldWithIncrIndexing( 1905 hdr_name=h2.HPackHdrString(data=h2.HPackZString('X-Generation-Date')), 1906 hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('2016-08-11')) 1907)) 1908 1909# Now trying to parse it with a max frame size large enough for x-long-header to 1910# fit in a frame 1911seq = h.parse_txt_hdrs(hdrs, stream_id=1, max_frm_sz=8192) 1912assert(isinstance(seq, h2.H2Seq)) 1913assert(len(seq.frames) == 1) 1914p = seq.frames[0] 1915assert(isinstance(p, h2.H2Frame)) 1916assert(p.type == 1) 1917assert(len(p.flags) == 2) 1918assert('EH' in p.flags) 1919assert('ES' in p.flags) 1920assert(p.stream_id == 1) 1921assert(isinstance(p.payload, h2.H2HeadersFrame)) 1922hdrs_frm = p[h2.H2HeadersFrame] 1923assert(len(p.hdrs) == 9) 1924hdr = p.hdrs[0] 1925assert(isinstance(hdr, h2.HPackIndexedHdr)) 1926assert(hdr.magic == 1) 1927assert(hdr.index == 3) 1928hdr = p.hdrs[1] 1929assert(isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)) 1930assert(hdr.magic == 0) 1931assert(hdr.never_index == 0) 1932assert(hdr.index in [4, 5]) 1933assert(hdr.hdr_name is None) 1934assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 1935assert(hdr.hdr_value.data == 'HPackZString(/login.php)') 1936hdr = p.hdrs[2] 1937assert(isinstance(hdr, h2.HPackIndexedHdr)) 1938assert(hdr.magic == 1) 1939assert(hdr.index == 7) 1940hdr = p.hdrs[3] 1941assert(isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)) 1942assert(hdr.magic == 0) 1943assert(hdr.never_index == 0) 1944assert(hdr.index == 31) 1945assert(hdr.hdr_name is None) 1946assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 1947assert(hdr.hdr_value.data == 'HPackZString(application/x-www-form-urlencoded)') 1948hdr = p.hdrs[4] 1949assert(isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)) 1950assert(hdr.magic == 0) 1951assert(hdr.never_index == 0) 1952assert(hdr.index == 28) 1953assert(hdr.hdr_name is None) 1954assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 1955assert(hdr.hdr_value.data == 'HPackLiteralString(22)') 1956hdr = p.hdrs[5] 1957assert(isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)) 1958assert(hdr.magic == 0) 1959assert(hdr.never_index == 0) 1960assert(hdr.index == 58) 1961assert(hdr.hdr_name is None) 1962assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 1963assert(hdr.hdr_value.data == 'HPackZString(Mozilla/5.0 Generated by hand)') 1964hdr = p.hdrs[6] 1965assert(isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)) 1966assert(hdr.magic == 0) 1967assert(hdr.never_index == 0) 1968assert(hdr.index == 0) 1969assert(isinstance(hdr.hdr_name, h2.HPackHdrString)) 1970assert(hdr.hdr_name.data == 'HPackZString(x-generated-by)') 1971assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 1972assert(hdr.hdr_value.data == 'HPackLiteralString(Me)') 1973hdr = p.hdrs[7] 1974assert(isinstance(hdr, h2.HPackIndexedHdr)) 1975assert(hdr.magic == 1) 1976assert(hdr.index == 62) 1977hdr = p.hdrs[8] 1978assert(isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)) 1979assert(hdr.magic == 0) 1980assert(hdr.never_index == 0) 1981assert(hdr.index == 0) 1982assert(isinstance(hdr.hdr_name, h2.HPackHdrString)) 1983assert(hdr.hdr_name.data == 'HPackZString(x-long-header)') 1984assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 1985assert(hdr.hdr_value.data == 'HPackZString({})'.format('a'*5000)) 1986 1987= HTTP/2 HPackHdrTable : Parsing Textual Representation with two very large headers and a large authorized frame size 1988~ http2 hpack hpackhdrtable helpers 1989 1990body = b'login=titi&passwd=toto' 1991hdrs = raw(''':method POST 1992:path /login.php 1993:scheme https 1994content-type: application/x-www-form-urlencoded 1995content-length: {} 1996user-agent: Mozilla/5.0 Generated by hand 1997x-generated-by: Me 1998x-generation-date: 2016-08-11 1999x-long-header: {} 2000x-long-header: {} 2001'''.format(len(body), 'a'*5000, 'b'*5000)) 2002 2003h = h2.HPackHdrTable() 2004h.register(h2.HPackLitHdrFldWithIncrIndexing( 2005 hdr_name=h2.HPackHdrString(data=h2.HPackZString('X-Generation-Date')), 2006 hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('2016-08-11')) 2007)) 2008 2009# Now trying to parse it with a max frame size large enough for x-long-header to 2010# fit in a frame but a maximum header fragment size that is not large enough to 2011# store two x-long-header 2012seq = h.parse_txt_hdrs(hdrs, stream_id=1, max_frm_sz=8192) 2013assert(isinstance(seq, h2.H2Seq)) 2014assert(len(seq.frames) == 2) 2015p = seq.frames[0] 2016assert(isinstance(p, h2.H2Frame)) 2017assert(p.type == 1) 2018assert(len(p.flags) == 1) 2019assert('ES' in p.flags) 2020assert(p.stream_id == 1) 2021assert(isinstance(p.payload, h2.H2HeadersFrame)) 2022hdrs_frm = p[h2.H2HeadersFrame] 2023assert(len(p.hdrs) == 9) 2024hdr = p.hdrs[0] 2025assert(isinstance(hdr, h2.HPackIndexedHdr)) 2026assert(hdr.magic == 1) 2027assert(hdr.index == 3) 2028hdr = p.hdrs[1] 2029assert(isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)) 2030assert(hdr.magic == 0) 2031assert(hdr.never_index == 0) 2032assert(hdr.index in [4, 5]) 2033assert(hdr.hdr_name is None) 2034assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 2035assert(hdr.hdr_value.data == 'HPackZString(/login.php)') 2036hdr = p.hdrs[2] 2037assert(isinstance(hdr, h2.HPackIndexedHdr)) 2038assert(hdr.magic == 1) 2039assert(hdr.index == 7) 2040hdr = p.hdrs[3] 2041assert(isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)) 2042assert(hdr.magic == 0) 2043assert(hdr.never_index == 0) 2044assert(hdr.index == 31) 2045assert(hdr.hdr_name is None) 2046assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 2047assert(hdr.hdr_value.data == 'HPackZString(application/x-www-form-urlencoded)') 2048hdr = p.hdrs[4] 2049assert(isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)) 2050assert(hdr.magic == 0) 2051assert(hdr.never_index == 0) 2052assert(hdr.index == 28) 2053assert(hdr.hdr_name is None) 2054assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 2055assert(hdr.hdr_value.data == 'HPackLiteralString(22)') 2056hdr = p.hdrs[5] 2057assert(isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)) 2058assert(hdr.magic == 0) 2059assert(hdr.never_index == 0) 2060assert(hdr.index == 58) 2061assert(hdr.hdr_name is None) 2062assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 2063assert(hdr.hdr_value.data == 'HPackZString(Mozilla/5.0 Generated by hand)') 2064hdr = p.hdrs[6] 2065assert(isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)) 2066assert(hdr.magic == 0) 2067assert(hdr.never_index == 0) 2068assert(hdr.index == 0) 2069assert(isinstance(hdr.hdr_name, h2.HPackHdrString)) 2070assert(hdr.hdr_name.data == 'HPackZString(x-generated-by)') 2071assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 2072assert(hdr.hdr_value.data == 'HPackLiteralString(Me)') 2073hdr = p.hdrs[7] 2074assert(isinstance(hdr, h2.HPackIndexedHdr)) 2075assert(hdr.magic == 1) 2076assert(hdr.index == 62) 2077hdr = p.hdrs[8] 2078assert(isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)) 2079assert(hdr.magic == 0) 2080assert(hdr.never_index == 0) 2081assert(hdr.index == 0) 2082assert(isinstance(hdr.hdr_name, h2.HPackHdrString)) 2083assert(hdr.hdr_name.data == 'HPackZString(x-long-header)') 2084assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 2085assert(hdr.hdr_value.data == 'HPackZString({})'.format('a'*5000)) 2086p = seq.frames[1] 2087assert(isinstance(p, h2.H2Frame)) 2088assert(p.type == 9) 2089assert(len(p.flags) == 1) 2090assert('EH' in p.flags) 2091assert(p.stream_id == 1) 2092assert(isinstance(p.payload, h2.H2ContinuationFrame)) 2093hdrs_frm = p[h2.H2ContinuationFrame] 2094assert(len(p.hdrs) == 1) 2095hdr = p.hdrs[0] 2096assert(isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)) 2097assert(hdr.magic == 0) 2098assert(hdr.never_index == 0) 2099assert(hdr.index == 0) 2100assert(isinstance(hdr.hdr_name, h2.HPackHdrString)) 2101assert(hdr.hdr_name.data == 'HPackZString(x-long-header)') 2102assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 2103assert(hdr.hdr_value.data == 'HPackZString({})'.format('b'*5000)) 2104 2105= HTTP/2 HPackHdrTable : Parsing Textual Representation with two very large headers, a large authorized frame size and a "small" max header list size 2106~ http2 hpack hpackhdrtable helpers 2107 2108body = b'login=titi&passwd=toto' 2109hdrs = raw(''':method POST 2110:path /login.php 2111:scheme https 2112content-type: application/x-www-form-urlencoded 2113content-length: {} 2114user-agent: Mozilla/5.0 Generated by hand 2115x-generated-by: Me 2116x-generation-date: 2016-08-11 2117x-long-header: {} 2118x-long-header: {} 2119'''.format(len(body), 'a'*5000, 'b'*5000)) 2120 2121h = h2.HPackHdrTable() 2122h.register(h2.HPackLitHdrFldWithIncrIndexing( 2123 hdr_name=h2.HPackHdrString(data=h2.HPackZString('X-Generation-Date')), 2124 hdr_value=h2.HPackHdrString(data=h2.HPackLiteralString('2016-08-11')) 2125)) 2126 2127# Now trying to parse it with a max frame size large enough for x-long-header to 2128# fit in a frame but and a max header list size that is large enough to fit one 2129# but not two 2130seq = h.parse_txt_hdrs(hdrs, stream_id=1, max_frm_sz=8192, max_hdr_lst_sz=5050) 2131assert(isinstance(seq, h2.H2Seq)) 2132assert(len(seq.frames) == 3) 2133p = seq.frames[0] 2134assert(isinstance(p, h2.H2Frame)) 2135assert(p.type == 1) 2136assert(len(p.flags) == 1) 2137assert('ES' in p.flags) 2138assert(p.stream_id == 1) 2139assert(isinstance(p.payload, h2.H2HeadersFrame)) 2140hdrs_frm = p[h2.H2HeadersFrame] 2141assert(len(p.hdrs) == 8) 2142hdr = p.hdrs[0] 2143assert(isinstance(hdr, h2.HPackIndexedHdr)) 2144assert(hdr.magic == 1) 2145assert(hdr.index == 3) 2146hdr = p.hdrs[1] 2147assert(isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)) 2148assert(hdr.magic == 0) 2149assert(hdr.never_index == 0) 2150assert(hdr.index in [4, 5]) 2151assert(hdr.hdr_name is None) 2152assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 2153assert(hdr.hdr_value.data == 'HPackZString(/login.php)') 2154hdr = p.hdrs[2] 2155assert(isinstance(hdr, h2.HPackIndexedHdr)) 2156assert(hdr.magic == 1) 2157assert(hdr.index == 7) 2158hdr = p.hdrs[3] 2159assert(isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)) 2160assert(hdr.magic == 0) 2161assert(hdr.never_index == 0) 2162assert(hdr.index == 31) 2163assert(hdr.hdr_name is None) 2164assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 2165assert(hdr.hdr_value.data == 'HPackZString(application/x-www-form-urlencoded)') 2166hdr = p.hdrs[4] 2167assert(isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)) 2168assert(hdr.magic == 0) 2169assert(hdr.never_index == 0) 2170assert(hdr.index == 28) 2171assert(hdr.hdr_name is None) 2172assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 2173assert(hdr.hdr_value.data == 'HPackLiteralString(22)') 2174hdr = p.hdrs[5] 2175assert(isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)) 2176assert(hdr.magic == 0) 2177assert(hdr.never_index == 0) 2178assert(hdr.index == 58) 2179assert(hdr.hdr_name is None) 2180assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 2181assert(hdr.hdr_value.data == 'HPackZString(Mozilla/5.0 Generated by hand)') 2182hdr = p.hdrs[6] 2183assert(isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)) 2184assert(hdr.magic == 0) 2185assert(hdr.never_index == 0) 2186assert(hdr.index == 0) 2187assert(isinstance(hdr.hdr_name, h2.HPackHdrString)) 2188assert(hdr.hdr_name.data == 'HPackZString(x-generated-by)') 2189assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 2190assert(hdr.hdr_value.data == 'HPackLiteralString(Me)') 2191hdr = p.hdrs[7] 2192assert(isinstance(hdr, h2.HPackIndexedHdr)) 2193assert(hdr.magic == 1) 2194assert(hdr.index == 62) 2195p = seq.frames[1] 2196assert(isinstance(p, h2.H2Frame)) 2197assert(p.type == 9) 2198assert(len(p.flags) == 0) 2199assert(p.stream_id == 1) 2200assert(isinstance(p.payload, h2.H2ContinuationFrame)) 2201hdrs_frm = p[h2.H2ContinuationFrame] 2202assert(len(p.hdrs) == 1) 2203hdr = p.hdrs[0] 2204assert(isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)) 2205assert(hdr.magic == 0) 2206assert(hdr.never_index == 0) 2207assert(hdr.index == 0) 2208assert(isinstance(hdr.hdr_name, h2.HPackHdrString)) 2209assert(hdr.hdr_name.data == 'HPackZString(x-long-header)') 2210assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 2211assert(hdr.hdr_value.data == 'HPackZString({})'.format('a'*5000)) 2212p = seq.frames[2] 2213assert(isinstance(p, h2.H2Frame)) 2214assert(p.type == 9) 2215assert(len(p.flags) == 1) 2216assert('EH' in p.flags) 2217assert(p.stream_id == 1) 2218assert(isinstance(p.payload, h2.H2ContinuationFrame)) 2219hdrs_frm = p[h2.H2ContinuationFrame] 2220assert(len(p.hdrs) == 1) 2221hdr = p.hdrs[0] 2222assert(isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)) 2223assert(hdr.magic == 0) 2224assert(hdr.never_index == 0) 2225assert(hdr.index == 0) 2226assert(isinstance(hdr.hdr_name, h2.HPackHdrString)) 2227assert(hdr.hdr_name.data == 'HPackZString(x-long-header)') 2228assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 2229assert(hdr.hdr_value.data == 'HPackZString({})'.format('b'*5000)) 2230 2231= HTTP/2 HPackHdrTable : Parsing Textual Representation with sensitive headers and non-indexable ones 2232~ http2 hpack hpackhdrtable helpers 2233 2234hdrs = raw(''':method POST 2235:path /login.php 2236:scheme https 2237content-type: application/x-www-form-urlencoded 2238content-length: {} 2239user-agent: Mozilla/5.0 Generated by hand 2240x-generated-by: Me 2241x-generation-date: 2016-08-11 2242'''.format(len(body))) 2243 2244h = h2.HPackHdrTable() 2245seq = 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') 2246assert(isinstance(seq, h2.H2Seq)) 2247assert(len(seq.frames) == 2) 2248p = seq.frames[0] 2249assert(isinstance(p, h2.H2Frame)) 2250assert(p.type == 1) 2251assert(len(p.flags) == 1) 2252assert('EH' in p.flags) 2253assert(p.stream_id == 1) 2254assert(isinstance(p.payload, h2.H2HeadersFrame)) 2255hdrs_frm = p[h2.H2HeadersFrame] 2256assert(len(p.hdrs) == 8) 2257hdr = p.hdrs[0] 2258assert(isinstance(hdr, h2.HPackIndexedHdr)) 2259assert(hdr.magic == 1) 2260assert(hdr.index == 3) 2261hdr = p.hdrs[1] 2262assert(isinstance(hdr, h2.HPackLitHdrFldWithIncrIndexing)) 2263assert(hdr.magic == 1) 2264assert(hdr.index in [4, 5]) 2265assert(hdr.hdr_name is None) 2266assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 2267assert(hdr.hdr_value.data == 'HPackZString(/login.php)') 2268hdr = p.hdrs[2] 2269assert(isinstance(hdr, h2.HPackIndexedHdr)) 2270assert(hdr.magic == 1) 2271assert(hdr.index == 7) 2272hdr = p.hdrs[3] 2273assert(isinstance(hdr, h2.HPackLitHdrFldWithIncrIndexing)) 2274assert(hdr.magic == 1) 2275assert(hdr.index == 31) 2276assert(hdr.hdr_name is None) 2277assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 2278assert(hdr.hdr_value.data == 'HPackZString(application/x-www-form-urlencoded)') 2279hdr = p.hdrs[4] 2280assert(isinstance(hdr, h2.HPackLitHdrFldWithIncrIndexing)) 2281assert(hdr.magic == 1) 2282assert(hdr.index == 28) 2283assert(hdr.hdr_name is None) 2284assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 2285assert(hdr.hdr_value.data == 'HPackLiteralString(22)') 2286hdr = p.hdrs[5] 2287assert(isinstance(hdr, h2.HPackLitHdrFldWithIncrIndexing)) 2288assert(hdr.magic == 1) 2289assert(hdr.index == 58) 2290assert(hdr.hdr_name is None) 2291assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 2292assert(hdr.hdr_value.data == 'HPackZString(Mozilla/5.0 Generated by hand)') 2293hdr = p.hdrs[6] 2294assert(isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)) 2295assert(hdr.magic == 0) 2296assert(hdr.never_index == 0) 2297assert(hdr.index == 0) 2298assert(isinstance(hdr.hdr_name, h2.HPackHdrString)) 2299assert(hdr.hdr_name.data == 'HPackZString(x-generated-by)') 2300assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 2301assert(hdr.hdr_value.data == 'HPackLiteralString(Me)') 2302hdr = p.hdrs[7] 2303assert(isinstance(hdr, h2.HPackLitHdrFldWithoutIndexing)) 2304assert(hdr.magic == 0) 2305assert(hdr.never_index == 1) 2306assert(hdr.index == 0) 2307assert(isinstance(hdr.hdr_name, h2.HPackHdrString)) 2308assert(hdr.hdr_name.data == 'HPackZString(x-generation-date)') 2309assert(isinstance(hdr.hdr_value, h2.HPackHdrString)) 2310assert(hdr.hdr_value.data == 'HPackZString(2016-08-11)') 2311p = seq.frames[1] 2312assert(isinstance(p, h2.H2Frame)) 2313assert(p.type == 0) 2314assert(len(p.flags) == 1) 2315assert('ES' in p.flags) 2316assert(p.stream_id == 1) 2317assert(isinstance(p.payload, h2.H2DataFrame)) 2318pay = p[h2.H2DataFrame] 2319assert(pay.data == body) 2320