Permalink
Browse files

Adding compress.js from connect 2.X

  • Loading branch information...
1 parent f87c427 commit 5533cad1a08c47f9c4219730943ff2d564c9f77f @tomgco committed Dec 26, 2011
Showing with 141 additions and 1 deletion.
  1. +2 −1 index.js
  2. +139 −0 lib/compress.js
View
@@ -1 +1,2 @@
-exports.staticGzip = require("./lib/staticGzip.js");
+exports.staticGzip = require("./lib/staticGzip.js");
+exports.compress = require("./lib/compress.js");
View
@@ -0,0 +1,139 @@
+
+/*!
+ * Connect - compress
+ * Copyright(c) 2010 Sencha Inc.
+ * Copyright(c) 2011 TJ Holowaychuk
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var zlib = require('zlib');
+
+/**
+ * Supported content-encoding methods.
+ */
+
+exports.methods = {
+ gzip: zlib.createGzip,
+ deflate: zlib.createDeflate
+};
+
+/**
+ * Default filter function.
+ */
+
+exports.filter = function(req, res){
+ var type = res.getHeader('Content-Type') || '';
+ return type.match(/json|text|javascript/);
+};
+
+/**
+ * Compress response data with gzip/deflate.
+ *
+ * Filter:
+ *
+ * A `filter` callback function may be passed to
+ * replace the default logic of:
+ *
+ * exports.filter = function(req, res){
+ * var type = res.getHeader('Content-Type') || '';
+ * return type.match(/json|text|javascript/);
+ * };
+ *
+ * Options:
+ *
+ * All remaining options are passed to the gzip/deflate
+ * creation functions. Consult node's docs for additional details.
+ *
+ * - `chunkSize` (default: 16*1024)
+ * - `windowBits`
+ * - `level`: 0-9 where 0 is no compression, and 9 is slow but best compression
+ * - `memLevel`: 1-9 low is slower but uses less memory, high is fast but uses more
+ * - `strategy`: compression strategy
+ *
+ * @param {Object} options
+ * @return {Function}
+ * @api public
+ */
+
+module.exports = function compress(options) {
+ var options = options || {}
+ , names = Object.keys(exports.methods)
+ , filter = options.filter || exports.filter;
+
+ return function(req, res, next){
+ var accept = req.headers['accept-encoding']
+ , write = res.write
+ , end = res.end
+ , stream
+ , method;
+
+ // vary
+ res.setHeader('Vary', 'Accept-Encoding');
+
+ // proxy
+
+ res.write = function(chunk, encoding){
+ if (!this.headerSent) this._implicitHeader();
+ return stream
+ ? stream.write(chunk, encoding)
+ : write.call(res, chunk, encoding);
+ };
+
+ res.end = function(chunk, encoding){
+ if (chunk) this.write(chunk, encoding);
+ return stream
+ ? stream.end()
+ : end.call(res);
+ };
+
+ res.on('header', function(){
+ // default request filter
+ if (!filter(req, res)) return;
+
+ // SHOULD use identity
+ if (!accept) return;
+
+ // head
+ if ('HEAD' == req.method) return;
+
+ // default to gzip
+ if ('*' == accept.trim()) method = 'gzip';
+
+ // compression method
+ if (!method) {
+ for (var i = 0, len = names.length; i < len; ++i) {
+ if (~accept.indexOf(names[i])) {
+ method = names[i];
+ break;
+ }
+ }
+ }
+
+ // compression method
+ if (!method) return;
+
+ // compression stream
+ stream = exports.methods[method](options);
+
+ // header fields
+ res.setHeader('Content-Encoding', method);
+ res.removeHeader('Content-Length');
+
+ // compression
+
+ stream.on('data', function(chunk){
+ write.call(res, chunk);
+ });
+
+ stream.on('end', function(){
+ end.call(res);
+ });
+ });
+
+ next();
+ };
+}

0 comments on commit 5533cad

Please sign in to comment.