diff --git a/lib/connect-cachify.js b/lib/connect-cachify.js
index fb366cb..a40e98d 100644
--- a/lib/connect-cachify.js
+++ b/lib/connect-cachify.js
@@ -64,7 +64,7 @@ exports.setup = function (assets, options) {
}
if (m && m.index === 0) {
// 10 first characters of md5 + 1 for slash
- true_path = req.url.slice(prefix.length + 11);
+ true_path = req.url.slice(prefix.length + 11);
exists = false;
if (opts.prefix !== '' &&
@@ -120,20 +120,27 @@ exports.setup = function (assets, options) {
* foo.js -> a998d8e98f/foo.js
* http://example.com/foo.js -> http://example.com/foo.js
*/
-var hashify = function (filename, hash) {
- if (typeof filename !== 'string')
- throw "cachify ERROR, expected string for filename, got " + filename;
- if (filename.indexOf('://') !== -1) {
- return filename;
+var hashify = function (resource, hash) {
+ if (typeof resource !== 'string')
+ throw "cachify ERROR, expected string for resource, got " + resource;
+ if (resource.indexOf('://') !== -1) {
+ return resource;
}
+
if (! hash && opts.global_hash) {
hash = opts.global_hash;
}
if (opts.production !== true &&
opts.debug === false) {
- return filename;
+ return resource;
}
+
+ // fragment identifiers on URLs are never sent to the server and they
+ // should not exist on the filename. When looking up the resource on
+ // disk, do so without the fragment identifier.
+ var filename = resource.replace(/#.*$/, '');
+
if (hash) {
// No-op, specifing a hash skips all this craziness
} else if (_cache[filename] && _cache[filename].hash) {
@@ -144,22 +151,24 @@ var hashify = function (filename, hash) {
var md5 = crypto.createHash('md5');
try {
var data = fs.readFileSync(path.join(opts.root, filename));
+
md5.update(data);
// Expensive, maintain in-memory cache
if (! _cache[filename]) _cache[filename] = {exists: true};
hash = _cache[filename].hash = md5.digest('hex').slice(0, 10);
} catch (e) {
// Not intersting to cache, programmer error?
+ exports.uncached_resources.push(resource);
console.error('Cachify bailing on hash... no such file ' + filename );
console.error(e);
- return filename;
+ return resource;
}
}
if (opts.prefix.indexOf('://') === -1 &&
- filename[0] === '/') {
- return format('/%s%s%s', opts.prefix, hash, filename);
+ resource[0] === '/') {
+ return format('/%s%s%s', opts.prefix, hash, resource);
} else {
- return format('%s%s%s%s', opts.prefix, hash, filename[0] === '/' ? '' : '/', filename);
+ return format('%s%s%s%s', opts.prefix, hash, resource[0] === '/' ? '' : '/', resource);
}
};
@@ -207,3 +216,5 @@ var no_url = function (prefix) {
var escape_regex = function (str) {
return str.replace('/', '\/');
};
+
+exports.uncached_resources = [];
diff --git a/test/connect-cachify-test.js b/test/connect-cachify-test.js
index 4f3e414..b237fcc 100644
--- a/test/connect-cachify-test.js
+++ b/test/connect-cachify-test.js
@@ -15,8 +15,10 @@ var resetConfig = function () {
var make_assets = function () { return {
"/js/main.min.js": [
- "/js/lib/jquery.js", "/js/lib/jquery-foomatic.js",
- "/js/main.js"
+ "/js/lib/jquery.js",
+ "/js/lib/jquery-foomatic.js",
+ "/js/main.js",
+ "/js/font-loader.js#with_fragment_id"
]}; };
exports.setup = nodeunit.testCase({
@@ -39,6 +41,9 @@ exports.setup = nodeunit.testCase({
function (err) {
fs.writeFile('/tmp/js/main.js', "", "utf8", this);
},
+ function (err) {
+ fs.writeFile('/tmp/js/font-loader.js', "", "utf8", this);
+ },
function (err) {
cb();
}
@@ -48,13 +53,16 @@ exports.setup = nodeunit.testCase({
step(
fs.unlink('/tmp/js/main.js', this),
function (err) {
- fs.unlink('/tmp/js/lib/jquery-foomatic.js', this);
+ fs.unlink('/tmp/js/main.min.js', this);
},
function (err) {
fs.unlink('/tmp/js/lib/jquery.js', this);
},
function (err) {
- fs.unlink('/tmp/js/main.min.js', this);
+ fs.unlink('/tmp/js/lib/jquery-foomatic.js', this);
+ },
+ function (err) {
+ fs.unlink('/tmp/js/font-loader.js', this);
},
function (err) {
fs.rmdir('/tmp/js/lib', this);
@@ -76,10 +84,12 @@ exports.setup = nodeunit.testCase({
files,
links,
mddlwr;
+
mddlwr = cachify.setup(assets, {
root: '/tmp',
production: false,
debug: true});
+
links = cachify.cachify_js("/js/main.min.js").split('\n');
test.equal(links[0], '',
"debug option puts hash in all urls");
@@ -112,11 +122,17 @@ exports.setup = nodeunit.testCase({
production: false
});
var links = cachify.cachify_js("/js/main.min.js").split('\n');
- test.ok(links.length, "Multiple script tags");
+ test.equal(links.length, assets["/js/main.min.js"].length,
+ "All script tags created");
test.equal(links[0], '',
"No hashes in all urls during development");
+ test.equal(links[3], '',
+ "Fragment identifier in URL is preserved");
+ test.equal(cachify.uncached_resources.indexOf("/js/font-loader.js#with_fragment_id"), -1,
+ "Fragment identifiers are never sent to server, search on disk for resource by removing fragment id");
var files = cachify.cachify("/js/main.min.js").split('\n');
- test.ok(files.length, "Multiple script tags");
+ test.equal(files.length, assets["/js/main.min.js"].length,
+ "All urls created");
test.equal(files[0], '/js/lib/jquery.js',
"No hashes in all urls during development");
mddlwr(req, resp, function () {
@@ -240,4 +256,4 @@ exports.setup = nodeunit.testCase({
test.done();
});
}
-});
\ No newline at end of file
+});