From 51d33edb7973cb9ecec404d03e62d1ef9dff4a92 Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Mon, 25 Aug 2014 01:07:01 -0400 Subject: [PATCH] Use etag to generate ETag headers --- History.md | 1 + lib/utils.js | 31 ++++++++++--------------------- package.json | 1 + test/res.send.js | 26 ++++++++++++++------------ test/utils.js | 6 +++--- 5 files changed, 29 insertions(+), 36 deletions(-) diff --git a/History.md b/History.md index e3e5cc34..5efd387b 100644 --- a/History.md +++ b/History.md @@ -5,6 +5,7 @@ unreleased - Applies to `res.sendFile`, `res.sendfile`, and `res.download` - `err` will be populated with request aborted error * Support IP address host in `req.subdomains` + * Use `etag` to generate `ETag` headers * deps: accepts@~1.1.0 - update `mime-types` * deps: cookie-signature@1.0.5 diff --git a/lib/utils.js b/lib/utils.js index 9f9fdfd6..8dd29664 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -3,9 +3,8 @@ */ var mime = require('send').mime; -var crc32 = require('buffer-crc32'); -var crypto = require('crypto'); var basename = require('path').basename; +var etag = require('etag'); var proxyaddr = require('proxy-addr'); var qs = require('qs'); var querystring = require('querystring'); @@ -20,17 +19,12 @@ var typer = require('media-typer'); * @api private */ -exports.etag = function etag(body, encoding){ - if (body.length === 0) { - // fast-path empty body - return '"1B2M2Y8AsgTpgAmY7PhCfg=="' - } +exports.etag = function (body, encoding) { + var buf = !Buffer.isBuffer(body) + ? new Buffer(body, encoding) + : body - var hash = crypto - .createHash('md5') - .update(body, encoding) - .digest('base64') - return '"' + hash + '"' + return etag(buf, {weak: false}) }; /** @@ -43,16 +37,11 @@ exports.etag = function etag(body, encoding){ */ exports.wetag = function wetag(body, encoding){ - if (body.length === 0) { - // fast-path empty body - return 'W/"0-0"' - } + var buf = !Buffer.isBuffer(body) + ? new Buffer(body, encoding) + : body - var buf = Buffer.isBuffer(body) - ? body - : new Buffer(body, encoding) - var len = buf.length - return 'W/"' + len.toString(16) + '-' + crc32.unsigned(buf) + '"' + return etag(buf, {weak: true}) }; /** diff --git a/package.json b/package.json index 688e8b6d..d8dfc886 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "debug": "~2.0.0", "depd": "0.4.4", "escape-html": "1.0.1", + "etag": "~1.3.0", "finalhandler": "0.2.0", "fresh": "0.2.4", "media-typer": "0.3.0", diff --git a/test/res.send.js b/test/res.send.js index a3d9d217..6148e002 100644 --- a/test/res.send.js +++ b/test/res.send.js @@ -118,13 +118,13 @@ describe('res', function(){ var app = express(); app.use(function(req, res){ - var str = Array(1024 * 2).join('-'); + var str = Array(1000).join('-'); res.send(str); }); request(app) .get('/') - .expect('ETag', 'W/"7ff-2796319984"') + .expect('ETag', 'W/"3e7-8084ccd1"') .end(done); }) @@ -132,7 +132,7 @@ describe('res', function(){ var app = express(); app.use(function(req, res){ - var str = Array(1024 * 2).join('-'); + var str = Array(1000).join('-'); res.send(str); }); @@ -207,13 +207,13 @@ describe('res', function(){ var app = express(); app.use(function(req, res){ - var str = Array(1024 * 2).join('-'); + var str = Array(1000).join('-'); res.send(new Buffer(str)); }); request(app) .get('/') - .expect('ETag', 'W/"7ff-2796319984"') + .expect('ETag', 'W/"3e7-8084ccd1"') .end(done); }) @@ -321,15 +321,17 @@ describe('res', function(){ it('should respond with 304 Not Modified when fresh', function(done){ var app = express(); + var etag = '"asdf"'; app.use(function(req, res){ - var str = Array(1024 * 2).join('-'); + var str = Array(1000).join('-'); + res.set('ETag', etag); res.send(str); }); request(app) .get('/') - .set('If-None-Match', 'W/"7ff-2796319984"') + .set('If-None-Match', etag) .expect(304, done); }) @@ -375,7 +377,7 @@ describe('res', function(){ request(app) .get('/') - .expect('etag', 'W/"c-1525560792"', done) + .expect('etag', 'W/"c-5aee35d8"', done) }) it('should send ETag for empty string response', function(done){ @@ -396,7 +398,7 @@ describe('res', function(){ var app = express(); app.use(function(req, res){ - var str = Array(1024 * 2).join('-'); + var str = Array(1000).join('-'); res.send(str); }); @@ -404,7 +406,7 @@ describe('res', function(){ request(app) .get('/') - .expect('etag', 'W/"7ff-2796319984"', done) + .expect('etag', 'W/"3e7-8084ccd1"', done) }); it('should not override ETag when manually set', function(done){ @@ -445,7 +447,7 @@ describe('res', function(){ var app = express(); app.use(function(req, res){ - var str = Array(1024 * 2).join('-'); + var str = Array(1000).join('-'); res.send(str); }); @@ -503,7 +505,7 @@ describe('res', function(){ request(app) .get('/') - .expect('etag', 'W/"d-1486392595"', done) + .expect('etag', 'W/"d-58988d13"', done) }) }) diff --git a/test/utils.js b/test/utils.js index 89601a5e..399b3f5b 100644 --- a/test/utils.js +++ b/test/utils.js @@ -28,18 +28,18 @@ describe('utils.etag(body, encoding)', function(){ describe('utils.wetag(body, encoding)', function(){ it('should support strings', function(){ utils.wetag('express!') - .should.eql('W/"8-3098196679"') + .should.eql('W/"8-b8aabac7"') }) it('should support utf8 strings', function(){ utils.wetag('express❤', 'utf8') - .should.eql('W/"a-1751845617"') + .should.eql('W/"a-686b0af1"') }) it('should support buffer', function(){ var buf = new Buffer('express!') utils.wetag(buf) - .should.eql('W/"8-3098196679"'); + .should.eql('W/"8-b8aabac7"'); }) it('should support empty string', function(){