-
Notifications
You must be signed in to change notification settings - Fork 6
/
index.js
101 lines (86 loc) · 2.58 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
'use strict';
var execFile = require('child_process').execFile;
var fs = require('fs');
var webpBinPath = require('cwebp-bin');
var mime = require('mime');
var crypto = require('crypto');
var path = require('path');
var mkdirp = require('mkdirp');
var vary = require('vary');
var supportedMimes = [
'image/jpeg',
'image/png',
'image/tiff'
];
var _tempCache = [];
var send = function send(res, path, cb) {
var sendMethod = typeof res.sendFile === 'undefined' ?
res.sendfile :
res.sendFile;
vary(res, 'Accept');
sendMethod.call(res, path, cb);
}
var sendAndSave = function sendAndSave(res, path, cb) {
_tempCache.push(path);
send(res, path, cb);
};
module.exports = function(basePath, options) {
// use custom dir or choose default
options = options || {};
var cacheDir = options.cacheDir ?
options.cacheDir :
path.join(process.cwd(), 'webp-cache');
// compute options in external file
var optionArr = require('./compute-options')(options);
// create cache dir if not exists
var cachePathExists = fs.existsSync(path.join(cacheDir));
if (!cachePathExists) {
mkdirp.sync(path.join(cacheDir));
}
/**
* handles each request and sends a webp image format if the client supports it
*/
return function webpMiddleware(req, res, next) {
var mimeType = mime.getType(req.originalUrl);
var pathOptions = [];
var accept = req.headers.accept;
var hasMimetype = supportedMimes.indexOf(mimeType) !== -1;
var acceptWebp = accept && accept.indexOf('image/webp') !== -1;
// just move on if mimetypes does not match
if (!hasMimetype || !acceptWebp) {
next();
return;
}
var hash = crypto.createHash('md5').update(req.originalUrl).digest('hex');
var cachePath = path.join(cacheDir, hash + '.webp');
var imgPath = path.join(basePath, req.originalUrl);
// try lookup cache for fast access
if (_tempCache.indexOf(cachePath) !== -1) {
send(res, cachePath, function(err) {
if (err) {
_tempCache.splice(_tempCache.indexOf(cachePath), 1);
webpMiddleware(req, res, next);
}
});
return;
}
fs.exists(cachePath, function(exists) {
if (exists) {
sendAndSave(res, cachePath);
return;
}
pathOptions.push(imgPath);
pathOptions = pathOptions.concat(optionArr);
pathOptions.push('-o');
pathOptions.push(cachePath);
execFile(webpBinPath, pathOptions, function(err) {
if (err) {
console.error(err);
next();
return;
}
sendAndSave(res, cachePath);
});
});
};
};