Skip to content
Browse files

Added basic cookie functionality.

  • Loading branch information...
1 parent 039c4fa commit 5bb8cf99a0c5713cf8573ae7d53e8c39a3414156 @thatismatt committed Jul 6, 2010
Showing with 75 additions and 14 deletions.
  1. +11 −11 lib/josi/actionresults.js
  2. +45 −1 lib/josi/server.js
  3. +19 −2 tests/results.js
View
22 lib/josi/actionresults.js
@@ -6,7 +6,7 @@ var utilities = require('josi/utilities');
this.ActionResult = ActionResult = Class.extend({
init: function(body, headers, statusCode) {
this.statusCode = statusCode || 200;
- this.headers = headers || { 'Content-Type': 'text/html' };
+ this.headers = headers || [ ['Content-Type', 'text/html'] ];
this.body = body;
},
execute: function(req, res) {
@@ -67,8 +67,8 @@ this.ContentResult = ContentResult = ActionResult.extend({
notModified().execute(req, res);
return;
}
- self.headers['Content-Length'] = stat.size;
- self.headers['ETag'] = etag;
+ self.headers.push(['Content-Length', stat.size]);
+ self.headers.push(['ETag', etag]);
var first = true;
var stream = fs.createReadStream(filename);
stream
@@ -82,8 +82,8 @@ this.ContentResult = ContentResult = ActionResult.extend({
.addListener('data', function(data){
if (first) {
first = false;
- self.headers['Transfer-Encoding'] = 'chunked';
- self.headers['Content-Type'] = utilities.mime.lookup(utilities.extension(filename));
+ self.headers.push(['Transfer-Encoding', 'chunked']);
+ self.headers.push(['Content-Type', utilities.mime.lookup(utilities.extension(filename))]);
res.writeHead(200, self.headers);
}
res.write(data, 'binary');
@@ -115,28 +115,28 @@ this.view = function(data, action, controller) {
};
this.redirect = function(url) {
- return new ActionResult('Redirecting...', { 'Content-Type': 'text/html', 'Location': url }, 301);
+ return new ActionResult('Redirecting...', [ ['Content-Type', 'text/html'], ['Location', url] ], 301);
};
this.notFound = notFound = function(msg) {
- return new ActionResult(msg || 'Not found.', { 'Content-Type': 'text/html' }, 404);
+ return new ActionResult(msg || 'Not found.', [ ['Content-Type', 'text/html'] ], 404);
};
this.notModified = notModified = function() {
- return new ActionResult(null, { 'Content-Type': 'text/html' }, 304);
+ return new ActionResult(null, [ ['Content-Type', 'text/html'] ], 304);
};
this.error = error = function(err) {
var msg = err instanceof Error ? err.message + '\r\n' + err.stack : err;
- return new ActionResult(msg, { 'Content-Type': 'text/plain' }, 500);
+ return new ActionResult(msg, [ ['Content-Type', 'text/plain'] ], 500);
};
this.raw = function(data) {
- return new ActionResult(data, { 'Content-Type': 'text/plain' });
+ return new ActionResult(data, [ ['Content-Type', 'text/plain'] ]);
};
this.json = function(data) {
- return new ActionResult(JSON.stringify(data), { 'Content-Type': 'application/json' });
+ return new ActionResult(JSON.stringify(data), [ ['Content-Type', 'application/json'] ]);
};
this.content = function(filename) {
View
46 lib/josi/server.js
@@ -37,14 +37,52 @@ this.Server = function(dir) {
}
};
+ var parseCookies = function(header) {
+ var cookies = {};
+ if (header) {
+ header
+ .split(';')
+ .forEach(function(cookie) {
+ var pair = cookie.split('=');
+ pair = pair.map(function(p) { return p.trim(); });
+ pair.length === 1 ?
+ cookies[''] = pair[0] :
+ cookies[pair[0]] = pair[1];
+ });
+ }
+ return cookies;
+ };
+
var server = http.createServer(function(req, res) {
var parsedUrl = url.parse(req.url);
+ var cookie = (function() {
+ var reqCookies = parseCookies(req.headers['cookie']);
+ var resCookies = {};
+ return {
+ get: function(key) {
+ return reqCookies[key];
+ },
+ // todo: enable cookie expiry, domain, path & secure
+ set: function(key, value) {
+ resCookies[key] = value;
+ },
+ toHeaders: function() {
+ var cookies = [];
+ for (var key in resCookies) {
+ cookies.push(key + '=' + resCookies[key] + ';');
+ }
+ return cookies;
+ }
+ // todo: enable cookie removal
+ };
+ })();
var routeResult = app.router.route(parsedUrl.pathname);
var actionContext = {
route: routeResult.route || {},
query: querystring.parse(parsedUrl.query),
form: {},
- files: {}
+ files: {},
+ cookie: cookie
};
var callback = function() {
actionContext.params = utilities.merge(actionContext.query, actionContext.form);
@@ -68,6 +106,12 @@ this.Server = function(dir) {
throw new Error('Result from router not an instance of RouteResult.');
}
actionResult = processActionResult(actionResult, actionContext);
+ var cookieHeaders = cookie.toHeaders();
+ if (cookieHeaders) {
+ cookieHeaders.forEach(function(header) {
+ actionResult.headers.push(['Set-Cookie', header]);
+ });
+ }
actionResult.execute(req, res, app);
} catch (e) {
actionresults.error(e).execute(req, res);
View
21 tests/results.js
@@ -3,13 +3,30 @@ var actionresults = require('josi/actionresults');
this.name = 'Results Tests';
+var getHeader = function(headers, key) {
+ for (var i in headers) {
+ var header = headers[i];
+ if (header[0] === key) {
+ return header[1];
+ }
+ }
+};
+
this.tests = {
'Content Type of view is HTML': function() {
var result = actionresults.view({});
- assert.equal(result.headers['Content-Type'], 'text/html');
+ assert.equal(getHeader(result.headers, 'Content-Type'), 'text/html');
},
'Content Type of json is json': function() {
var result = actionresults.json({});
- assert.equal(result.headers['Content-Type'], 'application/json');
+ assert.equal(getHeader(result.headers, 'Content-Type'), 'application/json');
+ },
+ 'Content Type of raw is plain text': function() {
+ var result = actionresults.raw({});
+ assert.equal(getHeader(result.headers, 'Content-Type'), 'text/plain');
+ },
+ 'Content Type of error is plain text': function() {
+ var result = actionresults.error({});
+ assert.equal(getHeader(result.headers, 'Content-Type'), 'text/plain');
},
};

0 comments on commit 5bb8cf9

Please sign in to comment.
Something went wrong with that request. Please try again.