Permalink
Browse files

update docs

  • Loading branch information...
1 parent 8d28eb6 commit 66d45034361994bf97934414fd60f50172e93a17 @tj tj committed Aug 20, 2012
View
@@ -56,14 +56,14 @@
var pause = utils.pause(req);
callback(user, pass, function(err, user){
if (err || !user) return unauthorized(res, realm);
- req.user = user;
+ req.user = req.remoteUser = user;
next();
pause.resume();
});
// sync
} else {
if (callback(user, pass)) {
- req.user = user;
+ req.user = req.remoteUser = user;
next();
} else {
unauthorized(res, realm);
View
@@ -0,0 +1,22 @@
+<!DOCTYPE html><html><head><title>Connect - High quality middleware for node.js</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><link rel="stylesheet" href="style.css"><script src="jquery.js"></script><script src="docs.js"></script></head><body><div id="content"><h1>Connect</h1><div id="module.exports" class="comment"><h2></h2><div class="description"><p>Expose <code>Cache</code>.</p></div><h3>Source</h3><pre><code>module.exports = Cache;</code></pre></div><div id="Cache" class="comment"><h2>Cache()</h2><div class="description"><p>LRU cache store.</p></div><ul class="tags"><li><em>Number</em> limit </li></ul><h3>Source</h3><pre><code>function Cache(limit) {
+ this.store = {};
+ this.keys = [];
+ this.limit = limit;
+}</code></pre></div><div id="Cache.prototype.touch" class="comment"><h2>Cache#touch()</h2><div class="description"><p>Touch <code>key</code>, promoting the object.</p></div><ul class="tags"><li><em>String</em> key </li><li><em>Number</em> i </li></ul><h3>Source</h3><pre><code>Cache.prototype.touch = function(key, i){
+ this.keys.splice(i,1);
+ this.keys.push(key);
+};</code></pre></div><div id="Cache.prototype.remove" class="comment"><h2>Cache#remove()</h2><div class="description"><p>Remove <code>key</code>.</p></div><ul class="tags"><li><em>String</em> key </li></ul><h3>Source</h3><pre><code>Cache.prototype.remove = function(key){
+ delete this.store[key];
+};</code></pre></div><div id="Cache.prototype.get" class="comment"><h2>Cache#get()</h2><div class="description"><p>Get the object stored for <code>key</code>.</p></div><ul class="tags"><li><em>String</em> key </li><li>returns <em>Array</em> </li></ul><h3>Source</h3><pre><code>Cache.prototype.get = function(key){
+ return this.store[key];
+};</code></pre></div><div id="Cache.prototype.add" class="comment"><h2>Cache#add()</h2><div class="description"><p>Add a cache <code>key</code>.</p></div><ul class="tags"><li><em>String</em> key </li><li>returns <em>Array</em> </li></ul><h3>Source</h3><pre><code>Cache.prototype.add = function(key){
+ // initialize store
+ var len = this.keys.push(key);
+
+ // limit reached, invalidate LRU
+ if (len > this.limit) this.remove(this.keys.shift());
+
+ var arr = this.store[key] = [];
+ arr.createdAt = new Date;
+ return arr;
+};</code></pre></div></div><ul id="menu"><li><a href="#module.exports"></a></li><li><a href="#Cache">Cache()</a></li><li><a href="#Cache.prototype.touch">Cache#touch()</a></li><li><a href="#Cache.prototype.remove">Cache#remove()</a></li><li><a href="#Cache.prototype.get">Cache#get()</a></li><li><a href="#Cache.prototype.add">Cache#add()</a></li></ul></body></html>
View
@@ -2,21 +2,17 @@
gzip: zlib.createGzip
, deflate: zlib.createDeflate
};</code></pre></div><div id="exports.filter" class="comment"><h2>exports.filter()</h2><div class="description"><p>Default filter function.</p></div><h3>Source</h3><pre><code>exports.filter = function(req, res){
- var type = res.getHeader('Content-Type') || '';
- return type.match(/json|text|javascript/);
+ return /json|text|javascript/.test(res.getHeader('Content-Type'));
};</code></pre></div><div id="module.exports" class="comment"><h2></h2><div class="description"><h2>Compress</h2>
<p>Compress response data with gzip/deflate.</p>
<h2>Filter</h2>
-<p>A <code>filter</code> callback function may be passed to</p>
-
-<h2>replace the default logic of</h2>
+<p>A <code>filter</code> callback function may be passed to<br /> replace the default logic of:</p>
<pre><code>exports.filter = function(req, res){
- var type = res.getHeader('Content-Type') || '';
- return type.match(/json|text|javascript/);
+ return /json|text|javascript/.test(res.getHeader('Content-Type'));
};
</code></pre>
@@ -50,7 +46,7 @@
res.write = function(chunk, encoding){
if (!this.headerSent) this._implicitHeader();
return stream
- ? stream.write(chunk, encoding)
+ ? stream.write(new Buffer(chunk, encoding))
: write.call(res, chunk, encoding);
};
@@ -103,7 +99,10 @@
stream.on('end', function(){
end.call(res);
});
-
+
+ stream.on('drain', function() {
+ res.emit('drain');
+ });
});
next();
View
@@ -1,14 +1,17 @@
-<!DOCTYPE html><html><head><title>Connect - High quality middleware for node.js</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><link rel="stylesheet" href="style.css"><script src="jquery.js"></script><script src="docs.js"></script></head><body><div id="content"><h1>Connect</h1><div id="exports.version" class="comment"><h2>exports.version</h2><div class="description"><p>Framework version.</p></div><h3>Source</h3><pre><code>exports.version = '2.0.3';</code></pre></div><div id="exports.proto" class="comment"><h2>exports.proto</h2><div class="description"><p>Expose the prototype.</p></div><h3>Source</h3><pre><code>exports.proto = proto;</code></pre></div><div id="exports.middleware" class="comment"><h2>exports.middleware</h2><div class="description"><p>Auto-load middleware getters.</p></div><h3>Source</h3><pre><code>exports.middleware = {};</code></pre></div><div id="exports.utils" class="comment"><h2>exports.utils</h2><div class="description"><p>Expose utilities.</p></div><h3>Source</h3><pre><code>exports.utils = utils;</code></pre></div><div id="createServer" class="comment"><h2>createServer()</h2><div class="description"><p>Create a new connect server.</p></div><ul class="tags"><li>returns <em>Function</em> </li></ul><h3>Source</h3><pre><code>function createServer() {
+<!DOCTYPE html><html><head><title>Connect - High quality middleware for node.js</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><link rel="stylesheet" href="style.css"><script src="jquery.js"></script><script src="docs.js"></script></head><body><div id="content"><h1>Connect</h1><div id="exports.version" class="comment"><h2>exports.version</h2><div class="description"><p>Framework version.</p></div><h3>Source</h3><pre><code>exports.version = '2.4.3';</code></pre></div><div id="exports.mime" class="comment"><h2>exports.mime</h2><div class="description"><p>Expose mime module.</p></div><h3>Source</h3><pre><code>exports.mime = require('./middleware/static').mime;</code></pre></div><div id="exports.proto" class="comment"><h2>exports.proto</h2><div class="description"><p>Expose the prototype.</p></div><h3>Source</h3><pre><code>exports.proto = proto;</code></pre></div><div id="exports.middleware" class="comment"><h2>exports.middleware</h2><div class="description"><p>Auto-load middleware getters.</p></div><h3>Source</h3><pre><code>exports.middleware = {};</code></pre></div><div id="exports.utils" class="comment"><h2>exports.utils</h2><div class="description"><p>Expose utilities.</p></div><h3>Source</h3><pre><code>exports.utils = utils;</code></pre></div><div id="createServer" class="comment"><h2>createServer()</h2><div class="description"><p>Create a new connect server.</p></div><ul class="tags"><li>returns <em>Function</em> </li></ul><h3>Source</h3><pre><code>function createServer() {
function app(req, res){ app.handle(req, res); }
utils.merge(app, proto);
utils.merge(app, EventEmitter.prototype);
app.route = '/';
- app.stack = [].slice.apply(arguments);
+ app.stack = [];
+ for (var i = 0; i < arguments.length; ++i) {
+ app.use(arguments[i]);
+ }
return app;
};</code></pre></div><div id="createServer.createServer" class="comment"><h2>createServer.createServer</h2><div class="description"><p>Support old <code>.createServer()</code> method.</p></div><h3>Source</h3><pre><code>createServer.createServer = createServer;</code></pre></div><div id="" class="comment"><h2></h2><div class="description"><p>Auto-load bundled middleware with getters.</p></div><h3>Source</h3><pre><code>fs.readdirSync(__dirname + '/middleware').forEach(function(filename){
if (!/\.js$/.test(filename)) return;
var name = basename(filename, '.js');
function load(){ return require('./middleware/' + name); }
exports.middleware.__defineGetter__(name, load);
exports.__defineGetter__(name, load);
-});</code></pre></div></div><ul id="menu"><li><a href="#exports.version">exports.version</a></li><li><a href="#exports.proto">exports.proto</a></li><li><a href="#exports.middleware">exports.middleware</a></li><li><a href="#exports.utils">exports.utils</a></li><li><a href="#createServer">createServer()</a></li><li><a href="#createServer.createServer">createServer.createServer</a></li><li><a href="#"></a></li></ul></body></html>
+});</code></pre></div></div><ul id="menu"><li><a href="#exports.version">exports.version</a></li><li><a href="#exports.mime">exports.mime</a></li><li><a href="#exports.proto">exports.proto</a></li><li><a href="#exports.middleware">exports.middleware</a></li><li><a href="#exports.utils">exports.utils</a></li><li><a href="#createServer">createServer()</a></li><li><a href="#createServer.createServer">createServer.createServer</a></li><li><a href="#"></a></li></ul></body></html>
View
@@ -1,31 +1,30 @@
<!DOCTYPE html><html><head><title>Connect - High quality middleware for node.js</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><link rel="stylesheet" href="style.css"><script src="jquery.js"></script><script src="docs.js"></script></head><body><div id="content"><h1>Connect</h1><div id="module.exports" class="comment"><h2></h2><div class="description"><h2>Cookie parser</h2>
-<p>Parse <em>Cookie</em> header and populate <code>req.cookies</code><br />with an object keyed by the cookie names. Optionally<br />you may enabled signed cookie support by passing<br />a <code>secret</code> string, which assigns <code>req.secret</code> so<br />it may be used by other middleware such as <code>session()</code>.</p>
+<p>Parse <em>Cookie</em> header and populate <code>req.cookies</code><br />with an object keyed by the cookie names. Optionally<br />you may enabled signed cookie support by passing<br />a <code>secret</code> string, which assigns <code>req.secret</code> so<br />it may be used by other middleware.</p>
<h2>Examples</h2>
<pre><code>connect()
- .use(connect.cookieParser('keyboard cat'))
+ .use(connect.cookieParser('optional secret string'))
.use(function(req, res, next){
res.end(JSON.stringify(req.cookies));
})
</code></pre></div><ul class="tags"><li><em>String</em> secret </li><li>returns <em>Function</em> </li></ul><h3>Source</h3><pre><code>module.exports = function cookieParser(secret){
return function cookieParser(req, res, next) {
- var cookie = req.headers.cookie;
if (req.cookies) return next();
+ var cookies = req.headers.cookie;
req.secret = secret;
req.cookies = {};
req.signedCookies = {};
-
- if (cookie) {
+
+ if (cookies) {
try {
- req.cookies = utils.parseCookie(cookie);
+ req.cookies = cookie.parse(cookies);
if (secret) {
req.signedCookies = utils.parseSignedCookies(req.cookies, secret);
var obj = utils.parseJSONCookies(req.signedCookies);
- req.signedCookies = obj.cookies;
- req.cookieHashes = obj.hashes;
+ req.signedCookies = obj;
}
req.cookies = utils.parseJSONCookies(req.cookies);
} catch (err) {
View
@@ -3,38 +3,67 @@
<p>Cookie session middleware.</p>
<pre><code> var app = connect();
- app.use(connect.cookieParser('tobo!'));
- app.use(connect.cookieSession({ cookie: { maxAge: 60 * 60 * 1000 }}));
+ app.use(connect.cookieParser());
+ app.use(connect.cookieSession({ secret: 'tobo!', cookie: { maxAge: 60 * 60 * 1000 }}));
</code></pre>
<h2>Options</h2>
<ul>
<li><code>key</code> cookie name defaulting to <code>connect.sess</code></li>
+<li><code>secret</code> prevents cookie tampering</li>
<li><code>cookie</code> session cookie settings, defaulting to <code>{ path: '/', httpOnly: true, maxAge: null }</code></li>
<li><code>proxy</code> trust the reverse proxy when setting secure cookies (via "x-forwarded-proto")</li>
-</ul></div><ul class="tags"><li><em>Object</em> options </li><li>returns <em>Function</em> </li></ul><h3>Source</h3><pre><code>module.exports = function cookieSession(options){
- // TODO: utilize Session/Cookie to unify API
- // TODO: only set-cookie on changes to the session data
+</ul>
+
+<h2>Clearing sessions</h2>
+
+<p>To clear the session simply set its value to <code>null</code>,<br /> <code>cookieSession()</code> will then respond with a 1970 Set-Cookie.</p>
+<pre><code>req.session = null;
+</code></pre></div><ul class="tags"><li><em>Object</em> options </li><li>returns <em>Function</em> </li></ul><h3>Source</h3><pre><code>module.exports = function cookieSession(options){
+ // TODO: utilize Session/Cookie to unify API
var options = options || {}
, key = options.key || 'connect.sess'
- , cookie = options.cookie
, trustProxy = options.proxy;
return function cookieSession(req, res, next) {
- req.session = req.signedCookies[key] || {};
- req.session.cookie = new Cookie(req, cookie);
+
+ // req.secret is for backwards compatibility
+ var secret = options.secret || req.secret;
+ if (!secret) throw new Error('`secret` option required for cookie sessions');
+
+ // default session
+ req.session = {};
+ var cookie = req.session.cookie = new Cookie(options.cookie);
+
+ // pathname mismatch
+ if (0 != req.originalUrl.indexOf(cookie.path)) return next();
+
+ // cookieParser secret
+ if (!options.secret && req.secret) {
+ req.session = req.signedCookies[key] || {};
+ } else {
+ // TODO: refactor
+ var rawCookie = req.cookies[key];
+ if (rawCookie) {
+ var unsigned = utils.parseSignedCookie(rawCookie, secret);
+ if (unsigned) {
+ var originalHash = crc16(unsigned);
+ req.session = utils.parseJSONCookie(unsigned) || {};
+ }
+ }
+ }
res.on('header', function(){
// removed
if (!req.session) {
debug('clear session');
- res.setHeader('Set-Cookie', key + '=; expires=' + new Date(0).toUTCString());
+ cookie.expires = new Date(0);
+ res.setHeader('Set-Cookie', cookie.serialize(key, ''));
return;
}
- var cookie = req.session.cookie;
delete req.session.cookie;
// check security
@@ -49,14 +78,12 @@
debug('serializing %j', 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');
+ // compare hashes, no need to set-cookie if unchanged
+ if (originalHash == crc16(val)) return debug('unmodified session');
// set-cookie
- val = utils.sign(val, req.secret);
- val = utils.serializeCookie(key, val, cookie);
+ val = 's:' + utils.sign(val, secret);
+ val = cookie.serialize(key, val);
debug('set-cookie %j', cookie);
res.setHeader('Set-Cookie', val);
});
View
@@ -20,8 +20,8 @@
// generate CSRF token
var token = req.session._csrf || (req.session._csrf = utils.uid(24));
- // ignore GET & HEAD (for now)
- if ('GET' == req.method || 'HEAD' == req.method) return next();
+ // ignore these methods
+ if ('GET' == req.method || 'HEAD' == req.method || 'OPTIONS' == req.method) return next();
// determine value
var val = value(req);
View
@@ -19,6 +19,8 @@
, root = normalize(root);
return function directory(req, res, next) {
+ if ('GET' != req.method && 'HEAD' != req.method) return next();
+
var accept = req.headers.accept || 'text/plain'
, url = parse(req.url)
, dir = decodeURIComponent(url.pathname)
View
@@ -56,14 +56,14 @@
var pause = utils.pause(req);
callback(user, pass, function(err, user){
if (err || !user) return unauthorized(res, realm);
- req.user = user;
+ req.user = req.remoteUser = user;
next();
pause.resume();
});
// sync
} else {
if (callback(user, pass)) {
- req.user = user;
+ req.user = req.remoteUser = user;
next();
} else {
unauthorized(res, realm);
View
@@ -2,21 +2,17 @@
gzip: zlib.createGzip
, deflate: zlib.createDeflate
};</code></pre></div><div id="exports.filter" class="comment"><h2>exports.filter()</h2><div class="description"><p>Default filter function.</p></div><h3>Source</h3><pre><code>exports.filter = function(req, res){
- var type = res.getHeader('Content-Type') || '';
- return type.match(/json|text|javascript/);
+ return /json|text|javascript/.test(res.getHeader('Content-Type'));
};</code></pre></div><div id="module.exports" class="comment"><h2></h2><div class="description"><h2>Compress</h2>
<p>Compress response data with gzip/deflate.</p>
<h2>Filter</h2>
-<p>A <code>filter</code> callback function may be passed to</p>
-
-<h2>replace the default logic of</h2>
+<p>A <code>filter</code> callback function may be passed to<br /> replace the default logic of:</p>
<pre><code>exports.filter = function(req, res){
- var type = res.getHeader('Content-Type') || '';
- return type.match(/json|text|javascript/);
+ return /json|text|javascript/.test(res.getHeader('Content-Type'));
};
</code></pre>
@@ -50,7 +46,7 @@
res.write = function(chunk, encoding){
if (!this.headerSent) this._implicitHeader();
return stream
- ? stream.write(chunk, encoding)
+ ? stream.write(new Buffer(chunk, encoding))
: write.call(res, chunk, encoding);
};
@@ -103,7 +99,10 @@
stream.on('end', function(){
end.call(res);
});
-
+
+ stream.on('drain', function() {
+ res.emit('drain');
+ });
});
next();
Oops, something went wrong.

0 comments on commit 66d4503

Please sign in to comment.