draft: refactor project so it sits on top of a standalone app
This commit is contained in:
+2
@@ -0,0 +1,2 @@
|
||||
node_modules/
|
||||
npm-debug.log
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "iojs"
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
# HPACK.js
|
||||
|
||||
[](http://travis-ci.org/indutny/hpack.js)
|
||||
[](http://badge.fury.io/js/hpack.js)
|
||||
|
||||
Plain-JS implementation of [HPACK][0].
|
||||
|
||||
## Usage
|
||||
|
||||
```javascript
|
||||
var hpack = require('hpack.js');
|
||||
|
||||
var comp = hpack.compressor.create({ table: { size: 256 } });
|
||||
var decomp = hpack.decompressor.create({ table: { size: 256 } });
|
||||
|
||||
comp.write([ { name: 'host', value: 'localhost' } ]);
|
||||
var raw = comp.read();
|
||||
console.log(raw);
|
||||
// <Buffer 66 86 a0 e4 1d 13 9d 09>
|
||||
|
||||
decomp.write(raw);
|
||||
decomp.execute();
|
||||
console.log(decomp.read());
|
||||
// { name: 'host', value: 'localhost', neverIndex: false }
|
||||
```
|
||||
|
||||
#### LICENSE
|
||||
|
||||
This software is licensed under the MIT License.
|
||||
|
||||
Copyright Fedor Indutny, 2015.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included
|
||||
in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
||||
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
[0]: https://tools.ietf.org/html/rfc7541
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env node
|
||||
var hpack = require('../');
|
||||
|
||||
var options = {
|
||||
table: { size: 1024 }
|
||||
};
|
||||
|
||||
var compressor = hpack.compressor.create(options);
|
||||
|
||||
var vector = [];
|
||||
for (var i = 0; i < 1024; i++) {
|
||||
vector.push({
|
||||
name: 'kind-of-big-header-name__',
|
||||
value: 'not-so-small value yes!',
|
||||
huffman: true,
|
||||
neverIndex: true
|
||||
});
|
||||
}
|
||||
compressor.write(vector);
|
||||
var input = compressor.read();
|
||||
|
||||
console.time('decompressor');
|
||||
for (var i = 0; i < 2000; i++) {
|
||||
var decompressor = hpack.decompressor.create(options);
|
||||
|
||||
decompressor.write(input);
|
||||
decompressor.execute();
|
||||
while (true) {
|
||||
var chunk = decompressor.read();
|
||||
if (!chunk)
|
||||
break;
|
||||
}
|
||||
}
|
||||
console.timeEnd('decompressor');
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
var hpack = exports;
|
||||
|
||||
hpack.utils = require('./hpack/utils');
|
||||
hpack.huffman = require('./hpack/huffman');
|
||||
hpack['static-table'] = require('./hpack/static-table');
|
||||
hpack.table = require('./hpack/table');
|
||||
|
||||
hpack.decoder = require('./hpack/decoder');
|
||||
hpack.decompressor = require('./hpack/decompressor');
|
||||
|
||||
hpack.encoder = require('./hpack/encoder');
|
||||
hpack.compressor = require('./hpack/compressor');
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
var hpack = require('../hpack');
|
||||
var utils = hpack.utils;
|
||||
var encoder = hpack.encoder;
|
||||
var table = hpack.table;
|
||||
var assert = utils.assert;
|
||||
|
||||
var inherits = require('inherits');
|
||||
var Duplex = require('readable-stream').Duplex;
|
||||
|
||||
function Compressor(options) {
|
||||
Duplex.call(this, {
|
||||
writableObjectMode: true
|
||||
});
|
||||
|
||||
this._encoder = null;
|
||||
this._table = table.create(options.table);
|
||||
}
|
||||
inherits(Compressor, Duplex);
|
||||
module.exports = Compressor;
|
||||
|
||||
Compressor.create = function create(options) {
|
||||
return new Compressor(options);
|
||||
};
|
||||
|
||||
Compressor.prototype._read = function _read() {
|
||||
// We only push!
|
||||
};
|
||||
|
||||
Compressor.prototype._write = function _write(data, enc, cb) {
|
||||
assert(Array.isArray(data), 'Compressor.write() expects list of headers');
|
||||
|
||||
this._encoder = encoder.create();
|
||||
for (var i = 0; i < data.length; i++)
|
||||
this._encodeHeader(data[i]);
|
||||
|
||||
var data = this._encoder.render();
|
||||
this._encoder = null;
|
||||
|
||||
cb(null);
|
||||
for (var i = 0; i < data.length; i++)
|
||||
this.push(data[i]);
|
||||
};
|
||||
|
||||
Compressor.prototype.updateTableSize = function updateTableSize(size) {
|
||||
if (size >= this._table.protocolMaxSize) {
|
||||
size = this._table.protocolMaxSize;
|
||||
|
||||
var enc = encoder.create();
|
||||
|
||||
// indexed = 0
|
||||
// incremental = 0
|
||||
// update = 1
|
||||
enc.encodeBits(1, 3);
|
||||
enc.encodeInt(size);
|
||||
|
||||
var data = enc.render();
|
||||
for (var i = 0; i < data.length; i++)
|
||||
this.push(data[i]);
|
||||
}
|
||||
|
||||
this._table.updateSize(size);
|
||||
};
|
||||
|
||||
Compressor.prototype.reset = function reset() {
|
||||
var enc = encoder.create();
|
||||
var size = this._table.maxSize;
|
||||
|
||||
// indexed = 0
|
||||
// incremental = 0
|
||||
// update = 1
|
||||
enc.encodeBits(1, 3);
|
||||
enc.encodeInt(0);
|
||||
|
||||
// Evict everything
|
||||
this._table.updateSize(0);
|
||||
|
||||
// indexed = 0
|
||||
// incremental = 0
|
||||
// update = 1
|
||||
enc.encodeBits(1, 3);
|
||||
enc.encodeInt(size);
|
||||
|
||||
// Revert size
|
||||
this._table.updateSize(size);
|
||||
|
||||
var data = enc.render();
|
||||
for (var i = 0; i < data.length; i++)
|
||||
this.push(data[i]);
|
||||
};
|
||||
|
||||
Compressor.prototype._encodeHeader = function _encodeHeader(header) {
|
||||
if (header.neverIndex) {
|
||||
var index = 0;
|
||||
var neverIndex = 1;
|
||||
var isIndexed = 0;
|
||||
var isIncremental = 0;
|
||||
} else {
|
||||
var index = this._table.reverseLookup(header.name, header.value);
|
||||
var isIndexed = index > 0;
|
||||
var isIncremental = header.incremental !== false;
|
||||
var neverIndex = 0;
|
||||
}
|
||||
|
||||
this._encoder.encodeBit(isIndexed);
|
||||
if (isIndexed) {
|
||||
this._encoder.encodeInt(index);
|
||||
return;
|
||||
}
|
||||
|
||||
var name = utils.toArray(header.name);
|
||||
var value = utils.toArray(header.value);
|
||||
|
||||
this._encoder.encodeBit(isIncremental);
|
||||
if (isIncremental) {
|
||||
this._table.add(header.name, header.value, name.length, value.length);
|
||||
} else {
|
||||
// Update = false
|
||||
this._encoder.encodeBit(0);
|
||||
this._encoder.encodeBit(neverIndex);
|
||||
}
|
||||
|
||||
// index is negative for `name`-only headers
|
||||
this._encoder.encodeInt(-index);
|
||||
if (index === 0)
|
||||
this._encoder.encodeStr(name, header.huffman !== false);
|
||||
this._encoder.encodeStr(value, header.huffman !== false);
|
||||
};
|
||||
+169
@@ -0,0 +1,169 @@
|
||||
var hpack = require('../hpack');
|
||||
var utils = hpack.utils;
|
||||
var huffman = hpack.huffman.decode;
|
||||
var assert = utils.assert;
|
||||
|
||||
var OffsetBuffer = require('obuf');
|
||||
|
||||
function Decoder() {
|
||||
this.buffer = new OffsetBuffer();
|
||||
this.bitOffset = 0;
|
||||
|
||||
// Used internally in decodeStr
|
||||
this._huffmanNode = null;
|
||||
}
|
||||
module.exports = Decoder;
|
||||
|
||||
Decoder.create = function create() {
|
||||
return new Decoder();
|
||||
};
|
||||
|
||||
Decoder.prototype.isEmpty = function isEmpty() {
|
||||
return this.buffer.isEmpty();
|
||||
};
|
||||
|
||||
Decoder.prototype.push = function push(chunk) {
|
||||
this.buffer.push(chunk);
|
||||
};
|
||||
|
||||
Decoder.prototype.decodeBit = function decodeBit() {
|
||||
// Need at least one octet
|
||||
assert(this.buffer.has(1), 'Buffer too small for an int');
|
||||
|
||||
var octet;
|
||||
var offset = this.bitOffset;
|
||||
|
||||
if (++this.bitOffset === 8) {
|
||||
octet = this.buffer.readUInt8();
|
||||
this.bitOffset = 0;
|
||||
} else {
|
||||
octet = this.buffer.peekUInt8();
|
||||
}
|
||||
return (octet >>> (7 - offset)) & 1;
|
||||
};
|
||||
|
||||
// Just for testing
|
||||
Decoder.prototype.skipBits = function skipBits(n) {
|
||||
this.bitOffset += n;
|
||||
this.buffer.skip(this.bitOffset >> 3);
|
||||
this.bitOffset &= 0x7;
|
||||
};
|
||||
|
||||
Decoder.prototype.decodeInt = function decodeInt() {
|
||||
// Need at least one octet
|
||||
assert(this.buffer.has(1), 'Buffer too small for an int');
|
||||
|
||||
var prefix = 8 - this.bitOffset;
|
||||
|
||||
// We are going to end up octet-aligned
|
||||
this.bitOffset = 0;
|
||||
|
||||
var max = (1 << prefix) - 1;
|
||||
var octet = this.buffer.readUInt8() & max;
|
||||
|
||||
// Fast case - int fits into the prefix
|
||||
if (octet !== max)
|
||||
return octet;
|
||||
|
||||
// TODO(indutny): what about > 32bit numbers?
|
||||
var res = 0;
|
||||
var isLast = false;
|
||||
var len = 0;
|
||||
do {
|
||||
octet = this.buffer.readUInt8();
|
||||
isLast = (octet & 0x80) === 0;
|
||||
|
||||
res <<= 7;
|
||||
res |= octet & 0x7f;
|
||||
len++;
|
||||
} while (!isLast);
|
||||
assert(isLast, 'Incomplete data for multi-octet integer');
|
||||
assert(len <= 4, 'Integer does not fit into 32 bits');
|
||||
|
||||
// Reverse bits
|
||||
res = (res >>> 21) |
|
||||
(((res >> 14) & 0x7f) << 7) |
|
||||
(((res >> 7) & 0x7f) << 14) |
|
||||
((res & 0x7f) << 21);
|
||||
res >>= (4 - len) * 7;
|
||||
|
||||
// Append prefix max
|
||||
res += max;
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
Decoder.prototype.decodeHuffmanWord = function decodeHuffmanWord(input,
|
||||
inputBits,
|
||||
out) {
|
||||
var root = huffman;
|
||||
var node = this._huffmanNode;
|
||||
var word = input;
|
||||
var bits = inputBits;
|
||||
|
||||
for (; bits > 0; word &= (1 << bits) - 1) {
|
||||
// Nudge the word bit length to match it
|
||||
for (var i = Math.max(0, bits - 8); i < bits; i++) {
|
||||
var subnode = node[word >>> i];
|
||||
if (typeof subnode !== 'number') {
|
||||
node = subnode;
|
||||
bits = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (subnode === 0)
|
||||
continue;
|
||||
|
||||
// Word bit length should match
|
||||
if ((subnode >>> 9) !== bits - i) {
|
||||
subnode = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
var octet = subnode & 0x1ff;
|
||||
assert(octet !== 256, 'EOS in encoding');
|
||||
out.push(octet);
|
||||
node = root;
|
||||
|
||||
bits = i;
|
||||
break;
|
||||
}
|
||||
if (subnode === 0)
|
||||
break;
|
||||
}
|
||||
this._huffmanNode = node;
|
||||
|
||||
return bits;
|
||||
};
|
||||
|
||||
Decoder.prototype.decodeStr = function decodeStr() {
|
||||
var isHuffman = this.decodeBit();
|
||||
var len = this.decodeInt();
|
||||
assert(this.buffer.has(len), 'Not enough octets for string');
|
||||
|
||||
if (!isHuffman)
|
||||
return this.buffer.take(len);
|
||||
|
||||
this._huffmanNode = huffman;
|
||||
|
||||
var out = [];
|
||||
|
||||
var word = 0;
|
||||
var bits = 0;
|
||||
var lastKey = 0;
|
||||
for (var i = 0; i < len; i++) {
|
||||
word <<= 8;
|
||||
word |= this.buffer.readUInt8();
|
||||
bits += 8;
|
||||
|
||||
bits = this.decodeHuffmanWord(word, bits, out);
|
||||
lastKey = word >> bits;
|
||||
word &= (1 << bits) - 1;
|
||||
}
|
||||
assert(this._huffmanNode === huffman, '8-bit EOS');
|
||||
assert(word + 1 === (1 << bits), 'Final sequence is not EOS');
|
||||
|
||||
this._huffmanNode = null;
|
||||
|
||||
return out;
|
||||
};
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
var hpack = require('../hpack');
|
||||
var utils = hpack.utils;
|
||||
var decoder = hpack.decoder;
|
||||
var table = hpack.table;
|
||||
var assert = utils.assert;
|
||||
|
||||
var inherits = require('inherits');
|
||||
var Duplex = require('readable-stream').Duplex;
|
||||
|
||||
function Decompressor(options) {
|
||||
Duplex.call(this, {
|
||||
readableObjectMode: true
|
||||
});
|
||||
|
||||
this._decoder = decoder.create();
|
||||
this._table = table.create(options.table);
|
||||
}
|
||||
inherits(Decompressor, Duplex);
|
||||
module.exports = Decompressor;
|
||||
|
||||
Decompressor.create = function create(options) {
|
||||
return new Decompressor(options);
|
||||
};
|
||||
|
||||
Decompressor.prototype._read = function _read() {
|
||||
// We only push!
|
||||
};
|
||||
|
||||
Decompressor.prototype._write = function _write(data, enc, cb) {
|
||||
this._decoder.push(data);
|
||||
|
||||
cb(null);
|
||||
};
|
||||
|
||||
Decompressor.prototype.execute = function execute(cb) {
|
||||
while (!this._decoder.isEmpty()) {
|
||||
try {
|
||||
this._execute();
|
||||
} catch (err) {
|
||||
if (cb)
|
||||
return done(err);
|
||||
else
|
||||
return this.emit('error', err);
|
||||
}
|
||||
}
|
||||
|
||||
if (cb)
|
||||
done(null);
|
||||
|
||||
function done(err) {
|
||||
process.nextTick(function() {
|
||||
cb(err);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Decompressor.prototype.updateTableSize = function updateTableSize(size) {
|
||||
this._table.updateSize(size);
|
||||
};
|
||||
|
||||
Decompressor.prototype._execute = function _execute() {
|
||||
var isIndexed = this._decoder.decodeBit();
|
||||
if (isIndexed)
|
||||
return this._processIndexed();
|
||||
|
||||
var isIncremental = this._decoder.decodeBit();
|
||||
var neverIndex = 0;
|
||||
if (!isIncremental) {
|
||||
var isUpdate = this._decoder.decodeBit();
|
||||
if (isUpdate)
|
||||
return this._processUpdate();
|
||||
|
||||
neverIndex = this._decoder.decodeBit();
|
||||
}
|
||||
|
||||
this._processLiteral(isIncremental, neverIndex);
|
||||
};
|
||||
|
||||
Decompressor.prototype._processIndexed = function _processIndexed() {
|
||||
var index = this._decoder.decodeInt();
|
||||
|
||||
var lookup = this._table.lookup(index);
|
||||
this.push({ name: lookup.name, value: lookup.value, neverIndex: false });
|
||||
};
|
||||
|
||||
Decompressor.prototype._processLiteral = function _processLiteral(inc, never) {
|
||||
var index = this._decoder.decodeInt();
|
||||
|
||||
var name;
|
||||
var nameSize;
|
||||
|
||||
// Literal header-name too
|
||||
if (index === 0) {
|
||||
name = this._decoder.decodeStr();
|
||||
nameSize = name.length;
|
||||
name = utils.stringify(name);
|
||||
} else {
|
||||
var lookup = this._table.lookup(index);
|
||||
nameSize = lookup.nameSize;
|
||||
name = lookup.name;
|
||||
}
|
||||
|
||||
var value = this._decoder.decodeStr();
|
||||
var valueSize = value.length;
|
||||
value = utils.stringify(value);
|
||||
|
||||
if (inc)
|
||||
this._table.add(name, value, nameSize, valueSize);
|
||||
|
||||
this.push({ name: name, value: value, neverIndex: never !== 0});
|
||||
};
|
||||
|
||||
Decompressor.prototype._processUpdate = function _processUpdate() {
|
||||
var size = this._decoder.decodeInt();
|
||||
this.updateTableSize(size);
|
||||
};
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
var hpack = require('../hpack');
|
||||
var utils = hpack.utils;
|
||||
var huffman = hpack.huffman.encode;
|
||||
var assert = utils.assert;
|
||||
|
||||
var WBuf = require('wbuf');
|
||||
|
||||
function Encoder() {
|
||||
this.buffer = new WBuf();
|
||||
this.word = 0;
|
||||
this.bitOffset = 0;
|
||||
}
|
||||
module.exports = Encoder;
|
||||
|
||||
Encoder.create = function create() {
|
||||
return new Encoder();
|
||||
};
|
||||
|
||||
Encoder.prototype.render = function render() {
|
||||
return this.buffer.render();
|
||||
};
|
||||
|
||||
Encoder.prototype.encodeBit = function encodeBit(bit) {
|
||||
var octet;
|
||||
|
||||
this.word <<= 1;
|
||||
this.word |= bit;
|
||||
this.bitOffset++;
|
||||
|
||||
if (this.bitOffset === 8) {
|
||||
this.buffer.writeUInt8(this.word);
|
||||
this.word = 0;
|
||||
this.bitOffset = 0;
|
||||
}
|
||||
};
|
||||
|
||||
Encoder.prototype.encodeBits = function encodeBits(bits, len) {
|
||||
var left = bits;
|
||||
var leftLen = len;
|
||||
|
||||
while (leftLen > 0) {
|
||||
var avail = Math.min(leftLen, 8 - this.bitOffset);
|
||||
var toWrite = left >>> (leftLen - avail);
|
||||
|
||||
if (avail === 8) {
|
||||
this.buffer.writeUInt8(toWrite);
|
||||
} else {
|
||||
this.word <<= avail;
|
||||
this.word |= toWrite;
|
||||
this.bitOffset += avail;
|
||||
if (this.bitOffset === 8) {
|
||||
this.buffer.writeUInt8(this.word);
|
||||
this.word = 0;
|
||||
this.bitOffset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
leftLen -= avail;
|
||||
left &= (1 << leftLen) - 1;
|
||||
}
|
||||
};
|
||||
|
||||
// Just for testing
|
||||
Encoder.prototype.skipBits = function skipBits(num) {
|
||||
this.bitOffset += num;
|
||||
this.buffer.skip(this.bitOffset >> 3);
|
||||
this.bitOffset &= 0x7;
|
||||
};
|
||||
|
||||
Encoder.prototype.encodeInt = function encodeInt(num) {
|
||||
var prefix = 8 - this.bitOffset;
|
||||
|
||||
// We are going to end up octet-aligned
|
||||
this.bitOffset = 0;
|
||||
|
||||
var max = (1 << prefix) - 1;
|
||||
|
||||
// Fast case - int fits into the prefix
|
||||
if (num < max) {
|
||||
this.buffer.writeUInt8((this.word << prefix) | num);
|
||||
return octet;
|
||||
}
|
||||
|
||||
var left = num - max;
|
||||
this.buffer.writeUInt8((this.word << prefix) | max);
|
||||
do {
|
||||
var octet = left & 0x7f;
|
||||
left >>= 7;
|
||||
if (left !== 0)
|
||||
octet |= 0x80;
|
||||
|
||||
this.buffer.writeUInt8(octet);
|
||||
} while (left !== 0);
|
||||
};
|
||||
|
||||
Encoder.prototype.encodeStr = function encodeStr(value, isHuffman) {
|
||||
this.encodeBit(isHuffman ? 1 : 0);
|
||||
|
||||
if (!isHuffman) {
|
||||
this.buffer.reserve(value.length + 1);
|
||||
this.encodeInt(value.length);
|
||||
for (var i = 0; i < value.length; i++)
|
||||
this.buffer.writeUInt8(value[i]);
|
||||
return;
|
||||
}
|
||||
|
||||
var codes = [];
|
||||
var len = 0;
|
||||
var pad = 0;
|
||||
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
var code = huffman[value[i]];
|
||||
codes.push(code);
|
||||
len += code[0];
|
||||
}
|
||||
if (len % 8 !== 0)
|
||||
pad = 8 - (len % 8);
|
||||
len += pad;
|
||||
|
||||
this.buffer.reserve((len / 8) + 1);
|
||||
this.encodeInt(len / 8);
|
||||
for (var i = 0; i < codes.length; i++) {
|
||||
var code = codes[i];
|
||||
this.encodeBits(code[1], code[0]);
|
||||
}
|
||||
|
||||
// Append padding
|
||||
this.encodeBits(0xff >>> (8 - pad), pad);
|
||||
};
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
exports.decode =
|
||||
[2608,2609,2610,2657,2659,2661,2665,2671,2675,2676,0,0,0,0,0,0,0,0,0,0,
|
||||
3104,3109,3117,3118,3119,3123,3124,3125,3126,3127,3128,3129,3133,3137,3167,
|
||||
3170,3172,3174,3175,3176,3180,3181,3182,3184,3186,3189,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
3642,3650,3651,3652,3653,3654,3655,3656,3657,3658,3659,3660,3661,3662,3663,
|
||||
3664,3665,3666,3667,3668,3669,3670,3671,3673,3690,3691,3697,3702,3703,3704,
|
||||
3705,3706,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4134,4138,4140,4155,4184,4186,[1057,
|
||||
1058,1064,1065,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
||||
[1087,0,1575,1579,1660,0,0,0,0,0,2083,2110,0,0,0,0,0,0,0,0,0,0,0,0,2560,
|
||||
2596,2624,2651,2653,2686,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,3166,3197,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3644,
|
||||
3680,3707,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[1628,1731,1744,0,0,0,2176,2178,
|
||||
2179,2210,2232,2242,2272,2274,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2713,2721,2727,
|
||||
2732,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0],[2736,2737,2739,2769,2776,2777,2787,2789,2790,0,0,0,0,0,0,0,0,0,
|
||||
3201,3204,3205,3206,3208,3218,3226,3228,3232,3235,3236,3241,3242,3245,3250,
|
||||
3253,3257,3258,3259,3261,3262,3268,3270,3300,3304,3305,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3585,
|
||||
3719,3721,3722,3723,3724,3725,3727,3731,3733,3734,3735,3736,3739,3741,3742,
|
||||
3749,3750,3752,3758,3759,3764,3766,3767,3772,3775,3781,3815,3823,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,4105,4238,4240,4241,4244,4255,4267,4302,4311,4321,4332,4333,[711,719,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[746,747,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[1216,1217,
|
||||
1224,1225,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
||||
[1226,1229,1234,1237,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0],[1242,1243,1262,1264,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0],[1266,1267,1279,0,0,0,1739,1740,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0],[1747,1748,1750,1757,1758,1759,1777,1780,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[1781,1782,1783,1784,1786,
|
||||
1787,1788,1789,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[1790,0,
|
||||
2050,2051,2052,2053,2054,2055,2056,2059,2060,2062,2063,2064,2065,2066,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[2067,2068,2069,2071,2072,2073,2074,2075,
|
||||
2076,2077,2078,2079,2175,2268,2297,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3082,3085,3094,3328,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
||||
0,0,0,0,0]]]];
|
||||
exports.encode =
|
||||
[[13,8184],[23,8388568],[28,268435426],[28,268435427],[28,268435428],[28,
|
||||
268435429],[28,268435430],[28,268435431],[28,268435432],[24,16777194],[30,
|
||||
1073741820],[28,268435433],[28,268435434],[30,1073741821],[28,268435435],
|
||||
[28,268435436],[28,268435437],[28,268435438],[28,268435439],[28,268435440],
|
||||
[28,268435441],[28,268435442],[30,1073741822],[28,268435443],[28,
|
||||
268435444],[28,268435445],[28,268435446],[28,268435447],[28,268435448],[28,
|
||||
268435449],[28,268435450],[28,268435451],[6,20],[10,1016],[10,1017],[12,
|
||||
4090],[13,8185],[6,21],[8,248],[11,2042],[10,1018],[10,1019],[8,249],[11,
|
||||
2043],[8,250],[6,22],[6,23],[6,24],[5,0],[5,1],[5,2],[6,25],[6,26],[6,27],
|
||||
[6,28],[6,29],[6,30],[6,31],[7,92],[8,251],[15,32764],[6,32],[12,4091],[10,
|
||||
1020],[13,8186],[6,33],[7,93],[7,94],[7,95],[7,96],[7,97],[7,98],[7,99],[7,
|
||||
100],[7,101],[7,102],[7,103],[7,104],[7,105],[7,106],[7,107],[7,108],[7,
|
||||
109],[7,110],[7,111],[7,112],[7,113],[7,114],[8,252],[7,115],[8,253],[13,
|
||||
8187],[19,524272],[13,8188],[14,16380],[6,34],[15,32765],[5,3],[6,35],[5,
|
||||
4],[6,36],[5,5],[6,37],[6,38],[6,39],[5,6],[7,116],[7,117],[6,40],[6,41],
|
||||
[6,42],[5,7],[6,43],[7,118],[6,44],[5,8],[5,9],[6,45],[7,119],[7,120],[7,
|
||||
121],[7,122],[7,123],[15,32766],[11,2044],[14,16381],[13,8189],[28,
|
||||
268435452],[20,1048550],[22,4194258],[20,1048551],[20,1048552],[22,
|
||||
4194259],[22,4194260],[22,4194261],[23,8388569],[22,4194262],[23,8388570],
|
||||
[23,8388571],[23,8388572],[23,8388573],[23,8388574],[24,16777195],[23,
|
||||
8388575],[24,16777196],[24,16777197],[22,4194263],[23,8388576],[24,
|
||||
16777198],[23,8388577],[23,8388578],[23,8388579],[23,8388580],[21,2097116],
|
||||
[22,4194264],[23,8388581],[22,4194265],[23,8388582],[23,8388583],[24,
|
||||
16777199],[22,4194266],[21,2097117],[20,1048553],[22,4194267],[22,4194268],
|
||||
[23,8388584],[23,8388585],[21,2097118],[23,8388586],[22,4194269],[22,
|
||||
4194270],[24,16777200],[21,2097119],[22,4194271],[23,8388587],[23,8388588],
|
||||
[21,2097120],[21,2097121],[22,4194272],[21,2097122],[23,8388589],[22,
|
||||
4194273],[23,8388590],[23,8388591],[20,1048554],[22,4194274],[22,4194275],
|
||||
[22,4194276],[23,8388592],[22,4194277],[22,4194278],[23,8388593],[26,
|
||||
67108832],[26,67108833],[20,1048555],[19,524273],[22,4194279],[23,8388594],
|
||||
[22,4194280],[25,33554412],[26,67108834],[26,67108835],[26,67108836],[27,
|
||||
134217694],[27,134217695],[26,67108837],[24,16777201],[25,33554413],[19,
|
||||
524274],[21,2097123],[26,67108838],[27,134217696],[27,134217697],[26,
|
||||
67108839],[27,134217698],[24,16777202],[21,2097124],[21,2097125],[26,
|
||||
67108840],[26,67108841],[28,268435453],[27,134217699],[27,134217700],[27,
|
||||
134217701],[20,1048556],[24,16777203],[20,1048557],[21,2097126],[22,
|
||||
4194281],[21,2097127],[21,2097128],[23,8388595],[22,4194282],[22,4194283],
|
||||
[25,33554414],[25,33554415],[24,16777204],[24,16777205],[26,67108842],[23,
|
||||
8388596],[26,67108843],[27,134217702],[26,67108844],[26,67108845],[27,
|
||||
134217703],[27,134217704],[27,134217705],[27,134217706],[27,134217707],[28,
|
||||
268435454],[27,134217708],[27,134217709],[27,134217710],[27,134217711],[27,
|
||||
134217712],[26,67108846],[30,1073741823]];
|
||||
+691
@@ -0,0 +1,691 @@
|
||||
exports.table = [
|
||||
{
|
||||
"name": ":authority",
|
||||
"value": "",
|
||||
"nameSize": 10,
|
||||
"totalSize": 42
|
||||
},
|
||||
{
|
||||
"name": ":method",
|
||||
"value": "GET",
|
||||
"nameSize": 7,
|
||||
"totalSize": 42
|
||||
},
|
||||
{
|
||||
"name": ":method",
|
||||
"value": "POST",
|
||||
"nameSize": 7,
|
||||
"totalSize": 43
|
||||
},
|
||||
{
|
||||
"name": ":path",
|
||||
"value": "/",
|
||||
"nameSize": 5,
|
||||
"totalSize": 38
|
||||
},
|
||||
{
|
||||
"name": ":path",
|
||||
"value": "/index.html",
|
||||
"nameSize": 5,
|
||||
"totalSize": 48
|
||||
},
|
||||
{
|
||||
"name": ":scheme",
|
||||
"value": "http",
|
||||
"nameSize": 7,
|
||||
"totalSize": 43
|
||||
},
|
||||
{
|
||||
"name": ":scheme",
|
||||
"value": "https",
|
||||
"nameSize": 7,
|
||||
"totalSize": 44
|
||||
},
|
||||
{
|
||||
"name": ":status",
|
||||
"value": "200",
|
||||
"nameSize": 7,
|
||||
"totalSize": 42
|
||||
},
|
||||
{
|
||||
"name": ":status",
|
||||
"value": "204",
|
||||
"nameSize": 7,
|
||||
"totalSize": 42
|
||||
},
|
||||
{
|
||||
"name": ":status",
|
||||
"value": "206",
|
||||
"nameSize": 7,
|
||||
"totalSize": 42
|
||||
},
|
||||
{
|
||||
"name": ":status",
|
||||
"value": "304",
|
||||
"nameSize": 7,
|
||||
"totalSize": 42
|
||||
},
|
||||
{
|
||||
"name": ":status",
|
||||
"value": "400",
|
||||
"nameSize": 7,
|
||||
"totalSize": 42
|
||||
},
|
||||
{
|
||||
"name": ":status",
|
||||
"value": "404",
|
||||
"nameSize": 7,
|
||||
"totalSize": 42
|
||||
},
|
||||
{
|
||||
"name": ":status",
|
||||
"value": "500",
|
||||
"nameSize": 7,
|
||||
"totalSize": 42
|
||||
},
|
||||
{
|
||||
"name": "accept-charset",
|
||||
"value": "",
|
||||
"nameSize": 14,
|
||||
"totalSize": 46
|
||||
},
|
||||
{
|
||||
"name": "accept-encoding",
|
||||
"value": "gzip, deflate",
|
||||
"nameSize": 15,
|
||||
"totalSize": 60
|
||||
},
|
||||
{
|
||||
"name": "accept-language",
|
||||
"value": "",
|
||||
"nameSize": 15,
|
||||
"totalSize": 47
|
||||
},
|
||||
{
|
||||
"name": "accept-ranges",
|
||||
"value": "",
|
||||
"nameSize": 13,
|
||||
"totalSize": 45
|
||||
},
|
||||
{
|
||||
"name": "accept",
|
||||
"value": "",
|
||||
"nameSize": 6,
|
||||
"totalSize": 38
|
||||
},
|
||||
{
|
||||
"name": "access-control-allow-origin",
|
||||
"value": "",
|
||||
"nameSize": 27,
|
||||
"totalSize": 59
|
||||
},
|
||||
{
|
||||
"name": "age",
|
||||
"value": "",
|
||||
"nameSize": 3,
|
||||
"totalSize": 35
|
||||
},
|
||||
{
|
||||
"name": "allow",
|
||||
"value": "",
|
||||
"nameSize": 5,
|
||||
"totalSize": 37
|
||||
},
|
||||
{
|
||||
"name": "authorization",
|
||||
"value": "",
|
||||
"nameSize": 13,
|
||||
"totalSize": 45
|
||||
},
|
||||
{
|
||||
"name": "cache-control",
|
||||
"value": "",
|
||||
"nameSize": 13,
|
||||
"totalSize": 45
|
||||
},
|
||||
{
|
||||
"name": "content-disposition",
|
||||
"value": "",
|
||||
"nameSize": 19,
|
||||
"totalSize": 51
|
||||
},
|
||||
{
|
||||
"name": "content-encoding",
|
||||
"value": "",
|
||||
"nameSize": 16,
|
||||
"totalSize": 48
|
||||
},
|
||||
{
|
||||
"name": "content-language",
|
||||
"value": "",
|
||||
"nameSize": 16,
|
||||
"totalSize": 48
|
||||
},
|
||||
{
|
||||
"name": "content-length",
|
||||
"value": "",
|
||||
"nameSize": 14,
|
||||
"totalSize": 46
|
||||
},
|
||||
{
|
||||
"name": "content-location",
|
||||
"value": "",
|
||||
"nameSize": 16,
|
||||
"totalSize": 48
|
||||
},
|
||||
{
|
||||
"name": "content-range",
|
||||
"value": "",
|
||||
"nameSize": 13,
|
||||
"totalSize": 45
|
||||
},
|
||||
{
|
||||
"name": "content-type",
|
||||
"value": "",
|
||||
"nameSize": 12,
|
||||
"totalSize": 44
|
||||
},
|
||||
{
|
||||
"name": "cookie",
|
||||
"value": "",
|
||||
"nameSize": 6,
|
||||
"totalSize": 38
|
||||
},
|
||||
{
|
||||
"name": "date",
|
||||
"value": "",
|
||||
"nameSize": 4,
|
||||
"totalSize": 36
|
||||
},
|
||||
{
|
||||
"name": "etag",
|
||||
"value": "",
|
||||
"nameSize": 4,
|
||||
"totalSize": 36
|
||||
},
|
||||
{
|
||||
"name": "expect",
|
||||
"value": "",
|
||||
"nameSize": 6,
|
||||
"totalSize": 38
|
||||
},
|
||||
{
|
||||
"name": "expires",
|
||||
"value": "",
|
||||
"nameSize": 7,
|
||||
"totalSize": 39
|
||||
},
|
||||
{
|
||||
"name": "from",
|
||||
"value": "",
|
||||
"nameSize": 4,
|
||||
"totalSize": 36
|
||||
},
|
||||
{
|
||||
"name": "host",
|
||||
"value": "",
|
||||
"nameSize": 4,
|
||||
"totalSize": 36
|
||||
},
|
||||
{
|
||||
"name": "if-match",
|
||||
"value": "",
|
||||
"nameSize": 8,
|
||||
"totalSize": 40
|
||||
},
|
||||
{
|
||||
"name": "if-modified-since",
|
||||
"value": "",
|
||||
"nameSize": 17,
|
||||
"totalSize": 49
|
||||
},
|
||||
{
|
||||
"name": "if-none-match",
|
||||
"value": "",
|
||||
"nameSize": 13,
|
||||
"totalSize": 45
|
||||
},
|
||||
{
|
||||
"name": "if-range",
|
||||
"value": "",
|
||||
"nameSize": 8,
|
||||
"totalSize": 40
|
||||
},
|
||||
{
|
||||
"name": "if-unmodified-since",
|
||||
"value": "",
|
||||
"nameSize": 19,
|
||||
"totalSize": 51
|
||||
},
|
||||
{
|
||||
"name": "last-modified",
|
||||
"value": "",
|
||||
"nameSize": 13,
|
||||
"totalSize": 45
|
||||
},
|
||||
{
|
||||
"name": "link",
|
||||
"value": "",
|
||||
"nameSize": 4,
|
||||
"totalSize": 36
|
||||
},
|
||||
{
|
||||
"name": "location",
|
||||
"value": "",
|
||||
"nameSize": 8,
|
||||
"totalSize": 40
|
||||
},
|
||||
{
|
||||
"name": "max-forwards",
|
||||
"value": "",
|
||||
"nameSize": 12,
|
||||
"totalSize": 44
|
||||
},
|
||||
{
|
||||
"name": "proxy-authenticate",
|
||||
"value": "",
|
||||
"nameSize": 18,
|
||||
"totalSize": 50
|
||||
},
|
||||
{
|
||||
"name": "proxy-authorization",
|
||||
"value": "",
|
||||
"nameSize": 19,
|
||||
"totalSize": 51
|
||||
},
|
||||
{
|
||||
"name": "range",
|
||||
"value": "",
|
||||
"nameSize": 5,
|
||||
"totalSize": 37
|
||||
},
|
||||
{
|
||||
"name": "referer",
|
||||
"value": "",
|
||||
"nameSize": 7,
|
||||
"totalSize": 39
|
||||
},
|
||||
{
|
||||
"name": "refresh",
|
||||
"value": "",
|
||||
"nameSize": 7,
|
||||
"totalSize": 39
|
||||
},
|
||||
{
|
||||
"name": "retry-after",
|
||||
"value": "",
|
||||
"nameSize": 11,
|
||||
"totalSize": 43
|
||||
},
|
||||
{
|
||||
"name": "server",
|
||||
"value": "",
|
||||
"nameSize": 6,
|
||||
"totalSize": 38
|
||||
},
|
||||
{
|
||||
"name": "set-cookie",
|
||||
"value": "",
|
||||
"nameSize": 10,
|
||||
"totalSize": 42
|
||||
},
|
||||
{
|
||||
"name": "strict-transport-security",
|
||||
"value": "",
|
||||
"nameSize": 25,
|
||||
"totalSize": 57
|
||||
},
|
||||
{
|
||||
"name": "transfer-encoding",
|
||||
"value": "",
|
||||
"nameSize": 17,
|
||||
"totalSize": 49
|
||||
},
|
||||
{
|
||||
"name": "user-agent",
|
||||
"value": "",
|
||||
"nameSize": 10,
|
||||
"totalSize": 42
|
||||
},
|
||||
{
|
||||
"name": "vary",
|
||||
"value": "",
|
||||
"nameSize": 4,
|
||||
"totalSize": 36
|
||||
},
|
||||
{
|
||||
"name": "via",
|
||||
"value": "",
|
||||
"nameSize": 3,
|
||||
"totalSize": 35
|
||||
},
|
||||
{
|
||||
"name": "www-authenticate",
|
||||
"value": "",
|
||||
"nameSize": 16,
|
||||
"totalSize": 48
|
||||
}
|
||||
];
|
||||
exports.map = {
|
||||
":authority": {
|
||||
"index": 1,
|
||||
"values": {
|
||||
"": 1
|
||||
}
|
||||
},
|
||||
":method": {
|
||||
"index": 2,
|
||||
"values": {
|
||||
"GET": 2,
|
||||
"POST": 3
|
||||
}
|
||||
},
|
||||
":path": {
|
||||
"index": 4,
|
||||
"values": {
|
||||
"/": 4,
|
||||
"/index.html": 5
|
||||
}
|
||||
},
|
||||
":scheme": {
|
||||
"index": 6,
|
||||
"values": {
|
||||
"http": 6,
|
||||
"https": 7
|
||||
}
|
||||
},
|
||||
":status": {
|
||||
"index": 8,
|
||||
"values": {
|
||||
"200": 8,
|
||||
"204": 9,
|
||||
"206": 10,
|
||||
"304": 11,
|
||||
"400": 12,
|
||||
"404": 13,
|
||||
"500": 14
|
||||
}
|
||||
},
|
||||
"accept-charset": {
|
||||
"index": 15,
|
||||
"values": {
|
||||
"": 15
|
||||
}
|
||||
},
|
||||
"accept-encoding": {
|
||||
"index": 16,
|
||||
"values": {
|
||||
"gzip, deflate": 16
|
||||
}
|
||||
},
|
||||
"accept-language": {
|
||||
"index": 17,
|
||||
"values": {
|
||||
"": 17
|
||||
}
|
||||
},
|
||||
"accept-ranges": {
|
||||
"index": 18,
|
||||
"values": {
|
||||
"": 18
|
||||
}
|
||||
},
|
||||
"accept": {
|
||||
"index": 19,
|
||||
"values": {
|
||||
"": 19
|
||||
}
|
||||
},
|
||||
"access-control-allow-origin": {
|
||||
"index": 20,
|
||||
"values": {
|
||||
"": 20
|
||||
}
|
||||
},
|
||||
"age": {
|
||||
"index": 21,
|
||||
"values": {
|
||||
"": 21
|
||||
}
|
||||
},
|
||||
"allow": {
|
||||
"index": 22,
|
||||
"values": {
|
||||
"": 22
|
||||
}
|
||||
},
|
||||
"authorization": {
|
||||
"index": 23,
|
||||
"values": {
|
||||
"": 23
|
||||
}
|
||||
},
|
||||
"cache-control": {
|
||||
"index": 24,
|
||||
"values": {
|
||||
"": 24
|
||||
}
|
||||
},
|
||||
"content-disposition": {
|
||||
"index": 25,
|
||||
"values": {
|
||||
"": 25
|
||||
}
|
||||
},
|
||||
"content-encoding": {
|
||||
"index": 26,
|
||||
"values": {
|
||||
"": 26
|
||||
}
|
||||
},
|
||||
"content-language": {
|
||||
"index": 27,
|
||||
"values": {
|
||||
"": 27
|
||||
}
|
||||
},
|
||||
"content-length": {
|
||||
"index": 28,
|
||||
"values": {
|
||||
"": 28
|
||||
}
|
||||
},
|
||||
"content-location": {
|
||||
"index": 29,
|
||||
"values": {
|
||||
"": 29
|
||||
}
|
||||
},
|
||||
"content-range": {
|
||||
"index": 30,
|
||||
"values": {
|
||||
"": 30
|
||||
}
|
||||
},
|
||||
"content-type": {
|
||||
"index": 31,
|
||||
"values": {
|
||||
"": 31
|
||||
}
|
||||
},
|
||||
"cookie": {
|
||||
"index": 32,
|
||||
"values": {
|
||||
"": 32
|
||||
}
|
||||
},
|
||||
"date": {
|
||||
"index": 33,
|
||||
"values": {
|
||||
"": 33
|
||||
}
|
||||
},
|
||||
"etag": {
|
||||
"index": 34,
|
||||
"values": {
|
||||
"": 34
|
||||
}
|
||||
},
|
||||
"expect": {
|
||||
"index": 35,
|
||||
"values": {
|
||||
"": 35
|
||||
}
|
||||
},
|
||||
"expires": {
|
||||
"index": 36,
|
||||
"values": {
|
||||
"": 36
|
||||
}
|
||||
},
|
||||
"from": {
|
||||
"index": 37,
|
||||
"values": {
|
||||
"": 37
|
||||
}
|
||||
},
|
||||
"host": {
|
||||
"index": 38,
|
||||
"values": {
|
||||
"": 38
|
||||
}
|
||||
},
|
||||
"if-match": {
|
||||
"index": 39,
|
||||
"values": {
|
||||
"": 39
|
||||
}
|
||||
},
|
||||
"if-modified-since": {
|
||||
"index": 40,
|
||||
"values": {
|
||||
"": 40
|
||||
}
|
||||
},
|
||||
"if-none-match": {
|
||||
"index": 41,
|
||||
"values": {
|
||||
"": 41
|
||||
}
|
||||
},
|
||||
"if-range": {
|
||||
"index": 42,
|
||||
"values": {
|
||||
"": 42
|
||||
}
|
||||
},
|
||||
"if-unmodified-since": {
|
||||
"index": 43,
|
||||
"values": {
|
||||
"": 43
|
||||
}
|
||||
},
|
||||
"last-modified": {
|
||||
"index": 44,
|
||||
"values": {
|
||||
"": 44
|
||||
}
|
||||
},
|
||||
"link": {
|
||||
"index": 45,
|
||||
"values": {
|
||||
"": 45
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"index": 46,
|
||||
"values": {
|
||||
"": 46
|
||||
}
|
||||
},
|
||||
"max-forwards": {
|
||||
"index": 47,
|
||||
"values": {
|
||||
"": 47
|
||||
}
|
||||
},
|
||||
"proxy-authenticate": {
|
||||
"index": 48,
|
||||
"values": {
|
||||
"": 48
|
||||
}
|
||||
},
|
||||
"proxy-authorization": {
|
||||
"index": 49,
|
||||
"values": {
|
||||
"": 49
|
||||
}
|
||||
},
|
||||
"range": {
|
||||
"index": 50,
|
||||
"values": {
|
||||
"": 50
|
||||
}
|
||||
},
|
||||
"referer": {
|
||||
"index": 51,
|
||||
"values": {
|
||||
"": 51
|
||||
}
|
||||
},
|
||||
"refresh": {
|
||||
"index": 52,
|
||||
"values": {
|
||||
"": 52
|
||||
}
|
||||
},
|
||||
"retry-after": {
|
||||
"index": 53,
|
||||
"values": {
|
||||
"": 53
|
||||
}
|
||||
},
|
||||
"server": {
|
||||
"index": 54,
|
||||
"values": {
|
||||
"": 54
|
||||
}
|
||||
},
|
||||
"set-cookie": {
|
||||
"index": 55,
|
||||
"values": {
|
||||
"": 55
|
||||
}
|
||||
},
|
||||
"strict-transport-security": {
|
||||
"index": 56,
|
||||
"values": {
|
||||
"": 56
|
||||
}
|
||||
},
|
||||
"transfer-encoding": {
|
||||
"index": 57,
|
||||
"values": {
|
||||
"": 57
|
||||
}
|
||||
},
|
||||
"user-agent": {
|
||||
"index": 58,
|
||||
"values": {
|
||||
"": 58
|
||||
}
|
||||
},
|
||||
"vary": {
|
||||
"index": 59,
|
||||
"values": {
|
||||
"": 59
|
||||
}
|
||||
},
|
||||
"via": {
|
||||
"index": 60,
|
||||
"values": {
|
||||
"": 60
|
||||
}
|
||||
},
|
||||
"www-authenticate": {
|
||||
"index": 61,
|
||||
"values": {
|
||||
"": 61
|
||||
}
|
||||
}
|
||||
};
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
var hpack = require('../hpack');
|
||||
var utils = hpack.utils;
|
||||
var assert = utils.assert;
|
||||
|
||||
function Table(options) {
|
||||
this['static'] = hpack['static-table'];
|
||||
this.dynamic = [];
|
||||
this.size = 0;
|
||||
this.maxSize = 0;
|
||||
this.length = this['static'].table.length;
|
||||
this.protocolMaxSize = options.maxSize;
|
||||
this.maxSize = this.protocolMaxSize;
|
||||
this.lookupDepth = options.lookupDepth || 32;
|
||||
}
|
||||
module.exports = Table;
|
||||
|
||||
Table.create = function create(options) {
|
||||
return new Table(options);
|
||||
};
|
||||
|
||||
Table.prototype.lookup = function lookup(index) {
|
||||
assert(index !== 0, 'Zero indexed field');
|
||||
assert(index <= this.length, 'Indexed field OOB')
|
||||
|
||||
if (index <= this['static'].table.length)
|
||||
return this['static'].table[index - 1];
|
||||
else
|
||||
return this.dynamic[this.length - index];
|
||||
};
|
||||
|
||||
Table.prototype.reverseLookup = function reverseLookup(name, value) {
|
||||
var staticEntry = this['static'].map[name];
|
||||
if (staticEntry && staticEntry.values[value])
|
||||
return staticEntry.values[value];
|
||||
|
||||
// Reverse search dynamic table (new items are at the end of it)
|
||||
var limit = Math.max(0, this.dynamic.length - this.lookupDepth);
|
||||
for (var i = this.dynamic.length - 1; i >= limit; i--) {
|
||||
var entry = this.dynamic[i];
|
||||
if (entry.name === name && entry.value === value)
|
||||
return this.length - i;
|
||||
|
||||
if (entry.name === name) {
|
||||
// Prefer smaller index
|
||||
if (staticEntry)
|
||||
break;
|
||||
return -(this.length - i);
|
||||
}
|
||||
}
|
||||
|
||||
if (staticEntry)
|
||||
return -staticEntry.index;
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
Table.prototype.add = function add(name, value, nameSize, valueSize) {
|
||||
var totalSize = nameSize + valueSize + 32;
|
||||
|
||||
this.dynamic.push({
|
||||
name: name,
|
||||
value: value,
|
||||
nameSize: nameSize,
|
||||
totalSize: totalSize
|
||||
});
|
||||
this.size += totalSize;
|
||||
this.length++;
|
||||
|
||||
this.evict();
|
||||
};
|
||||
|
||||
Table.prototype.evict = function evict() {
|
||||
while (this.size > this.maxSize) {
|
||||
var entry = this.dynamic.shift();
|
||||
this.size -= entry.totalSize;
|
||||
this.length--;
|
||||
}
|
||||
assert(this.size >= 0, 'Table size sanity check failed');
|
||||
};
|
||||
|
||||
Table.prototype.updateSize = function updateSize(size) {
|
||||
assert(size <= this.protocolMaxSize, 'Table size bigger than maximum');
|
||||
this.maxSize = size;
|
||||
this.evict();
|
||||
};
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
exports.assert = function assert(cond, text) {
|
||||
if (!cond)
|
||||
throw new Error(text);
|
||||
};
|
||||
|
||||
exports.stringify = function stringify(arr) {
|
||||
var res = '';
|
||||
for (var i = 0; i < arr.length; i++)
|
||||
res += String.fromCharCode(arr[i]);
|
||||
return res;
|
||||
};
|
||||
|
||||
exports.toArray = function toArray(str) {
|
||||
var res = [];
|
||||
for (var i = 0; i < str.length; i++) {
|
||||
var c = str.charCodeAt(i);
|
||||
var hi = c >>> 8;
|
||||
var lo = c & 0xff;
|
||||
if (hi)
|
||||
res.push(hi, lo);
|
||||
else
|
||||
res.push(lo);
|
||||
}
|
||||
return res;
|
||||
};
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
{
|
||||
"_from": "hpack.js@^2.1.6",
|
||||
"_id": "hpack.js@2.1.6",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=",
|
||||
"_location": "/hpack.js",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "hpack.js@^2.1.6",
|
||||
"name": "hpack.js",
|
||||
"escapedName": "hpack.js",
|
||||
"rawSpec": "^2.1.6",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^2.1.6"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/spdy-transport"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz",
|
||||
"_shasum": "87774c0949e513f42e84575b3c45681fade2a0b2",
|
||||
"_spec": "hpack.js@^2.1.6",
|
||||
"_where": "O:\\zero\\zero.Web\\node_modules\\spdy-transport",
|
||||
"author": {
|
||||
"name": "Fedor Indutny",
|
||||
"email": "fedor@indutny.com"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/indutny/hpack.js/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"dependencies": {
|
||||
"inherits": "^2.0.1",
|
||||
"obuf": "^1.0.0",
|
||||
"readable-stream": "^2.0.1",
|
||||
"wbuf": "^1.1.0"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "HPACK implementation",
|
||||
"devDependencies": {
|
||||
"mocha": "^2.2.5"
|
||||
},
|
||||
"homepage": "https://github.com/indutny/hpack.js#readme",
|
||||
"keywords": [
|
||||
"HPACK",
|
||||
"HTTP2",
|
||||
"compress",
|
||||
"decompress",
|
||||
"headers"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "lib/hpack.js",
|
||||
"name": "hpack.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+ssh://git@github.com/indutny/hpack.js.git"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha test/*-test.js"
|
||||
},
|
||||
"version": "2.1.6"
|
||||
}
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
var assert = require('assert');
|
||||
var hpack = require('../');
|
||||
var fixtures = require('./fixtures');
|
||||
|
||||
describe('hpack/compressor', function() {
|
||||
var comp;
|
||||
|
||||
beforeEach(function() {
|
||||
comp = hpack.compressor.create({
|
||||
table: {
|
||||
maxSize: 1024
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function expect(arr, enc) {
|
||||
function isNumber(num) {
|
||||
return typeof num === 'number';
|
||||
}
|
||||
|
||||
var out = comp.read().toString('hex');
|
||||
if (Array.isArray(arr) && !arr.every(isNumber)) {
|
||||
arr = arr.map(function(item) {
|
||||
return new Buffer(item, enc);
|
||||
});
|
||||
arr = Buffer.concat(arr);
|
||||
} else {
|
||||
arr = new Buffer(arr, enc);
|
||||
}
|
||||
var actual = arr.toString('hex');
|
||||
assert.equal(out, actual);
|
||||
}
|
||||
|
||||
describe('indexed field', function() {
|
||||
it('should lookup entry from static table', function() {
|
||||
comp.write([{ name: ':method', value: 'GET' }]);
|
||||
expect([ 0b10000000 | 2 ]);
|
||||
});
|
||||
|
||||
it('should fetch entry from the end of the static table', function() {
|
||||
comp.write([{ name: 'www-authenticate', value: '' }]);
|
||||
expect([ 0b10000000 | 61 ]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('literal field', function() {
|
||||
it('should lookup name in the table (incremental)', function() {
|
||||
comp.write([{ name: 'host', value: 'localhost' }]);
|
||||
expect('6686a0e41d139d09', 'hex');
|
||||
|
||||
comp.write([{ name: 'host', value: 'localhost' }]);
|
||||
expect([ 0b10000000 | 62 ]);
|
||||
});
|
||||
|
||||
it('should lookup name in the table (not-incremental)', function() {
|
||||
comp.write([{ name: 'host', value: 'localhost', incremental: false }]);
|
||||
expect('0f1786a0e41d139d09', 'hex');
|
||||
|
||||
// Should not use the table
|
||||
comp.write([{ name: 'host', value: 'localhost' }]);
|
||||
expect('6686a0e41d139d09', 'hex');
|
||||
});
|
||||
|
||||
it('should evict header field from the table', function() {
|
||||
for (var i = 0; i < 1000; i++) {
|
||||
comp.write([{ name: 'host', value: 'localhost' + i }]);
|
||||
comp.read();
|
||||
}
|
||||
|
||||
assert(comp._table.size < comp._table.maxSize);
|
||||
assert.equal(comp._table.dynamic.length, 21);
|
||||
});
|
||||
});
|
||||
|
||||
describe('update size', function() {
|
||||
it('should evict header field from the table', function() {
|
||||
comp.write([{ name: 'host', value: 'localhost' }]);
|
||||
expect('6686a0e41d139d09', 'hex');
|
||||
|
||||
comp.reset();
|
||||
|
||||
// update=0, update=maxSize
|
||||
expect('203fe107', 'hex');
|
||||
|
||||
comp.write([{ name: 'host', value: 'localhost' }]);
|
||||
expect('6686a0e41d139d09', 'hex');
|
||||
});
|
||||
|
||||
it('should send dynamic update if size >= protocolMaxSize', function() {
|
||||
comp.updateTableSize(Infinity);
|
||||
|
||||
// update=maxSize
|
||||
expect('3fe107', 'hex');
|
||||
});
|
||||
});
|
||||
|
||||
describe('spec examples', function() {
|
||||
beforeEach(function() {
|
||||
comp = hpack.compressor.create({
|
||||
table: {
|
||||
maxSize: 256
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
var tests = fixtures.specExamples;
|
||||
|
||||
tests.forEach(function(test, i) {
|
||||
var prev = tests[i - 1];
|
||||
it('should give expected output on ' + test.id, function() {
|
||||
var startFrom = test.continuation ? prev.comp : comp;
|
||||
if (!startFrom)
|
||||
throw new Error('Previous test failed');
|
||||
comp = startFrom;
|
||||
|
||||
comp.write(test.output.map(function(pair) {
|
||||
return { name: pair[0], value: pair[1], huffman: test.huffman };
|
||||
}));
|
||||
expect(test.input.replace(/ /g, ''), 'hex');
|
||||
|
||||
// Verify table contents
|
||||
assert.deepEqual(comp._table.dynamic.map(function(header) {
|
||||
return [ header.name, header.value, header.totalSize ];
|
||||
}).reverse(), test.table);
|
||||
|
||||
// Verify table size
|
||||
var expectedSize = test.table.reduce(function(acc, item) {
|
||||
return acc + item[2];
|
||||
}, 0);
|
||||
assert.equal(comp._table.size, expectedSize);
|
||||
|
||||
test.comp = comp;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
var assert = require('assert');
|
||||
var hpack = require('../');
|
||||
|
||||
describe('hpack/decoder', function() {
|
||||
var decoder;
|
||||
|
||||
beforeEach(function() {
|
||||
decoder = hpack.decoder.create();
|
||||
});
|
||||
|
||||
describe('bit', function() {
|
||||
it('should decode number bit-by-bit', function() {
|
||||
decoder.push([ 0b11101010, 0b10101111 ]);
|
||||
var out = '';
|
||||
for (var i = 0; i < 16; i++)
|
||||
out += decoder.decodeBit();
|
||||
assert.equal(out, '11101010' + '10101111');
|
||||
});
|
||||
});
|
||||
|
||||
describe('integer', function() {
|
||||
it('should decode 10 in prefix-5 (C.1.1)', function() {
|
||||
decoder.push([ 0b11101010 ]);
|
||||
decoder.skipBits(3);
|
||||
assert.equal(decoder.decodeInt(), 10);
|
||||
});
|
||||
|
||||
it('should decode 1337 in prefix-5 (C.1.2)', function() {
|
||||
decoder.push([ 0b11111111, 0b10011010, 0b00001010 ]);
|
||||
decoder.skipBits(3);
|
||||
assert.equal(decoder.decodeInt(), 1337);
|
||||
});
|
||||
|
||||
it('should decode 42 at octect boundary (C.1.3)', function() {
|
||||
decoder.push([ 0b00101010 ]);
|
||||
assert.equal(decoder.decodeInt(8), 42);
|
||||
});
|
||||
|
||||
it('should throw on empty input', function() {
|
||||
assert.throws(function() {
|
||||
decoder.decodeInt();
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw on incomplete int', function() {
|
||||
decoder.push([ 0b11111111, 0b10011010 ]);
|
||||
decoder.skipBits(3);
|
||||
assert.throws(function() {
|
||||
decoder.decodeInt();
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw on overflowing int', function() {
|
||||
decoder.push([
|
||||
0b11111111,
|
||||
0b10011010,
|
||||
0b10011010,
|
||||
0b10011010,
|
||||
0b10011010,
|
||||
0b10011010
|
||||
]);
|
||||
decoder.skipBits(3);
|
||||
assert.throws(function() {
|
||||
decoder.decodeInt();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('string', function() {
|
||||
it('should decode literal from (C.2.1)', function() {
|
||||
decoder.push([ 0x0a ]);
|
||||
decoder.push(new Buffer('custom-key'));
|
||||
|
||||
assert.equal(decoder.decodeStr().toString(), 'custom-key');
|
||||
});
|
||||
|
||||
it('should decode literal from (C.4.1)', function() {
|
||||
decoder.push(new Buffer(
|
||||
'8c' +
|
||||
'f1e3 c2e5 f23a 6ba0 ab90 f4ff'.replace(/ /g, ''),
|
||||
'hex'));
|
||||
|
||||
assert.equal(new Buffer(decoder.decodeStr()).toString(),
|
||||
'www.example.com');
|
||||
});
|
||||
|
||||
it('should decode literal from (C.4.2)', function() {
|
||||
decoder.push(new Buffer(
|
||||
'86' +
|
||||
'a8eb 1064 9cbf'.replace(/ /g, ''),
|
||||
'hex'));
|
||||
|
||||
assert.equal(new Buffer(decoder.decodeStr()).toString(), 'no-cache');
|
||||
});
|
||||
|
||||
it('should decode literal from (C.4.3) #1', function() {
|
||||
decoder.push(new Buffer(
|
||||
'88' +
|
||||
'25a8 49e9 5ba9 7d7f'.replace(/ /g, ''),
|
||||
'hex'));
|
||||
|
||||
assert.equal(new Buffer(decoder.decodeStr()).toString(), 'custom-key');
|
||||
});
|
||||
|
||||
it('should decode literal from (C.4.3) #2', function() {
|
||||
decoder.push(new Buffer(
|
||||
'89' +
|
||||
'25a8 49e9 5bb8 e8b4 bf'.replace(/ /g, ''),
|
||||
'hex'));
|
||||
|
||||
assert.equal(new Buffer(decoder.decodeStr()).toString(), 'custom-value');
|
||||
});
|
||||
|
||||
it('should decode literal from (C.6.1) #1', function() {
|
||||
decoder.push(new Buffer(
|
||||
('96' +
|
||||
'd07a be94 1054 d444 a820 0595 040b 8166' +
|
||||
'e082 a62d 1bff').replace(/ /g, ''),
|
||||
'hex'));
|
||||
|
||||
assert.equal(new Buffer(decoder.decodeStr()).toString(),
|
||||
'Mon, 21 Oct 2013 20:13:21 GMT');
|
||||
});
|
||||
|
||||
it('should decode literal from (C.6.1) #2', function() {
|
||||
decoder.push(new Buffer(
|
||||
('91' +
|
||||
'9d29 ad17 1863 c78f 0b97 c8e9 ae82 ae43' +
|
||||
'd3').replace(/ /g, ''),
|
||||
'hex'));
|
||||
assert.equal(new Buffer(decoder.decodeStr()).toString(),
|
||||
'https://www.example.com');
|
||||
});
|
||||
|
||||
it('should decode many 5 bit chars', function() {
|
||||
// e = 00101, 0x294A5294A5 = 00101 x 8
|
||||
decoder.push(new Buffer('85294A5294A5', 'hex'));
|
||||
assert.equal(new Buffer(decoder.decodeStr()).toString(), 'eeeeeeee');
|
||||
});
|
||||
|
||||
it('should decode many 5 bit chars with 3-bit EOS', function() {
|
||||
// e = 00101, EOS=111,
|
||||
// 0x294A5294A52F = 00101 x 9 + 111
|
||||
decoder.push(new Buffer('86294A5294A52F', 'hex'));
|
||||
assert.equal(new Buffer(decoder.decodeStr()).toString(), 'eeeeeeeee');
|
||||
});
|
||||
|
||||
it('should decode many 5 bit chars with 2-bit EOS', function() {
|
||||
// e = 00101, EOS=11,
|
||||
// 0x294A5297 = 00101 x 6 + 11
|
||||
decoder.push(new Buffer('84294A5297', 'hex'));
|
||||
assert.equal(new Buffer(decoder.decodeStr()).toString(), 'eeeeee');
|
||||
});
|
||||
|
||||
it('should decode many multi-octet chars', function() {
|
||||
decoder.push(new Buffer(
|
||||
'97ffffb1ffff63fffec7fffd8ffffb1ffff63fffec7fffd8',
|
||||
'hex'));
|
||||
assert.deepEqual(decoder.decodeStr(), [
|
||||
1, 1, 1, 1, 1, 1, 1, 1
|
||||
]);
|
||||
});
|
||||
|
||||
it('should fail on 8 bit EOS', function() {
|
||||
// e = 00101, 0x294A5294A5 = 00101 x 8
|
||||
decoder.push(new Buffer('86294A5294A5ff', 'hex'));
|
||||
assert.throws(function() {
|
||||
decoder.decodeStr();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fail on invalid 2-bit EOS', function() {
|
||||
// e = 00101, EOS=10,
|
||||
// 0x294A5297 = 00101 x 6 + 11
|
||||
decoder.push(new Buffer('84294A5296', 'hex'));
|
||||
assert.throws(function() {
|
||||
decoder.decodeStr();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
+184
@@ -0,0 +1,184 @@
|
||||
var assert = require('assert');
|
||||
var hpack = require('../');
|
||||
var fixtures = require('./fixtures');
|
||||
|
||||
describe('hpack/decompressor', function() {
|
||||
var decomp;
|
||||
|
||||
beforeEach(function() {
|
||||
decomp = hpack.decompressor.create({
|
||||
table: {
|
||||
maxSize: 1024
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('indexed field', function() {
|
||||
it('should fail on 0-index', function(cb) {
|
||||
decomp.write(new Buffer([ 0b10000000 ]));
|
||||
decomp.execute(function(err) {
|
||||
assert(/zero index/i.test(err.message), err.message);
|
||||
cb();
|
||||
});
|
||||
});
|
||||
|
||||
it('should fetch entry from static table', function() {
|
||||
decomp.write(new Buffer([ 0b10000000 | 2 ]));
|
||||
decomp.execute();
|
||||
var field = decomp.read();
|
||||
assert.equal(field.name, ':method');
|
||||
assert.equal(field.value, 'GET');
|
||||
});
|
||||
|
||||
it('should fetch entry from the end of the static table', function() {
|
||||
decomp.write(new Buffer([ 0b10000000 | 61 ]));
|
||||
decomp.execute();
|
||||
var field = decomp.read();
|
||||
assert.equal(field.name, 'www-authenticate');
|
||||
assert.equal(field.value, '');
|
||||
});
|
||||
|
||||
it('should fail on OOB-index', function(cb) {
|
||||
decomp.write(new Buffer([ 0b11000000 ]));
|
||||
decomp.execute(function(err) {
|
||||
assert(/field oob/i.test(err.message), err.message);
|
||||
cb();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('literal field', function() {
|
||||
it('should lookup name in the table (incremental)', function() {
|
||||
var value = new Buffer('localhost');
|
||||
var header = new Buffer([
|
||||
0b01000000 | 38, // 38th element from static table
|
||||
value.length
|
||||
]);
|
||||
decomp.write(Buffer.concat([ header, value ]));
|
||||
decomp.execute();
|
||||
|
||||
var field = decomp.read();
|
||||
assert.equal(field.name, 'host');
|
||||
assert.equal(field.value, 'localhost');
|
||||
|
||||
decomp.write(new Buffer([ 0b10000000 | 62 ]));
|
||||
decomp.execute();
|
||||
var field = decomp.read();
|
||||
assert.equal(field.name, 'host');
|
||||
assert.equal(field.value, 'localhost');
|
||||
});
|
||||
|
||||
it('should lookup name in the table (not-incremental)', function(cb) {
|
||||
var value = new Buffer('localhost');
|
||||
var header = new Buffer([
|
||||
0b00001111,
|
||||
0b00000000 | 23,
|
||||
value.length
|
||||
]);
|
||||
decomp.write(Buffer.concat([ header, value ]));
|
||||
decomp.execute();
|
||||
|
||||
var field = decomp.read();
|
||||
assert.equal(field.name, 'host');
|
||||
assert.equal(field.value, 'localhost');
|
||||
|
||||
decomp.write(new Buffer([ 0b10000000 | 62 ]));
|
||||
decomp.execute(function(err) {
|
||||
assert(/field oob/i.test(err.message), err.message);
|
||||
cb();
|
||||
});
|
||||
});
|
||||
|
||||
it('should evict header field from the table', function() {
|
||||
var value = new Buffer('localhost');
|
||||
var header = new Buffer([
|
||||
0b01000000 | 38, // 38th element from static table
|
||||
value.length
|
||||
]);
|
||||
for (var i = 0; i < 1000; i++) {
|
||||
decomp.write(Buffer.concat([ header, value ]));
|
||||
decomp.execute();
|
||||
var field = decomp.read();
|
||||
assert.equal(field.name, 'host');
|
||||
assert.equal(field.value, 'localhost');
|
||||
}
|
||||
|
||||
assert(decomp._table.size < decomp._table.maxSize);
|
||||
assert.equal(decomp._table.dynamic.length, 22);
|
||||
});
|
||||
});
|
||||
|
||||
describe('update size', function() {
|
||||
it('should evict header field from the table', function() {
|
||||
var value = new Buffer('localhost');
|
||||
var header = new Buffer([
|
||||
0b01000000 | 38, // 38th element from static table
|
||||
value.length
|
||||
]);
|
||||
|
||||
decomp.write(Buffer.concat([ header, value ]));
|
||||
decomp.execute();
|
||||
var field = decomp.read();
|
||||
assert.equal(field.name, 'host');
|
||||
assert.equal(field.value, 'localhost');
|
||||
assert.equal(decomp._table.dynamic.length, 1);
|
||||
|
||||
decomp.write(new Buffer([
|
||||
0b00100000
|
||||
]));
|
||||
decomp.execute();
|
||||
|
||||
assert.equal(decomp._table.dynamic.length, 0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('spec examples', function() {
|
||||
var decomp;
|
||||
beforeEach(function() {
|
||||
decomp = hpack.decompressor.create({
|
||||
table: {
|
||||
maxSize: 256
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
var tests = fixtures.specExamples;
|
||||
|
||||
tests.forEach(function(test, i) {
|
||||
var prev = tests[i - 1];
|
||||
it('should give expected output on ' + test.id, function() {
|
||||
var startFrom = test.continuation ? prev.decomp : decomp;
|
||||
if (!startFrom)
|
||||
throw new Error('Previous test failed');
|
||||
decomp = startFrom;
|
||||
|
||||
decomp.write(new Buffer(test.input.replace(/ /g, ''), 'hex'));
|
||||
decomp.execute();
|
||||
|
||||
var output = [];
|
||||
for (;;) {
|
||||
var chunk = decomp.read();
|
||||
if (!chunk)
|
||||
break;
|
||||
|
||||
output.push([ chunk.name, chunk.value ]);
|
||||
}
|
||||
|
||||
assert.deepEqual(output, test.output);
|
||||
|
||||
// Verify table contents
|
||||
assert.deepEqual(decomp._table.dynamic.map(function(header) {
|
||||
return [ header.name, header.value, header.totalSize ];
|
||||
}).reverse(), test.table);
|
||||
|
||||
// Verify table size
|
||||
var expectedSize = test.table.reduce(function(acc, item) {
|
||||
return acc + item[2];
|
||||
}, 0);
|
||||
assert.equal(decomp._table.size, expectedSize);
|
||||
|
||||
test.decomp = decomp;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
+166
@@ -0,0 +1,166 @@
|
||||
var assert = require('assert');
|
||||
var hpack = require('../');
|
||||
|
||||
describe('hpack/encoder', function() {
|
||||
var encoder;
|
||||
|
||||
beforeEach(function() {
|
||||
encoder = hpack.encoder.create();
|
||||
});
|
||||
|
||||
function expect(arr, enc) {
|
||||
function isNumber(num) {
|
||||
return typeof num === 'number';
|
||||
}
|
||||
|
||||
var out = Buffer.concat(encoder.render()).toString('hex');
|
||||
if (Array.isArray(arr) && !arr.every(isNumber)) {
|
||||
arr = arr.map(function(item) {
|
||||
return new Buffer(item, enc);
|
||||
});
|
||||
arr = Buffer.concat(arr);
|
||||
} else {
|
||||
arr = new Buffer(arr, enc);
|
||||
}
|
||||
var actual = arr.toString('hex');
|
||||
assert.equal(out, actual);
|
||||
}
|
||||
|
||||
describe('bit', function() {
|
||||
it('should encode number bit-by-bit', function() {
|
||||
[ 1, 1, 1, 0, 1, 0, 1, 0,
|
||||
1, 0, 1, 0, 1, 1, 1, 1 ].forEach(function(bit) {
|
||||
encoder.encodeBit(bit);
|
||||
});
|
||||
expect([
|
||||
0b11101010,
|
||||
0b10101111
|
||||
]);
|
||||
});
|
||||
|
||||
it('should encode number using multiple bits', function() {
|
||||
for (var i = 0; i < 8; i++)
|
||||
encoder.encodeBits(0b1011010, 7);
|
||||
expect([
|
||||
0b10110101,
|
||||
0b01101010,
|
||||
0b11010101,
|
||||
0b10101011,
|
||||
0b01010110,
|
||||
0b10101101,
|
||||
0b01011010
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('integer', function() {
|
||||
it('should encode 10 in prefix-5 (C.1.1)', function() {
|
||||
encoder.skipBits(3);
|
||||
encoder.encodeInt(10);
|
||||
expect([ 0x0a ]);
|
||||
});
|
||||
|
||||
it('should decode 1337 in prefix-5 (C.1.2)', function() {
|
||||
encoder.skipBits(3);
|
||||
encoder.encodeInt(1337);
|
||||
expect([
|
||||
0b00011111,
|
||||
0b10011010,
|
||||
0b00001010
|
||||
]);
|
||||
});
|
||||
|
||||
it('should decode 42 at octect boundary (C.1.3)', function() {
|
||||
encoder.encodeInt(42);
|
||||
expect([ 0b00101010 ]);
|
||||
});
|
||||
|
||||
it('should regression 6-bit test', function() {
|
||||
encoder.skipBits(2);
|
||||
encoder.encodeInt(63);
|
||||
expect([ 0b00111111, 0b00000000 ]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('string', function() {
|
||||
it('should encode literal from (C.2.1)', function() {
|
||||
encoder.encodeStr(new Buffer('custom-key'), false);
|
||||
expect([ [ 0x0a ], 'custom-key' ]);
|
||||
});
|
||||
|
||||
it('should encode literal from (C.4.1)', function() {
|
||||
encoder.encodeStr(new Buffer('www.example.com'), true);
|
||||
expect('8c' +
|
||||
'f1e3 c2e5 f23a 6ba0 ab90 f4ff'.replace(/ /g, ''),
|
||||
'hex');
|
||||
});
|
||||
|
||||
it('should decode literal from (C.4.2)', function() {
|
||||
encoder.encodeStr(new Buffer('no-cache'), true);
|
||||
expect(
|
||||
'86' +
|
||||
'a8eb 1064 9cbf'.replace(/ /g, ''),
|
||||
'hex');
|
||||
});
|
||||
|
||||
it('should encode literal from (C.4.3) #1', function() {
|
||||
encoder.encodeStr(new Buffer('custom-key'), true);
|
||||
expect(
|
||||
'88' +
|
||||
'25a8 49e9 5ba9 7d7f'.replace(/ /g, ''),
|
||||
'hex');
|
||||
});
|
||||
|
||||
it('should encode literal from (C.4.3) #2', function() {
|
||||
encoder.encodeStr(new Buffer('custom-value'), true);
|
||||
expect(
|
||||
'89' +
|
||||
'25a8 49e9 5bb8 e8b4 bf'.replace(/ /g, ''),
|
||||
'hex');
|
||||
});
|
||||
|
||||
it('should encode literal from (C.6.1) #1', function() {
|
||||
encoder.encodeStr(new Buffer('Mon, 21 Oct 2013 20:13:21 GMT'), true);
|
||||
expect(
|
||||
('96' +
|
||||
'd07a be94 1054 d444 a820 0595 040b 8166' +
|
||||
'e082 a62d 1bff').replace(/ /g, ''),
|
||||
'hex');
|
||||
});
|
||||
|
||||
it('should encode literal from (C.6.1) #2', function() {
|
||||
encoder.encodeStr(new Buffer('https://www.example.com'), true);
|
||||
expect(
|
||||
('91' +
|
||||
'9d29 ad17 1863 c78f 0b97 c8e9 ae82 ae43' +
|
||||
'd3').replace(/ /g, ''),
|
||||
'hex');
|
||||
});
|
||||
|
||||
it('should encode many 5 bit chars', function() {
|
||||
encoder.encodeStr(new Buffer('eeeeeeee'), true);
|
||||
// e = 00101, 0x294A5294A5 = 00101 x 8
|
||||
expect('85294A5294A5', 'hex');
|
||||
});
|
||||
|
||||
it('should encode many 5 bit chars with 3-bit EOS', function() {
|
||||
// e = 00101, EOS=111,
|
||||
// 0x294A5294A52F = 00101 x 9 + 111
|
||||
encoder.encodeStr(new Buffer('eeeeeeeee'), true);
|
||||
expect('86294A5294A52F', 'hex');
|
||||
});
|
||||
|
||||
it('should decode many 5 bit chars with 2-bit EOS', function() {
|
||||
// e = 00101, EOS=11,
|
||||
// 0x294A5297 = 00101 x 6 + 11
|
||||
encoder.encodeStr(new Buffer('eeeeee'), true);
|
||||
expect('84294A5297', 'hex');
|
||||
});
|
||||
|
||||
it('should decode many multi-octet chars', function() {
|
||||
encoder.encodeStr([ 1, 1, 1, 1, 1, 1, 1, 1 ], true);
|
||||
expect('97ffffb1ffff63fffec7fffd8ffffb1ffff63fffec7fffd8',
|
||||
'hex');
|
||||
});
|
||||
});
|
||||
});
|
||||
+232
@@ -0,0 +1,232 @@
|
||||
exports.specExamples = [
|
||||
{
|
||||
id: 'C.3.1',
|
||||
huffman: false,
|
||||
input: '8286 8441 0f77 7777 2e65 7861 6d70 6c65' +
|
||||
'2e63 6f6d',
|
||||
output: [
|
||||
[ ':method', 'GET' ],
|
||||
[ ':scheme', 'http' ],
|
||||
[ ':path', '/' ],
|
||||
[ ':authority', 'www.example.com' ]
|
||||
],
|
||||
table: [
|
||||
[ ':authority', 'www.example.com', 57 ]
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'C.3.2',
|
||||
continuation: true,
|
||||
huffman: false,
|
||||
input: '8286 84be 5808 6e6f 2d63 6163 6865',
|
||||
output: [
|
||||
[ ':method', 'GET' ],
|
||||
[ ':scheme', 'http' ],
|
||||
[ ':path', '/' ],
|
||||
[ ':authority', 'www.example.com' ],
|
||||
[ 'cache-control', 'no-cache' ]
|
||||
],
|
||||
table: [
|
||||
[ 'cache-control', 'no-cache', 53 ],
|
||||
[ ':authority', 'www.example.com', 57 ]
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'C.3.3',
|
||||
continuation: true,
|
||||
huffman: false,
|
||||
input: '8287 85bf 400a 6375 7374 6f6d 2d6b 6579' +
|
||||
'0c63 7573 746f 6d2d 7661 6c75 65',
|
||||
output: [
|
||||
[ ':method', 'GET' ],
|
||||
[ ':scheme', 'https' ],
|
||||
[ ':path', '/index.html' ],
|
||||
[ ':authority', 'www.example.com' ],
|
||||
[ 'custom-key', 'custom-value' ]
|
||||
],
|
||||
table: [
|
||||
[ 'custom-key', 'custom-value', 54 ],
|
||||
[ 'cache-control', 'no-cache', 53 ],
|
||||
[ ':authority', 'www.example.com', 57 ]
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
id: 'C.4.1',
|
||||
input: '8286 8441 8cf1 e3c2 e5f2 3a6b a0ab 90f4' +
|
||||
'ff',
|
||||
output: [
|
||||
[ ':method', 'GET' ],
|
||||
[ ':scheme', 'http' ],
|
||||
[ ':path', '/' ],
|
||||
[ ':authority', 'www.example.com' ]
|
||||
],
|
||||
table: [
|
||||
[ ':authority', 'www.example.com', 57 ]
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'C.4.2',
|
||||
continuation: true,
|
||||
input: '8286 84be 5886 a8eb 1064 9cbf',
|
||||
output: [
|
||||
[ ':method', 'GET' ],
|
||||
[ ':scheme', 'http' ],
|
||||
[ ':path', '/' ],
|
||||
[ ':authority', 'www.example.com' ],
|
||||
[ 'cache-control', 'no-cache' ]
|
||||
],
|
||||
table: [
|
||||
[ 'cache-control', 'no-cache', 53 ],
|
||||
[ ':authority', 'www.example.com', 57 ]
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'C.4.3',
|
||||
continuation: true,
|
||||
input: '8287 85bf 4088 25a8 49e9 5ba9 7d7f 8925' +
|
||||
'a849 e95b b8e8 b4bf',
|
||||
output: [
|
||||
[ ':method', 'GET' ],
|
||||
[ ':scheme', 'https' ],
|
||||
[ ':path', '/index.html' ],
|
||||
[ ':authority', 'www.example.com' ],
|
||||
[ 'custom-key', 'custom-value' ]
|
||||
],
|
||||
table: [
|
||||
[ 'custom-key', 'custom-value', 54 ],
|
||||
[ 'cache-control', 'no-cache', 53 ],
|
||||
[ ':authority', 'www.example.com', 57 ]
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
id: 'C.5.1',
|
||||
huffman: false,
|
||||
input: '4803 3330 3258 0770 7269 7661 7465 611d' +
|
||||
'4d6f 6e2c 2032 3120 4f63 7420 3230 3133' +
|
||||
'2032 303a 3133 3a32 3120 474d 546e 1768' +
|
||||
'7474 7073 3a2f 2f77 7777 2e65 7861 6d70' +
|
||||
'6c65 2e63 6f6d',
|
||||
output: [
|
||||
[ ':status', '302' ],
|
||||
[ 'cache-control', 'private' ],
|
||||
[ 'date', 'Mon, 21 Oct 2013 20:13:21 GMT' ],
|
||||
[ 'location', 'https://www.example.com' ]
|
||||
],
|
||||
table: [
|
||||
[ 'location', 'https://www.example.com', 63 ],
|
||||
[ 'date', 'Mon, 21 Oct 2013 20:13:21 GMT', 65 ],
|
||||
[ 'cache-control', 'private', 52 ],
|
||||
[ ':status', '302', 42 ]
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'C.5.2',
|
||||
huffman: false,
|
||||
continuation: true,
|
||||
input: '4803 3330 37c1 c0bf',
|
||||
output: [
|
||||
[ ':status', '307' ],
|
||||
[ 'cache-control', 'private' ],
|
||||
[ 'date', 'Mon, 21 Oct 2013 20:13:21 GMT' ],
|
||||
[ 'location', 'https://www.example.com' ]
|
||||
],
|
||||
table: [
|
||||
[ ':status', '307', 42 ],
|
||||
[ 'location', 'https://www.example.com', 63 ],
|
||||
[ 'date', 'Mon, 21 Oct 2013 20:13:21 GMT', 65 ],
|
||||
[ 'cache-control', 'private', 52 ]
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'C.5.3',
|
||||
huffman: false,
|
||||
continuation: true,
|
||||
input: '88c1 611d 4d6f 6e2c 2032 3120 4f63 7420' +
|
||||
'3230 3133 2032 303a 3133 3a32 3220 474d' +
|
||||
'54c0 5a04 677a 6970 7738 666f 6f3d 4153' +
|
||||
'444a 4b48 514b 425a 584f 5157 454f 5049' +
|
||||
'5541 5851 5745 4f49 553b 206d 6178 2d61' +
|
||||
'6765 3d33 3630 303b 2076 6572 7369 6f6e' +
|
||||
'3d31',
|
||||
output: [
|
||||
[ ':status', '200' ],
|
||||
[ 'cache-control', 'private' ],
|
||||
[ 'date', 'Mon, 21 Oct 2013 20:13:22 GMT' ],
|
||||
[ 'location', 'https://www.example.com' ],
|
||||
[ 'content-encoding', 'gzip' ],
|
||||
[ 'set-cookie',
|
||||
'foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1' ]
|
||||
],
|
||||
table: [
|
||||
[ 'set-cookie',
|
||||
'foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1',
|
||||
98 ],
|
||||
[ 'content-encoding', 'gzip', 52 ],
|
||||
[ 'date', 'Mon, 21 Oct 2013 20:13:22 GMT', 65 ]
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
id: 'C.6.1',
|
||||
input: '4882 6402 5885 aec3 771a 4b61 96d0 7abe' +
|
||||
'9410 54d4 44a8 2005 9504 0b81 66e0 82a6' +
|
||||
'2d1b ff6e 919d 29ad 1718 63c7 8f0b 97c8' +
|
||||
'e9ae 82ae 43d3',
|
||||
output: [
|
||||
[ ':status', '302' ],
|
||||
[ 'cache-control', 'private' ],
|
||||
[ 'date', 'Mon, 21 Oct 2013 20:13:21 GMT' ],
|
||||
[ 'location', 'https://www.example.com' ]
|
||||
],
|
||||
table: [
|
||||
[ 'location', 'https://www.example.com', 63 ],
|
||||
[ 'date', 'Mon, 21 Oct 2013 20:13:21 GMT', 65 ],
|
||||
[ 'cache-control', 'private', 52 ],
|
||||
[ ':status', '302', 42 ]
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'C.6.2',
|
||||
continuation: true,
|
||||
input: '4883 640e ffc1 c0bf',
|
||||
output: [
|
||||
[ ':status', '307' ],
|
||||
[ 'cache-control', 'private' ],
|
||||
[ 'date', 'Mon, 21 Oct 2013 20:13:21 GMT' ],
|
||||
[ 'location', 'https://www.example.com' ]
|
||||
],
|
||||
table: [
|
||||
[ ':status', '307', 42 ],
|
||||
[ 'location', 'https://www.example.com', 63 ],
|
||||
[ 'date', 'Mon, 21 Oct 2013 20:13:21 GMT', 65 ],
|
||||
[ 'cache-control', 'private', 52 ]
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'C.6.3',
|
||||
continuation: true,
|
||||
input: '88c1 6196 d07a be94 1054 d444 a820 0595' +
|
||||
'040b 8166 e084 a62d 1bff c05a 839b d9ab' +
|
||||
'77ad 94e7 821d d7f2 e6c7 b335 dfdf cd5b' +
|
||||
'3960 d5af 2708 7f36 72c1 ab27 0fb5 291f' +
|
||||
'9587 3160 65c0 03ed 4ee5 b106 3d50 07',
|
||||
output: [
|
||||
[ ':status', '200' ],
|
||||
[ 'cache-control', 'private' ],
|
||||
[ 'date', 'Mon, 21 Oct 2013 20:13:22 GMT' ],
|
||||
[ 'location', 'https://www.example.com' ],
|
||||
[ 'content-encoding', 'gzip' ],
|
||||
[ 'set-cookie',
|
||||
'foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1' ]
|
||||
],
|
||||
table: [
|
||||
[ 'set-cookie',
|
||||
'foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1',
|
||||
98 ],
|
||||
[ 'content-encoding', 'gzip', 52 ],
|
||||
[ 'date', 'Mon, 21 Oct 2013 20:13:22 GMT', 65 ]
|
||||
]
|
||||
}
|
||||
];
|
||||
+309
@@ -0,0 +1,309 @@
|
||||
var utils = require('./utils');
|
||||
|
||||
var table = `
|
||||
( 0) |11111111|11000 1ff8 [13]
|
||||
( 1) |11111111|11111111|1011000 7fffd8 [23]
|
||||
( 2) |11111111|11111111|11111110|0010 fffffe2 [28]
|
||||
( 3) |11111111|11111111|11111110|0011 fffffe3 [28]
|
||||
( 4) |11111111|11111111|11111110|0100 fffffe4 [28]
|
||||
( 5) |11111111|11111111|11111110|0101 fffffe5 [28]
|
||||
( 6) |11111111|11111111|11111110|0110 fffffe6 [28]
|
||||
( 7) |11111111|11111111|11111110|0111 fffffe7 [28]
|
||||
( 8) |11111111|11111111|11111110|1000 fffffe8 [28]
|
||||
( 9) |11111111|11111111|11101010 ffffea [24]
|
||||
( 10) |11111111|11111111|11111111|111100 3ffffffc [30]
|
||||
( 11) |11111111|11111111|11111110|1001 fffffe9 [28]
|
||||
( 12) |11111111|11111111|11111110|1010 fffffea [28]
|
||||
( 13) |11111111|11111111|11111111|111101 3ffffffd [30]
|
||||
( 14) |11111111|11111111|11111110|1011 fffffeb [28]
|
||||
( 15) |11111111|11111111|11111110|1100 fffffec [28]
|
||||
( 16) |11111111|11111111|11111110|1101 fffffed [28]
|
||||
( 17) |11111111|11111111|11111110|1110 fffffee [28]
|
||||
( 18) |11111111|11111111|11111110|1111 fffffef [28]
|
||||
( 19) |11111111|11111111|11111111|0000 ffffff0 [28]
|
||||
( 20) |11111111|11111111|11111111|0001 ffffff1 [28]
|
||||
( 21) |11111111|11111111|11111111|0010 ffffff2 [28]
|
||||
( 22) |11111111|11111111|11111111|111110 3ffffffe [30]
|
||||
( 23) |11111111|11111111|11111111|0011 ffffff3 [28]
|
||||
( 24) |11111111|11111111|11111111|0100 ffffff4 [28]
|
||||
( 25) |11111111|11111111|11111111|0101 ffffff5 [28]
|
||||
( 26) |11111111|11111111|11111111|0110 ffffff6 [28]
|
||||
( 27) |11111111|11111111|11111111|0111 ffffff7 [28]
|
||||
( 28) |11111111|11111111|11111111|1000 ffffff8 [28]
|
||||
( 29) |11111111|11111111|11111111|1001 ffffff9 [28]
|
||||
( 30) |11111111|11111111|11111111|1010 ffffffa [28]
|
||||
( 31) |11111111|11111111|11111111|1011 ffffffb [28]
|
||||
' ' ( 32) |010100 14 [ 6]
|
||||
'!' ( 33) |11111110|00 3f8 [10]
|
||||
'"' ( 34) |11111110|01 3f9 [10]
|
||||
'#' ( 35) |11111111|1010 ffa [12]
|
||||
'$' ( 36) |11111111|11001 1ff9 [13]
|
||||
'%' ( 37) |010101 15 [ 6]
|
||||
'&' ( 38) |11111000 f8 [ 8]
|
||||
''' ( 39) |11111111|010 7fa [11]
|
||||
'(' ( 40) |11111110|10 3fa [10]
|
||||
')' ( 41) |11111110|11 3fb [10]
|
||||
'*' ( 42) |11111001 f9 [ 8]
|
||||
'+' ( 43) |11111111|011 7fb [11]
|
||||
',' ( 44) |11111010 fa [ 8]
|
||||
'-' ( 45) |010110 16 [ 6]
|
||||
'.' ( 46) |010111 17 [ 6]
|
||||
'/' ( 47) |011000 18 [ 6]
|
||||
'0' ( 48) |00000 0 [ 5]
|
||||
'1' ( 49) |00001 1 [ 5]
|
||||
'2' ( 50) |00010 2 [ 5]
|
||||
'3' ( 51) |011001 19 [ 6]
|
||||
'4' ( 52) |011010 1a [ 6]
|
||||
'5' ( 53) |011011 1b [ 6]
|
||||
'6' ( 54) |011100 1c [ 6]
|
||||
'7' ( 55) |011101 1d [ 6]
|
||||
'8' ( 56) |011110 1e [ 6]
|
||||
'9' ( 57) |011111 1f [ 6]
|
||||
':' ( 58) |1011100 5c [ 7]
|
||||
';' ( 59) |11111011 fb [ 8]
|
||||
'<' ( 60) |11111111|1111100 7ffc [15]
|
||||
'=' ( 61) |100000 20 [ 6]
|
||||
'>' ( 62) |11111111|1011 ffb [12]
|
||||
'?' ( 63) |11111111|00 3fc [10]
|
||||
'@' ( 64) |11111111|11010 1ffa [13]
|
||||
'A' ( 65) |100001 21 [ 6]
|
||||
'B' ( 66) |1011101 5d [ 7]
|
||||
'C' ( 67) |1011110 5e [ 7]
|
||||
'D' ( 68) |1011111 5f [ 7]
|
||||
'E' ( 69) |1100000 60 [ 7]
|
||||
'F' ( 70) |1100001 61 [ 7]
|
||||
'G' ( 71) |1100010 62 [ 7]
|
||||
'H' ( 72) |1100011 63 [ 7]
|
||||
'I' ( 73) |1100100 64 [ 7]
|
||||
'J' ( 74) |1100101 65 [ 7]
|
||||
'K' ( 75) |1100110 66 [ 7]
|
||||
'L' ( 76) |1100111 67 [ 7]
|
||||
'M' ( 77) |1101000 68 [ 7]
|
||||
'N' ( 78) |1101001 69 [ 7]
|
||||
'O' ( 79) |1101010 6a [ 7]
|
||||
'P' ( 80) |1101011 6b [ 7]
|
||||
'Q' ( 81) |1101100 6c [ 7]
|
||||
'R' ( 82) |1101101 6d [ 7]
|
||||
'S' ( 83) |1101110 6e [ 7]
|
||||
'T' ( 84) |1101111 6f [ 7]
|
||||
'U' ( 85) |1110000 70 [ 7]
|
||||
'V' ( 86) |1110001 71 [ 7]
|
||||
'W' ( 87) |1110010 72 [ 7]
|
||||
'X' ( 88) |11111100 fc [ 8]
|
||||
'Y' ( 89) |1110011 73 [ 7]
|
||||
'Z' ( 90) |11111101 fd [ 8]
|
||||
'[' ( 91) |11111111|11011 1ffb [13]
|
||||
'\\' ( 92) |11111111|11111110|000 7fff0 [19]
|
||||
']' ( 93) |11111111|11100 1ffc [13]
|
||||
'^' ( 94) |11111111|111100 3ffc [14]
|
||||
'_' ( 95) |100010 22 [ 6]
|
||||
'\`' ( 96) |11111111|1111101 7ffd [15]
|
||||
'a' ( 97) |00011 3 [ 5]
|
||||
'b' ( 98) |100011 23 [ 6]
|
||||
'c' ( 99) |00100 4 [ 5]
|
||||
'd' (100) |100100 24 [ 6]
|
||||
'e' (101) |00101 5 [ 5]
|
||||
'f' (102) |100101 25 [ 6]
|
||||
'g' (103) |100110 26 [ 6]
|
||||
'h' (104) |100111 27 [ 6]
|
||||
'i' (105) |00110 6 [ 5]
|
||||
'j' (106) |1110100 74 [ 7]
|
||||
'k' (107) |1110101 75 [ 7]
|
||||
'l' (108) |101000 28 [ 6]
|
||||
'm' (109) |101001 29 [ 6]
|
||||
'n' (110) |101010 2a [ 6]
|
||||
'o' (111) |00111 7 [ 5]
|
||||
'p' (112) |101011 2b [ 6]
|
||||
'q' (113) |1110110 76 [ 7]
|
||||
'r' (114) |101100 2c [ 6]
|
||||
's' (115) |01000 8 [ 5]
|
||||
't' (116) |01001 9 [ 5]
|
||||
'u' (117) |101101 2d [ 6]
|
||||
'v' (118) |1110111 77 [ 7]
|
||||
'w' (119) |1111000 78 [ 7]
|
||||
'x' (120) |1111001 79 [ 7]
|
||||
'y' (121) |1111010 7a [ 7]
|
||||
'z' (122) |1111011 7b [ 7]
|
||||
'{' (123) |11111111|1111110 7ffe [15]
|
||||
'|' (124) |11111111|100 7fc [11]
|
||||
'}' (125) |11111111|111101 3ffd [14]
|
||||
'~' (126) |11111111|11101 1ffd [13]
|
||||
(127) |11111111|11111111|11111111|1100 ffffffc [28]
|
||||
(128) |11111111|11111110|0110 fffe6 [20]
|
||||
(129) |11111111|11111111|010010 3fffd2 [22]
|
||||
(130) |11111111|11111110|0111 fffe7 [20]
|
||||
(131) |11111111|11111110|1000 fffe8 [20]
|
||||
(132) |11111111|11111111|010011 3fffd3 [22]
|
||||
(133) |11111111|11111111|010100 3fffd4 [22]
|
||||
(134) |11111111|11111111|010101 3fffd5 [22]
|
||||
(135) |11111111|11111111|1011001 7fffd9 [23]
|
||||
(136) |11111111|11111111|010110 3fffd6 [22]
|
||||
(137) |11111111|11111111|1011010 7fffda [23]
|
||||
(138) |11111111|11111111|1011011 7fffdb [23]
|
||||
(139) |11111111|11111111|1011100 7fffdc [23]
|
||||
(140) |11111111|11111111|1011101 7fffdd [23]
|
||||
(141) |11111111|11111111|1011110 7fffde [23]
|
||||
(142) |11111111|11111111|11101011 ffffeb [24]
|
||||
(143) |11111111|11111111|1011111 7fffdf [23]
|
||||
(144) |11111111|11111111|11101100 ffffec [24]
|
||||
(145) |11111111|11111111|11101101 ffffed [24]
|
||||
(146) |11111111|11111111|010111 3fffd7 [22]
|
||||
(147) |11111111|11111111|1100000 7fffe0 [23]
|
||||
(148) |11111111|11111111|11101110 ffffee [24]
|
||||
(149) |11111111|11111111|1100001 7fffe1 [23]
|
||||
(150) |11111111|11111111|1100010 7fffe2 [23]
|
||||
(151) |11111111|11111111|1100011 7fffe3 [23]
|
||||
(152) |11111111|11111111|1100100 7fffe4 [23]
|
||||
(153) |11111111|11111110|11100 1fffdc [21]
|
||||
(154) |11111111|11111111|011000 3fffd8 [22]
|
||||
(155) |11111111|11111111|1100101 7fffe5 [23]
|
||||
(156) |11111111|11111111|011001 3fffd9 [22]
|
||||
(157) |11111111|11111111|1100110 7fffe6 [23]
|
||||
(158) |11111111|11111111|1100111 7fffe7 [23]
|
||||
(159) |11111111|11111111|11101111 ffffef [24]
|
||||
(160) |11111111|11111111|011010 3fffda [22]
|
||||
(161) |11111111|11111110|11101 1fffdd [21]
|
||||
(162) |11111111|11111110|1001 fffe9 [20]
|
||||
(163) |11111111|11111111|011011 3fffdb [22]
|
||||
(164) |11111111|11111111|011100 3fffdc [22]
|
||||
(165) |11111111|11111111|1101000 7fffe8 [23]
|
||||
(166) |11111111|11111111|1101001 7fffe9 [23]
|
||||
(167) |11111111|11111110|11110 1fffde [21]
|
||||
(168) |11111111|11111111|1101010 7fffea [23]
|
||||
(169) |11111111|11111111|011101 3fffdd [22]
|
||||
(170) |11111111|11111111|011110 3fffde [22]
|
||||
(171) |11111111|11111111|11110000 fffff0 [24]
|
||||
(172) |11111111|11111110|11111 1fffdf [21]
|
||||
(173) |11111111|11111111|011111 3fffdf [22]
|
||||
(174) |11111111|11111111|1101011 7fffeb [23]
|
||||
(175) |11111111|11111111|1101100 7fffec [23]
|
||||
(176) |11111111|11111111|00000 1fffe0 [21]
|
||||
(177) |11111111|11111111|00001 1fffe1 [21]
|
||||
(178) |11111111|11111111|100000 3fffe0 [22]
|
||||
(179) |11111111|11111111|00010 1fffe2 [21]
|
||||
(180) |11111111|11111111|1101101 7fffed [23]
|
||||
(181) |11111111|11111111|100001 3fffe1 [22]
|
||||
(182) |11111111|11111111|1101110 7fffee [23]
|
||||
(183) |11111111|11111111|1101111 7fffef [23]
|
||||
(184) |11111111|11111110|1010 fffea [20]
|
||||
(185) |11111111|11111111|100010 3fffe2 [22]
|
||||
(186) |11111111|11111111|100011 3fffe3 [22]
|
||||
(187) |11111111|11111111|100100 3fffe4 [22]
|
||||
(188) |11111111|11111111|1110000 7ffff0 [23]
|
||||
(189) |11111111|11111111|100101 3fffe5 [22]
|
||||
(190) |11111111|11111111|100110 3fffe6 [22]
|
||||
(191) |11111111|11111111|1110001 7ffff1 [23]
|
||||
(192) |11111111|11111111|11111000|00 3ffffe0 [26]
|
||||
(193) |11111111|11111111|11111000|01 3ffffe1 [26]
|
||||
(194) |11111111|11111110|1011 fffeb [20]
|
||||
(195) |11111111|11111110|001 7fff1 [19]
|
||||
(196) |11111111|11111111|100111 3fffe7 [22]
|
||||
(197) |11111111|11111111|1110010 7ffff2 [23]
|
||||
(198) |11111111|11111111|101000 3fffe8 [22]
|
||||
(199) |11111111|11111111|11110110|0 1ffffec [25]
|
||||
(200) |11111111|11111111|11111000|10 3ffffe2 [26]
|
||||
(201) |11111111|11111111|11111000|11 3ffffe3 [26]
|
||||
(202) |11111111|11111111|11111001|00 3ffffe4 [26]
|
||||
(203) |11111111|11111111|11111011|110 7ffffde [27]
|
||||
(204) |11111111|11111111|11111011|111 7ffffdf [27]
|
||||
(205) |11111111|11111111|11111001|01 3ffffe5 [26]
|
||||
(206) |11111111|11111111|11110001 fffff1 [24]
|
||||
(207) |11111111|11111111|11110110|1 1ffffed [25]
|
||||
(208) |11111111|11111110|010 7fff2 [19]
|
||||
(209) |11111111|11111111|00011 1fffe3 [21]
|
||||
(210) |11111111|11111111|11111001|10 3ffffe6 [26]
|
||||
(211) |11111111|11111111|11111100|000 7ffffe0 [27]
|
||||
(212) |11111111|11111111|11111100|001 7ffffe1 [27]
|
||||
(213) |11111111|11111111|11111001|11 3ffffe7 [26]
|
||||
(214) |11111111|11111111|11111100|010 7ffffe2 [27]
|
||||
(215) |11111111|11111111|11110010 fffff2 [24]
|
||||
(216) |11111111|11111111|00100 1fffe4 [21]
|
||||
(217) |11111111|11111111|00101 1fffe5 [21]
|
||||
(218) |11111111|11111111|11111010|00 3ffffe8 [26]
|
||||
(219) |11111111|11111111|11111010|01 3ffffe9 [26]
|
||||
(220) |11111111|11111111|11111111|1101 ffffffd [28]
|
||||
(221) |11111111|11111111|11111100|011 7ffffe3 [27]
|
||||
(222) |11111111|11111111|11111100|100 7ffffe4 [27]
|
||||
(223) |11111111|11111111|11111100|101 7ffffe5 [27]
|
||||
(224) |11111111|11111110|1100 fffec [20]
|
||||
(225) |11111111|11111111|11110011 fffff3 [24]
|
||||
(226) |11111111|11111110|1101 fffed [20]
|
||||
(227) |11111111|11111111|00110 1fffe6 [21]
|
||||
(228) |11111111|11111111|101001 3fffe9 [22]
|
||||
(229) |11111111|11111111|00111 1fffe7 [21]
|
||||
(230) |11111111|11111111|01000 1fffe8 [21]
|
||||
(231) |11111111|11111111|1110011 7ffff3 [23]
|
||||
(232) |11111111|11111111|101010 3fffea [22]
|
||||
(233) |11111111|11111111|101011 3fffeb [22]
|
||||
(234) |11111111|11111111|11110111|0 1ffffee [25]
|
||||
(235) |11111111|11111111|11110111|1 1ffffef [25]
|
||||
(236) |11111111|11111111|11110100 fffff4 [24]
|
||||
(237) |11111111|11111111|11110101 fffff5 [24]
|
||||
(238) |11111111|11111111|11111010|10 3ffffea [26]
|
||||
(239) |11111111|11111111|1110100 7ffff4 [23]
|
||||
(240) |11111111|11111111|11111010|11 3ffffeb [26]
|
||||
(241) |11111111|11111111|11111100|110 7ffffe6 [27]
|
||||
(242) |11111111|11111111|11111011|00 3ffffec [26]
|
||||
(243) |11111111|11111111|11111011|01 3ffffed [26]
|
||||
(244) |11111111|11111111|11111100|111 7ffffe7 [27]
|
||||
(245) |11111111|11111111|11111101|000 7ffffe8 [27]
|
||||
(246) |11111111|11111111|11111101|001 7ffffe9 [27]
|
||||
(247) |11111111|11111111|11111101|010 7ffffea [27]
|
||||
(248) |11111111|11111111|11111101|011 7ffffeb [27]
|
||||
(249) |11111111|11111111|11111111|1110 ffffffe [28]
|
||||
(250) |11111111|11111111|11111101|100 7ffffec [27]
|
||||
(251) |11111111|11111111|11111101|101 7ffffed [27]
|
||||
(252) |11111111|11111111|11111101|110 7ffffee [27]
|
||||
(253) |11111111|11111111|11111101|111 7ffffef [27]
|
||||
(254) |11111111|11111111|11111110|000 7fffff0 [27]
|
||||
(255) |11111111|11111111|11111011|10 3ffffee [26]
|
||||
EOS (256) |11111111|11111111|11111111|111111 3fffffff [30]
|
||||
`;
|
||||
|
||||
table = table.split('\n').filter(function(line) {
|
||||
return line.length > 0;
|
||||
});
|
||||
|
||||
function createNode() {
|
||||
// See `encodeBits`
|
||||
var arr = new Array(256);
|
||||
for (var i = 0; i < arr.length; i++)
|
||||
arr[i] = 0;
|
||||
return arr;
|
||||
}
|
||||
|
||||
var decode = createNode();
|
||||
var encode = createNode();
|
||||
|
||||
function encodeBits(bits) {
|
||||
var num = parseInt(bits, 2);
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
table.forEach(function(line) {
|
||||
var match = line.match(/\(\s*([\d]+)\)\s+\|([^\s]+)\s+([^\s]+)/);
|
||||
var octet = match[1] | 0;
|
||||
var bits = match[2].split(/\|/g);
|
||||
var hex = parseInt(match[3], 16);
|
||||
|
||||
var node = decode;
|
||||
var totalLen = 0;
|
||||
for (var i = 0; i < bits.length - 1; i++) {
|
||||
var b = encodeBits(bits[i]);
|
||||
totalLen += bits[i].length;
|
||||
if (node[b] === 0)
|
||||
node[b] = createNode();
|
||||
node = node[b];
|
||||
}
|
||||
totalLen += bits[i].length;
|
||||
node[encodeBits(bits[i])] = (bits[i].length << 9) | octet;
|
||||
encode[octet] = [ totalLen, hex ];
|
||||
});
|
||||
|
||||
// Wrap lines after 79 chars
|
||||
out = 'exports.decode =\n' + utils.wrap(JSON.stringify(decode)) + ';';
|
||||
console.log(out);
|
||||
|
||||
out = 'exports.encode =\n' + utils.wrap(JSON.stringify(encode)) + ';';
|
||||
console.log(out);
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
var utils = require('./utils');
|
||||
|
||||
var table = `
|
||||
1 :authority
|
||||
2 :method GET
|
||||
3 :method POST
|
||||
4 :path /
|
||||
5 :path /index.html
|
||||
6 :scheme http
|
||||
7 :scheme https
|
||||
8 :status 200
|
||||
9 :status 204
|
||||
10 :status 206
|
||||
11 :status 304
|
||||
12 :status 400
|
||||
13 :status 404
|
||||
14 :status 500
|
||||
15 accept-charset
|
||||
16 accept-encoding gzip, deflate
|
||||
17 accept-language
|
||||
18 accept-ranges
|
||||
19 accept
|
||||
20 access-control-allow-origin
|
||||
21 age
|
||||
22 allow
|
||||
23 authorization
|
||||
24 cache-control
|
||||
25 content-disposition
|
||||
26 content-encoding
|
||||
27 content-language
|
||||
28 content-length
|
||||
29 content-location
|
||||
30 content-range
|
||||
31 content-type
|
||||
32 cookie
|
||||
33 date
|
||||
34 etag
|
||||
35 expect
|
||||
36 expires
|
||||
37 from
|
||||
38 host
|
||||
39 if-match
|
||||
40 if-modified-since
|
||||
41 if-none-match
|
||||
42 if-range
|
||||
43 if-unmodified-since
|
||||
44 last-modified
|
||||
45 link
|
||||
46 location
|
||||
47 max-forwards
|
||||
48 proxy-authenticate
|
||||
49 proxy-authorization
|
||||
50 range
|
||||
51 referer
|
||||
52 refresh
|
||||
53 retry-after
|
||||
54 server
|
||||
55 set-cookie
|
||||
56 strict-transport-security
|
||||
57 transfer-encoding
|
||||
58 user-agent
|
||||
59 vary
|
||||
60 via
|
||||
61 www-authenticate
|
||||
`;
|
||||
|
||||
var out = [];
|
||||
table.split('\n').filter(function(line) {
|
||||
return line;
|
||||
}).forEach(function(line) {
|
||||
var columns = line.split(/\t/g);
|
||||
var name = columns[1];
|
||||
var value = columns[2];
|
||||
var nameSize = Buffer.byteLength(name);
|
||||
var valueSize = Buffer.byteLength(value);
|
||||
out.push({
|
||||
name: name,
|
||||
value: value,
|
||||
nameSize: nameSize,
|
||||
totalSize: nameSize + valueSize + 32
|
||||
});
|
||||
});
|
||||
|
||||
console.log('exports.table = ' + JSON.stringify(out, false, 2) + ';');
|
||||
|
||||
var map = {};
|
||||
table.split('\n').filter(function(line) {
|
||||
return line;
|
||||
}).forEach(function(line) {
|
||||
var columns = line.split(/\t/g);
|
||||
var name = columns[1];
|
||||
var value = columns[2];
|
||||
|
||||
var index = columns[0] | 0;
|
||||
if (!map[name]) {
|
||||
map[name] = {
|
||||
index: index,
|
||||
values: {}
|
||||
};
|
||||
}
|
||||
map[name].values[value] = index;
|
||||
});
|
||||
console.log('exports.map = ' + JSON.stringify(map, false, 2) + ';');
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
// Wrap lines after 79 chars
|
||||
exports.wrap = function wrap(str) {
|
||||
var out = [];
|
||||
var pad = ' ';
|
||||
var line = pad;
|
||||
|
||||
var chunks = str.split(/,/g);
|
||||
chunks.forEach(function(chunk, i) {
|
||||
var append = chunk;
|
||||
if (i !== chunks.length - 1)
|
||||
append += ',';
|
||||
|
||||
if (line.length + append.length > 79) {
|
||||
out.push(line);
|
||||
line = pad;
|
||||
}
|
||||
line += append;
|
||||
});
|
||||
if (line !== pad)
|
||||
out.push(line);
|
||||
|
||||
return out.join('\n');
|
||||
};
|
||||
Reference in New Issue
Block a user