mirror of
https://github.com/seejohnrun/haste-server
synced 2025-07-14 17:13:45 -07:00
Added node modules
This commit is contained in:
parent
ca9d4c18f7
commit
d1e0644a4e
575 changed files with 77900 additions and 6 deletions
346
node_modules/connect/lib/middleware/session.js
generated
vendored
Normal file
346
node_modules/connect/lib/middleware/session.js
generated
vendored
Normal file
|
@ -0,0 +1,346 @@
|
|||
|
||||
/*!
|
||||
* Connect - session
|
||||
* Copyright(c) 2010 Sencha Inc.
|
||||
* Copyright(c) 2011 TJ Holowaychuk
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Session = require('./session/session')
|
||||
, MemoryStore = require('./session/memory')
|
||||
, Cookie = require('./session/cookie')
|
||||
, Store = require('./session/store')
|
||||
, utils = require('./../utils')
|
||||
, parse = require('url').parse
|
||||
, crypto = require('crypto');
|
||||
|
||||
// environment
|
||||
|
||||
var env = process.env.NODE_ENV;
|
||||
|
||||
/**
|
||||
* Expose the middleware.
|
||||
*/
|
||||
|
||||
exports = module.exports = session;
|
||||
|
||||
/**
|
||||
* Expose constructors.
|
||||
*/
|
||||
|
||||
exports.Store = Store;
|
||||
exports.Cookie = Cookie;
|
||||
exports.Session = Session;
|
||||
exports.MemoryStore = MemoryStore;
|
||||
|
||||
/**
|
||||
* Warning message for `MemoryStore` usage in production.
|
||||
*/
|
||||
|
||||
var warning = 'Warning: connection.session() MemoryStore is not\n'
|
||||
+ 'designed for a production environment, as it will leak\n'
|
||||
+ 'memory, and obviously only work within a single process.';
|
||||
|
||||
/**
|
||||
* Default finger-printing function.
|
||||
*/
|
||||
|
||||
function defaultFingerprint(req) {
|
||||
var ua = req.headers['user-agent'] || '';
|
||||
return ua.replace(/;?\schromeframe\/[\d\.]+/, '');
|
||||
};
|
||||
|
||||
/**
|
||||
* Paths to ignore.
|
||||
*/
|
||||
|
||||
exports.ignore = [];
|
||||
|
||||
/**
|
||||
* Setup session store with the given `options`.
|
||||
*
|
||||
* Session data is _not_ saved in the cookie itself, however
|
||||
* cookies are used, so we must use the [cookieParser()](middleware-cookieParser.html)
|
||||
* middleware _before_ `session()`.
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* connect.createServer(
|
||||
* connect.cookieParser()
|
||||
* , connect.session({ secret: 'keyboard cat' })
|
||||
* );
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* - `key` cookie name defaulting to `connect.sid`
|
||||
* - `store` Session store instance
|
||||
* - `fingerprint` Custom fingerprint generating function
|
||||
* - `cookie` Session cookie settings, defaulting to `{ path: '/', httpOnly: true, maxAge: 14400000 }`
|
||||
* - `secret` Secret string used to compute hash
|
||||
*
|
||||
* Ignore Paths:
|
||||
*
|
||||
* By default `/favicon.ico` is the only ignored path, all others
|
||||
* will utilize sessions, to manipulate the paths ignored, use
|
||||
* `connect.session.ignore.push('/my/path')`. This works for _full_
|
||||
* pathnames only, not segments nor substrings.
|
||||
*
|
||||
* connect.session.ignore.push('/robots.txt');
|
||||
*
|
||||
* ## req.session
|
||||
*
|
||||
* To store or access session data, simply use the request property `req.session`,
|
||||
* which is (generally) serialized as JSON by the store, so nested objects
|
||||
* are typically fine. For example below is a user-specific view counter:
|
||||
*
|
||||
* connect(
|
||||
* connect.cookieParser()
|
||||
* , connect.session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }})
|
||||
* , connect.favicon()
|
||||
* , function(req, res, next){
|
||||
* var sess = req.session;
|
||||
* if (sess.views) {
|
||||
* res.setHeader('Content-Type', 'text/html');
|
||||
* res.write('<p>views: ' + sess.views + '</p>');
|
||||
* res.write('<p>expires in: ' + (sess.cookie.maxAge / 1000) + 's</p>');
|
||||
* res.end();
|
||||
* sess.views++;
|
||||
* } else {
|
||||
* sess.views = 1;
|
||||
* res.end('welcome to the session demo. refresh!');
|
||||
* }
|
||||
* }
|
||||
* ).listen(3000);
|
||||
*
|
||||
* ## Session#regenerate()
|
||||
*
|
||||
* To regenerate the session simply invoke the method, once complete
|
||||
* a new SID and `Session` instance will be initialized at `req.session`.
|
||||
*
|
||||
* req.session.regenerate(function(err){
|
||||
* // will have a new session here
|
||||
* });
|
||||
*
|
||||
* ## Session#destroy()
|
||||
*
|
||||
* Destroys the session, removing `req.session`, will be re-generated next request.
|
||||
*
|
||||
* req.session.destroy(function(err){
|
||||
* // cannot access session here
|
||||
* });
|
||||
*
|
||||
* ## Session#reload()
|
||||
*
|
||||
* Reloads the session data.
|
||||
*
|
||||
* req.session.reload(function(err){
|
||||
* // session updated
|
||||
* });
|
||||
*
|
||||
* ## Session#save()
|
||||
*
|
||||
* Save the session.
|
||||
*
|
||||
* req.session.save(function(err){
|
||||
* // session saved
|
||||
* });
|
||||
*
|
||||
* ## Session#touch()
|
||||
*
|
||||
* Updates the `.maxAge`, and `.lastAccess` properties. Typically this is
|
||||
* not necessary to call, as the session middleware does this for you.
|
||||
*
|
||||
* ## Session#cookie
|
||||
*
|
||||
* Each session has a unique cookie object accompany it. This allows
|
||||
* you to alter the session cookie per visitor. For example we can
|
||||
* set `req.session.cookie.expires` to `false` to enable the cookie
|
||||
* to remain for only the duration of the user-agent.
|
||||
*
|
||||
* ## Session#maxAge
|
||||
*
|
||||
* Alternatively `req.session.cookie.maxAge` will return the time
|
||||
* remaining in milliseconds, which we may also re-assign a new value
|
||||
* to adjust the `.expires` property appropriately. The following
|
||||
* are essentially equivalent
|
||||
*
|
||||
* var hour = 3600000;
|
||||
* req.session.cookie.expires = new Date(Date.now() + hour);
|
||||
* req.session.cookie.maxAge = hour;
|
||||
*
|
||||
* For example when `maxAge` is set to `60000` (one minute), and 30 seconds
|
||||
* has elapsed it will return `30000` until the current request has completed,
|
||||
* at which time `req.session.touch()` is called to update `req.session.lastAccess`,
|
||||
* and reset `req.session.maxAge` to its original value.
|
||||
*
|
||||
* req.session.cookie.maxAge;
|
||||
* // => 30000
|
||||
*
|
||||
* Session Store Implementation:
|
||||
*
|
||||
* Every session store _must_ implement the following methods
|
||||
*
|
||||
* - `.get(sid, callback)`
|
||||
* - `.set(sid, session, callback)`
|
||||
* - `.destroy(sid, callback)`
|
||||
*
|
||||
* Recommended methods include, but are not limited to:
|
||||
*
|
||||
* - `.length(callback)`
|
||||
* - `.clear(callback)`
|
||||
*
|
||||
* For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo.
|
||||
*
|
||||
* @param {Object} options
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function session(options){
|
||||
var options = options || {}
|
||||
, key = options.key || 'connect.sid'
|
||||
, secret = options.secret
|
||||
, store = options.store || new MemoryStore
|
||||
, fingerprint = options.fingerprint || defaultFingerprint
|
||||
, cookie = options.cookie;
|
||||
|
||||
// notify user that this store is not
|
||||
// meant for a production environment
|
||||
if ('production' == env && store instanceof MemoryStore) {
|
||||
console.warn(warning);
|
||||
}
|
||||
|
||||
// ensure secret is present
|
||||
if (!secret) {
|
||||
throw new Error('connect.session({ secret: "string" }) required for security');
|
||||
}
|
||||
|
||||
// session hashing function
|
||||
store.hash = function(req, base) {
|
||||
return crypto
|
||||
.createHmac('sha256', secret)
|
||||
.update(base + fingerprint(req))
|
||||
.digest('base64')
|
||||
.replace(/=*$/, '');
|
||||
};
|
||||
|
||||
// generates the new session
|
||||
store.generate = function(req){
|
||||
var base = utils.uid(24);
|
||||
var sessionID = base + '.' + store.hash(req, base);
|
||||
req.sessionID = sessionID;
|
||||
req.session = new Session(req);
|
||||
req.session.cookie = new Cookie(cookie);
|
||||
};
|
||||
|
||||
return function session(req, res, next) {
|
||||
// self-awareness
|
||||
if (req.session) return next();
|
||||
|
||||
// parse url
|
||||
var url = parse(req.url)
|
||||
, path = url.pathname;
|
||||
|
||||
// ignorable paths
|
||||
if (~exports.ignore.indexOf(path)) return next();
|
||||
|
||||
// expose store
|
||||
req.sessionStore = store;
|
||||
|
||||
// proxy writeHead() to Set-Cookie
|
||||
var writeHead = res.writeHead;
|
||||
res.writeHead = function(status, headers){
|
||||
if (req.session) {
|
||||
var cookie = req.session.cookie;
|
||||
// only send secure session cookies when there is a secure connection.
|
||||
// proxySecure is a custom attribute to allow for a reverse proxy
|
||||
// to handle SSL connections and to communicate to connect over HTTP that
|
||||
// the incoming connection is secure.
|
||||
var secured = cookie.secure && (req.connection.encrypted || req.connection.proxySecure);
|
||||
if (secured || !cookie.secure) {
|
||||
res.setHeader('Set-Cookie', cookie.serialize(key, req.sessionID));
|
||||
}
|
||||
}
|
||||
|
||||
res.writeHead = writeHead;
|
||||
return res.writeHead(status, headers);
|
||||
};
|
||||
|
||||
// proxy end() to commit the session
|
||||
var end = res.end;
|
||||
res.end = function(data, encoding){
|
||||
res.end = end;
|
||||
if (req.session) {
|
||||
// HACK: ensure Set-Cookie for implicit writeHead()
|
||||
if (!res._header) res._implicitHeader();
|
||||
req.session.resetMaxAge();
|
||||
req.session.save(function(){
|
||||
res.end(data, encoding);
|
||||
});
|
||||
} else {
|
||||
res.end(data, encoding);
|
||||
}
|
||||
};
|
||||
|
||||
// session hashing
|
||||
function hash(base) {
|
||||
return store.hash(req, base);
|
||||
}
|
||||
|
||||
// generate the session
|
||||
function generate() {
|
||||
store.generate(req);
|
||||
}
|
||||
|
||||
// get the sessionID from the cookie
|
||||
req.sessionID = req.cookies[key];
|
||||
|
||||
// make a new session if the browser doesn't send a sessionID
|
||||
if (!req.sessionID) {
|
||||
generate();
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
// check the fingerprint
|
||||
var parts = req.sessionID.split('.');
|
||||
if (parts[1] != hash(parts[0])) {
|
||||
generate();
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
// generate the session object
|
||||
var pause = utils.pause(req);
|
||||
store.get(req.sessionID, function(err, sess){
|
||||
// proxy to resume() events
|
||||
var _next = next;
|
||||
next = function(err){
|
||||
_next(err);
|
||||
pause.resume();
|
||||
}
|
||||
|
||||
// error handling
|
||||
if (err) {
|
||||
if ('ENOENT' == err.code) {
|
||||
generate();
|
||||
next();
|
||||
} else {
|
||||
next(err);
|
||||
}
|
||||
// no session
|
||||
} else if (!sess) {
|
||||
generate();
|
||||
next();
|
||||
// populate req.session
|
||||
} else {
|
||||
store.createSession(req, sess);
|
||||
next();
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue