Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Use node zlib when supported and no bin option supplied. #15

Closed
wants to merge 1 commit into from

1 participant

@dougwilson

This added zlib support, but just optional instead of requiring node 0.6.x for the module and keeps backward compatibility in the API (will go back to spawning processes if the user provides bin or flags options).

This only adds support to gzip and not staticGzip.

@dougwilson

I'm closing this PR because the library doesn't particularly have any activity and middleware like compression exists.

@dougwilson dougwilson closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
Showing with 96 additions and 0 deletions.
  1. +96 −0 lib/gzip.js
View
96 lib/gzip.js
@@ -5,6 +5,9 @@
*/
var spawn = require('child_process').spawn;
+var zlib;
+
+try { zlib = require('zlib'); } catch (e) {}
/**
* Connect middleware providing gzip compression on the fly. By default, it
@@ -29,6 +32,10 @@ exports = module.exports = function gzip(options) {
if (!matchType.test) throw new Error('option matchType must be a regular expression');
+ if (zlib && !options.bin && !options.flags) {
+ return zlibGzip(options);
+ }
+
flags = (flags) ? '-c ' + flags : '-c';
flags = flags.split(' ');
@@ -110,3 +117,92 @@ exports = module.exports = function gzip(options) {
next();
};
};
+
+function zlibGzip(options) {
+ var options = options || {},
+ matchType = options.matchType || /text|javascript|json/;
+
+ if (!matchType.test) throw new Error('option matchType must be a regular expression');
+
+ return function gzip(req, res, next) {
+ var writeHead = res.writeHead,
+ defaults = {};
+
+ ['write', 'end'].forEach(function(name) {
+ defaults[name] = res[name];
+ res[name] = function() {
+ // Make sure headers are setup if they haven't been called yet
+ if (res.writeHead !== writeHead) {
+ res.writeHead(res.statusCode);
+ }
+ res[name].apply(this, arguments);
+ };
+ });
+
+ res.writeHead = function(code) {
+ var args = Array.prototype.slice.call(arguments, 0),
+ write = defaults.write,
+ end = defaults.end,
+ headers, key, accept, type, encoding, gzip, ua;
+ if (args.length > 1) {
+ headers = args.pop();
+ for (key in headers) {
+ res.setHeader(key, headers[key]);
+ }
+ }
+
+ ua = req.headers['user-agent'] || '';
+ accept = req.headers['accept-encoding'] || '';
+ type = res.getHeader('content-type') || '';
+ encoding = res.getHeader('content-encoding');
+
+ if (req.method === 'HEAD' || code !== 200 || !~accept.indexOf('gzip') ||
+ !matchType.test(type) || encoding ||
+ (~ua.indexOf('MSIE 6') && !~ua.indexOf('SV1'))) {
+ res.write = write;
+ res.end = end;
+ return finish();
+ }
+
+ res.setHeader('Content-Encoding', 'gzip');
+ res.setHeader('Vary', 'Accept-Encoding');
+ res.removeHeader('Content-Length');
+
+ gzip = zlib.createGzip();
+
+ res.write = function(chunk, encoding) {
+ gzip.write(chunk, encoding);
+ };
+
+ res.end = function(chunk, encoding) {
+ if (chunk) {
+ res.write(chunk, encoding);
+ }
+ gzip.end();
+ };
+
+ gzip.on('data', function(chunk) {
+ write.call(res, chunk);
+ });
+
+ gzip.on('end', function() {
+ res.write = write;
+ res.end = end;
+ res.end();
+ });
+
+ gzip.on('drain', function(chunk) {
+ res.emit('drain');
+ });
+
+ finish();
+
+ function finish() {
+ res.writeHead = writeHead;
+ res.writeHead.apply(res, args);
+ }
+ };
+
+ next();
+ };
+};
Something went wrong with that request. Please try again.