3 * Copyright(c) 2010 Sencha Inc.
4 * Copyright(c) 2011 TJ Holowaychuk
12 var zlib = require('zlib');
15 * Supported content-encoding methods.
20 , deflate: zlib.createDeflate
24 * Default filter function.
27 exports.filter = function(req, res){
28 return /json|text|javascript/.test(res.getHeader('Content-Type'));
34 * Compress response data with gzip/deflate.
38 * A `filter` callback function may be passed to
39 * replace the default logic of:
41 * exports.filter = function(req, res){
42 * return /json|text|javascript/.test(res.getHeader('Content-Type'));
47 * All remaining options are passed to the gzip/deflate
48 * creation functions. Consult node's docs for additional details.
50 * - `chunkSize` (default: 16*1024)
52 * - `level`: 0-9 where 0 is no compression, and 9 is slow but best compression
53 * - `memLevel`: 1-9 low is slower but uses less memory, high is fast but uses more
54 * - `strategy`: compression strategy
56 * @param {Object} options
61 module.exports = function compress(options) {
62 var options = options || {}
63 , names = Object.keys(exports.methods)
64 , filter = options.filter || exports.filter;
66 return function(req, res, next){
67 var accept = req.headers['accept-encoding']
74 res.setHeader('Vary', 'Accept-Encoding');
78 res.write = function(chunk, encoding){
79 if (!this.headerSent) this._implicitHeader();
81 ? stream.write(new Buffer(chunk, encoding))
82 : write.call(res, chunk, encoding);
85 res.end = function(chunk, encoding){
86 if (chunk) this.write(chunk, encoding);
92 res.on('header', function(){
93 // default request filter
94 if (!filter(req, res)) return;
96 // SHOULD use identity
100 if ('HEAD' == req.method) return;
103 if ('*' == accept.trim()) method = 'gzip';
105 // compression method
107 for (var i = 0, len = names.length; i < len; ++i) {
108 if (~accept.indexOf(names[i])) {
115 // compression method
118 // compression stream
119 stream = exports.methods[method](options);
122 res.setHeader('Content-Encoding', method);
123 res.removeHeader('Content-Length');
127 stream.on('data', function(chunk){
128 write.call(res, chunk);
131 stream.on('end', function(){
135 stream.on('drain', function() {