Skip to content

Commit

Permalink
Added: cookieSession() only set-cookie on change. Clos senchalabs#442
Browse files Browse the repository at this point in the history
  • Loading branch information
tj committed Mar 9, 2012
1 parent 13dc2be commit b028b4f
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 5 deletions.
4 changes: 3 additions & 1 deletion lib/middleware/cookieParser.js
Expand Up @@ -48,7 +48,9 @@ module.exports = function cookieParser(secret){
req.cookies = utils.parseCookie(cookie); req.cookies = utils.parseCookie(cookie);
if (secret) { if (secret) {
req.signedCookies = utils.parseSignedCookies(req.cookies, secret); req.signedCookies = utils.parseSignedCookies(req.cookies, secret);
req.signedCookies = utils.parseJSONCookies(req.signedCookies); var obj = utils.parseJSONCookies(req.signedCookies);
req.signedCookies = obj.cookies;
req.cookieHashes = obj.hashes;
} }
req.cookies = utils.parseJSONCookies(req.cookies); req.cookies = utils.parseJSONCookies(req.cookies);
} catch (err) { } catch (err) {
Expand Down
14 changes: 11 additions & 3 deletions lib/middleware/cookieSession.js
Expand Up @@ -11,7 +11,8 @@


var utils = require('./../utils') var utils = require('./../utils')
, Cookie = require('./session/cookie') , Cookie = require('./session/cookie')
, debug = require('debug')('connect:cookieSession'); , debug = require('debug')('connect:cookieSession')
, crc16 = require('crc').crc16;


// environment // environment


Expand Down Expand Up @@ -69,12 +70,19 @@ module.exports = function cookieSession(options){
// only send secure cookies via https // only send secure cookies via https
if (cookie.secure && !secured) return debug('not secured'); if (cookie.secure && !secured) return debug('not secured');


// set cookie // serialize
debug('serializing %j', req.session); debug('serializing %j', req.session);
var val = 'j:' + JSON.stringify(req.session); var val = 'j:' + JSON.stringify(req.session);

// compare hashes
var originalHash = req.cookieHashes && req.cookieHashes[key];
var hash = crc16(val);
if (originalHash == hash) return debug('unmodified session');

// set-cookie
val = utils.sign(val, req.secret); val = utils.sign(val, req.secret);
val = utils.serializeCookie(key, val, cookie); val = utils.serializeCookie(key, val, cookie);
debug('cookie %j', cookie); debug('set-cookie %j', cookie);
res.setHeader('Set-Cookie', val); res.setHeader('Set-Cookie', val);
}); });


Expand Down
10 changes: 9 additions & 1 deletion lib/utils.js
Expand Up @@ -12,6 +12,7 @@


var http = require('http') var http = require('http')
, crypto = require('crypto') , crypto = require('crypto')
, crc16 = require('crc').crc16
, Path = require('path') , Path = require('path')
, fs = require('fs'); , fs = require('fs');


Expand Down Expand Up @@ -188,17 +189,24 @@ exports.parseSignedCookies = function(obj, secret){
*/ */


exports.parseJSONCookies = function(obj){ exports.parseJSONCookies = function(obj){
var hashes = {};

Object.keys(obj).forEach(function(key){ Object.keys(obj).forEach(function(key){
var val = obj[key]; var val = obj[key];
if (0 == val.indexOf('j:')) { if (0 == val.indexOf('j:')) {
try { try {
hashes[key] = crc16(val); // only crc json cookies for now
obj[key] = JSON.parse(val.slice(2)); obj[key] = JSON.parse(val.slice(2));
} catch (err) { } catch (err) {
// nothing // nothing
} }
} }
}); });
return obj;
return {
cookies: obj,
hashes: hashes
};
}; };


/** /**
Expand Down
5 changes: 5 additions & 0 deletions package.json
Expand Up @@ -9,7 +9,12 @@
"dependencies": { "dependencies": {
"qs": "0.4.2", "qs": "0.4.2",
"mime": "1.2.4", "mime": "1.2.4",
<<<<<<< HEAD
"formidable": "1.0.9", "formidable": "1.0.9",
=======
"formidable": "1.0.x",
"crc": "0.1.0",
>>>>>>> crc-sessions
"debug": "*" "debug": "*"
}, },
"devDependencies": { "devDependencies": {
Expand Down
71 changes: 71 additions & 0 deletions test/cookieSession.js
Expand Up @@ -145,6 +145,77 @@ describe('connect.cookieSession()', function(){
}) })
}) })


describe('when modified', function(){
it('should set-cookie', function(done){
var n = 0;
var app = connect()
.use(connect.cookieParser('keyboard cat'))
.use(connect.cookieSession())
.use(function(req, res, next){
req.session.foo = ++n;
res.end();
});

app.request()
.get('/')
.end(function(res){
res.headers.should.have.property('set-cookie');

app.request()
.get('/')
.set('Cookie', sess(res))
.end(function(res){
res.headers.should.have.property('set-cookie');
done();
});
});
})
})

describe('when un-modified', function(){
it('should set-cookie only the initial time', function(done){
var modify;

var app = connect()
.use(connect.cookieParser('keyboard cat'))
.use(connect.cookieSession())
.use(function(req, res, next){
if (modify) req.session.foo = 'bar';
res.end();
});

app.request()
.get('/')
.end(function(res){
res.headers.should.have.property('set-cookie');
var cookie = sess(res);

app.request()
.get('/')
.set('Cookie', cookie)
.end(function(res){
res.headers.should.not.have.property('set-cookie');

app.request()
.get('/')
.set('Cookie', cookie)
.end(function(res){
res.headers.should.not.have.property('set-cookie');
modify = true;

app.request()
.get('/')
.set('Cookie', cookie)
.end(function(res){
res.headers.should.have.property('set-cookie');
done();
});
});
});
});
})
})

describe('.secure', function(){ describe('.secure', function(){
it('should not set-cookie when insecure', function(done){ it('should not set-cookie when insecure', function(done){
var app = connect() var app = connect()
Expand Down

0 comments on commit b028b4f

Please sign in to comment.