diff options
Diffstat (limited to 'node_modules/http-basic/lib')
| -rw-r--r-- | node_modules/http-basic/lib/cache-utils.js | 29 | ||||
| -rw-r--r-- | node_modules/http-basic/lib/file-cache.js | 62 | ||||
| -rw-r--r-- | node_modules/http-basic/lib/memory-cache.js | 39 |
3 files changed, 130 insertions, 0 deletions
diff --git a/node_modules/http-basic/lib/cache-utils.js b/node_modules/http-basic/lib/cache-utils.js new file mode 100644 index 0000000..3f76b0f --- /dev/null +++ b/node_modules/http-basic/lib/cache-utils.js @@ -0,0 +1,29 @@ +'use strict'; + +exports.isMatch = function (requestHeaders, cachedResponse) { + if (cachedResponse.headers['vary'] && cachedResponse.requestHeaders) { + return cachedResponse.headers['vary'].split(',').map(function (header) { return header.trim().toLowerCase(); }).every(function (header) { + return requestHeaders[header] === cachedResponse.requestHeaders[header]; + }); + } else { + return true; + } +}; +exports.isExpired = function (cachedResponse) { + var match + if (cachedResponse.headers['cache-control'] && (match = /^public\, *max\-age\=(\d+)$/.exec(cachedResponse.headers['cache-control']))) { + var time = (Date.now() - cachedResponse.requestTimestamp) / 1000; + if ((+match[1]) > time) { + return false; + } + } + if (cachedResponse.statusCode === 301 || cachedResponse.statusCode === 308) return false; + return true; +}; +exports.canCache = function (res) { + if (res.headers['etag']) return true; + if (/^public\, *max\-age\=(\d+)$/.test(res.headers['cache-control'])) return true; + if (res.statusCode === 301 || res.statusCode === 308) return true; + + return false; +}; diff --git a/node_modules/http-basic/lib/file-cache.js b/node_modules/http-basic/lib/file-cache.js new file mode 100644 index 0000000..9b90582 --- /dev/null +++ b/node_modules/http-basic/lib/file-cache.js @@ -0,0 +1,62 @@ +'use strict'; + +var fs = require('fs'); +var path = require('path'); +var crypto = require('crypto'); +var Response = require('http-response-object'); + +module.exports = FileCache; +function FileCache(location) { + this._location = location; +} + +FileCache.prototype.getResponse = function (url, callback) { + var key = path.resolve(this._location, getCacheKey(url)); + + fs.readFile(key + '.json', 'utf8', function (err, res) { + if (err && err.code === 'ENOENT') return callback(null, null); + else if (err) return callback(err); + try { + res = JSON.parse(res); + } catch (ex) { + return callback(ex); + } + var body = fs.createReadStream(key + '.body'); + res.body = body; + callback(null, res); + }); +}; +FileCache.prototype.setResponse = function (url, response) { + var key = path.resolve(this._location, getCacheKey(url)); + var errored = false; + + fs.mkdir(this._location, function (err) { + if (err && err.code !== 'EEXIST') { + console.warn('Error creating cache: ' + err.message); + return; + } + response.body.pipe(fs.createWriteStream(key + '.body')).on('error', function (err) { + errored = true; + console.warn('Error writing to cache: ' + err.message); + }).on('close', function () { + if (!errored) { + fs.writeFile(key + '.json', JSON.stringify({ + statusCode: response.statusCode, + headers: response.headers, + requestHeaders: response.requestHeaders, + requestTimestamp: response.requestTimestamp + }, null, ' '), function (err) { + if (err) { + console.warn('Error writing to cache: ' + err.message); + } + }); + } + }); + }); +}; + +function getCacheKey(url) { + var hash = crypto.createHash('sha512') + hash.update(url) + return hash.digest('hex') +} diff --git a/node_modules/http-basic/lib/memory-cache.js b/node_modules/http-basic/lib/memory-cache.js new file mode 100644 index 0000000..cf1f5a9 --- /dev/null +++ b/node_modules/http-basic/lib/memory-cache.js @@ -0,0 +1,39 @@ +'use strict'; + +var PassThrough = require('stream').PassThrough; +var concat = require('concat-stream'); +var Response = require('http-response-object'); + +module.exports = MemoryCache; +function MemoryCache() { + this._cache = {}; +} + +MemoryCache.prototype.getResponse = function (url, callback) { + var cache = this._cache; + if (cache[url]) { + var body = new PassThrough(); + body.end(cache[url].body); + callback(null, { + statusCode: cache[url].statusCode, + headers: cache[url].headers, + body: body, + requestHeaders: cache[url].requestHeaders, + requestTimestamp: cache[url].requestTimestamp + }); + } else { + callback(null, null); + } +}; +MemoryCache.prototype.setResponse = function (url, response) { + var cache = this._cache; + response.body.pipe(concat(function (body) { + cache[url] = { + statusCode: response.statusCode, + headers: response.headers, + body: body, + requestHeaders: response.requestHeaders, + requestTimestamp: response.requestTimestamp + }; + })); +}; |