Skip to content

Commit

Permalink
Merge branch 'master' of github.com:rainjs/rainjs
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexandru Bularca committed Jun 11, 2012
2 parents f6f3962 + 7cacd68 commit 5c1c14a
Show file tree
Hide file tree
Showing 30 changed files with 298 additions and 476 deletions.
6 changes: 5 additions & 1 deletion Changelog.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
# Changelog

## 0.11.0

* Added an article about Node's best programming practices.

## 0.10.0

* Changed licensing model from MIT to BSD
* Changed licensing model from MIT to BSD.

## 0.9.0

Expand Down
4 changes: 1 addition & 3 deletions components/core/client/js/raintime.js
Original file line number Diff line number Diff line change
Expand Up @@ -387,9 +387,7 @@ define(['raintime/lib/promise',
return;
}

if (typeof controller[eventName] == 'function') {
controller.emit(eventName, data);
}
controller.emit(eventName, data);
}

/**
Expand Down
8 changes: 7 additions & 1 deletion doc/source/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,17 @@
Changelog
=========

------
v 0.11
------

+ Added an article about Node's best programming practices.

------
v 0.10
------

+ Changed licensing model from MIT to BSD
+ Changed licensing model from MIT to BSD.

-----
v 0.9
Expand Down
4 changes: 2 additions & 2 deletions doc/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@
# built documents.
#
# The short X.Y version.
version = '0.10'
version = '0.11'
# The full version, including alpha/beta/rc tags.
release = '0.10.0'
release = '0.11.0'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
128 changes: 34 additions & 94 deletions lib/proxy_store.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,42 +25,43 @@

"use strict";

var Store = require('connect/lib/middleware/session/store');
var MemoryStore = require('connect/lib/middleware/session/memory');
var Cookie = require('connect/lib/middleware/session/cookie');
var Session = require('connect/lib/middleware/session/session');
var util = require('util');
var extend = require('node.extend');
var Store = require('connect/lib/middleware/session/store'),
MemoryStore = require('connect/lib/middleware/session/memory'),
Cookie = require('connect/lib/middleware/session/cookie'),
Session = require('connect/lib/middleware/session/session'),
util = require('util'),
extend = require('node.extend');

/**
* Proxy store implementation for connect. Uses dependency injection to aggregate implementations
* for local and remote stores. By default, a :js:class:`MemoryStore` is used for the local store
* and a :js:class:`MemoryStore` is used for the remote store. It uses lazy instantiation of stores.
*
* It exposes the :js:func:`ProxyStore#authorize` method for switching the store implementation at
* runtime, i.e. providing a way to switch the store at runtime after login.
* Proxy store implementation for connect. Uses dependency injection to set the store implementation.
* By default, a :js:class:`MemoryStore` is used. It uses lazy instantiation.
*
* @name ProxyStore
* @constructor
* @param {connect.session.Store} [LocalStore=MemoryStore] store class to use for local storage
* @param {connect.session.Store} [RemoteStore=MemoryStore] store class to use for remote storage
* @property {connect.session.Store} localStore the local store instance
* @property {connect.session.Store} remoteStore the remote store instance
* @property {Object} authorizedSessions the object associating authorized sids with remote sids
* @param {connect.session.Store} [Store=MemoryStore] store implementation
* @param {Object} cookie the cookie configuration for the session store
* @param {String} cookie.path the path to be set to the cookies
* @param {Boolean} cookie.httpOnly wether the cookie is http only or not
* @property {connect.session.Store} store the store instance
* @property {Object} sessionCache cache for session objects for concurrent access control to the store
*/
var ProxyStore = function (LocalStore, RemoteStore) {
var local;
var remote;
var ProxyStore = function (Store, cookie) {
var store;

Object.defineProperty(this, 'localStore', {
get: function () { return local = local || new (LocalStore || MemoryStore)(); }
Object.defineProperty(this, 'store', {
get: function () { return store = store || new (Store || MemoryStore)(cookie); }
});

Object.defineProperty(this, 'remoteStore', {
get: function () { return remote = remote || new (RemoteStore || MemoryStore)(); }
});
// if the store has a generate method make it un writable so that it can't be overriden by the
// session middleware
if (this.store.generate) {
Object.defineProperty(this, 'generate', {
value: function (request) { return (this.store.generate && this.store.generate.apply(this.store, arguments)); }
});
}

this.authorizedSessions = {};
// Cache for concurrent access control to the store.
// This is a work-around that works only for one RAIN server!
this.sessionCache = {};
};

Expand All @@ -81,44 +82,19 @@ ProxyStore.prototype.get = function (sid, fn) {
return;
}

getStore(self, sid).get(getId(self, sid), function (err, session) {
self.store.get(sid, function (err, sess) {
if (!err) {
self.sessionCache[sid] = {
refCount: 1,
session: session
session: sess
};
}

fn(err, session);
fn(err, sess);
});
});
};

/**
* Get the correct session id to pass to the store.
* A local store must use the cookie sid, a remote store must use
* the sid stored in the authorizedSesssions map.
*
* @param {ProxyStore} self the class instance
* @param {String} sid the local session id
* @private
* @memberOf ProxyStore#
*/
function getId(self, sid) {
return self.authorizedSessions[sid] || sid;
}

/**
* Return the store associated with a session.
*
* @param {ProxyStore} self the class instance
* @param {String} sid the session id
* @returns {connect.session.Store} the store associated to the session
*/
function getStore(self, sid) {
return (sid in self.authorizedSessions) ? self.remoteStore : self.localStore;
}

/**
* Save the session to the store with a given session id.
*
Expand All @@ -134,62 +110,27 @@ ProxyStore.prototype.set = function (sid, sess, fn) {
delete self.sessionCache[sid];
}

getStore(self, sid).set(getId(self, sid), sess, fn);
self.store.set(sid, sess, fn);
});
};

/**
* Destroys the session with a given session id.
*
* Destroys the session both on the remote and on the local stores.
*
* @param {String} sid the session id
* @param {Function} fn the callback that is invoked after the session is destroyed
*/
ProxyStore.prototype.destroy = function (sid, fn) {
var self = this;
process.nextTick(function () {
var remotesid = self.authorizedSessions[sid];
if (self.sessionCache[sid]) {
delete self.sessionCache[sid];
}

if (remotesid) {
delete self.authorizedSessions[sid];

self.remoteStore.destroy(remotesid, function () {
self.localStore.destroy(sid, fn);
});
} else {
self.localStore.destroy(sid, fn);
}
self.store.destroy(sid, fn);
});
};

/**
* Authorizes a session.
*
* Stores the session id in the list of authorized sessions that use the remote store.
*
* @param {String} sid the session id to be authorized
* @param {String} remotesid the remote session id
* @param {connect.session.Session} sess the session to authorize
*/
ProxyStore.prototype.authorize = function (sid, remotesid, sess) {
this.authorizedSessions[sid] = remotesid;
};

/**
* Gets the remote session id.
*
* @param {String} sid the session id
* @returns {String} the remote session id
*/
ProxyStore.prototype.getRemoteSid = function (sid) {
return this.authorizedSessions[sid];
};

/**
* Create session from JSON `sess` data.
*
Expand All @@ -198,10 +139,9 @@ ProxyStore.prototype.getRemoteSid = function (sid) {
* @return {Session}
* @private
*/
ProxyStore.prototype.createSession = function(req, sess, update){
ProxyStore.prototype.createSession = function (req, sess) {
var expires = sess.cookie.expires;
var orig = sess.cookie.originalMaxAge;
var update = null == update ? true : false;

sess.cookie = new Cookie(req, sess.cookie);
if ('string' == typeof expires) {
Expand All @@ -210,7 +150,7 @@ ProxyStore.prototype.createSession = function(req, sess, update){

sess.cookie.originalMaxAge = orig;

req.session = sess; //new Session(req, sess);
req.session = sess;
if (!req.session.req) {
Object.defineProperty(req.session, 'req', {value: req});
}
Expand Down
1 change: 1 addition & 0 deletions lib/rain_error.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ RainError.ERROR_NET = 1;
RainError.ERROR_PRECONDITION_FAILED = 2;
RainError.ERROR_HTTP = 3;
RainError.ERROR_SOCKET = 4;
RainError.ERROR_AUTHORIZATION = 5;

util.inherits(RainError, Error);

Expand Down
38 changes: 18 additions & 20 deletions lib/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
"use strict";

// Initialize global objects
var logger = require('./logger');
require('./globals');
var logger = require('./logger');

var fs = require('fs');
var program = require('commander');
Expand All @@ -53,45 +53,45 @@ var routerUtils = require('./router_utils');
*
* @property {Configuration} config the server configuration
*/
function Server() {
}
function Server() {}

/**
* Starts the server.
*
* @param {Server} self the class instance
* @param {String} configPath the server configuration path
* @private
* @memberOf Server#
*/
Server.prototype.initialize = function () {
var LocalStore, RemoteStore;
var Store, session;
try {
LocalStore = config.session && config.session.local
? require(path.join(process.cwd(), config.session.local))
: null;
Store = config.session && config.session.store ?
require(path.join(process.cwd(), config.session.store))
: null;
} catch (e) {
console.error("Can't load LocalStore plugin");
throw new RainError('Failed to load session store.', RainError.ERROR_IO);
}
try {
RemoteStore = config.session && config.session.remote
? require(path.join(process.cwd(), config.session.remote))
: null;
session = config.session && config.session.middleware ?
require(path.join(process.cwd(), config.session.middleware))
: connect.session;
} catch (e) {
console.error("Can't load RemoteStore plugin");
throw new RainError('Failed to load session middleware.', RainError.ERROR_IO);
}

var sessionStore = new ProxyStore(LocalStore, RemoteStore);
var sessionStore = new ProxyStore(Store, {
path: '/',
httpOnly: true
});

var server = connect()
.use(connect.favicon())
.use(connect.cookieParser('let it rain ;)'))
.use(connect.session({
.use(session({
key: 'rain.sid',
secret: 'let it rain ;)',
store: sessionStore,
cookie: {
path: '/',
httpOnly: false
httpOnly: true
}
}))
.use(connect.query())
Expand All @@ -106,8 +106,6 @@ Server.prototype.initialize = function () {
this.sessionStore = sessionStore;
componentRegistry.initialize();
console.log("Server started");
//watch files
require('./watcher').initialize();
};

module.exports = new Server();
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "rain",
"description": "A component-based and distributed web application framework",
"version": "0.10.0",
"version": "0.11.0",
"author": "Rain Team <rain-team@1and1.ro>",
"contributors": [
{ "name": "Mitko Tschimev", "email": "mitko.tschimev@1und1.de" },
Expand Down
Loading

0 comments on commit 5c1c14a

Please sign in to comment.