Permalink
Browse files

tests.md

  • Loading branch information...
tj committed Mar 22, 2012
1 parent 0f27020 commit 90a725343c2945aaee637e799b1cd11e065b2bff
View
@@ -0,0 +1,73 @@
+<!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>Basic Auth</h2>
+
+<p>Enfore basic authentication by providing a <code>callback(user, pass)</code>,<br />which must return <code>true</code> in order to gain access. Alternatively an async<br />method is provided as well, invoking <code>callback(user, pass, callback)</code>. Populates<br /><code>req.user</code>. The final alternative is simply passing username / password<br />strings.</p>
+
+<p>Simple username and password</p>
+
+<pre><code>connect(connect.basicAuth('username', 'password'));
+</code></pre>
+
+<p>Callback verification</p>
+
+<pre><code>connect()
+ .use(connect.basicAuth(function(user, pass){
+ return 'tj' == user &amp; 'wahoo' == pass;
+ }))
+</code></pre>
+
+<p>Async callback verification, accepting <code>fn(err, user)</code>.</p>
+
+<pre><code>connect()
+ .use(connect.basicAuth(function(user, pass, fn){
+ User.authenticate({ user: user, pass: pass }, fn);
+ }))
+</code></pre></div><ul class="tags"><li><em>Function | String</em> callback or username</li><li><em>String</em> realm </li></ul><h3>Source</h3><pre><code>module.exports = function basicAuth(callback, realm) {
+ var username, password;
+
+ // user / pass strings
+ if ('string' == typeof callback) {
+ username = callback;
+ password = realm;
+ if ('string' != typeof password) throw new Error('password argument required');
+ realm = arguments[2];
+ callback = function(user, pass){
+ return user == username && pass == password;
+ }
+ }
+
+ realm = realm || 'Authorization Required';
+
+ return function(req, res, next) {
+ var authorization = req.headers.authorization;
+
+ if (req.user) return next();
+ if (!authorization) return unauthorized(res, realm);
+
+ var parts = authorization.split(' ')
+ , scheme = parts[0]
+ , credentials = new Buffer(parts[1], 'base64').toString().split(':')
+ , user = credentials[0]
+ , pass = credentials[1];
+
+ if ('Basic' != scheme) return next(utils.error(400));
+
+ // async
+ if (callback.length >= 3) {
+ var pause = utils.pause(req);
+ callback(user, pass, function(err, user){
+ if (err || !user) return unauthorized(res, realm);
+ req.user = user;
+ next();
+ pause.resume();
+ });
+ // sync
+ } else {
+ if (callback(user, pass)) {
+ req.user = user;
+ next();
+ } else {
+ unauthorized(res, realm);
+ }
+ }
+ }
+};</code></pre></div></div><ul id="menu"><li><a href="#module.exports"></a></li></ul></body></html>
View
@@ -0,0 +1,38 @@
+<!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="" class="comment"><h2></h2><div class="description"><h2>Body parser</h2>
+
+<p>Parse request bodies, supports <em>application/json</em>,<br /> <em>application/x-www-form-urlencoded</em>, and <em>multipart/form-data</em>.</p>
+
+<p>This is equivalent to: </p>
+
+<pre><code>app.use(connect.json());
+app.use(connect.urlencoded());
+app.use(connect.multipart());
+</code></pre>
+
+<h2>Examples</h2>
+
+<pre><code> connect()
+ .use(connect.bodyParser())
+ .use(function(req, res) {
+ res.end('viewing user ' + req.body.user.name);
+ });
+
+ $ curl -d 'user[name]=tj' <a href='http://local/'>http://local/</a>
+ $ curl -d '{"user":{"name":"tj"}}' -H "Content-Type: application/json" <a href='http://local/'>http://local/</a>
+</code></pre>
+
+<p>View <a href="json.html">json</a>, <a href="urlencoded.html">urlencoded</a>, and <a href="multipart.html">multipart</a> for more info.</p></div><ul class="tags"><li><em>Object</em> options </li><li>returns <em>Function</em> </li></ul><h3>Source</h3><pre><code>exports = module.exports = function bodyParser(options){
+ var _urlencoded = urlencoded(options)
+ , _multipart = multipart(options)
+ , _json = json(options);
+
+ return function bodyParser(req, res, next) {
+ _json(req, res, function(err){
+ if (err) return next(err);
+ _urlencoded(req, res, function(err){
+ if (err) return next(err);
+ _multipart(req, res, next);
+ });
+ });
+ }
+};</code></pre></div></div><ul id="menu"><li><a href="#"></a></li></ul></body></html>
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
@@ -0,0 +1,111 @@
+<!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.methods" class="comment"><h2>exports.methods</h2><div class="description"><p>Supported content-encoding methods.</p></div><h3>Source</h3><pre><code>exports.methods = {
+ 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/);
+};</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>
+
+<pre><code>exports.filter = function(req, res){
+ var type = res.getHeader('Content-Type') || '';
+ return type.match(/json|text|javascript/);
+};
+</code></pre>
+
+<h2>Options</h2>
+
+<p>All remaining options are passed to the gzip/deflate<br /> creation functions. Consult node's docs for additional details.</p>
+
+<ul>
+<li><code>chunkSize</code> (default: 16*1024)</li>
+<li><code>windowBits</code></li>
+<li><code>level</code>: 0-9 where 0 is no compression, and 9 is slow but best compression</li>
+<li><code>memLevel</code>: 1-9 low is slower but uses less memory, high is fast but uses more</li>
+<li><code>strategy</code>: compression strategy</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 compress(options) {
+ var options = options || {}
+ , names = Object.keys(exports.methods)
+ , filter = options.filter || exports.filter;
+
+ return function(req, res, next){
+ var accept = req.headers['accept-encoding']
+ , write = res.write
+ , end = res.end
+ , stream
+ , method;
+
+ // vary
+ res.setHeader('Vary', 'Accept-Encoding');
+
+ // proxy
+
+ res.write = function(chunk, encoding){
+ if (!this.headerSent) this._implicitHeader();
+ return stream
+ ? stream.write(chunk, encoding)
+ : write.call(res, chunk, encoding);
+ };
+
+ res.end = function(chunk, encoding){
+ if (chunk) this.write(chunk, encoding);
+ return stream
+ ? stream.end()
+ : end.call(res);
+ };
+
+ res.on('header', function(){
+ // default request filter
+ if (!filter(req, res)) return;
+
+ // SHOULD use identity
+ if (!accept) return;
+
+ // head
+ if ('HEAD' == req.method) return;
+
+ // default to gzip
+ if ('*' == accept.trim()) method = 'gzip';
+
+ // compression method
+ if (!method) {
+ for (var i = 0, len = names.length; i < len; ++i) {
+ if (~accept.indexOf(names[i])) {
+ method = names[i];
+ break;
+ }
+ }
+ }
+
+ // compression method
+ if (!method) return;
+
+ // compression stream
+ stream = exports.methods[method](options);
+
+ // header fields
+ res.setHeader('Content-Encoding', method);
+ res.removeHeader('Content-Length');
+
+ // compression
+
+ stream.on('data', function(chunk){
+ write.call(res, chunk);
+ });
+
+ stream.on('end', function(){
+ end.call(res);
+ });
+
+ });
+
+ next();
+ };
+}</code></pre></div></div><ul id="menu"><li><a href="#exports.methods">exports.methods</a></li><li><a href="#exports.filter">exports.filter()</a></li><li><a href="#module.exports"></a></li></ul></body></html>
View
@@ -0,0 +1,16 @@
+<!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.0alpha1';</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);
+ 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>
View
@@ -0,0 +1,35 @@
+<!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>
+
+<h2>Examples</h2>
+
+<pre><code>connect()
+ .use(connect.cookieParser('keyboard cat'))
+ .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();
+
+ req.secret = secret;
+ req.cookies = {};
+ req.signedCookies = {};
+
+ if (cookie) {
+ try {
+ req.cookies = utils.parseCookie(cookie);
+ if (secret) {
+ req.signedCookies = utils.parseSignedCookies(req.cookies, secret);
+ req.signedCookies = utils.parseJSONCookies(req.signedCookies);
+ }
+ req.cookies = utils.parseJSONCookies(req.cookies);
+ } catch (err) {
+ return next(err);
+ }
+ }
+ next();
+ };
+};</code></pre></div></div><ul id="menu"><li><a href="#module.exports"></a></li></ul></body></html>
View
@@ -0,0 +1,59 @@
+<!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 Session</h2>
+
+<p>Cookie session middleware.</p>
+
+<pre><code> var app = connect();
+ app.use(connect.cookieParser('tobo!'));
+ app.use(connect.cookieSession({ 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>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
+
+ 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);
+
+ res.on('header', function(){
+ // removed
+ if (!req.session) {
+ debug('clear session');
+ res.setHeader('Set-Cookie', key + '=; expires=' + new Date(0).toUTCString());
+ return;
+ }
+
+ var cookie = req.session.cookie;
+ delete req.session.cookie;
+
+ // check security
+ var proto = (req.headers['x-forwarded-proto'] || '').toLowerCase()
+ , tls = req.connection.encrypted || (trustProxy && 'https' == proto)
+ , secured = cookie.secure && tls;
+
+ // only send secure cookies via https
+ if (cookie.secure && !secured) return debug('not secured');
+
+ // set cookie
+ debug('serializing %j', req.session);
+ var val = 'j:' + JSON.stringify(req.session);
+ val = utils.sign(val, req.secret);
+ val = utils.serializeCookie(key, val, cookie);
+ debug('cookie %j', cookie);
+ res.setHeader('Set-Cookie', val);
+ });
+
+ next();
+ };
+};</code></pre></div></div><ul id="menu"><li><a href="#module.exports"></a></li></ul></body></html>
Oops, something went wrong.

0 comments on commit 90a7253

Please sign in to comment.