Added image compression plugin.

This commit is contained in:
Sylvain Cleymans 2014-05-29 13:25:06 -07:00
Родитель 538e73eea6
Коммит 7746544d96
4 изменённых файлов: 84 добавлений и 6 удалений

Просмотреть файл

@ -43,6 +43,8 @@ cache:
enabled: true
limit: 2000
imgcompression:
enabled: true
gzip:
# Compression level for gzip.
@ -50,4 +52,4 @@ gzip:
# Block gif2video by default
gif2video:
enabled: false
enabled: false

Просмотреть файл

@ -0,0 +1,71 @@
var fs = require('fs');
var temp = require ('temp');
var execFile = require('child_process').execFile;
var mozjpeg = require('mozjpeg').path;
var pngquant = require('pngquant-bin').path;
var imgtype = require('imagetype');
exports.name = 'imgcompression';
exports.handleResponse = function(request, source, dest) {
// If this is an image we first write it into a file, then optimize it
// and send it
if (source.headers['content-type'] === 'image/jpeg' ||
source.headers['content-type'] === 'image/png') {
var path = temp.path();
var optPath = path + '.opt';
var imageFile = fs.createWriteStream(path);
source.pipe(imageFile);
imageFile.on('finish', function() {
function sendImage(path) {
fs.stat(path, function(err, stats) {
dest.headers['content-length'] = stats.size.toString();
imageFile = fs.createReadStream(path);
imageFile.pipe(dest);
dest.on('end', function() {
fs.unlink(path);
});
});
}
// We need to check the actual type of the downloaded image.
// Some websites (e.g. mozilla.org) are sending JPEGs as PNGs.
imgtype(path, function(type) {
if (type === 'png') {
execFile(pngquant,
['--skip-if-larger', '-o', optPath, path],
function(err) {
if (err) {
sendImage(path);
} else {
sendImage(optPath);
fs.unlink(path);
}
});
} else if (type === 'jpeg') {
execFile(mozjpeg,
['-outfile', optPath, path],
function(err, stdout, stderr) {
if (err) {
console.log('error:', stderr);
sendImage(path);
} else {
sendImage(optPath);
fs.unlink(path);
}
});
} else {
sendImage(path);
}
});
});
} else {
source.pipe(dest);
}
source.resume();
};

Просмотреть файл

@ -5,4 +5,4 @@ request:
# Response plugins go here, and the response pipeline is
# constructed in the order given
response:
[ingress, gunzip, dom/gif2video, dom, gzip, cachesave, egress]
[ingress, imgcompression, gunzip, dom/gif2video, dom, gzip, cachesave, egress]

Просмотреть файл

@ -16,23 +16,28 @@
"proxy"
],
"author": "Eugen Sawin <esawin@mozilla.com>",
"contributors": [ "Sylvain Cleymans <sylvain.cleymans@gmail.com>" ],
"license": "MIT",
"dependencies": {
"cheerio": "0.15.0",
"config": "^0.4.36",
"follow-redirects": "0.0.3",
"hiredis": "^0.1.17",
"imagetype": "^0.2.0",
"js-yaml": "^3.0.2",
"memory-cache": "0.0.5",
"mozjpeg": "^0.1.2",
"optimist": "~0.6.1",
"png": "~3.0.3",
"pngquant-bin": "^0.3.1",
"redis": "^0.10.3",
"spdy": "~1.26.0",
"synchronize": "^0.9.3",
"cheerio": "0.15.0",
"temp": "^0.7.0",
"js-yaml": "^3.0.2",
"follow-redirects": "0.0.3"
"temp": "^0.7.0"
},
"devDependencies": {
"jscs": "^1.4.5",
"jshint": "^2.5.1"
}
}