grpc-libp2p-client 0.0.38 → 0.0.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -268,7 +268,6 @@ export class HPACK {
268
268
  this.dynamicTable.unshift([name, value]);
269
269
  this.dynamicTableSize += size;
270
270
  }
271
- this.dynamicTable.push([name, value]);
272
271
  }
273
272
 
274
273
  // 获取索引的头部
@@ -393,6 +392,9 @@ export class HPACK {
393
392
  // Huffman编码实现
394
393
  huffmanEncode(bytes: Uint8Array) {
395
394
  const result : number[] = [];
395
+ // 使用高精度浮点数累积位,避免 JS 32-bit 有符号整数在位数 >31 时溢出。
396
+ // Huffman 码最长 30 bits,加上未输出的最多 7 bits = 37 bits,超过 32-bit 安全范围。
397
+ // Number 可精确表示 2^53 以内的整数,足够累积多个码字。
396
398
  let current = 0;
397
399
  let bits = 0;
398
400
 
@@ -401,18 +403,22 @@ export class HPACK {
401
403
  const code = this.huffmanTable.codes[b];
402
404
  const length = this.huffmanTable.lengths[b];
403
405
 
406
+ // 用乘法左移替代 <<,避免 32-bit 截断
407
+ current = current * (1 << length) + code;
404
408
  bits += length;
405
- current = (current << length) | code;
406
409
 
407
410
  while (bits >= 8) {
408
411
  bits -= 8;
409
- result.push((current >> bits) & 0xFF);
412
+ result.push(Math.floor(current / (1 << bits)) & 0xFF);
413
+ // 保留低 bits 位
414
+ current = current % (1 << bits);
410
415
  }
411
416
  }
412
417
 
413
- // 处理剩余的位
418
+ // 处理剩余的位(用 EOS 填充 1)
414
419
  if (bits > 0) {
415
- current = (current << (8 - bits)) | ((1 << (8 - bits)) - 1);
420
+ const pad = 8 - bits;
421
+ current = current * (1 << pad) + ((1 << pad) - 1);
416
422
  result.push(current & 0xFF);
417
423
  }
418
424
 
@@ -438,8 +444,15 @@ export class HPACK {
438
444
  if (name && value) headers.set(name, value);
439
445
  index = newIndex;
440
446
  }
441
- else if ((firstByte & 0x20) !== 0) { // 001xxxxx - Dynamic Table Size Update
442
- index++; // 简单跳过,实际应该更新动态表大小
447
+ else if ((firstByte & 0x20) !== 0) { // 001xxxxx - Dynamic Table Size Update (RFC 7541 §6.3)
448
+ const [newSize, newIndex] = this.decodeInteger(buffer, index, 5);
449
+ this.maxDynamicTableSize = newSize;
450
+ // evict entries that exceed the new limit
451
+ while (this.dynamicTableSize > this.maxDynamicTableSize && this.dynamicTable.length > 0) {
452
+ const entry = this.dynamicTable.pop();
453
+ if (entry) this.dynamicTableSize -= entry[0].length + entry[1].length + 32;
454
+ }
455
+ index = newIndex;
443
456
  }
444
457
  else if ((firstByte & 0x10) !== 0) { // 0001xxxx - Literal Header Field Never Indexed
445
458
  const [name, value, newIndex] = this.decodeLiteralHeaderWithoutIndexing(buffer, index);
@@ -521,7 +534,7 @@ export class HPACK {
521
534
  return ['', '', newIndex];
522
535
  }
523
536
 
524
- const headerField = this.staticTable[staticIndex];
537
+ const headerField = this.getIndexedHeader(staticIndex);
525
538
  if (!headerField) {
526
539
  return ['', '', newIndex];
527
540
  }
@@ -530,12 +543,12 @@ export class HPACK {
530
543
  }
531
544
 
532
545
  decodeLiteralHeaderWithIndexing(buffer:Uint8Array, index:number):[string, string, number] {
533
- const [staticIndex, nameIndex] = this.decodeInteger(buffer, index, 6);
534
- index = nameIndex;
546
+ const [nameIndex, nextIndex] = this.decodeInteger(buffer, index, 6);
547
+ index = nextIndex;
535
548
 
536
549
  let name;
537
- if (staticIndex > 0) {
538
- const headerField = this.staticTable[staticIndex];
550
+ if (nameIndex > 0) {
551
+ const headerField = this.getIndexedHeader(nameIndex);
539
552
  name = headerField ? headerField[0] : '';
540
553
  } else {
541
554
  const [decodedName, newIndex] = this.decodeLiteralString(buffer, index);
@@ -544,11 +557,28 @@ export class HPACK {
544
557
  }
545
558
 
546
559
  const [value, finalIndex] = this.decodeLiteralString(buffer, index);
560
+ // RFC 7541 §6.2.1: Literal Header Field with Incremental Indexing must add to dynamic table
561
+ this.addToDynamicTable(name, value);
547
562
  return [name, value, finalIndex];
548
563
  }
549
564
 
550
565
  decodeLiteralHeaderWithoutIndexing(buffer:Uint8Array, index:number): [string, string, number] {
551
- return this.decodeLiteralHeaderWithIndexing(buffer, index);
566
+ // RFC 7541 §6.2.2 / §6.2.3: 4-bit prefix, do NOT add to dynamic table
567
+ const [nameIndex, nextIndex] = this.decodeInteger(buffer, index, 4);
568
+ index = nextIndex;
569
+
570
+ let name;
571
+ if (nameIndex > 0) {
572
+ const headerField = this.getIndexedHeader(nameIndex);
573
+ name = headerField ? headerField[0] : '';
574
+ } else {
575
+ const [decodedName, newIndex] = this.decodeLiteralString(buffer, index);
576
+ name = decodedName;
577
+ index = newIndex;
578
+ }
579
+
580
+ const [value, finalIndex] = this.decodeLiteralString(buffer, index);
581
+ return [name, value, finalIndex];
552
582
  }
553
583
 
554
584