[6a3a178] | 1 | var assert = require('assert');
|
---|
| 2 | var hpack = require('../');
|
---|
| 3 | var fixtures = require('./fixtures');
|
---|
| 4 |
|
---|
| 5 | describe('hpack/decompressor', function() {
|
---|
| 6 | var decomp;
|
---|
| 7 |
|
---|
| 8 | beforeEach(function() {
|
---|
| 9 | decomp = hpack.decompressor.create({
|
---|
| 10 | table: {
|
---|
| 11 | maxSize: 1024
|
---|
| 12 | }
|
---|
| 13 | });
|
---|
| 14 | });
|
---|
| 15 |
|
---|
| 16 | describe('indexed field', function() {
|
---|
| 17 | it('should fail on 0-index', function(cb) {
|
---|
| 18 | decomp.write(new Buffer([ 0b10000000 ]));
|
---|
| 19 | decomp.execute(function(err) {
|
---|
| 20 | assert(/zero index/i.test(err.message), err.message);
|
---|
| 21 | cb();
|
---|
| 22 | });
|
---|
| 23 | });
|
---|
| 24 |
|
---|
| 25 | it('should fetch entry from static table', function() {
|
---|
| 26 | decomp.write(new Buffer([ 0b10000000 | 2 ]));
|
---|
| 27 | decomp.execute();
|
---|
| 28 | var field = decomp.read();
|
---|
| 29 | assert.equal(field.name, ':method');
|
---|
| 30 | assert.equal(field.value, 'GET');
|
---|
| 31 | });
|
---|
| 32 |
|
---|
| 33 | it('should fetch entry from the end of the static table', function() {
|
---|
| 34 | decomp.write(new Buffer([ 0b10000000 | 61 ]));
|
---|
| 35 | decomp.execute();
|
---|
| 36 | var field = decomp.read();
|
---|
| 37 | assert.equal(field.name, 'www-authenticate');
|
---|
| 38 | assert.equal(field.value, '');
|
---|
| 39 | });
|
---|
| 40 |
|
---|
| 41 | it('should fail on OOB-index', function(cb) {
|
---|
| 42 | decomp.write(new Buffer([ 0b11000000 ]));
|
---|
| 43 | decomp.execute(function(err) {
|
---|
| 44 | assert(/field oob/i.test(err.message), err.message);
|
---|
| 45 | cb();
|
---|
| 46 | });
|
---|
| 47 | });
|
---|
| 48 | });
|
---|
| 49 |
|
---|
| 50 | describe('literal field', function() {
|
---|
| 51 | it('should lookup name in the table (incremental)', function() {
|
---|
| 52 | var value = new Buffer('localhost');
|
---|
| 53 | var header = new Buffer([
|
---|
| 54 | 0b01000000 | 38, // 38th element from static table
|
---|
| 55 | value.length
|
---|
| 56 | ]);
|
---|
| 57 | decomp.write(Buffer.concat([ header, value ]));
|
---|
| 58 | decomp.execute();
|
---|
| 59 |
|
---|
| 60 | var field = decomp.read();
|
---|
| 61 | assert.equal(field.name, 'host');
|
---|
| 62 | assert.equal(field.value, 'localhost');
|
---|
| 63 |
|
---|
| 64 | decomp.write(new Buffer([ 0b10000000 | 62 ]));
|
---|
| 65 | decomp.execute();
|
---|
| 66 | var field = decomp.read();
|
---|
| 67 | assert.equal(field.name, 'host');
|
---|
| 68 | assert.equal(field.value, 'localhost');
|
---|
| 69 | });
|
---|
| 70 |
|
---|
| 71 | it('should lookup name in the table (not-incremental)', function(cb) {
|
---|
| 72 | var value = new Buffer('localhost');
|
---|
| 73 | var header = new Buffer([
|
---|
| 74 | 0b00001111,
|
---|
| 75 | 0b00000000 | 23,
|
---|
| 76 | value.length
|
---|
| 77 | ]);
|
---|
| 78 | decomp.write(Buffer.concat([ header, value ]));
|
---|
| 79 | decomp.execute();
|
---|
| 80 |
|
---|
| 81 | var field = decomp.read();
|
---|
| 82 | assert.equal(field.name, 'host');
|
---|
| 83 | assert.equal(field.value, 'localhost');
|
---|
| 84 |
|
---|
| 85 | decomp.write(new Buffer([ 0b10000000 | 62 ]));
|
---|
| 86 | decomp.execute(function(err) {
|
---|
| 87 | assert(/field oob/i.test(err.message), err.message);
|
---|
| 88 | cb();
|
---|
| 89 | });
|
---|
| 90 | });
|
---|
| 91 |
|
---|
| 92 | it('should evict header field from the table', function() {
|
---|
| 93 | var value = new Buffer('localhost');
|
---|
| 94 | var header = new Buffer([
|
---|
| 95 | 0b01000000 | 38, // 38th element from static table
|
---|
| 96 | value.length
|
---|
| 97 | ]);
|
---|
| 98 | for (var i = 0; i < 1000; i++) {
|
---|
| 99 | decomp.write(Buffer.concat([ header, value ]));
|
---|
| 100 | decomp.execute();
|
---|
| 101 | var field = decomp.read();
|
---|
| 102 | assert.equal(field.name, 'host');
|
---|
| 103 | assert.equal(field.value, 'localhost');
|
---|
| 104 | }
|
---|
| 105 |
|
---|
| 106 | assert(decomp._table.size < decomp._table.maxSize);
|
---|
| 107 | assert.equal(decomp._table.dynamic.length, 22);
|
---|
| 108 | });
|
---|
| 109 | });
|
---|
| 110 |
|
---|
| 111 | describe('update size', function() {
|
---|
| 112 | it('should evict header field from the table', function() {
|
---|
| 113 | var value = new Buffer('localhost');
|
---|
| 114 | var header = new Buffer([
|
---|
| 115 | 0b01000000 | 38, // 38th element from static table
|
---|
| 116 | value.length
|
---|
| 117 | ]);
|
---|
| 118 |
|
---|
| 119 | decomp.write(Buffer.concat([ header, value ]));
|
---|
| 120 | decomp.execute();
|
---|
| 121 | var field = decomp.read();
|
---|
| 122 | assert.equal(field.name, 'host');
|
---|
| 123 | assert.equal(field.value, 'localhost');
|
---|
| 124 | assert.equal(decomp._table.dynamic.length, 1);
|
---|
| 125 |
|
---|
| 126 | decomp.write(new Buffer([
|
---|
| 127 | 0b00100000
|
---|
| 128 | ]));
|
---|
| 129 | decomp.execute();
|
---|
| 130 |
|
---|
| 131 | assert.equal(decomp._table.dynamic.length, 0);
|
---|
| 132 | });
|
---|
| 133 | });
|
---|
| 134 |
|
---|
| 135 | describe('spec examples', function() {
|
---|
| 136 | var decomp;
|
---|
| 137 | beforeEach(function() {
|
---|
| 138 | decomp = hpack.decompressor.create({
|
---|
| 139 | table: {
|
---|
| 140 | maxSize: 256
|
---|
| 141 | }
|
---|
| 142 | });
|
---|
| 143 | });
|
---|
| 144 |
|
---|
| 145 | var tests = fixtures.specExamples;
|
---|
| 146 |
|
---|
| 147 | tests.forEach(function(test, i) {
|
---|
| 148 | var prev = tests[i - 1];
|
---|
| 149 | it('should give expected output on ' + test.id, function() {
|
---|
| 150 | var startFrom = test.continuation ? prev.decomp : decomp;
|
---|
| 151 | if (!startFrom)
|
---|
| 152 | throw new Error('Previous test failed');
|
---|
| 153 | decomp = startFrom;
|
---|
| 154 |
|
---|
| 155 | decomp.write(new Buffer(test.input.replace(/ /g, ''), 'hex'));
|
---|
| 156 | decomp.execute();
|
---|
| 157 |
|
---|
| 158 | var output = [];
|
---|
| 159 | for (;;) {
|
---|
| 160 | var chunk = decomp.read();
|
---|
| 161 | if (!chunk)
|
---|
| 162 | break;
|
---|
| 163 |
|
---|
| 164 | output.push([ chunk.name, chunk.value ]);
|
---|
| 165 | }
|
---|
| 166 |
|
---|
| 167 | assert.deepEqual(output, test.output);
|
---|
| 168 |
|
---|
| 169 | // Verify table contents
|
---|
| 170 | assert.deepEqual(decomp._table.dynamic.map(function(header) {
|
---|
| 171 | return [ header.name, header.value, header.totalSize ];
|
---|
| 172 | }).reverse(), test.table);
|
---|
| 173 |
|
---|
| 174 | // Verify table size
|
---|
| 175 | var expectedSize = test.table.reduce(function(acc, item) {
|
---|
| 176 | return acc + item[2];
|
---|
| 177 | }, 0);
|
---|
| 178 | assert.equal(decomp._table.size, expectedSize);
|
---|
| 179 |
|
---|
| 180 | test.decomp = decomp;
|
---|
| 181 | });
|
---|
| 182 | });
|
---|
| 183 | });
|
---|
| 184 | });
|
---|