diff --git a/lib/gzip.js b/lib/gzip.js index 0e31877..e2a7746 100644 --- a/lib/gzip.js +++ b/lib/gzip.js @@ -4,8 +4,6 @@ * MIT Licensed */ -var spawn = require('child_process').spawn; - /** * Connect middleware providing gzip compression on the fly. By default, it * compresses requests with mime types that match the expression @@ -14,23 +12,58 @@ var spawn = require('child_process').spawn; * Options: * * - `matchType` Regular expression matching mime types to be compressed - * - `flags` String of flags passed to the binary. Nothing by default - * - `bin` Binary executable defaulting to "gzip" + * - `flags` DEPRECATED: String of flags passed to the binary. Nothing + * by default * * @param {Object} options * @api public */ +var zlib = require('zlib'); + +function hasOwnProperty(o, key) { + return Object.prototype.hasOwnProperty.call(o, key); +} +function selectProperties(o, key1, key2) { + var object = {}; + for (var i = 1, ii = arguments.length; i < ii; i++) { + var key = arguments[i]; + if (hasOwnProperty(o, key)) { + object[key] = o[key]; + } + } + return object; +} + +// Do some cheap parsing of flags to ease deprecation. +function optionsFromGzipFlags(flags) { + var options = {}; + flags = (flags || '').split(' '); + if (flags.indexOf('--best') > 0) { + options.level = 9; + } + if (flags.indexOf('--fast') > 0) { + options.level = 1; + } + for (var i = 0, ii = 9; i < ii; i++) { + if (flags.indexOf('-' + i) > 0) { + options.level = i; + } + } + return i; +} + exports = module.exports = function gzip(options) { var options = options || {}, matchType = options.matchType || /text|javascript|json/, - bin = options.bin || 'gzip', - flags = options.flags || ''; + gzipOptions = selectProperties(options, + 'chunkSize', 'windowBits', 'level', 'memLevel', 'strategy'); if (!matchType.test) throw new Error('option matchType must be a regular expression'); - flags = (flags) ? '-c ' + flags : '-c'; - flags = flags.split(' '); + if (options.flags) { + options = optionsFromGzipFlags(options.flags); + } return function gzip(req, res, next) { var writeHead = res.writeHead, @@ -76,28 +109,32 @@ exports = module.exports = function gzip(options) { res.setHeader('Vary', 'Accept-Encoding'); res.removeHeader('Content-Length'); - gzip = spawn(bin, flags); + var gzip = zlib.createGzip(gzipOptions); res.write = function(chunk, encoding) { - gzip.stdin.write(chunk, encoding); + gzip.write(chunk, encoding); }; res.end = function(chunk, encoding) { if (chunk) { res.write(chunk, encoding); } - gzip.stdin.end(); + gzip.end(); }; - gzip.stdout.addListener('data', function(chunk) { + gzip.addListener('data', function(chunk) { write.call(res, chunk); }); - gzip.addListener('exit', function(code) { + gzip.addListener('end', function() { res.write = write; res.end = end; res.end(); }); + + gzip.addListener('error', function(error) { + res.close(); + }); finish(); diff --git a/package.json b/package.json index a460efe..e1b9baf 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "mime": ">=0.0.1" }, "engines": { - "node": "*" + "node": ">=0.6.0" }, "devDependencies": { "expresso": ">=0.9",