compressor.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576
  1. var expect = require('chai').expect;
  2. var util = require('./util');
  3. var compressor = require('../lib/protocol/compressor');
  4. var HeaderTable = compressor.HeaderTable;
  5. var HuffmanTable = compressor.HuffmanTable;
  6. var HeaderSetCompressor = compressor.HeaderSetCompressor;
  7. var HeaderSetDecompressor = compressor.HeaderSetDecompressor;
  8. var Compressor = compressor.Compressor;
  9. var Decompressor = compressor.Decompressor;
  10. var test_integers = [{
  11. N: 5,
  12. I: 10,
  13. buffer: new Buffer([10])
  14. }, {
  15. N: 0,
  16. I: 10,
  17. buffer: new Buffer([10])
  18. }, {
  19. N: 5,
  20. I: 1337,
  21. buffer: new Buffer([31, 128 + 26, 10])
  22. }, {
  23. N: 0,
  24. I: 1337,
  25. buffer: new Buffer([128 + 57, 10])
  26. }];
  27. var test_strings = [{
  28. string: 'www.foo.com',
  29. buffer: new Buffer('89f1e3c2f29ceb90f4ff', 'hex')
  30. }, {
  31. string: 'éáűőúöüó€',
  32. buffer: new Buffer('13c3a9c3a1c5b1c591c3bac3b6c3bcc3b3e282ac', 'hex')
  33. }];
  34. test_huffman_request = {
  35. 'GET': 'c5837f',
  36. 'http': '9d29af',
  37. '/': '63',
  38. 'www.foo.com': 'f1e3c2f29ceb90f4ff',
  39. 'https': '9d29ad1f',
  40. 'www.bar.com': 'f1e3c2f18ec5c87a7f',
  41. 'no-cache': 'a8eb10649cbf',
  42. '/custom-path.css': '6096a127a56ac699d72211',
  43. 'custom-key': '25a849e95ba97d7f',
  44. 'custom-value': '25a849e95bb8e8b4bf'
  45. };
  46. test_huffman_response = {
  47. '302': '6402',
  48. 'private': 'aec3771a4b',
  49. 'Mon, 21 OCt 2013 20:13:21 GMT': 'd07abe941054d5792a0801654102e059b820a98b46ff',
  50. ': https://www.bar.com': 'b8a4e94d68b8c31e3c785e31d8b90f4f',
  51. '200': '1001',
  52. 'Mon, 21 OCt 2013 20:13:22 GMT': 'd07abe941054d5792a0801654102e059b821298b46ff',
  53. 'https://www.bar.com': '9d29ad171863c78f0bc63b1721e9',
  54. 'gzip': '9bd9ab',
  55. 'foo=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
  56. AAAAAAAAAAAAAAAAAAAAAAAAAALASDJKHQKBZXOQWEOPIUAXQWEOIUAXLJKHQWOEIUAL\
  57. QWEOIUAXLQEUAXLLKJASDQWEOUIAXN1234LASDJKHQKBZXOQWEOPIUAXQWEOIUAXLJKH\
  58. QWOEIUALQWEOIUAXLQEUAXLLKJASDQWEOUIAXN1234LASDJKHQKBZXOQWEOPIUAXQWEO\
  59. IUAXLJKHQWOEIUALQWEOIUAXLQEUAXLLKJASDQWEOUIAXN1234LASDJKHQKBZXOQWEOP\
  60. IUAXQWEOIUAXLJKHQWOEIUALQWEOIUAXLQEUAXLLKJASDQWEOUIAXN1234ZZZZZZZZZZ\
  61. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ1234 m\
  62. ax-age=3600; version=1': '94e7821861861861861861861861861861861861861861861861861861861861861861861861861861861861861861861861861861861861873c3bafe5cd8f666bbfbf9ab672c1ab5e4e10fe6ce583564e10fe67cb9b1ece5ab064e10e7d9cb06ac9c21fccfb307087f33e7cd961dd7f672c1ab86487f34844cb59e1dd7f2e6c7b335dfdfcd5b3960d5af27087f3672c1ab27087f33e5cd8f672d583270873ece583564e10fe67d983843f99f3e6cb0eebfb3960d5c3243f9a42265acf0eebf97363d99aefefe6ad9cb06ad793843f9b3960d593843f99f2e6c7b396ac1938439f672c1ab27087f33ecc1c21fccf9f3658775fd9cb06ae1921fcd21132d678775fcb9b1eccd77f7f356ce58356bc9c21fcd9cb06ac9c21fccf97363d9cb560c9c21cfb3960d593843f99f660e10fe67cf9b2c3bafece583570c90fe6908996bf7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f42265a5291f9587316065c003ed4ee5b1063d5007f',
  63. 'foo=ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ\
  64. ZZZZZZZZZZZZZZZZZZZZZZZZZZLASDJKHQKBZXOQWEOPIUAXQWEOIUAXLJKHQWOEIUAL\
  65. QWEOIUAXLQEUAXLLKJASDQWEOUIAXN1234LASDJKHQKBZXOQWEOPIUAXQWEOIUAXLJKH\
  66. QWOEIUALQWEOIUAXLQEUAXLLKJASDQWEOUIAXN1234LASDJKHQKBZXOQWEOPIUAXQWEO\
  67. IUAXLJKHQWOEIUALQWEOIUAXLQEUAXLLKJASDQWEOUIAXN1234LASDJKHQKBZXOQWEOP\
  68. IUAXQWEOIUAXLJKHQWOEIUALQWEOIUAXLQEUAXLLKJASDQWEOUIAXN1234AAAAAAAAAA\
  69. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1234 m\
  70. ax-age=3600; version=1': '94e783f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f73c3bafe5cd8f666bbfbf9ab672c1ab5e4e10fe6ce583564e10fe67cb9b1ece5ab064e10e7d9cb06ac9c21fccfb307087f33e7cd961dd7f672c1ab86487f34844cb59e1dd7f2e6c7b335dfdfcd5b3960d5af27087f3672c1ab27087f33e5cd8f672d583270873ece583564e10fe67d983843f99f3e6cb0eebfb3960d5c3243f9a42265acf0eebf97363d99aefefe6ad9cb06ad793843f9b3960d593843f99f2e6c7b396ac1938439f672c1ab27087f33ecc1c21fccf9f3658775fd9cb06ae1921fcd21132d678775fcb9b1eccd77f7f356ce58356bc9c21fcd9cb06ac9c21fccf97363d9cb560c9c21cfb3960d593843f99f660e10fe67cf9b2c3bafece583570c90fe6908996a1861861861861861861861861861861861861861861861861861861861861861861861861861861861861861861861861861861861842265a5291f9587316065c003ed4ee5b1063d5007f'
  71. };
  72. var test_headers = [{
  73. // index
  74. header: {
  75. name: 1,
  76. value: 1,
  77. index: false,
  78. mustNeverIndex: false,
  79. contextUpdate: false,
  80. newMaxSize: 0
  81. },
  82. buffer: new Buffer('82', 'hex')
  83. }, {
  84. // index
  85. header: {
  86. name: 5,
  87. value: 5,
  88. index: false,
  89. mustNeverIndex: false,
  90. contextUpdate: false,
  91. newMaxSize: 0
  92. },
  93. buffer: new Buffer('86', 'hex')
  94. }, {
  95. // index
  96. header: {
  97. name: 3,
  98. value: 3,
  99. index: false,
  100. mustNeverIndex: false,
  101. contextUpdate: false,
  102. newMaxSize: 0
  103. },
  104. buffer: new Buffer('84', 'hex')
  105. }, {
  106. // literal w/index, name index
  107. header: {
  108. name: 0,
  109. value: 'www.foo.com',
  110. index: true,
  111. mustNeverIndex: false,
  112. contextUpdate: false,
  113. newMaxSize: 0
  114. },
  115. buffer: new Buffer('41' + '89f1e3c2f29ceb90f4ff', 'hex')
  116. }, {
  117. // indexed
  118. header: {
  119. name: 1,
  120. value: 1,
  121. index: false,
  122. mustNeverIndex: false,
  123. contextUpdate: false,
  124. newMaxSize: 0
  125. },
  126. buffer: new Buffer('82', 'hex')
  127. }, {
  128. // indexed
  129. header: {
  130. name: 6,
  131. value: 6,
  132. index: false,
  133. mustNeverIndex: false,
  134. contextUpdate: false,
  135. newMaxSize: 0
  136. },
  137. buffer: new Buffer('87', 'hex')
  138. }, {
  139. // indexed
  140. header: {
  141. name: 3,
  142. value: 3,
  143. index: false,
  144. mustNeverIndex: false,
  145. contextUpdate: false,
  146. newMaxSize: 0
  147. },
  148. buffer: new Buffer('84', 'hex')
  149. }, {
  150. // literal w/index, name index
  151. header: {
  152. name: 0,
  153. value: 'www.bar.com',
  154. index: true,
  155. mustNeverIndex: false,
  156. contextUpdate: false,
  157. newMaxSize: 0
  158. },
  159. buffer: new Buffer('41' + '89f1e3c2f18ec5c87a7f', 'hex')
  160. }, {
  161. // literal w/index, name index
  162. header: {
  163. name: 23,
  164. value: 'no-cache',
  165. index: true,
  166. mustNeverIndex: false,
  167. contextUpdate: false,
  168. newMaxSize: 0
  169. },
  170. buffer: new Buffer('58' + '86a8eb10649cbf', 'hex')
  171. }, {
  172. // index
  173. header: {
  174. name: 1,
  175. value: 1,
  176. index: false,
  177. mustNeverIndex: false,
  178. contextUpdate: false,
  179. newMaxSize: 0
  180. },
  181. buffer: new Buffer('82', 'hex')
  182. }, {
  183. // index
  184. header: {
  185. name: 6,
  186. value: 6,
  187. index: false,
  188. mustNeverIndex: false,
  189. contextUpdate: false,
  190. newMaxSize: 0
  191. },
  192. buffer: new Buffer('87', 'hex')
  193. }, {
  194. // literal w/index, name index
  195. header: {
  196. name: 3,
  197. value: '/custom-path.css',
  198. index: true,
  199. mustNeverIndex: false,
  200. contextUpdate: false,
  201. newMaxSize: 0
  202. },
  203. buffer: new Buffer('44' + '8b6096a127a56ac699d72211', 'hex')
  204. }, {
  205. // index
  206. header: {
  207. name: 63,
  208. value: 63,
  209. index: false,
  210. mustNeverIndex: false,
  211. contextUpdate: false,
  212. newMaxSize: 0
  213. },
  214. buffer: new Buffer('C0', 'hex')
  215. }, {
  216. // literal w/index, new name & value
  217. header: {
  218. name: 'custom-key',
  219. value: 'custom-value',
  220. index: true,
  221. mustNeverIndex: false,
  222. contextUpdate: false,
  223. newMaxSize: 0
  224. },
  225. buffer: new Buffer('40' + '8825a849e95ba97d7f' + '8925a849e95bb8e8b4bf', 'hex')
  226. }, {
  227. // index
  228. header: {
  229. name: 1,
  230. value: 1,
  231. index: false,
  232. mustNeverIndex: false,
  233. contextUpdate: false,
  234. newMaxSize: 0
  235. },
  236. buffer: new Buffer('82', 'hex')
  237. }, {
  238. // index
  239. header: {
  240. name: 6,
  241. value: 6,
  242. index: false,
  243. mustNeverIndex: false,
  244. contextUpdate: false,
  245. newMaxSize: 0
  246. },
  247. buffer: new Buffer('87', 'hex')
  248. }, {
  249. // index
  250. header: {
  251. name: 62,
  252. value: 62,
  253. index: false,
  254. mustNeverIndex: false,
  255. contextUpdate: false,
  256. newMaxSize: 0
  257. },
  258. buffer: new Buffer('BF', 'hex')
  259. }, {
  260. // index
  261. header: {
  262. name: 65,
  263. value: 65,
  264. index: false,
  265. mustNeverIndex: false,
  266. contextUpdate: false,
  267. newMaxSize: 0
  268. },
  269. buffer: new Buffer('C2', 'hex')
  270. }, {
  271. // index
  272. header: {
  273. name: 64,
  274. value: 64,
  275. index: false,
  276. mustNeverIndex: false,
  277. contextUpdate: false,
  278. newMaxSize: 0
  279. },
  280. buffer: new Buffer('C1', 'hex')
  281. }, {
  282. // index
  283. header: {
  284. name: 61,
  285. value: 61,
  286. index: false,
  287. mustNeverIndex: false,
  288. contextUpdate: false,
  289. newMaxSize: 0
  290. },
  291. buffer: new Buffer('BE', 'hex')
  292. }, {
  293. // Literal w/o index, name index
  294. header: {
  295. name: 6,
  296. value: "whatever",
  297. index: false,
  298. mustNeverIndex: false,
  299. contextUpdate: false,
  300. newMaxSize: 0
  301. },
  302. buffer: new Buffer('07' + '86f138d25ee5b3', 'hex')
  303. }, {
  304. // Literal w/o index, new name & value
  305. header: {
  306. name: "foo",
  307. value: "bar",
  308. index: false,
  309. mustNeverIndex: false,
  310. contextUpdate: false,
  311. newMaxSize: 0
  312. },
  313. buffer: new Buffer('00' + '8294e7' + '03626172', 'hex')
  314. }, {
  315. // Literal never indexed, name index
  316. header: {
  317. name: 6,
  318. value: "whatever",
  319. index: false,
  320. mustNeverIndex: true,
  321. contextUpdate: false,
  322. newMaxSize: 0
  323. },
  324. buffer: new Buffer('17' + '86f138d25ee5b3', 'hex')
  325. }, {
  326. // Literal never indexed, new name & value
  327. header: {
  328. name: "foo",
  329. value: "bar",
  330. index: false,
  331. mustNeverIndex: true,
  332. contextUpdate: false,
  333. newMaxSize: 0
  334. },
  335. buffer: new Buffer('10' + '8294e7' + '03626172', 'hex')
  336. }, {
  337. header: {
  338. name: -1,
  339. value: -1,
  340. index: false,
  341. mustNeverIndex: false,
  342. contextUpdate: true,
  343. newMaxSize: 100
  344. },
  345. buffer: new Buffer('3F45', 'hex')
  346. }];
  347. var test_header_sets = [{
  348. headers: {
  349. ':method': 'GET',
  350. ':scheme': 'http',
  351. ':path': '/',
  352. ':authority': 'www.foo.com'
  353. },
  354. buffer: util.concat(test_headers.slice(0, 4).map(function(test) { return test.buffer; }))
  355. }, {
  356. headers: {
  357. ':method': 'GET',
  358. ':scheme': 'https',
  359. ':path': '/',
  360. ':authority': 'www.bar.com',
  361. 'cache-control': 'no-cache'
  362. },
  363. buffer: util.concat(test_headers.slice(4, 9).map(function(test) { return test.buffer; }))
  364. }, {
  365. headers: {
  366. ':method': 'GET',
  367. ':scheme': 'https',
  368. ':path': '/custom-path.css',
  369. ':authority': 'www.bar.com',
  370. 'custom-key': 'custom-value'
  371. },
  372. buffer: util.concat(test_headers.slice(9, 14).map(function(test) { return test.buffer; }))
  373. }, {
  374. headers: {
  375. ':method': 'GET',
  376. ':scheme': 'https',
  377. ':path': '/custom-path.css',
  378. ':authority': ['www.foo.com', 'www.bar.com'],
  379. 'custom-key': 'custom-value'
  380. },
  381. buffer: util.concat(test_headers.slice(14, 19).map(function(test) { return test.buffer; }))
  382. }];
  383. describe('compressor.js', function() {
  384. describe('HeaderTable', function() {
  385. });
  386. describe('HuffmanTable', function() {
  387. describe('method encode(buffer)', function() {
  388. it('should return the Huffman encoded version of the input buffer', function() {
  389. var table = HuffmanTable.huffmanTable;
  390. for (var decoded in test_huffman_request) {
  391. var encoded = test_huffman_request[decoded];
  392. expect(table.encode(new Buffer(decoded)).toString('hex')).to.equal(encoded);
  393. }
  394. table = HuffmanTable.huffmanTable;
  395. for (decoded in test_huffman_response) {
  396. encoded = test_huffman_response[decoded];
  397. expect(table.encode(new Buffer(decoded)).toString('hex')).to.equal(encoded);
  398. }
  399. });
  400. });
  401. describe('method decode(buffer)', function() {
  402. it('should return the Huffman decoded version of the input buffer', function() {
  403. var table = HuffmanTable.huffmanTable;
  404. for (var decoded in test_huffman_request) {
  405. var encoded = test_huffman_request[decoded];
  406. expect(table.decode(new Buffer(encoded, 'hex')).toString()).to.equal(decoded);
  407. }
  408. table = HuffmanTable.huffmanTable;
  409. for (decoded in test_huffman_response) {
  410. encoded = test_huffman_response[decoded];
  411. expect(table.decode(new Buffer(encoded, 'hex')).toString()).to.equal(decoded);
  412. }
  413. });
  414. });
  415. });
  416. describe('HeaderSetCompressor', function() {
  417. describe('static method .integer(I, N)', function() {
  418. it('should return an array of buffers that represent the N-prefix coded form of the integer I', function() {
  419. for (var i = 0; i < test_integers.length; i++) {
  420. var test = test_integers[i];
  421. test.buffer.cursor = 0;
  422. expect(util.concat(HeaderSetCompressor.integer(test.I, test.N))).to.deep.equal(test.buffer);
  423. }
  424. });
  425. });
  426. describe('static method .string(string)', function() {
  427. it('should return an array of buffers that represent the encoded form of the string', function() {
  428. var table = HuffmanTable.huffmanTable;
  429. for (var i = 0; i < test_strings.length; i++) {
  430. var test = test_strings[i];
  431. expect(util.concat(HeaderSetCompressor.string(test.string, table))).to.deep.equal(test.buffer);
  432. }
  433. });
  434. });
  435. describe('static method .header({ name, value, index })', function() {
  436. it('should return an array of buffers that represent the encoded form of the header', function() {
  437. var table = HuffmanTable.huffmanTable;
  438. for (var i = 0; i < test_headers.length; i++) {
  439. var test = test_headers[i];
  440. expect(util.concat(HeaderSetCompressor.header(test.header, table))).to.deep.equal(test.buffer);
  441. }
  442. });
  443. });
  444. });
  445. describe('HeaderSetDecompressor', function() {
  446. describe('static method .integer(buffer, N)', function() {
  447. it('should return the parsed N-prefix coded number and increase the cursor property of buffer', function() {
  448. for (var i = 0; i < test_integers.length; i++) {
  449. var test = test_integers[i];
  450. test.buffer.cursor = 0;
  451. expect(HeaderSetDecompressor.integer(test.buffer, test.N)).to.equal(test.I);
  452. expect(test.buffer.cursor).to.equal(test.buffer.length);
  453. }
  454. });
  455. });
  456. describe('static method .string(buffer)', function() {
  457. it('should return the parsed string and increase the cursor property of buffer', function() {
  458. var table = HuffmanTable.huffmanTable;
  459. for (var i = 0; i < test_strings.length; i++) {
  460. var test = test_strings[i];
  461. test.buffer.cursor = 0;
  462. expect(HeaderSetDecompressor.string(test.buffer, table)).to.equal(test.string);
  463. expect(test.buffer.cursor).to.equal(test.buffer.length);
  464. }
  465. });
  466. });
  467. describe('static method .header(buffer)', function() {
  468. it('should return the parsed header and increase the cursor property of buffer', function() {
  469. var table = HuffmanTable.huffmanTable;
  470. for (var i = 0; i < test_headers.length; i++) {
  471. var test = test_headers[i];
  472. test.buffer.cursor = 0;
  473. expect(HeaderSetDecompressor.header(test.buffer, table)).to.deep.equal(test.header);
  474. expect(test.buffer.cursor).to.equal(test.buffer.length);
  475. }
  476. });
  477. });
  478. });
  479. describe('Decompressor', function() {
  480. describe('method decompress(buffer)', function() {
  481. it('should return the parsed header set in { name1: value1, name2: [value2, value3], ... } format', function() {
  482. var decompressor = new Decompressor(util.log, 'REQUEST');
  483. for (var i = 0; i < test_header_sets.length - 1; i++) {
  484. var header_set = test_header_sets[i];
  485. expect(decompressor.decompress(header_set.buffer)).to.deep.equal(header_set.headers);
  486. }
  487. });
  488. });
  489. describe('transform stream', function() {
  490. it('should emit an error event if a series of header frames is interleaved with other frames', function() {
  491. var decompressor = new Decompressor(util.log, 'REQUEST');
  492. var error_occured = false;
  493. decompressor.on('error', function() {
  494. error_occured = true;
  495. });
  496. decompressor.write({
  497. type: 'HEADERS',
  498. flags: {
  499. END_HEADERS: false
  500. },
  501. data: new Buffer(5)
  502. });
  503. decompressor.write({
  504. type: 'DATA',
  505. flags: {},
  506. data: new Buffer(5)
  507. });
  508. expect(error_occured).to.be.equal(true);
  509. });
  510. });
  511. });
  512. describe('invariant', function() {
  513. describe('decompressor.decompress(compressor.compress(headerset)) === headerset', function() {
  514. it('should be true for any header set if the states are synchronized', function() {
  515. var compressor = new Compressor(util.log, 'REQUEST');
  516. var decompressor = new Decompressor(util.log, 'REQUEST');
  517. var n = test_header_sets.length;
  518. for (var i = 0; i < 10; i++) {
  519. var headers = test_header_sets[i%n].headers;
  520. var compressed = compressor.compress(headers);
  521. var decompressed = decompressor.decompress(compressed);
  522. expect(decompressed).to.deep.equal(headers);
  523. expect(compressor._table).to.deep.equal(decompressor._table);
  524. }
  525. });
  526. });
  527. describe('source.pipe(compressor).pipe(decompressor).pipe(destination)', function() {
  528. it('should behave like source.pipe(destination) for a stream of frames', function(done) {
  529. var compressor = new Compressor(util.log, 'RESPONSE');
  530. var decompressor = new Decompressor(util.log, 'RESPONSE');
  531. var n = test_header_sets.length;
  532. compressor.pipe(decompressor);
  533. for (var i = 0; i < 10; i++) {
  534. compressor.write({
  535. type: i%2 ? 'HEADERS' : 'PUSH_PROMISE',
  536. flags: {},
  537. headers: test_header_sets[i%n].headers
  538. });
  539. }
  540. setTimeout(function() {
  541. for (var j = 0; j < 10; j++) {
  542. expect(decompressor.read().headers).to.deep.equal(test_header_sets[j%n].headers);
  543. }
  544. done();
  545. }, 10);
  546. });
  547. });
  548. describe('huffmanTable.decompress(huffmanTable.compress(buffer)) === buffer', function() {
  549. it('should be true for any buffer', function() {
  550. for (var i = 0; i < 10; i++) {
  551. var buffer = [];
  552. while (Math.random() > 0.1) {
  553. buffer.push(Math.floor(Math.random() * 256))
  554. }
  555. buffer = new Buffer(buffer);
  556. var table = HuffmanTable.huffmanTable;
  557. var result = table.decode(table.encode(buffer));
  558. expect(result).to.deep.equal(buffer);
  559. }
  560. });
  561. });
  562. });
  563. });