arnaucube
arnaucube/raspberryGPIOhtmlserverPublic Self-hosted repository
raspberryGPIOhtmlserver/node_modules/connect/lib/middleware/compress.js
node_modules/connect/lib/middleware/compress.jsRaw
  1/*!
  2 * Connect - compress
  3 * Copyright(c) 2010 Sencha Inc.
  4 * Copyright(c) 2011 TJ Holowaychuk
  5 * MIT Licensed
  6 */
  7
  8/**
  9 * Module dependencies.
 10 */
 11
 12var zlib = require('zlib');
 13
 14/**
 15 * Supported content-encoding methods.
 16 */
 17
 18exports.methods = {
 19    gzip: zlib.createGzip
 20  , deflate: zlib.createDeflate
 21};
 22
 23/**
 24 * Default filter function.
 25 */
 26
 27exports.filter = function(req, res){
 28  return /json|text|javascript/.test(res.getHeader('Content-Type'));
 29};
 30
 31/**
 32 * Compress:
 33 *
 34 * Compress response data with gzip/deflate.
 35 *
 36 * Filter:
 37 *
 38 *  A `filter` callback function may be passed to
 39 *  replace the default logic of:
 40 *
 41 *     exports.filter = function(req, res){
 42 *       return /json|text|javascript/.test(res.getHeader('Content-Type'));
 43 *     };
 44 *
 45 * Options:
 46 *
 47 *  All remaining options are passed to the gzip/deflate
 48 *  creation functions. Consult node's docs for additional details.
 49 *
 50 *   - `chunkSize` (default: 16*1024)
 51 *   - `windowBits`
 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
 55 *
 56 * @param {Object} options
 57 * @return {Function}
 58 * @api public
 59 */
 60
 61module.exports = function compress(options) {
 62  options = options || {};
 63  var names = Object.keys(exports.methods)
 64    , filter = options.filter || exports.filter;
 65
 66  return function compress(req, res, next){
 67    var accept = req.headers['accept-encoding']
 68      , vary = res.getHeader('Vary')
 69      , write = res.write
 70      , end = res.end
 71      , stream
 72      , method;
 73
 74    // vary
 75    if (!vary) {
 76      res.setHeader('Vary', 'Accept-Encoding');
 77    } else if (!~vary.indexOf('Accept-Encoding')) {
 78      res.setHeader('Vary', vary + ', Accept-Encoding');
 79    }
 80
 81    // see #724
 82    req.on('close', function(){
 83      res.write = res.end = function(){};
 84    });
 85
 86    // proxy
 87
 88    res.write = function(chunk, encoding){
 89      if (!this.headerSent) this._implicitHeader();
 90      return stream
 91        ? stream.write(new Buffer(chunk, encoding))
 92        : write.call(res, chunk, encoding);
 93    };
 94
 95    res.end = function(chunk, encoding){
 96      if (chunk) this.write(chunk, encoding);
 97      return stream
 98        ? stream.end()
 99        : end.call(res);
100    };
101
102    res.on('header', function(){
103      var encoding = res.getHeader('Content-Encoding') || 'identity';
104
105      // already encoded
106      if ('identity' != encoding) return;
107
108      // default request filter
109      if (!filter(req, res)) return;
110
111      // SHOULD use identity
112      if (!accept) return;
113
114      // head
115      if ('HEAD' == req.method) return;
116
117      // default to gzip
118      if ('*' == accept.trim()) method = 'gzip';
119
120      // compression method
121      if (!method) {
122        for (var i = 0, len = names.length; i < len; ++i) {
123          if (~accept.indexOf(names[i])) {
124            method = names[i];
125            break;
126          }
127        }
128      }
129
130      // compression method
131      if (!method) return;
132
133      // compression stream
134      stream = exports.methods[method](options);
135
136      // header fields
137      res.setHeader('Content-Encoding', method);
138      res.removeHeader('Content-Length');
139
140      // compression
141
142      stream.on('data', function(chunk){
143        write.call(res, chunk);
144      });
145
146      stream.on('end', function(){
147        end.call(res);
148      });
149
150      stream.on('drain', function() {
151        res.emit('drain');
152      });
153    });
154
155    next();
156  };
157};