mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-01-19 14:13:34 +01:00
caching_midleware: also run when nodejs does not have crypto module
According to the nodejs docs [0] the `crypto` module might be unavailable on
some platforms:
> It is possible for Node.js to be built without including support for the
> crypto module. In such cases, calling require('crypto') will result in an
> error being thrown
A description of such scenarios can be found here [1].
> * running non-standard node in a resource- or security-constrained
> environment
> * running in emulated environment (browserify, webpack etc.)
> * building node from source and omitting openssl/crypto for random reason
TypeScript guys dealt with this same issue and they resolved it in an elegant
way in [2].
We copy that approach here: if importing crypto fails at runtime, we replace
sha256 with djb2 [3], which is weaker, but works for our case.
The djb2 story is fun: see this Stack Overflow post [4], and the original
mailing list post from 1991 [5] by Daniel J. Bernstein [6].
He was 20 at the time!
[0] https://nodejs.org/docs/latest-v10.x/api/crypto.html#crypto_determining_if_crypto_support_is_unavailable
[1] https://github.com/microsoft/TypeScript/issues/19100#issuecomment-335871998
[2] 9677b0641c
[3] http://www.cse.yorku.ca/~oz/hash.html#djb2
[4] https://stackoverflow.com/questions/1579721/why-are-5381-and-33-so-important-in-the-djb2-algorithm
[5] https://groups.google.com/forum/#!msg/comp.lang.c/lSKWXiuNOAk/zstZ3SRhCjgJ
[6] https://en.wikipedia.org/wiki/Daniel_J._Bernstein
This commit is contained in:
parent
fc754c9a1d
commit
4ee5ddb496
1 changed files with 45 additions and 2 deletions
|
@ -22,13 +22,56 @@ var zlib = require('zlib');
|
|||
var settings = require('./Settings');
|
||||
var semver = require('semver');
|
||||
var existsSync = require('./path_exists');
|
||||
var crypto = require('crypto');
|
||||
|
||||
/*
|
||||
* The crypto module can be absent on reduced node installations.
|
||||
*
|
||||
* Here we copy the approach TypeScript guys used for https://github.com/microsoft/TypeScript/issues/19100
|
||||
* If importing crypto fails at runtime, we replace sha256 with djb2, which is
|
||||
* weaker, but works for our case.
|
||||
*
|
||||
* djb2 was written in 1991 by Daniel J. Bernstein.
|
||||
*
|
||||
*/
|
||||
|
||||
// MIMIC https://github.com/microsoft/TypeScript/commit/9677b0641cc5ba7d8b701b4f892ed7e54ceaee9a - START
|
||||
let _crypto;
|
||||
|
||||
try {
|
||||
_crypto = require('crypto');
|
||||
} catch {
|
||||
_crypto = undefined;
|
||||
}
|
||||
|
||||
var CACHE_DIR = path.normalize(path.join(settings.root, 'var/'));
|
||||
CACHE_DIR = existsSync(CACHE_DIR) ? CACHE_DIR : undefined;
|
||||
|
||||
var responseCache = {};
|
||||
|
||||
function djb2Hash(data) {
|
||||
const chars = data.split("").map(str => str.charCodeAt(0));
|
||||
return `${chars.reduce((prev, curr) => ((prev << 5) + prev) + curr, 5381)}`;
|
||||
}
|
||||
|
||||
function generateCacheKeyWithSha256(path) {
|
||||
return _crypto.createHash('sha256').update(path).digest('hex');
|
||||
}
|
||||
|
||||
function generateCacheKeyWithDjb2(path) {
|
||||
return Buffer.from(djb2Hash(path)).toString('hex');
|
||||
}
|
||||
|
||||
let generateCacheKey;
|
||||
|
||||
if (_crypto) {
|
||||
generateCacheKey = generateCacheKeyWithSha256;
|
||||
} else {
|
||||
generateCacheKey = generateCacheKeyWithDjb2;
|
||||
console.warn('No crypto support in this nodejs runtime. A fallback to Djb2 (weaker) will be used.');
|
||||
}
|
||||
|
||||
// MIMIC https://github.com/microsoft/TypeScript/commit/9677b0641cc5ba7d8b701b4f892ed7e54ceaee9a - END
|
||||
|
||||
/*
|
||||
This caches and compresses 200 and 404 responses to GET and HEAD requests.
|
||||
TODO: Caching and compressing are solved problems, a middleware configuration
|
||||
|
@ -50,7 +93,7 @@ CachingMiddleware.prototype = new function () {
|
|||
(req.get('Accept-Encoding') || '').indexOf('gzip') != -1;
|
||||
|
||||
var path = require('url').parse(req.url).path;
|
||||
var cacheKey = crypto.createHash('sha256').update(path).digest('hex');
|
||||
var cacheKey = generateCacheKey(path);
|
||||
|
||||
fs.stat(CACHE_DIR + 'minified_' + cacheKey, function (error, stats) {
|
||||
var modifiedSince = (req.headers['if-modified-since']
|
||||
|
|
Loading…
Reference in a new issue