1 | var assert = require('assert');
|
---|
2 | var hpack = require('../');
|
---|
3 | var fixtures = require('./fixtures');
|
---|
4 |
|
---|
5 | describe('hpack/compressor', function() {
|
---|
6 | var comp;
|
---|
7 |
|
---|
8 | beforeEach(function() {
|
---|
9 | comp = hpack.compressor.create({
|
---|
10 | table: {
|
---|
11 | maxSize: 1024
|
---|
12 | }
|
---|
13 | });
|
---|
14 | });
|
---|
15 |
|
---|
16 | function expect(arr, enc) {
|
---|
17 | function isNumber(num) {
|
---|
18 | return typeof num === 'number';
|
---|
19 | }
|
---|
20 |
|
---|
21 | var out = comp.read().toString('hex');
|
---|
22 | if (Array.isArray(arr) && !arr.every(isNumber)) {
|
---|
23 | arr = arr.map(function(item) {
|
---|
24 | return new Buffer(item, enc);
|
---|
25 | });
|
---|
26 | arr = Buffer.concat(arr);
|
---|
27 | } else {
|
---|
28 | arr = new Buffer(arr, enc);
|
---|
29 | }
|
---|
30 | var actual = arr.toString('hex');
|
---|
31 | assert.equal(out, actual);
|
---|
32 | }
|
---|
33 |
|
---|
34 | describe('indexed field', function() {
|
---|
35 | it('should lookup entry from static table', function() {
|
---|
36 | comp.write([{ name: ':method', value: 'GET' }]);
|
---|
37 | expect([ 0b10000000 | 2 ]);
|
---|
38 | });
|
---|
39 |
|
---|
40 | it('should fetch entry from the end of the static table', function() {
|
---|
41 | comp.write([{ name: 'www-authenticate', value: '' }]);
|
---|
42 | expect([ 0b10000000 | 61 ]);
|
---|
43 | });
|
---|
44 | });
|
---|
45 |
|
---|
46 | describe('literal field', function() {
|
---|
47 | it('should lookup name in the table (incremental)', function() {
|
---|
48 | comp.write([{ name: 'host', value: 'localhost' }]);
|
---|
49 | expect('6686a0e41d139d09', 'hex');
|
---|
50 |
|
---|
51 | comp.write([{ name: 'host', value: 'localhost' }]);
|
---|
52 | expect([ 0b10000000 | 62 ]);
|
---|
53 | });
|
---|
54 |
|
---|
55 | it('should lookup name in the table (not-incremental)', function() {
|
---|
56 | comp.write([{ name: 'host', value: 'localhost', incremental: false }]);
|
---|
57 | expect('0f1786a0e41d139d09', 'hex');
|
---|
58 |
|
---|
59 | // Should not use the table
|
---|
60 | comp.write([{ name: 'host', value: 'localhost' }]);
|
---|
61 | expect('6686a0e41d139d09', 'hex');
|
---|
62 | });
|
---|
63 |
|
---|
64 | it('should evict header field from the table', function() {
|
---|
65 | for (var i = 0; i < 1000; i++) {
|
---|
66 | comp.write([{ name: 'host', value: 'localhost' + i }]);
|
---|
67 | comp.read();
|
---|
68 | }
|
---|
69 |
|
---|
70 | assert(comp._table.size < comp._table.maxSize);
|
---|
71 | assert.equal(comp._table.dynamic.length, 21);
|
---|
72 | });
|
---|
73 | });
|
---|
74 |
|
---|
75 | describe('update size', function() {
|
---|
76 | it('should evict header field from the table', function() {
|
---|
77 | comp.write([{ name: 'host', value: 'localhost' }]);
|
---|
78 | expect('6686a0e41d139d09', 'hex');
|
---|
79 |
|
---|
80 | comp.reset();
|
---|
81 |
|
---|
82 | // update=0, update=maxSize
|
---|
83 | expect('203fe107', 'hex');
|
---|
84 |
|
---|
85 | comp.write([{ name: 'host', value: 'localhost' }]);
|
---|
86 | expect('6686a0e41d139d09', 'hex');
|
---|
87 | });
|
---|
88 |
|
---|
89 | it('should send dynamic update if size >= protocolMaxSize', function() {
|
---|
90 | comp.updateTableSize(Infinity);
|
---|
91 |
|
---|
92 | // update=maxSize
|
---|
93 | expect('3fe107', 'hex');
|
---|
94 | });
|
---|
95 | });
|
---|
96 |
|
---|
97 | describe('spec examples', function() {
|
---|
98 | beforeEach(function() {
|
---|
99 | comp = hpack.compressor.create({
|
---|
100 | table: {
|
---|
101 | maxSize: 256
|
---|
102 | }
|
---|
103 | });
|
---|
104 | });
|
---|
105 |
|
---|
106 | var tests = fixtures.specExamples;
|
---|
107 |
|
---|
108 | tests.forEach(function(test, i) {
|
---|
109 | var prev = tests[i - 1];
|
---|
110 | it('should give expected output on ' + test.id, function() {
|
---|
111 | var startFrom = test.continuation ? prev.comp : comp;
|
---|
112 | if (!startFrom)
|
---|
113 | throw new Error('Previous test failed');
|
---|
114 | comp = startFrom;
|
---|
115 |
|
---|
116 | comp.write(test.output.map(function(pair) {
|
---|
117 | return { name: pair[0], value: pair[1], huffman: test.huffman };
|
---|
118 | }));
|
---|
119 | expect(test.input.replace(/ /g, ''), 'hex');
|
---|
120 |
|
---|
121 | // Verify table contents
|
---|
122 | assert.deepEqual(comp._table.dynamic.map(function(header) {
|
---|
123 | return [ header.name, header.value, header.totalSize ];
|
---|
124 | }).reverse(), test.table);
|
---|
125 |
|
---|
126 | // Verify table size
|
---|
127 | var expectedSize = test.table.reduce(function(acc, item) {
|
---|
128 | return acc + item[2];
|
---|
129 | }, 0);
|
---|
130 | assert.equal(comp._table.size, expectedSize);
|
---|
131 |
|
---|
132 | test.comp = comp;
|
---|
133 | });
|
---|
134 | });
|
---|
135 | });
|
---|
136 | });
|
---|