You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

116 lines
2.6 KiB

4 years ago
  1. var hpack = require('../hpack');
  2. var utils = hpack.utils;
  3. var decoder = hpack.decoder;
  4. var table = hpack.table;
  5. var assert = utils.assert;
  6. var inherits = require('inherits');
  7. var Duplex = require('readable-stream').Duplex;
  8. function Decompressor(options) {
  9. Duplex.call(this, {
  10. readableObjectMode: true
  11. });
  12. this._decoder = decoder.create();
  13. this._table = table.create(options.table);
  14. }
  15. inherits(Decompressor, Duplex);
  16. module.exports = Decompressor;
  17. Decompressor.create = function create(options) {
  18. return new Decompressor(options);
  19. };
  20. Decompressor.prototype._read = function _read() {
  21. // We only push!
  22. };
  23. Decompressor.prototype._write = function _write(data, enc, cb) {
  24. this._decoder.push(data);
  25. cb(null);
  26. };
  27. Decompressor.prototype.execute = function execute(cb) {
  28. while (!this._decoder.isEmpty()) {
  29. try {
  30. this._execute();
  31. } catch (err) {
  32. if (cb)
  33. return done(err);
  34. else
  35. return this.emit('error', err);
  36. }
  37. }
  38. if (cb)
  39. done(null);
  40. function done(err) {
  41. process.nextTick(function() {
  42. cb(err);
  43. });
  44. }
  45. };
  46. Decompressor.prototype.updateTableSize = function updateTableSize(size) {
  47. this._table.updateSize(size);
  48. };
  49. Decompressor.prototype._execute = function _execute() {
  50. var isIndexed = this._decoder.decodeBit();
  51. if (isIndexed)
  52. return this._processIndexed();
  53. var isIncremental = this._decoder.decodeBit();
  54. var neverIndex = 0;
  55. if (!isIncremental) {
  56. var isUpdate = this._decoder.decodeBit();
  57. if (isUpdate)
  58. return this._processUpdate();
  59. neverIndex = this._decoder.decodeBit();
  60. }
  61. this._processLiteral(isIncremental, neverIndex);
  62. };
  63. Decompressor.prototype._processIndexed = function _processIndexed() {
  64. var index = this._decoder.decodeInt();
  65. var lookup = this._table.lookup(index);
  66. this.push({ name: lookup.name, value: lookup.value, neverIndex: false });
  67. };
  68. Decompressor.prototype._processLiteral = function _processLiteral(inc, never) {
  69. var index = this._decoder.decodeInt();
  70. var name;
  71. var nameSize;
  72. // Literal header-name too
  73. if (index === 0) {
  74. name = this._decoder.decodeStr();
  75. nameSize = name.length;
  76. name = utils.stringify(name);
  77. } else {
  78. var lookup = this._table.lookup(index);
  79. nameSize = lookup.nameSize;
  80. name = lookup.name;
  81. }
  82. var value = this._decoder.decodeStr();
  83. var valueSize = value.length;
  84. value = utils.stringify(value);
  85. if (inc)
  86. this._table.add(name, value, nameSize, valueSize);
  87. this.push({ name: name, value: value, neverIndex: never !== 0});
  88. };
  89. Decompressor.prototype._processUpdate = function _processUpdate() {
  90. var size = this._decoder.decodeInt();
  91. this.updateTableSize(size);
  92. };