decompressor-test.js 5.1 KB

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