Skip to content

Instantly share code, notes, and snippets.

@AndreasMadsen
Created June 9, 2012 20:55
Show Gist options
  • Save AndreasMadsen/2902573 to your computer and use it in GitHub Desktop.
Save AndreasMadsen/2902573 to your computer and use it in GitHub Desktop.
compress bug?
var fs = require('fs');
var url = require('url');
var path = require('path');
var http = require('http');
var mime = require('mime');
var zlib = require('zlib');
// Define compression types
var compressors = {
gzip: zlib.createGzip,
deflate: zlib.createDeflate
};
var server = http.createServer();
server.on('request', function (req, res) {
if (req.url === '/favicon.ico') {
res.end();
return;
}
route(req, res);
});
server.listen(8000, '127.0.0.1');
function route(req, res) {
var pathname = path.join(
path.dirname(module.filename),
'../../project/static',
url.parse(req.url).pathname
);
// set response code
res.statusCode = 200;
// Set cache control headers
res.setHeader('Expires', 'Mon, 26 Jul 1997 05:00:00 GMT');
res.setHeader('Cache-Control', 'no-cache, private, must-revalidate, ' +
'max-stale=0, post-check=0, pre-check=0 no-store');
res.setHeader('Pragma', 'no-cache');
// get content type header
var type = mime.lookup(pathname);
var charset = mime.charsets.lookup(type);
// assume charset is UTF-8 if is handled by a compress stream
if (!charset && /json|text|javascript/.test(type)) {
charset = 'UTF-8';
}
// set mime and charset
res.setHeader('Content-Type', type + (charset ? '; charset=' + charset : ''));
// create read stream and add to domain
var file = fs.createReadStream(pathname);
file.pause();
fs.stat(pathname, function (error, stat) {
if (error) return file.emit('error', error);
file.mtime = stat.mtime;
file.size = stat.size;
file.emit('ready');
});
file.once('ready', function () {
// set mtime and size headers
res.setHeader('Last-Modified', file.mtime.toUTCString());
res.setHeader('Content-Length', file.size); // don't do this - bug
var stream = open(req, res);
// HEAD request, nothing should be writen
if (stream === false) {
file.destroy();
}
// pipe file content to http response stream
else {
file.pipe( stream );
file.resume();
}
});
}
function open(req, res) {
// set Date header
res.setHeader('Date', new Date().toUTCString());
// do only compress plain text
if (/json|text|javascript/.test(res.getHeader('Content-Type')) === false) {
return res;
}
// get accept encodeing
var accept = req.headers['accept-encoding'];
// Indicate the the respons is depends on accept-encoding
res.setHeader('Vary', 'Accept-Encoding');
// get compressor
var method = null;
if (accept === undefined) {
method = null;
} else if (accept.trim() === '*') {
method = 'gzip';
} else if (accept.indexOf('deflate') !== -1) {
method = 'gzip';
} else if (accept.indexOf('gzip') !== -1) {
method = 'deflate';
}
// set content-encoding if possible
if (method) {
res.setHeader('Content-Encoding', method);
}
// http HEAD means that no respons is wanted,
// but the header should be the same as it GET coresponding request
if ('HEAD' == req.method) {
res.end();
return false;
}
// return write stream
if (method) {
var stream = compressors[method]();
stream.pipe(res);
return stream;
}
// default to identity encodeing
return res;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment