express-disk-cache
Advanced tools
Comparing version 1.0.3 to 1.0.4
@@ -1,8 +0,8 @@ | ||
var Buffer = require('safe-buffer').Buffer; | ||
var basename = require('path').basename; | ||
var on_headers = require('on-headers'); | ||
var join = require('path').join; | ||
var uuid = require('uuid/v1'); | ||
var fs = require('fs-extra'); | ||
var debug = function(){}; | ||
var Buffer = require("safe-buffer").Buffer; | ||
var basename = require("path").basename; | ||
var on_headers = require("on-headers"); | ||
var join = require("path").join; | ||
var uuid = require("uuid/v1"); | ||
var fs = require("fs-extra"); | ||
var debug = function() {}; | ||
@@ -14,17 +14,15 @@ // Regex to check the Cache-Control header to | ||
// Header strings | ||
var CACHE_CONTROL = 'Cache-Control'; | ||
var CONTENT_TYPE = 'Content-Type'; | ||
var CACHE_CONTROL = "Cache-Control"; | ||
var CONTENT_TYPE = "Content-Type"; | ||
module.exports = function (cache_directory) { | ||
module.exports = function(cache_directory) { | ||
var tmp_directory; | ||
if (!cache_directory) throw new Error('Pass a cache directory'); | ||
if (!cache_directory) throw new Error("Pass a cache directory"); | ||
// Ensure the temp directory exists | ||
tmp_directory = join(cache_directory, '.tmp'); | ||
tmp_directory = join(cache_directory, ".tmp"); | ||
fs.ensureDirSync(tmp_directory); | ||
return function disk_cache (req, res, next){ | ||
return function disk_cache(req, res, next) { | ||
var called_end = false; | ||
@@ -35,6 +33,5 @@ var stream, final_path, tmp_path, tmp_name, protocol; | ||
var _end = res.end; | ||
res.write = function (chunk, encoding) { | ||
debug('write called', chunk, encoding); | ||
res.write = function(chunk, encoding) { | ||
debug("write called", chunk, encoding); | ||
@@ -49,3 +46,3 @@ // Trigger the onHeaders function below | ||
// below. This prevents a 'double write' | ||
// when calling end with a final chunk. | ||
// when calling end with a final chunk. | ||
// I don't understand why this flag isn't | ||
@@ -56,3 +53,3 @@ // needed when calling the original _write | ||
// The return value of response.write is | ||
// meaningful and tells | ||
// meaningful and tells | ||
// I believe it dictates whether or not the stream | ||
@@ -64,16 +61,15 @@ // is ready to be written too again. So we need to return it | ||
res.end = function (chunk, encoding) { | ||
res.end = function(chunk, encoding) { | ||
debug("end called", chunk, encoding); | ||
debug('end called', chunk, encoding); | ||
// This flag is used to prevent a 'double write' | ||
// if response.end is invoked with a chunk of data | ||
// You can end a writeable stream with or without | ||
// You can end a writeable stream with or without | ||
// some final piece of data. Calling res.end | ||
// with a final piece of data neccessarily invokes | ||
// res.write afterwards for a reason I don't | ||
// res.write afterwards for a reason I don't | ||
// quite yet understand, so we set this flag to allow | ||
// our res.write function not to write the data a second time | ||
called_end = true; | ||
// Triggers the onHeaders function below | ||
@@ -83,3 +79,3 @@ // if we have not set any headers ourselves | ||
// We need to create a buffer from the data | ||
// We need to create a buffer from the data | ||
// chunk passed to response.end. I'm not sure exactly | ||
@@ -93,3 +89,3 @@ // why but it's what the compression middleware does. | ||
// Again, like res.write, the return value of the end | ||
// Again, like res.write, the return value of the end | ||
// function is meaningful so don't move this elsewhere | ||
@@ -101,15 +97,14 @@ return _end.call(this, chunk, encoding); | ||
// is cacheable when the headers are sent. | ||
on_headers(res, function onResponseHeaders () { | ||
on_headers(res, function onResponseHeaders() { | ||
// Don't cache requests with sessions. This prevents | ||
// sensitive data from appearing in the site's cache. | ||
if (req.session && req.session.uid) { | ||
debug('has session'); | ||
debug("has session"); | ||
return; | ||
} | ||
} | ||
// Check if the response has the no-cache header set | ||
// Don't cache the response if so! | ||
if (no_cache(req, res)) { | ||
debug('no cache'); | ||
debug("no cache"); | ||
return; | ||
@@ -120,6 +115,6 @@ } | ||
// POST or HEAD requests, ever. | ||
if (req.method !== 'GET') { | ||
debug('Non-GET request'); | ||
if (req.method !== "GET") { | ||
debug("Non-GET request"); | ||
return; | ||
} | ||
} | ||
@@ -130,3 +125,3 @@ // Don't cache 404 pages or other error pages | ||
if (res.statusCode !== 200) { | ||
debug('BAD status ' + req.originalUrl + ' ' + res.statusCode); | ||
debug("BAD status " + req.originalUrl + " " + res.statusCode); | ||
return; | ||
@@ -137,3 +132,3 @@ } | ||
// when we save the file to disk, the query string ought to be included. | ||
// However, when we do this, NGINX can't determine the correct mimetype | ||
// However, when we do this, NGINX can't determine the correct mimetype | ||
// for a file like /cache/example.com/style.css?foo=123 because its file | ||
@@ -144,4 +139,4 @@ // extension is 'css?foo=123' I should look into whether it is possible | ||
if (Object.keys(req.query).length && req.query.extension === undefined) { | ||
debug('Has query string'); | ||
return; | ||
debug("Has query string"); | ||
return; | ||
} | ||
@@ -160,7 +155,7 @@ | ||
// I suspect this catches an error which results when you flush the | ||
// cache for a given site, whilst caching the response to a request to | ||
// I suspect this catches an error which results when you flush the | ||
// cache for a given site, whilst caching the response to a request to | ||
// a page on the site. Allow a sudden, the file to which the stream | ||
// points will no longer exist. There are probably other errors here too. | ||
stream.on('error', function(err){ | ||
stream.on("error", function(err) { | ||
debug(err); | ||
@@ -172,15 +167,21 @@ stream.close(); | ||
// all the data has been written to the response. | ||
// Now we can move the temporary file to its final location. | ||
stream.on('finish', function onStreamEnd () { | ||
debug('stream has finished'); | ||
// Now we can move the temporary file to its final location. | ||
stream.on("finish", function onStreamEnd() { | ||
debug("stream has finished"); | ||
stream.close(); | ||
content_type = res.getHeader(CONTENT_TYPE); | ||
cache_control = res.getHeader(CACHE_CONTROL); | ||
has_max_age = cache_control && cache_control.indexOf('max-age') > -1; | ||
cache_age = has_max_age ? 'permanent' : 'temporary'; | ||
protocol = req.headers['x-forwarded-proto'] || req.protocol; | ||
has_max_age = cache_control && cache_control.indexOf("max-age") > -1; | ||
cache_age = has_max_age ? "permanent" : "temporary"; | ||
protocol = req.protocol; | ||
// Trust header added by proxy indicating that before the proxy | ||
// the request was over HTTPS. This could be spoofed, but the worst | ||
// that can happen is a cache miss. I don't want to open myself up | ||
// to some dumb vulnerability by blindly copying the value of a header... | ||
if (protocol === "http" && req.headers["x-forwarded-proto"] === "https") | ||
protocol = "https"; | ||
// We create a directory structure to make life as simple as | ||
@@ -192,3 +193,3 @@ // possible for try_files in NGINX. | ||
cache_directory, | ||
req.hostname, // hostname allows the static file server to | ||
req.hostname, // hostname allows the static file server to | ||
protocol, // protocol to allow us to preserve HTTP -> HTTPS redirects | ||
@@ -201,4 +202,4 @@ cache_age, // cache_age, either permanent or temporary | ||
// file for this request. Maps requests to /about to /about/index.html | ||
if (needs_index(content_type, req.path)) { | ||
final_path = join(final_path, 'index.html'); | ||
if (needs_index(content_type, req.path)) { | ||
final_path = join(final_path, "index.html"); | ||
} | ||
@@ -208,16 +209,14 @@ | ||
// containing the full, successfully-sent response to this request. | ||
fs.move(tmp_path, final_path, {overwrite: true}, function(err){ | ||
fs.move(tmp_path, final_path, { overwrite: true }, function(err) { | ||
if (!err) return; // We moved the file successfully | ||
if (!err) return; // We moved the file successfully | ||
// We encountered some file system error moving the temp | ||
// file to its final location in the cache directory. | ||
// file to its final location in the cache directory. | ||
// Remove the temporary output and go on with our lives. | ||
debug(err); | ||
fs.remove(tmp_path, function(err){ | ||
fs.remove(tmp_path, function(err) { | ||
// Nothing else we can really do here | ||
if (err) debug(err); | ||
}); | ||
}); | ||
}); | ||
}); | ||
@@ -230,6 +229,5 @@ }); | ||
// Don't compress for Cache-Control: no-cache | ||
function no_cache (req, res) { | ||
function no_cache(req, res) { | ||
var cache_control = res.getHeader("Cache-Control"); | ||
var cache_control = res.getHeader('Cache-Control'); | ||
// There is no cache control header set, so we default | ||
@@ -242,4 +240,8 @@ // to allowing it. | ||
function needs_index (content_type, path) { | ||
return content_type && content_type.indexOf('text/html') > -1 && path.indexOf('.') === -1; | ||
function needs_index(content_type, path) { | ||
return ( | ||
content_type && | ||
content_type.indexOf("text/html") > -1 && | ||
path.indexOf(".") === -1 | ||
); | ||
} |
{ | ||
"name": "express-disk-cache", | ||
"version": "1.0.3", | ||
"version": "1.0.4", | ||
"main": "index.js", | ||
@@ -5,0 +5,0 @@ "license": "CC0", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
21579
225