testing/xpcshell/node-http2/node_modules/http2-protocol/test/compressor.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 var expect = require('chai').expect;
     2 var util = require('./util');
     4 var compressor = require('../lib/compressor');
     5 var HeaderTable = compressor.HeaderTable;
     6 var HuffmanTable = compressor.HuffmanTable;
     7 var HeaderSetCompressor = compressor.HeaderSetCompressor;
     8 var HeaderSetDecompressor = compressor.HeaderSetDecompressor;
     9 var Compressor = compressor.Compressor;
    10 var Decompressor = compressor.Decompressor;
    12 var test_integers = [{
    13   N: 5,
    14   I: 10,
    15   buffer: new Buffer([10])
    16 }, {
    17   N: 0,
    18   I: 10,
    19   buffer: new Buffer([10])
    20 }, {
    21   N: 5,
    22   I: 1337,
    23   buffer: new Buffer([31, 128 + 26, 10])
    24 }, {
    25   N: 0,
    26   I: 1337,
    27   buffer: new Buffer([128 + 57, 10])
    28 }];
    30 var test_strings = [{
    31   string: 'www.foo.com',
    32   buffer: new Buffer('88db6d898b5a44b74f', 'hex')
    33 }, {
    34   string: 'éáűőúöüó€',
    35   buffer: new Buffer('13C3A9C3A1C5B1C591C3BAC3B6C3BCC3B3E282AC', 'hex')
    36 }];
    38 test_huffman_request = {
    39   'GET': 'f77778ff',
    40   'http': 'ce3177',
    41   '/': '0f',
    42   'www.foo.com': 'db6d898b5a44b74f',
    43   'https': 'ce31743f',
    44   'www.bar.com': 'db6d897a1e44b74f',
    45   'no-cache': '63654a1398ff',
    46   '/custom-path.css': '04eb08b7495c88e644c21f',
    47   'custom-key': '4eb08b749790fa7f',
    48   'custom-value': '4eb08b74979a17a8ff'
    49 };
    51 test_huffman_response = {
    52   '302': '98a7',
    53   'private': '73d5cd111f',
    54   'Mon, 21 OCt 2013 20:13:21 GMT': 'ef6b3a7a0e6e8fa7647a0e534dd072fb0d37b0e6e8f777f8ff',
    55   ': https://www.bar.com': 'f6746718ba1ec00db6d897a1e44b74',
    56   '200': '394b',
    57   'Mon, 21 OCt 2013 20:13:22 GMT': 'ef6b3a7a0e6e8fa7647a0e534dd072fb0d37b0e7e8f777f8ff',
    58   'https://www.bar.com': 'ce31743d801b6db12f43c896e9',
    59   'gzip': 'cbd54e',
    60   'foo=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
    61 AAAAAAAAAAAAAAAAAAAAAAAAAALASDJKHQKBZXOQWEOPIUAXQWEOIUAXLJKHQWOEIUAL\
    62 QWEOIUAXLQEUAXLLKJASDQWEOUIAXN1234LASDJKHQKBZXOQWEOPIUAXQWEOIUAXLJKH\
    63 QWOEIUALQWEOIUAXLQEUAXLLKJASDQWEOUIAXN1234LASDJKHQKBZXOQWEOPIUAXQWEO\
    64 IUAXLJKHQWOEIUALQWEOIUAXLQEUAXLLKJASDQWEOUIAXN1234LASDJKHQKBZXOQWEOP\
    65 IUAXQWEOIUAXLJKHQWOEIUALQWEOIUAXLQEUAXLLKJASDQWEOUIAXN1234ZZZZZZZZZZ\
    66 ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ1234 m\
    67 ax-age=3600; version=1': 'c5adb77efdfbf7efdfbf7efdfbf7efdfbf7efdfbf7\
    68 efdfbf7efdfbf7efdfbf7efdfbf7efdfbf7efdfbf7efdfbf7efdfbf7efdfbf7efdfb\
    69 f7efdfbf7efdfbf7efdfbfe5bfc3b7e3fdfbfedfdf5ff9fbfa7dbf5ddf4fafc3f1bf\
    70 f7f6fd777d3e1f8dffbf97c7fbf7fdbf5f4eef87e37fcbedfaeefa7c3f1bff7f2fb7\
    71 77e37fefe5f2fefe3bfc3b7edfaeefa7e3e1bff7f331e69fe5bfc3b7e3fdfbfedfdf\
    72 5ff9fbfa7dbf5ddf4fafc3f1bff7f6fd777d3e1f8dffbf97c7fbf7fdbf5f4eef87e3\
    73 7fcbedfaeefa7c3f1bff7f2fb777e37fefe5f2fefe3bfc3b7edfaeefa7e3e1bff7f3\
    74 31e69fe5bfc3b7e3fdfbfedfdf5ff9fbfa7dbf5ddf4fafc3f1bff7f6fd777d3e1f8d\
    75 ffbf97c7fbf7fdbf5f4eef87e37fcbedfaeefa7c3f1bff7f2fb777e37fefe5f2fefe\
    76 3bfc3b7edfaeefa7e3e1bff7f331e69fe5bfc3b7e3fdfbfedfdf5ff9fbfa7dbf5ddf\
    77 4fafc3f1bff7f6fd777d3e1f8dffbf97c7fbf7fdbf5f4eef87e37fcbedfaeefa7c3f\
    78 1bff7f2fb777e37fefe5f2fefe3bfc3b7edfaeefa7e3e1bff7f331e69ffcff3fcff3\
    79 fcff3fcff3fcff3fcff3fcff3fcff3fcff3fcff3fcff3fcff3fcff3fcff3fcff3fcf\
    80 f3fcff3fcff3fcff3fcff3fcff3fcff3fcff3fcff3fcff3fcff3fcff3fcff3fcff3f\
    81 cff3fcff3fcff3fcff3fcff3fcff3fcff0c79a7e8d11e72a321b66a4a5eae8e62f82\
    82 9acb4d',
    83   'foo=ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ\
    84 ZZZZZZZZZZZZZZZZZZZZZZZZZZLASDJKHQKBZXOQWEOPIUAXQWEOIUAXLJKHQWOEIUAL\
    85 QWEOIUAXLQEUAXLLKJASDQWEOUIAXN1234LASDJKHQKBZXOQWEOPIUAXQWEOIUAXLJKH\
    86 QWOEIUALQWEOIUAXLQEUAXLLKJASDQWEOUIAXN1234LASDJKHQKBZXOQWEOPIUAXQWEO\
    87 IUAXLJKHQWOEIUALQWEOIUAXLQEUAXLLKJASDQWEOUIAXN1234LASDJKHQKBZXOQWEOP\
    88 IUAXQWEOIUAXLJKHQWOEIUALQWEOIUAXLQEUAXLLKJASDQWEOUIAXN1234AAAAAAAAAA\
    89 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1234 m\
    90 ax-age=3600; version=1': 'c5adb7fcff3fcff3fcff3fcff3fcff3fcff3fcff3f\
    91 cff3fcff3fcff3fcff3fcff3fcff3fcff3fcff3fcff3fcff3fcff3fcff3fcff3fcff\
    92 3fcff3fcff3fcff3fcff3fcff3fcff3fcff3fcff3fcff3fcff3fcff3fcff3fcff3fc\
    93 ff3fcff3e5bfc3b7e3fdfbfedfdf5ff9fbfa7dbf5ddf4fafc3f1bff7f6fd777d3e1f\
    94 8dffbf97c7fbf7fdbf5f4eef87e37fcbedfaeefa7c3f1bff7f2fb777e37fefe5f2fe\
    95 fe3bfc3b7edfaeefa7e3e1bff7f331e69fe5bfc3b7e3fdfbfedfdf5ff9fbfa7dbf5d\
    96 df4fafc3f1bff7f6fd777d3e1f8dffbf97c7fbf7fdbf5f4eef87e37fcbedfaeefa7c\
    97 3f1bff7f2fb777e37fefe5f2fefe3bfc3b7edfaeefa7e3e1bff7f331e69fe5bfc3b7\
    98 e3fdfbfedfdf5ff9fbfa7dbf5ddf4fafc3f1bff7f6fd777d3e1f8dffbf97c7fbf7fd\
    99 bf5f4eef87e37fcbedfaeefa7c3f1bff7f2fb777e37fefe5f2fefe3bfc3b7edfaeef\
   100 a7e3e1bff7f331e69fe5bfc3b7e3fdfbfedfdf5ff9fbfa7dbf5ddf4fafc3f1bff7f6\
   101 fd777d3e1f8dffbf97c7fbf7fdbf5f4eef87e37fcbedfaeefa7c3f1bff7f2fb777e3\
   102 7fefe5f2fefe3bfc3b7edfaeefa7e3e1bff7f331e69f7efdfbf7efdfbf7efdfbf7ef\
   103 dfbf7efdfbf7efdfbf7efdfbf7efdfbf7efdfbf7efdfbf7efdfbf7efdfbf7efdfbf7\
   104 efdfbf7efdfbf7efdfbf7efdfbf7efdfbcc79a7e8d11e72a321b66a4a5eae8e62f82\
   105 9acb4d'
   106 };
   108 var test_headers = [{
   109   header: {
   110     name: 1,
   111     value: 'GET',
   112     index: true
   113   },
   114   buffer: new Buffer('02' + '03474554', 'hex')
   115 }, {
   116   header: {
   117     name: 6,
   118     value: 'http',
   119     index: true
   120   },
   121   buffer: new Buffer('07' + '83ce3177', 'hex')
   122 }, {
   123   header: {
   124     name: 5,
   125     value: '/',
   126     index: true
   127   },
   128   buffer: new Buffer('06' + '012f', 'hex')
   129 }, {
   130   header: {
   131     name: 3,
   132     value: 'www.foo.com',
   133     index: true
   134   },
   135   buffer: new Buffer('04' + '88db6d898b5a44b74f', 'hex')
   136 }, {
   137   header: {
   138     name: 2,
   139     value: 'https',
   140     index: true
   141   },
   142   buffer: new Buffer('03' + '84ce31743f', 'hex')
   143 }, {
   144   header: {
   145     name: 1,
   146     value: 'www.bar.com',
   147     index: true
   148   },
   149   buffer: new Buffer('02' + '88db6d897a1e44b74f', 'hex')
   150 }, {
   151   header: {
   152     name: 28,
   153     value: 'no-cache',
   154     index: true
   155   },
   156   buffer: new Buffer('1d' + '8663654a1398ff', 'hex')
   157 }, {
   158   header: {
   159     name: 3,
   160     value: 3,
   161     index: false
   162   },
   163   buffer: new Buffer('84', 'hex')
   164 }, {
   165   header: {
   166     name: 5,
   167     value: 5,
   168     index: false
   169   },
   170   buffer: new Buffer('86', 'hex')
   171 }, {
   172   header: {
   173     name: 4,
   174     value: '/custom-path.css',
   175     index: true
   176   },
   177   buffer: new Buffer('05' + '8b04eb08b7495c88e644c21f', 'hex')
   178 }, {
   179   header: {
   180     name: 'custom-key',
   181     value: 'custom-value',
   182     index: true
   183   },
   184   buffer: new Buffer('00' + '884eb08b749790fa7f' + '894eb08b74979a17a8ff', 'hex')
   185 }, {
   186   header: {
   187     name: 2,
   188     value: 2,
   189     index: false
   190   },
   191   buffer: new Buffer('83', 'hex')
   192 }, {
   193   header: {
   194     name: 6,
   195     value: 6,
   196     index: false
   197   },
   198   buffer: new Buffer('87', 'hex')
   199 }, {
   200   header: {
   201     name: -1,
   202     value: -1,
   203     index: true
   204   },
   205   buffer: new Buffer('8080', 'hex')
   206 }];
   208 var test_header_sets = [{
   209   headers: {
   210     ':method': 'GET',
   211     ':scheme': 'http',
   212     ':path': '/',
   213     ':authority': 'www.foo.com'
   214   },
   215   buffer: util.concat(test_headers.slice(0, 4).map(function(test) { return test.buffer; }))
   216 }, {
   217   headers: {
   218     ':method': 'GET',
   219     ':scheme': 'https',
   220     ':path': '/',
   221     ':authority': 'www.bar.com',
   222     'cache-control': 'no-cache'
   223   },
   224   buffer: util.concat(test_headers.slice(4, 9).map(function(test) { return test.buffer; }))
   225 }, {
   226   headers: {
   227     ':method': 'GET',
   228     ':scheme': 'https',
   229     ':path': '/custom-path.css',
   230     ':authority': 'www.bar.com',
   231     'custom-key': 'custom-value'
   232   },
   233   buffer: util.concat(test_headers.slice(9, 13).map(function(test) { return test.buffer; }))
   234 }, {
   235   headers: {
   236     ':method': 'GET',
   237     ':scheme': 'https',
   238     ':path': '/custom-path.css',
   239     ':authority': ['www.foo.com', 'www.bar.com'],
   240     'custom-key': 'custom-value'
   241   },
   242   buffer: test_headers[3].buffer
   243 }, {
   244   headers: {},
   245   buffer: test_headers[13].buffer
   246 }, {
   247   headers: {
   248     ':status': '200',
   249     'user-agent': 'my-user-agent',
   250     'cookie': 'first; second; third; third; fourth',
   251     'multiple': ['first', 'second', 'third', 'third; fourth'],
   252     'verylong': (new Buffer(9000)).toString('hex')
   253   }
   254 }];
   256 describe('compressor.js', function() {
   257   describe('HeaderTable', function() {
   258   });
   260   describe('HuffmanTable', function() {
   261     describe('method encode(buffer)', function() {
   262       it('should return the Huffman encoded version of the input buffer', function() {
   263         var table = HuffmanTable.huffmanTable;
   264         for (var decoded in test_huffman_request) {
   265           var encoded = test_huffman_request[decoded];
   266           expect(table.encode(new Buffer(decoded)).toString('hex')).to.equal(encoded);
   267         }
   268         table = HuffmanTable.huffmanTable;
   269         for (decoded in test_huffman_response) {
   270           encoded = test_huffman_response[decoded];
   271           expect(table.encode(new Buffer(decoded)).toString('hex')).to.equal(encoded);
   272         }
   273       });
   274     })
   275     describe('method decode(buffer)', function() {
   276       it('should return the Huffman decoded version of the input buffer', function() {
   277         var table = HuffmanTable.huffmanTable;
   278         for (var decoded in test_huffman_request) {
   279           var encoded = test_huffman_request[decoded];
   280           expect(table.decode(new Buffer(encoded, 'hex')).toString()).to.equal(decoded)
   281         }
   282         table = HuffmanTable.huffmanTable;
   283         for (decoded in test_huffman_response) {
   284           encoded = test_huffman_response[decoded];
   285           expect(table.decode(new Buffer(encoded, 'hex')).toString()).to.equal(decoded)
   286         }
   287       });
   288     })
   289   });
   291   describe('HeaderSetCompressor', function() {
   292     describe('static method .integer(I, N)', function() {
   293       it('should return an array of buffers that represent the N-prefix coded form of the integer I', function() {
   294         for (var i = 0; i < test_integers.length; i++) {
   295           var test = test_integers[i];
   296           test.buffer.cursor = 0;
   297           expect(util.concat(HeaderSetCompressor.integer(test.I, test.N))).to.deep.equal(test.buffer);
   298         }
   299       });
   300     });
   301     describe('static method .string(string)', function() {
   302       it('should return an array of buffers that represent the encoded form of the string', function() {
   303         var table = HuffmanTable.huffmanTable;
   304         for (var i = 0; i < test_strings.length; i++) {
   305           var test = test_strings[i];
   306           expect(util.concat(HeaderSetCompressor.string(test.string, table))).to.deep.equal(test.buffer);
   307         }
   308       });
   309     });
   310     describe('static method .header({ name, value, index })', function() {
   311       it('should return an array of buffers that represent the encoded form of the header', function() {
   312         var table = HuffmanTable.huffmanTable;
   313         for (var i = 0; i < test_headers.length; i++) {
   314           var test = test_headers[i];
   315           expect(util.concat(HeaderSetCompressor.header(test.header, table))).to.deep.equal(test.buffer);
   316         }
   317       });
   318     });
   319   });
   321   describe('HeaderSetDecompressor', function() {
   322     describe('static method .integer(buffer, N)', function() {
   323       it('should return the parsed N-prefix coded number and increase the cursor property of buffer', function() {
   324         for (var i = 0; i < test_integers.length; i++) {
   325           var test = test_integers[i];
   326           test.buffer.cursor = 0;
   327           expect(HeaderSetDecompressor.integer(test.buffer, test.N)).to.equal(test.I);
   328           expect(test.buffer.cursor).to.equal(test.buffer.length);
   329         }
   330       });
   331     });
   332     describe('static method .string(buffer)', function() {
   333       it('should return the parsed string and increase the cursor property of buffer', function() {
   334         var table = HuffmanTable.huffmanTable;
   335         for (var i = 0; i < test_strings.length; i++) {
   336           var test = test_strings[i];
   337           test.buffer.cursor = 0;
   338           expect(HeaderSetDecompressor.string(test.buffer, table)).to.equal(test.string);
   339           expect(test.buffer.cursor).to.equal(test.buffer.length);
   340         }
   341       });
   342     });
   343     describe('static method .header(buffer)', function() {
   344       it('should return the parsed header and increase the cursor property of buffer', function() {
   345         var table = HuffmanTable.huffmanTable;
   346         for (var i = 0; i < test_headers.length; i++) {
   347           var test = test_headers[i];
   348           test.buffer.cursor = 0;
   349           expect(HeaderSetDecompressor.header(test.buffer, table)).to.deep.equal(test.header);
   350           expect(test.buffer.cursor).to.equal(test.buffer.length);
   351         }
   352       });
   353     });
   354   });
   355   describe('Decompressor', function() {
   356     describe('method decompress(buffer)', function() {
   357       it('should return the parsed header set in { name1: value1, name2: [value2, value3], ... } format', function() {
   358         var decompressor = new Decompressor(util.log, 'REQUEST');
   359         for (var i = 0; i < 5; i++) {
   360           var header_set = test_header_sets[i];
   361           expect(decompressor.decompress(header_set.buffer)).to.deep.equal(header_set.headers);
   362         }
   363       });
   364     });
   365     describe('transform stream', function() {
   366       it('should emit an error event if a series of header frames is interleaved with other frames', function() {
   367         var decompressor = new Decompressor(util.log, 'REQUEST');
   368         var error_occured = false;
   369         decompressor.on('error', function() {
   370           error_occured = true;
   371         });
   372         decompressor.write({
   373           type: 'HEADERS',
   374           flags: {
   375             END_HEADERS: false
   376           },
   377           data: new Buffer(5)
   378         });
   379         decompressor.write({
   380           type: 'DATA',
   381           flags: {},
   382           data: new Buffer(5)
   383         });
   384         expect(error_occured).to.be.equal(true);
   385       });
   386     });
   387   });
   389   describe('invariant', function() {
   390     describe('decompressor.decompress(compressor.compress(headerset)) === headerset', function() {
   391       it('should be true for any header set if the states are synchronized', function() {
   392         var compressor = new Compressor(util.log, 'REQUEST');
   393         var decompressor = new Decompressor(util.log, 'REQUEST');
   394         var n = test_header_sets.length;
   395         for (var i = 0; i < 10; i++) {
   396           var headers = test_header_sets[i%n].headers;
   397           var compressed = compressor.compress(headers);
   398           var decompressed = decompressor.decompress(compressed);
   399           expect(decompressed).to.deep.equal(headers);
   400           expect(compressor._table).to.deep.equal(decompressor._table);
   401         }
   402       });
   403     });
   404     describe('source.pipe(compressor).pipe(decompressor).pipe(destination)', function() {
   405       it('should behave like source.pipe(destination) for a stream of frames', function(done) {
   406         var compressor = new Compressor(util.log, 'RESPONSE');
   407         var decompressor = new Decompressor(util.log, 'RESPONSE');
   408         var n = test_header_sets.length;
   409         compressor.pipe(decompressor);
   410         for (var i = 0; i < 10; i++) {
   411           compressor.write({
   412             type: i%2 ? 'HEADERS' : 'PUSH_PROMISE',
   413             flags: {},
   414             headers: test_header_sets[i%n].headers
   415           });
   416         }
   417         setTimeout(function() {
   418           for (var j = 0; j < 10; j++) {
   419             expect(decompressor.read().headers).to.deep.equal(test_header_sets[j%n].headers);
   420           }
   421           done();
   422         }, 10);
   423       });
   424     });
   425     describe('huffmanTable.decompress(huffmanTable.compress(buffer)) === buffer', function() {
   426       it('should be true for any buffer', function() {
   427         for (var i = 0; i < 10; i++) {
   428           var buffer = [];
   429           while (Math.random() > 0.1) {
   430             buffer.push(Math.floor(Math.random() * 256))
   431           }
   432           buffer = new Buffer(buffer);
   433           var table = HuffmanTable.huffmanTable;
   434           var result = table.decode(table.encode(buffer));
   435           expect(result).to.deep.equal(buffer);
   436         }
   437       })
   438     })
   439   });
   440 });

mercurial