1// Copyright Joyent, Inc. and other Node contributors. 2// 3// Permission is hereby granted, free of charge, to any person obtaining a 4// copy of this software and associated documentation files (the 5// "Software"), to deal in the Software without restriction, including 6// without limitation the rights to use, copy, modify, merge, publish, 7// distribute, sublicense, and/or sell copies of the Software, and to permit 8// persons to whom the Software is furnished to do so, subject to the 9// following conditions: 10// 11// The above copyright notice and this permission notice shall be included 12// in all copies or substantial portions of the Software. 13// 14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20// USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22'use strict'; 23// Test compression/decompression with dictionary 24 25const common = require('../common'); 26const assert = require('assert'); 27const zlib = require('zlib'); 28 29const spdyDict = Buffer.from([ 30 'optionsgetheadpostputdeletetraceacceptaccept-charsetaccept-encodingaccept-', 31 'languageauthorizationexpectfromhostif-modified-sinceif-matchif-none-matchi', 32 'f-rangeif-unmodifiedsincemax-forwardsproxy-authorizationrangerefererteuser', 33 '-agent10010120020120220320420520630030130230330430530630740040140240340440', 34 '5406407408409410411412413414415416417500501502503504505accept-rangesageeta', 35 'glocationproxy-authenticatepublicretry-afterservervarywarningwww-authentic', 36 'ateallowcontent-basecontent-encodingcache-controlconnectiondatetrailertran', 37 'sfer-encodingupgradeviawarningcontent-languagecontent-lengthcontent-locati', 38 'oncontent-md5content-rangecontent-typeetagexpireslast-modifiedset-cookieMo', 39 'ndayTuesdayWednesdayThursdayFridaySaturdaySundayJanFebMarAprMayJunJulAugSe', 40 'pOctNovDecchunkedtext/htmlimage/pngimage/jpgimage/gifapplication/xmlapplic', 41 'ation/xhtmltext/plainpublicmax-agecharset=iso-8859-1utf-8gzipdeflateHTTP/1', 42 '.1statusversionurl\0', 43].join('')); 44 45const input = [ 46 'HTTP/1.1 200 Ok', 47 'Server: node.js', 48 'Content-Length: 0', 49 '', 50].join('\r\n'); 51 52function basicDictionaryTest(spdyDict) { 53 let output = ''; 54 const deflate = zlib.createDeflate({ dictionary: spdyDict }); 55 const inflate = zlib.createInflate({ dictionary: spdyDict }); 56 inflate.setEncoding('utf-8'); 57 58 deflate.on('data', function(chunk) { 59 inflate.write(chunk); 60 }); 61 62 inflate.on('data', function(chunk) { 63 output += chunk; 64 }); 65 66 deflate.on('end', function() { 67 inflate.end(); 68 }); 69 70 inflate.on('end', common.mustCall(function() { 71 assert.strictEqual(input, output); 72 })); 73 74 deflate.write(input); 75 deflate.end(); 76} 77 78function deflateResetDictionaryTest(spdyDict) { 79 let doneReset = false; 80 let output = ''; 81 const deflate = zlib.createDeflate({ dictionary: spdyDict }); 82 const inflate = zlib.createInflate({ dictionary: spdyDict }); 83 inflate.setEncoding('utf-8'); 84 85 deflate.on('data', function(chunk) { 86 if (doneReset) 87 inflate.write(chunk); 88 }); 89 90 inflate.on('data', function(chunk) { 91 output += chunk; 92 }); 93 94 deflate.on('end', function() { 95 inflate.end(); 96 }); 97 98 inflate.on('end', common.mustCall(function() { 99 assert.strictEqual(input, output); 100 })); 101 102 deflate.write(input); 103 deflate.flush(function() { 104 deflate.reset(); 105 doneReset = true; 106 deflate.write(input); 107 deflate.end(); 108 }); 109} 110 111function rawDictionaryTest(spdyDict) { 112 let output = ''; 113 const deflate = zlib.createDeflateRaw({ dictionary: spdyDict }); 114 const inflate = zlib.createInflateRaw({ dictionary: spdyDict }); 115 inflate.setEncoding('utf-8'); 116 117 deflate.on('data', function(chunk) { 118 inflate.write(chunk); 119 }); 120 121 inflate.on('data', function(chunk) { 122 output += chunk; 123 }); 124 125 deflate.on('end', function() { 126 inflate.end(); 127 }); 128 129 inflate.on('end', common.mustCall(function() { 130 assert.strictEqual(input, output); 131 })); 132 133 deflate.write(input); 134 deflate.end(); 135} 136 137function deflateRawResetDictionaryTest(spdyDict) { 138 let doneReset = false; 139 let output = ''; 140 const deflate = zlib.createDeflateRaw({ dictionary: spdyDict }); 141 const inflate = zlib.createInflateRaw({ dictionary: spdyDict }); 142 inflate.setEncoding('utf-8'); 143 144 deflate.on('data', function(chunk) { 145 if (doneReset) 146 inflate.write(chunk); 147 }); 148 149 inflate.on('data', function(chunk) { 150 output += chunk; 151 }); 152 153 deflate.on('end', function() { 154 inflate.end(); 155 }); 156 157 inflate.on('end', common.mustCall(function() { 158 assert.strictEqual(input, output); 159 })); 160 161 deflate.write(input); 162 deflate.flush(function() { 163 deflate.reset(); 164 doneReset = true; 165 deflate.write(input); 166 deflate.end(); 167 }); 168} 169 170for (const dict of [spdyDict, ...common.getBufferSources(spdyDict)]) { 171 basicDictionaryTest(dict); 172 deflateResetDictionaryTest(dict); 173 rawDictionaryTest(dict); 174 deflateRawResetDictionaryTest(dict); 175} 176