diff -Nru node-fresh-0.2.0/benchmark/etag.js node-fresh-0.5.2/benchmark/etag.js --- node-fresh-0.2.0/benchmark/etag.js 1970-01-01 00:00:00.000000000 +0000 +++ node-fresh-0.5.2/benchmark/etag.js 2017-09-14 04:41:33.000000000 +0000 @@ -0,0 +1,47 @@ + +/** + * Module dependencies. + */ + +var benchmark = require('benchmark') +var benchmarks = require('beautify-benchmark') + +/** + * Globals for benchmark.js + */ + +global.fresh = require('..') + +var suite = new benchmark.Suite() + +suite.add({ + name: 'star', + minSamples: 100, + fn: 'var val = fresh({ \'if-none-match\': \'*\' }, { etag: \'"foo"\' })' +}) + +suite.add({ + name: 'single etag', + minSamples: 100, + fn: 'var val = fresh({ \'if-none-match\': \'"foo"\' }, { etag: \'"foo"\' })' +}) + +suite.add({ + name: 'several etags', + minSamples: 100, + fn: 'var val = fresh({ \'if-none-match\': \'"foo", "bar", "fizz", "buzz"\' }, { etag: \'"buzz"\' })' +}) + +suite.on('start', function onCycle (event) { + process.stdout.write(' etag\n\n') +}) + +suite.on('cycle', function onCycle (event) { + benchmarks.add(event.target) +}) + +suite.on('complete', function onComplete () { + benchmarks.log() +}) + +suite.run({async: false}) diff -Nru node-fresh-0.2.0/benchmark/index.js node-fresh-0.5.2/benchmark/index.js --- node-fresh-0.2.0/benchmark/index.js 1970-01-01 00:00:00.000000000 +0000 +++ node-fresh-0.5.2/benchmark/index.js 2017-09-14 04:41:33.000000000 +0000 @@ -0,0 +1,34 @@ +var fs = require('fs') +var path = require('path') +var spawn = require('child_process').spawn + +var exe = process.argv[0] +var cwd = process.cwd() + +for (var dep in process.versions) { + console.log(' %s@%s', dep, process.versions[dep]) +} + +console.log('') + +runScripts(fs.readdirSync(__dirname)) + +function runScripts (fileNames) { + var fileName = fileNames.shift() + + if (!fileName) return + if (!/\.js$/i.test(fileName)) return runScripts(fileNames) + if (fileName.toLowerCase() === 'index.js') return runScripts(fileNames) + + var fullPath = path.join(__dirname, fileName) + + console.log('> %s %s', exe, path.relative(cwd, fullPath)) + + var proc = spawn(exe, [fullPath], { + 'stdio': 'inherit' + }) + + proc.on('exit', function () { + runScripts(fileNames) + }) +} diff -Nru node-fresh-0.2.0/benchmark/modified.js node-fresh-0.5.2/benchmark/modified.js --- node-fresh-0.2.0/benchmark/modified.js 1970-01-01 00:00:00.000000000 +0000 +++ node-fresh-0.5.2/benchmark/modified.js 2017-09-14 04:41:33.000000000 +0000 @@ -0,0 +1,41 @@ + +/** + * Module dependencies. + */ + +var benchmark = require('benchmark') +var benchmarks = require('beautify-benchmark') + +/** + * Globals for benchmark.js + */ + +global.fresh = require('..') + +var suite = new benchmark.Suite() + +suite.add({ + name: 'not modified', + minSamples: 100, + fn: 'var val = fresh({ \'if-modified-since\': \'Fri, 01 Jan 2010 00:00:00 GMT\' }, { \'last-modified\': \'Sat, 01 Jan 2000 00:00:00 GMT\' })' +}) + +suite.add({ + name: 'modified', + minSamples: 100, + fn: 'var val = fresh({ \'if-modified-since\': \'Mon, 01 Jan 1990 00:00:00 GMT\' }, { \'last-modified\': \'Sat, 01 Jan 2000 00:00:00 GMT\' })' +}) + +suite.on('start', function onCycle (event) { + process.stdout.write(' modified\n\n') +}) + +suite.on('cycle', function onCycle (event) { + benchmarks.add(event.target) +}) + +suite.on('complete', function onComplete () { + benchmarks.log() +}) + +suite.run({async: false}) diff -Nru node-fresh-0.2.0/debian/changelog node-fresh-0.5.2/debian/changelog --- node-fresh-0.2.0/debian/changelog 2019-08-03 13:43:04.000000000 +0000 +++ node-fresh-0.5.2/debian/changelog 2019-12-04 19:33:06.000000000 +0000 @@ -1,3 +1,16 @@ +node-fresh (0.5.2-1) unstable; urgency=medium + + * Team upload + * Declare compliance with policy 4.4.1 + * Add "Rules-Requires-Root: no" + * New upstream version 0.5.2 + * Remove patches + * Update test + * Update debian/docs + * Install history + + -- Xavier Guimard Wed, 04 Dec 2019 20:33:06 +0100 + node-fresh (0.2.0-3) unstable; urgency=medium * Team upload diff -Nru node-fresh-0.2.0/debian/control node-fresh-0.5.2/debian/control --- node-fresh-0.2.0/debian/control 2019-08-01 06:01:00.000000000 +0000 +++ node-fresh-0.5.2/debian/control 2019-12-04 19:22:35.000000000 +0000 @@ -10,10 +10,11 @@ , mocha , nodejs , pkg-js-tools (>= 0.8.7) -Standards-Version: 4.4.0 +Standards-Version: 4.4.1 Vcs-Browser: https://salsa.debian.org/js-team/node-fresh Vcs-Git: https://salsa.debian.org/js-team/node-fresh.git Homepage: https://github.com/visionmedia/node-fresh +Rules-Requires-Root: no Package: node-fresh Architecture: all diff -Nru node-fresh-0.2.0/debian/docs node-fresh-0.5.2/debian/docs --- node-fresh-0.2.0/debian/docs 2019-07-30 11:34:11.000000000 +0000 +++ node-fresh-0.5.2/debian/docs 2019-12-04 19:27:58.000000000 +0000 @@ -1 +1 @@ -Readme.md +README.md diff -Nru node-fresh-0.2.0/debian/patches/CVE-2017-16119.diff node-fresh-0.5.2/debian/patches/CVE-2017-16119.diff --- node-fresh-0.2.0/debian/patches/CVE-2017-16119.diff 2019-07-30 11:34:11.000000000 +0000 +++ node-fresh-0.5.2/debian/patches/CVE-2017-16119.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,85 +0,0 @@ -Description: Fix for CVE-2017-16119 -Author: Xavier Guimard -Origin: upstream, https://github.com/jshttp/fresh/commit/21a0f0c2a5f447e0d40bc16be0c23fa98a7b46ec -Bug: https://www.npmjs.com/advisories/526 -Bug-Debian: https://bugs.debian.org/927715 -Forwarded: not-needed -Last-Update: 2019-04-25 - ---- a/index.js -+++ b/index.js -@@ -36,11 +36,27 @@ - // check for no-cache cache request directive - if (cc && cc.indexOf('no-cache') !== -1) return false; - -- // parse if-none-match -- if (noneMatch) noneMatch = noneMatch.split(/ *, */); -+ // parse if-none-match and etag -+ if (noneMatch && noneMatch !== '*') { - -- // if-none-match -- if (noneMatch) etagMatches = ~noneMatch.indexOf(etag) || '*' == noneMatch[0]; -+ if (!etag) { -+ return false -+ } -+ -+ var etagStale = true -+ var matches = parseTokenList(noneMatch) -+ for (var i = 0; i < matches.length; i++) { -+ var match = matches[i] -+ if (match === etag || match === 'W/' + etag || 'W/' + match === etag) { -+ etagStale = false -+ break -+ } -+ } -+ -+ if (etagStale) { -+ return false -+ } -+ } - - // if-modified-since - if (modifiedSince) { -@@ -50,4 +66,40 @@ - } - - return !! (etagMatches && notModified); --} -\ No newline at end of file -+} -+ -+/** -+ * Parse a HTTP token list. -+ * -+ * @param {string} str -+ * @private -+ */ -+ -+function parseTokenList (str) { -+ var end = 0 -+ var list = [] -+ var start = 0 -+ -+ // gather tokens -+ for (var i = 0, len = str.length; i < len; i++) { -+ switch (str.charCodeAt(i)) { -+ case 0x20: /* */ -+ if (start === end) { -+ start = end = i + 1 -+ } -+ break -+ case 0x2c: /* , */ -+ list.push(str.substring(start, end)) -+ start = end = i + 1 -+ break -+ default: -+ end = i + 1 -+ break -+ } -+ } -+ -+ // final token -+ list.push(str.substring(start, end)) -+ -+ return list -+} diff -Nru node-fresh-0.2.0/debian/patches/fix-tests.diff node-fresh-0.5.2/debian/patches/fix-tests.diff --- node-fresh-0.2.0/debian/patches/fix-tests.diff 2019-07-30 11:34:11.000000000 +0000 +++ node-fresh-0.5.2/debian/patches/fix-tests.diff 1970-01-01 00:00:00.000000000 +0000 @@ -1,147 +0,0 @@ -Description: Fix tests -Author: Xavier Guimard -Forwarded: not-needed -Last-Update: 2019-04-25 - ---- a/test/fresh.js -+++ b/test/fresh.js -@@ -1,12 +1,13 @@ - - var fresh = require('..'); -+var assert = require('assert'); - - describe('fresh(reqHeader, resHeader)', function(){ - describe('when a non-conditional GET is performed', function(){ - it('should be stale', function(){ - var req = {}; - var res = {}; -- fresh(req, res).should.be.false; -+ assert.equal(fresh(req, res),false); - }) - }) - -@@ -15,7 +16,7 @@ - it('should be fresh', function(){ - var req = { 'if-none-match': 'tobi' }; - var res = { 'etag': 'tobi' }; -- fresh(req, res).should.be.true; -+ assert.equal(fresh(req, res),true); - }) - }) - -@@ -23,7 +24,7 @@ - it('should be stale', function(){ - var req = { 'if-none-match': 'tobi' }; - var res = { 'etag': 'luna' }; -- fresh(req, res).should.be.false; -+ assert.equal(fresh(req, res),false); - }) - }) - -@@ -31,7 +32,7 @@ - it('should be stale', function(){ - var req = { 'if-none-match': 'tobi' }; - var res = {}; -- fresh(req, res).should.be.false; -+ assert.equal(fresh(req, res),false); - }) - }) - -@@ -39,7 +40,7 @@ - it('should be fresh', function(){ - var req = { 'if-none-match': '*' }; - var res = { 'etag': 'hey' }; -- fresh(req, res).should.be.true; -+ assert.equal(fresh(req, res),true); - }) - }) - }) -@@ -50,7 +51,7 @@ - var now = new Date; - var req = { 'if-modified-since': new Date(now - 4000).toUTCString() }; - var res = { 'last-modified': new Date(now - 2000).toUTCString() }; -- fresh(req, res).should.be.false; -+ assert.equal(fresh(req, res),false); - }) - }) - -@@ -59,7 +60,7 @@ - var now = new Date; - var req = { 'if-modified-since': new Date(now - 2000).toUTCString() }; - var res = { 'last-modified': new Date(now - 4000).toUTCString() }; -- fresh(req, res).should.be.true; -+ assert.equal(fresh(req, res),true); - }) - }) - -@@ -67,7 +68,7 @@ - it('should be stale', function(){ - var req = { 'if-none-match': new Date().toUTCString() }; - var res = {}; -- fresh(req, res).should.be.false; -+ assert.equal(fresh(req, res),false); - }) - }) - -@@ -75,7 +76,7 @@ - it('should be stale', function(){ - var req = { 'if-none-match': 'foo' }; - var res = {}; -- fresh(req, res).should.be.false; -+ assert.equal(fresh(req, res),false); - }) - }) - -@@ -83,7 +84,7 @@ - it('should be stale', function(){ - var req = { 'if-none-match': new Date().toUTCString() }; - var res = { 'modified-since': 'foo' }; -- fresh(req, res).should.be.false; -+ assert.equal(fresh(req, res),false); - }) - }) - }) -@@ -94,7 +95,7 @@ - var now = new Date; - var req = { 'if-none-match': 'tobi', 'if-modified-since': new Date(now - 2000).toUTCString() }; - var res = { 'etag': 'tobi', 'last-modified': new Date(now - 4000).toUTCString() }; -- fresh(req, res).should.be.true; -+ assert.equal(fresh(req, res),true); - }) - }) - -@@ -103,12 +104,12 @@ - var now = new Date; - var req = { 'if-none-match': 'tobi', 'if-modified-since': new Date(now - 4000).toUTCString() }; - var res = { 'etag': 'tobi', 'last-modified': new Date(now - 2000).toUTCString() }; -- fresh(req, res).should.be.false; -+ assert.equal(fresh(req, res),false); - - var now = new Date; - var req = { 'if-none-match': 'tobi', 'if-modified-since': new Date(now - 2000).toUTCString() }; - var res = { 'etag': 'luna', 'last-modified': new Date(now - 4000).toUTCString() }; -- fresh(req, res).should.be.false; -+ assert.equal(fresh(req, res),false); - }) - }) - -@@ -117,7 +118,7 @@ - var now = new Date; - var req = { 'if-none-match': 'tobi', 'if-modified-since': new Date(now - 4000).toUTCString() }; - var res = { 'etag': 'luna', 'last-modified': new Date(now - 2000).toUTCString() }; -- fresh(req, res).should.be.false; -+ assert.equal(fresh(req, res),false); - }) - }) - }) -@@ -126,7 +127,7 @@ - it('should be stale', function(){ - var req = { 'cache-control' : ' no-cache' }; - var res = {}; -- fresh(req, res).should.be.false; -+ assert.equal(fresh(req, res),false); - }) - }) --}) -\ No newline at end of file -+}) diff -Nru node-fresh-0.2.0/debian/patches/series node-fresh-0.5.2/debian/patches/series --- node-fresh-0.2.0/debian/patches/series 2019-07-30 11:34:11.000000000 +0000 +++ node-fresh-0.5.2/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -CVE-2017-16119.diff -fix-tests.diff diff -Nru node-fresh-0.2.0/debian/rules node-fresh-0.5.2/debian/rules --- node-fresh-0.2.0/debian/rules 2019-07-30 11:34:11.000000000 +0000 +++ node-fresh-0.5.2/debian/rules 2019-12-04 19:33:06.000000000 +0000 @@ -7,4 +7,5 @@ %: dh $@ --with nodejs -override_dh_auto_build: +override_dh_installchangelogs: + dh_installchangelogs -k HISTORY.md diff -Nru node-fresh-0.2.0/debian/tests/pkg-js/test node-fresh-0.5.2/debian/tests/pkg-js/test --- node-fresh-0.2.0/debian/tests/pkg-js/test 2019-07-30 11:34:11.000000000 +0000 +++ node-fresh-0.5.2/debian/tests/pkg-js/test 2019-12-04 19:25:47.000000000 +0000 @@ -1 +1 @@ -mocha --timeout 10000 test +mocha --timeout 10000 --bail --check-leaks test diff -Nru node-fresh-0.2.0/.eslintignore node-fresh-0.5.2/.eslintignore --- node-fresh-0.2.0/.eslintignore 1970-01-01 00:00:00.000000000 +0000 +++ node-fresh-0.5.2/.eslintignore 2017-09-14 04:41:33.000000000 +0000 @@ -0,0 +1,2 @@ +coverage +node_modules diff -Nru node-fresh-0.2.0/.eslintrc node-fresh-0.5.2/.eslintrc --- node-fresh-0.2.0/.eslintrc 1970-01-01 00:00:00.000000000 +0000 +++ node-fresh-0.5.2/.eslintrc 2017-09-14 04:41:33.000000000 +0000 @@ -0,0 +1,3 @@ +{ + "extends": "standard" +} diff -Nru node-fresh-0.2.0/.gitignore node-fresh-0.5.2/.gitignore --- node-fresh-0.2.0/.gitignore 2013-08-10 21:44:32.000000000 +0000 +++ node-fresh-0.5.2/.gitignore 2017-09-14 04:41:33.000000000 +0000 @@ -1 +1,3 @@ node_modules +coverage +package-lock.json diff -Nru node-fresh-0.2.0/HISTORY.md node-fresh-0.5.2/HISTORY.md --- node-fresh-0.2.0/HISTORY.md 1970-01-01 00:00:00.000000000 +0000 +++ node-fresh-0.5.2/HISTORY.md 2017-09-14 04:41:33.000000000 +0000 @@ -0,0 +1,70 @@ +0.5.2 / 2017-09-13 +================== + + * Fix regression matching multiple ETags in `If-None-Match` + * perf: improve `If-None-Match` token parsing + +0.5.1 / 2017-09-11 +================== + + * Fix handling of modified headers with invalid dates + * perf: improve ETag match loop + +0.5.0 / 2017-02-21 +================== + + * Fix incorrect result when `If-None-Match` has both `*` and ETags + * Fix weak `ETag` matching to match spec + * perf: delay reading header values until needed + * perf: skip checking modified time if ETag check failed + * perf: skip parsing `If-None-Match` when no `ETag` header + * perf: use `Date.parse` instead of `new Date` + +0.4.0 / 2017-02-05 +================== + + * Fix false detection of `no-cache` request directive + * perf: enable strict mode + * perf: hoist regular expressions + * perf: remove duplicate conditional + * perf: remove unnecessary boolean coercions + +0.3.0 / 2015-05-12 +================== + + * Add weak `ETag` matching support + +0.2.4 / 2014-09-07 +================== + + * Support Node.js 0.6 + +0.2.3 / 2014-09-07 +================== + + * Move repository to jshttp + +0.2.2 / 2014-02-19 +================== + + * Revert "Fix for blank page on Safari reload" + +0.2.1 / 2014-01-29 +================== + + * Fix for blank page on Safari reload + +0.2.0 / 2013-08-11 +================== + + * Return stale for `Cache-Control: no-cache` + +0.1.0 / 2012-06-15 +================== + + * Add `If-None-Match: *` support + +0.0.1 / 2012-06-10 +================== + + * Initial release diff -Nru node-fresh-0.2.0/index.js node-fresh-0.5.2/index.js --- node-fresh-0.2.0/index.js 2013-08-10 21:44:32.000000000 +0000 +++ node-fresh-0.5.2/index.js 2017-09-14 04:41:33.000000000 +0000 @@ -1,53 +1,137 @@ +/*! + * fresh + * Copyright(c) 2012 TJ Holowaychuk + * Copyright(c) 2016-2017 Douglas Christopher Wilson + * MIT Licensed + */ + +'use strict' /** - * Expose `fresh()`. + * RegExp to check for no-cache token in Cache-Control. + * @private */ -module.exports = fresh; +var CACHE_CONTROL_NO_CACHE_REGEXP = /(?:^|,)\s*?no-cache\s*?(?:,|$)/ /** - * Check freshness of `req` and `res` headers. - * - * When the cache is "fresh" __true__ is returned, - * otherwise __false__ is returned to indicate that - * the cache is now stale. + * Module exports. + * @public + */ + +module.exports = fresh + +/** + * Check freshness of the response using request and response headers. * - * @param {Object} req - * @param {Object} res + * @param {Object} reqHeaders + * @param {Object} resHeaders * @return {Boolean} - * @api public + * @public */ -function fresh(req, res) { - // defaults - var etagMatches = true; - var notModified = true; - +function fresh (reqHeaders, resHeaders) { // fields - var modifiedSince = req['if-modified-since']; - var noneMatch = req['if-none-match']; - var lastModified = res['last-modified']; - var etag = res['etag']; - var cc = req['cache-control']; + var modifiedSince = reqHeaders['if-modified-since'] + var noneMatch = reqHeaders['if-none-match'] // unconditional request - if (!modifiedSince && !noneMatch) return false; - - // check for no-cache cache request directive - if (cc && cc.indexOf('no-cache') !== -1) return false; + if (!modifiedSince && !noneMatch) { + return false + } - // parse if-none-match - if (noneMatch) noneMatch = noneMatch.split(/ *, */); + // Always return stale when Cache-Control: no-cache + // to support end-to-end reload requests + // https://tools.ietf.org/html/rfc2616#section-14.9.4 + var cacheControl = reqHeaders['cache-control'] + if (cacheControl && CACHE_CONTROL_NO_CACHE_REGEXP.test(cacheControl)) { + return false + } // if-none-match - if (noneMatch) etagMatches = ~noneMatch.indexOf(etag) || '*' == noneMatch[0]; + if (noneMatch && noneMatch !== '*') { + var etag = resHeaders['etag'] + + if (!etag) { + return false + } + + var etagStale = true + var matches = parseTokenList(noneMatch) + for (var i = 0; i < matches.length; i++) { + var match = matches[i] + if (match === etag || match === 'W/' + etag || 'W/' + match === etag) { + etagStale = false + break + } + } + + if (etagStale) { + return false + } + } // if-modified-since if (modifiedSince) { - modifiedSince = new Date(modifiedSince); - lastModified = new Date(lastModified); - notModified = lastModified <= modifiedSince; + var lastModified = resHeaders['last-modified'] + var modifiedStale = !lastModified || !(parseHttpDate(lastModified) <= parseHttpDate(modifiedSince)) + + if (modifiedStale) { + return false + } } - return !! (etagMatches && notModified); -} \ No newline at end of file + return true +} + +/** + * Parse an HTTP Date into a number. + * + * @param {string} date + * @private + */ + +function parseHttpDate (date) { + var timestamp = date && Date.parse(date) + + // istanbul ignore next: guard against date.js Date.parse patching + return typeof timestamp === 'number' + ? timestamp + : NaN +} + +/** + * Parse a HTTP token list. + * + * @param {string} str + * @private + */ + +function parseTokenList (str) { + var end = 0 + var list = [] + var start = 0 + + // gather tokens + for (var i = 0, len = str.length; i < len; i++) { + switch (str.charCodeAt(i)) { + case 0x20: /* */ + if (start === end) { + start = end = i + 1 + } + break + case 0x2c: /* , */ + list.push(str.substring(start, end)) + start = end = i + 1 + break + default: + end = i + 1 + break + } + } + + // final token + list.push(str.substring(start, end)) + + return list +} diff -Nru node-fresh-0.2.0/LICENSE node-fresh-0.5.2/LICENSE --- node-fresh-0.2.0/LICENSE 1970-01-01 00:00:00.000000000 +0000 +++ node-fresh-0.5.2/LICENSE 2017-09-14 04:41:33.000000000 +0000 @@ -0,0 +1,23 @@ +(The MIT License) + +Copyright (c) 2012 TJ Holowaychuk +Copyright (c) 2016-2017 Douglas Christopher Wilson + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff -Nru node-fresh-0.2.0/Makefile node-fresh-0.5.2/Makefile --- node-fresh-0.2.0/Makefile 2013-08-10 21:44:32.000000000 +0000 +++ node-fresh-0.5.2/Makefile 1970-01-01 00:00:00.000000000 +0000 @@ -1,7 +0,0 @@ - -test: - @./node_modules/.bin/mocha \ - --reporter spec \ - --require should - -.PHONY: test \ No newline at end of file diff -Nru node-fresh-0.2.0/.npmignore node-fresh-0.5.2/.npmignore --- node-fresh-0.2.0/.npmignore 2013-08-10 21:44:32.000000000 +0000 +++ node-fresh-0.5.2/.npmignore 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -test diff -Nru node-fresh-0.2.0/package.json node-fresh-0.5.2/package.json --- node-fresh-0.2.0/package.json 2013-08-10 21:44:32.000000000 +0000 +++ node-fresh-0.5.2/package.json 2017-09-14 04:41:33.000000000 +0000 @@ -1,14 +1,46 @@ { "name": "fresh", - "author": "TJ Holowaychuk (http://tjholowaychuk.com)", "description": "HTTP response freshness testing", - "version": "0.2.0", - "main": "index.js", - "repository": { "type": "git", "url": "https://github.com/visionmedia/node-fresh.git"}, - "dependencies": {}, - "repository": { "type": "git", "url": "https://github.com/visionmedia/node-fresh.git" }, + "version": "0.5.2", + "author": "TJ Holowaychuk (http://tjholowaychuk.com)", + "contributors": [ + "Douglas Christopher Wilson ", + "Jonathan Ong (http://jongleberry.com)" + ], + "license": "MIT", + "keywords": [ + "fresh", + "http", + "conditional", + "cache" + ], + "repository": "jshttp/fresh", "devDependencies": { - "mocha": "*", - "should": "*" + "beautify-benchmark": "0.2.4", + "benchmark": "2.1.4", + "eslint": "3.19.0", + "eslint-config-standard": "10.2.1", + "eslint-plugin-import": "2.7.0", + "eslint-plugin-markdown": "1.0.0-beta.6", + "eslint-plugin-node": "5.1.1", + "eslint-plugin-promise": "3.5.0", + "eslint-plugin-standard": "3.0.1", + "istanbul": "0.4.5", + "mocha": "1.21.5" + }, + "files": [ + "HISTORY.md", + "LICENSE", + "index.js" + ], + "engines": { + "node": ">= 0.6" + }, + "scripts": { + "bench": "node benchmark/index.js", + "lint": "eslint --plugin markdown --ext js,md .", + "test": "mocha --reporter spec --bail --check-leaks test/", + "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/", + "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter spec --check-leaks test/" } } diff -Nru node-fresh-0.2.0/Readme.md node-fresh-0.5.2/Readme.md --- node-fresh-0.2.0/Readme.md 2013-08-10 21:44:32.000000000 +0000 +++ node-fresh-0.5.2/Readme.md 1970-01-01 00:00:00.000000000 +0000 @@ -1,57 +0,0 @@ - -# node-fresh - - HTTP response freshness testing - -## fresh(req, res) - - Check freshness of `req` and `res` headers. - - When the cache is "fresh" __true__ is returned, - otherwise __false__ is returned to indicate that - the cache is now stale. - -## Example: - -```js -var req = { 'if-none-match': 'tobi' }; -var res = { 'etag': 'luna' }; -fresh(req, res); -// => false - -var req = { 'if-none-match': 'tobi' }; -var res = { 'etag': 'tobi' }; -fresh(req, res); -// => true -``` - -## Installation - -``` -$ npm install fresh -``` - -## License - -(The MIT License) - -Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca> - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff -Nru node-fresh-0.2.0/README.md node-fresh-0.5.2/README.md --- node-fresh-0.2.0/README.md 1970-01-01 00:00:00.000000000 +0000 +++ node-fresh-0.5.2/README.md 2017-09-14 04:41:33.000000000 +0000 @@ -0,0 +1,119 @@ +# fresh + +[![NPM Version][npm-image]][npm-url] +[![NPM Downloads][downloads-image]][downloads-url] +[![Node.js Version][node-version-image]][node-version-url] +[![Build Status][travis-image]][travis-url] +[![Test Coverage][coveralls-image]][coveralls-url] + +HTTP response freshness testing + +## Installation + +This is a [Node.js](https://nodejs.org/en/) module available through the +[npm registry](https://www.npmjs.com/). Installation is done using the +[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally): + +``` +$ npm install fresh +``` + +## API + + + +```js +var fresh = require('fresh') +``` + +### fresh(reqHeaders, resHeaders) + +Check freshness of the response using request and response headers. + +When the response is still "fresh" in the client's cache `true` is +returned, otherwise `false` is returned to indicate that the client +cache is now stale and the full response should be sent. + +When a client sends the `Cache-Control: no-cache` request header to +indicate an end-to-end reload request, this module will return `false` +to make handling these requests transparent. + +## Known Issues + +This module is designed to only follow the HTTP specifications, not +to work-around all kinda of client bugs (especially since this module +typically does not recieve enough information to understand what the +client actually is). + +There is a known issue that in certain versions of Safari, Safari +will incorrectly make a request that allows this module to validate +freshness of the resource even when Safari does not have a +representation of the resource in the cache. The module +[jumanji](https://www.npmjs.com/package/jumanji) can be used in +an Express application to work-around this issue and also provides +links to further reading on this Safari bug. + +## Example + +### API usage + + + +```js +var reqHeaders = { 'if-none-match': '"foo"' } +var resHeaders = { 'etag': '"bar"' } +fresh(reqHeaders, resHeaders) +// => false + +var reqHeaders = { 'if-none-match': '"foo"' } +var resHeaders = { 'etag': '"foo"' } +fresh(reqHeaders, resHeaders) +// => true +``` + +### Using with Node.js http server + +```js +var fresh = require('fresh') +var http = require('http') + +var server = http.createServer(function (req, res) { + // perform server logic + // ... including adding ETag / Last-Modified response headers + + if (isFresh(req, res)) { + // client has a fresh copy of resource + res.statusCode = 304 + res.end() + return + } + + // send the resource + res.statusCode = 200 + res.end('hello, world!') +}) + +function isFresh (req, res) { + return fresh(req.headers, { + 'etag': res.getHeader('ETag'), + 'last-modified': res.getHeader('Last-Modified') + }) +} + +server.listen(3000) +``` + +## License + +[MIT](LICENSE) + +[npm-image]: https://img.shields.io/npm/v/fresh.svg +[npm-url]: https://npmjs.org/package/fresh +[node-version-image]: https://img.shields.io/node/v/fresh.svg +[node-version-url]: https://nodejs.org/en/ +[travis-image]: https://img.shields.io/travis/jshttp/fresh/master.svg +[travis-url]: https://travis-ci.org/jshttp/fresh +[coveralls-image]: https://img.shields.io/coveralls/jshttp/fresh/master.svg +[coveralls-url]: https://coveralls.io/r/jshttp/fresh?branch=master +[downloads-image]: https://img.shields.io/npm/dm/fresh.svg +[downloads-url]: https://npmjs.org/package/fresh diff -Nru node-fresh-0.2.0/test/.eslintrc node-fresh-0.5.2/test/.eslintrc --- node-fresh-0.2.0/test/.eslintrc 1970-01-01 00:00:00.000000000 +0000 +++ node-fresh-0.5.2/test/.eslintrc 2017-09-14 04:41:33.000000000 +0000 @@ -0,0 +1,5 @@ +{ + "env": { + "mocha": true + } +} diff -Nru node-fresh-0.2.0/test/fresh.js node-fresh-0.5.2/test/fresh.js --- node-fresh-0.2.0/test/fresh.js 2013-08-10 21:44:32.000000000 +0000 +++ node-fresh-0.5.2/test/fresh.js 2017-09-14 04:41:33.000000000 +0000 @@ -1,132 +1,189 @@ -var fresh = require('..'); +var assert = require('assert') +var fresh = require('..') -describe('fresh(reqHeader, resHeader)', function(){ - describe('when a non-conditional GET is performed', function(){ - it('should be stale', function(){ - var req = {}; - var res = {}; - fresh(req, res).should.be.false; +describe('fresh(reqHeaders, resHeaders)', function () { + describe('when a non-conditional GET is performed', function () { + it('should be stale', function () { + var reqHeaders = {} + var resHeaders = {} + assert.ok(!fresh(reqHeaders, resHeaders)) }) }) - describe('when requested with If-None-Match', function(){ - describe('when ETags match', function(){ - it('should be fresh', function(){ - var req = { 'if-none-match': 'tobi' }; - var res = { 'etag': 'tobi' }; - fresh(req, res).should.be.true; + describe('when requested with If-None-Match', function () { + describe('when ETags match', function () { + it('should be fresh', function () { + var reqHeaders = { 'if-none-match': '"foo"' } + var resHeaders = { 'etag': '"foo"' } + assert.ok(fresh(reqHeaders, resHeaders)) }) }) - describe('when ETags mismatch', function(){ - it('should be stale', function(){ - var req = { 'if-none-match': 'tobi' }; - var res = { 'etag': 'luna' }; - fresh(req, res).should.be.false; + describe('when ETags mismatch', function () { + it('should be stale', function () { + var reqHeaders = { 'if-none-match': '"foo"' } + var resHeaders = { 'etag': '"bar"' } + assert.ok(!fresh(reqHeaders, resHeaders)) }) }) - describe('when etag is missing', function(){ - it('should be stale', function(){ - var req = { 'if-none-match': 'tobi' }; - var res = {}; - fresh(req, res).should.be.false; + describe('when at least one matches', function () { + it('should be fresh', function () { + var reqHeaders = { 'if-none-match': ' "bar" , "foo"' } + var resHeaders = { 'etag': '"foo"' } + assert.ok(fresh(reqHeaders, resHeaders)) }) }) - describe('when * is given', function(){ - it('should be fresh', function(){ - var req = { 'if-none-match': '*' }; - var res = { 'etag': 'hey' }; - fresh(req, res).should.be.true; + describe('when etag is missing', function () { + it('should be stale', function () { + var reqHeaders = { 'if-none-match': '"foo"' } + var resHeaders = {} + assert.ok(!fresh(reqHeaders, resHeaders)) + }) + }) + + describe('when ETag is weak', function () { + it('should be fresh on exact match', function () { + var reqHeaders = { 'if-none-match': 'W/"foo"' } + var resHeaders = { 'etag': 'W/"foo"' } + assert.ok(fresh(reqHeaders, resHeaders)) + }) + + it('should be fresh on strong match', function () { + var reqHeaders = { 'if-none-match': 'W/"foo"' } + var resHeaders = { 'etag': '"foo"' } + assert.ok(fresh(reqHeaders, resHeaders)) + }) + }) + + describe('when ETag is strong', function () { + it('should be fresh on exact match', function () { + var reqHeaders = { 'if-none-match': '"foo"' } + var resHeaders = { 'etag': '"foo"' } + assert.ok(fresh(reqHeaders, resHeaders)) + }) + + it('should be fresh on weak match', function () { + var reqHeaders = { 'if-none-match': '"foo"' } + var resHeaders = { 'etag': 'W/"foo"' } + assert.ok(fresh(reqHeaders, resHeaders)) + }) + }) + + describe('when * is given', function () { + it('should be fresh', function () { + var reqHeaders = { 'if-none-match': '*' } + var resHeaders = { 'etag': '"foo"' } + assert.ok(fresh(reqHeaders, resHeaders)) + }) + + it('should get ignored if not only value', function () { + var reqHeaders = { 'if-none-match': '*, "bar"' } + var resHeaders = { 'etag': '"foo"' } + assert.ok(!fresh(reqHeaders, resHeaders)) }) }) }) - describe('when requested with If-Modified-Since', function(){ - describe('when modified since the date', function(){ - it('should be stale', function(){ - var now = new Date; - var req = { 'if-modified-since': new Date(now - 4000).toUTCString() }; - var res = { 'last-modified': new Date(now - 2000).toUTCString() }; - fresh(req, res).should.be.false; + describe('when requested with If-Modified-Since', function () { + describe('when modified since the date', function () { + it('should be stale', function () { + var reqHeaders = { 'if-modified-since': 'Sat, 01 Jan 2000 00:00:00 GMT' } + var resHeaders = { 'last-modified': 'Sat, 01 Jan 2000 01:00:00 GMT' } + assert.ok(!fresh(reqHeaders, resHeaders)) }) }) - describe('when unmodified since the date', function(){ - it('should be fresh', function(){ - var now = new Date; - var req = { 'if-modified-since': new Date(now - 2000).toUTCString() }; - var res = { 'last-modified': new Date(now - 4000).toUTCString() }; - fresh(req, res).should.be.true; + describe('when unmodified since the date', function () { + it('should be fresh', function () { + var reqHeaders = { 'if-modified-since': 'Sat, 01 Jan 2000 01:00:00 GMT' } + var resHeaders = { 'last-modified': 'Sat, 01 Jan 2000 00:00:00 GMT' } + assert.ok(fresh(reqHeaders, resHeaders)) }) }) - describe('when last-modified is missing', function(){ - it('should be stale', function(){ - var req = { 'if-none-match': new Date().toUTCString() }; - var res = {}; - fresh(req, res).should.be.false; + describe('when Last-Modified is missing', function () { + it('should be stale', function () { + var reqHeaders = { 'if-modified-since': 'Sat, 01 Jan 2000 00:00:00 GMT' } + var resHeaders = {} + assert.ok(!fresh(reqHeaders, resHeaders)) }) }) - - describe('with invalid if-modified-since date', function(){ - it('should be stale', function(){ - var req = { 'if-none-match': 'foo' }; - var res = {}; - fresh(req, res).should.be.false; + + describe('with invalid If-Modified-Since date', function () { + it('should be stale', function () { + var reqHeaders = { 'if-modified-since': 'foo' } + var resHeaders = { 'last-modified': 'Sat, 01 Jan 2000 00:00:00 GMT' } + assert.ok(!fresh(reqHeaders, resHeaders)) }) }) - describe('with invalid modified-since date', function(){ - it('should be stale', function(){ - var req = { 'if-none-match': new Date().toUTCString() }; - var res = { 'modified-since': 'foo' }; - fresh(req, res).should.be.false; + describe('with invalid Last-Modified date', function () { + it('should be stale', function () { + var reqHeaders = { 'if-modified-since': 'Sat, 01 Jan 2000 00:00:00 GMT' } + var resHeaders = { 'last-modified': 'foo' } + assert.ok(!fresh(reqHeaders, resHeaders)) }) }) }) - describe('when requested with If-Modified-Since and If-None-Match', function(){ - describe('when both match', function(){ - it('should be fresh', function(){ - var now = new Date; - var req = { 'if-none-match': 'tobi', 'if-modified-since': new Date(now - 2000).toUTCString() }; - var res = { 'etag': 'tobi', 'last-modified': new Date(now - 4000).toUTCString() }; - fresh(req, res).should.be.true; + describe('when requested with If-Modified-Since and If-None-Match', function () { + describe('when both match', function () { + it('should be fresh', function () { + var reqHeaders = { 'if-none-match': '"foo"', 'if-modified-since': 'Sat, 01 Jan 2000 01:00:00 GMT' } + var resHeaders = { 'etag': '"foo"', 'last-modified': 'Sat, 01 Jan 2000 00:00:00 GMT' } + assert.ok(fresh(reqHeaders, resHeaders)) }) }) - describe('when only one matches', function(){ - it('should be stale', function(){ - var now = new Date; - var req = { 'if-none-match': 'tobi', 'if-modified-since': new Date(now - 4000).toUTCString() }; - var res = { 'etag': 'tobi', 'last-modified': new Date(now - 2000).toUTCString() }; - fresh(req, res).should.be.false; - - var now = new Date; - var req = { 'if-none-match': 'tobi', 'if-modified-since': new Date(now - 2000).toUTCString() }; - var res = { 'etag': 'luna', 'last-modified': new Date(now - 4000).toUTCString() }; - fresh(req, res).should.be.false; + describe('when only ETag matches', function () { + it('should be stale', function () { + var reqHeaders = { 'if-none-match': '"foo"', 'if-modified-since': 'Sat, 01 Jan 2000 00:00:00 GMT' } + var resHeaders = { 'etag': '"foo"', 'last-modified': 'Sat, 01 Jan 2000 01:00:00 GMT' } + assert.ok(!fresh(reqHeaders, resHeaders)) }) }) - describe('when none match', function(){ - it('should be stale', function(){ - var now = new Date; - var req = { 'if-none-match': 'tobi', 'if-modified-since': new Date(now - 4000).toUTCString() }; - var res = { 'etag': 'luna', 'last-modified': new Date(now - 2000).toUTCString() }; - fresh(req, res).should.be.false; + describe('when only Last-Modified matches', function () { + it('should be stale', function () { + var reqHeaders = { 'if-none-match': '"foo"', 'if-modified-since': 'Sat, 01 Jan 2000 01:00:00 GMT' } + var resHeaders = { 'etag': '"bar"', 'last-modified': 'Sat, 01 Jan 2000 00:00:00 GMT' } + assert.ok(!fresh(reqHeaders, resHeaders)) + }) + }) + + describe('when none match', function () { + it('should be stale', function () { + var reqHeaders = { 'if-none-match': '"foo"', 'if-modified-since': 'Sat, 01 Jan 2000 00:00:00 GMT' } + var resHeaders = { 'etag': '"bar"', 'last-modified': 'Sat, 01 Jan 2000 01:00:00 GMT' } + assert.ok(!fresh(reqHeaders, resHeaders)) }) }) }) - describe('when requested with Cache-Control: no-cache', function(){ - it('should be stale', function(){ - var req = { 'cache-control' : ' no-cache' }; - var res = {}; - fresh(req, res).should.be.false; + describe('when requested with Cache-Control: no-cache', function () { + it('should be stale', function () { + var reqHeaders = { 'cache-control': ' no-cache' } + var resHeaders = {} + assert.ok(!fresh(reqHeaders, resHeaders)) + }) + + describe('when ETags match', function () { + it('should be stale', function () { + var reqHeaders = { 'cache-control': ' no-cache', 'if-none-match': '"foo"' } + var resHeaders = { 'etag': '"foo"' } + assert.ok(!fresh(reqHeaders, resHeaders)) + }) + }) + + describe('when unmodified since the date', function () { + it('should be stale', function () { + var reqHeaders = { 'cache-control': ' no-cache', 'if-modified-since': 'Sat, 01 Jan 2000 01:00:00 GMT' } + var resHeaders = { 'last-modified': 'Sat, 01 Jan 2000 00:00:00 GMT' } + assert.ok(!fresh(reqHeaders, resHeaders)) + }) }) }) -}) \ No newline at end of file +}) diff -Nru node-fresh-0.2.0/.travis.yml node-fresh-0.5.2/.travis.yml --- node-fresh-0.2.0/.travis.yml 1970-01-01 00:00:00.000000000 +0000 +++ node-fresh-0.5.2/.travis.yml 2017-09-14 04:41:33.000000000 +0000 @@ -0,0 +1,32 @@ +language: node_js +node_js: + - "0.6" + - "0.8" + - "0.10" + - "0.12" + - "1.8" + - "2.5" + - "3.3" + - "4.8" + - "5.12" + - "6.11" + - "7.10" + - "8.5" +sudo: false +dist: precise +before_install: + # Skip updating shrinkwrap / lock + - "npm config set shrinkwrap false" + # Remove all non-test dependencies + - "npm rm --save-dev beautify-benchmark benchmark" + # Setup Node.js version-specific dependencies + - "test $TRAVIS_NODE_VERSION != '0.6' || npm rm --save-dev istanbul" + - "test $TRAVIS_NODE_VERSION != '0.8' || npm rm --save-dev istanbul" + - "test $(echo $TRAVIS_NODE_VERSION | cut -d. -f1) -ge 4 || npm rm --save-dev $(grep -E '\"eslint\\S*\"' package.json | cut -d'\"' -f2)" +script: + # Run test script, depending on istanbul install + - "test ! -z $(npm -ps ls istanbul) || npm test" + - "test -z $(npm -ps ls istanbul) || npm run-script test-travis" + - "test -z $(npm -ps ls eslint ) || npm run-script lint" +after_script: + - "test -e ./coverage/lcov.info && npm install coveralls@2 && cat ./coverage/lcov.info | coveralls"