added tests and started code for session state, you know, the whole point of sessions

This commit is contained in:
Ben Adida 2011-12-29 09:33:16 -08:00
Родитель 20101dc557
Коммит bc2d47077f
2 изменённых файлов: 73 добавлений и 5 удалений

Просмотреть файл

@ -3,6 +3,29 @@ var Cookies = require("cookies");
var Proxy = require("node-proxy");
var Handler = require("./ProxyHandler.js");
function base64urlencode(arg) {
var s = new Buffer(arg).toString('base64');
s = s.split('=')[0]; // Remove any trailing '='s
s = s.replace(/\+/g, '-'); // 62nd char of encoding
s = s.replace(/\//g, '_'); // 63rd char of encoding
// TODO optimize this; we can do much better
return s;
}
function base64urldecode(arg) {
var s = arg;
s = s.replace(/-/g, '+'); // 62nd char of encoding
s = s.replace(/_/g, '/'); // 63rd char of encoding
switch (s.length % 4) // Pad with trailing '='s
{
case 0: break; // No pad chars in this case
case 2: s += "=="; break; // Two pad chars
case 3: s += "="; break; // One pad char
default: throw new InputException("Illegal base64url string!");
}
return new Buffer(s, 'base64').toString('ascii'); // Standard base64 decoder
}
/*
* Session object
*
@ -14,6 +37,7 @@ function Session(req, res, cookies, opts) {
this.cookies = cookies;
this.opts = opts;
this.content = {};
this.loaded = false;
}
Session.prototype = {
@ -26,7 +50,18 @@ Session.prototype = {
},
updateCookie: function() {
this.cookies.set(this.opts.cookieName, JSON.stringify(this.content));
this.cookies.set(this.opts.cookieName, base64urlencode(JSON.stringify(this.content)));
},
loadFromCookie: function() {
// XXX ummm, sig verify?
var cookie = this.cookies.get(this.opts.cookieName);
if (cookie) {
this.content = JSON.parse(base64urldecode(cookie));
} else {
this.content = {};
}
this.loaded = true;
},
// called to create a proxy that monitors the session
@ -37,10 +72,13 @@ Session.prototype = {
// all values from content except special values
sessionHandler.get = function(rcvr, name) {
if (['clear', 'setExpires', 'updateCookie'].indexOf(name) > -1)
if (['clear', 'setExpires', 'updateCookie', 'loadFromCookie'].indexOf(name) > -1) {
return this.target[name].bind(this.target);
else
} else {
if (!this.target.loaded)
this.target.loadFromCookie();
return this.target.content[name];
}
};
// set all values to content

Просмотреть файл

@ -15,7 +15,7 @@ var middleware = cookieSessions({
var suite = vows.describe('all');
suite.addBatch({
"request object" : {
"a single request object" : {
topic: function() {
var self = this;
@ -23,7 +23,6 @@ suite.addBatch({
var app = express.createServer();
app.use(middleware);
app.get("/foo", function(req, res) {
console.log("yay");
self.callback(null, req);
res.send("hello");
});
@ -52,4 +51,35 @@ suite.addBatch({
}
});
suite.addBatch({
"across two requests" : {
topic: function() {
var self = this;
// simple app
var app = express.createServer();
app.use(middleware);
app.get("/foo", function(req, res) {
req.session.clear();
req.session.foo = 'foobar';
req.session.bar = [1, 2, 3];
res.send("foo");
});
app.get("/bar", function(req, res) {
self.callback(null, req);
res.send("bar");
});
var browser = tobi.createBrowser(app);
browser.get("/foo", function(res, $) {});
browser.get("/bar", function(res, $) {});
},
"session maintains state": function(err, req) {
assert.equal(req.session.foo, 'foobar');
assert.equal(req.session.bar, [1,2,3]);
}
}
});
suite.export(module);