ConnectHigh performance middleware for node. | |
bodyDecoder | lib/connect/middleware/bodyDecoder.js |
Module dependencies.
|
var queryString = require('querystring');
|
Supported decoders.
- application/x-www-form-urlencoded
- application/json
|
exports.decode = {
'application/x-www-form-urlencoded': queryString.parse,
'application/json': JSON.parse
};
|
Decode request bodies.
return: Function
api: public
|
module.exports = function bodyDecoder(){
return function handle(req, res, next) {
var decoder = exports.decode[mime(req)];
if (decoder) {
var data = '';
req.setEncoding('utf8');
req.addListener('data', function(chunk) { data += chunk; });
req.addListener('end', function() {
req.rawBody = data;
try {
req.body = data
? decoder(data)
: {};
} catch (err) {
return next(err);
}
next();
});
} else {
next();
}
}
};
|
cache | lib/connect/middleware/cache.js |
Module dependencies.
|
var Buffer = require('buffer').Buffer;
|
Cache in memory for the given cacheDuration .
|
module.exports = function cache(cacheDuration){
var cache = {},
queue = {};
return function handle(req, res, next) {
if (req.method !== "GET") {
next();
return;
}
var key = req.headers["accept-encoding"] + req.url,
writeHead = res.writeHead,
write = res.write,
end = res.end,
code,
headers,
chunks = [],
totalSize = 0;
function serve() {
var resp = cache[key];
var headers = resp.headers;
headers["Date"] = (new Date).toUTCString();
headers["Content-Length"] = resp.body.length;
if (localQueue) {
for (var i = 0, l = localQueue.length; i < l; i++) {
var localRes = localQueue[i];
localRes.writeHead(resp.code, headers);
localRes.end(resp.body);
}
delete queue[key];
} else {
res.writeHead(resp.code, headers);
res.end(resp.body);
}
}
if (cache[key]) {
serve();
return;
}
var localQueue = queue[key];
if (localQueue) {
localQueue[localQueue.length] = res;
return;
}
localQueue = queue[key] = [res];
res.writeHead = function (setCode, setHeaders) {
code = setCode;
headers = setHeaders;
};
res.write = function (chunk, encoding) {
if (typeof chunk === 'string') {
var length;
if (!encoding || encoding === 'utf8') {
length = Buffer.byteLength(chunk);
}
var buffer = new Buffer(length);
buffer.write(chunk, encoding);
chunks.push(buffer);
} else {
chunks.push(chunk);
}
totalSize += chunk.length;
};
res.end = function (chunk, encoding) {
if (chunk) {
res.write(chunk, encoding);
}
var body = new Buffer(totalSize);
var offset = 0;
chunks.forEach(function (chunk) {
chunk.copy(body, offset);
offset += chunk.length;
});
cache[key] = {
body: body,
code: code,
headers: headers
};
res.writeHead = writeHead;
res.write = write;
res.end = end;
serve();
if (cacheDuration) {
setTimeout(function(){
delete cache[key];
}, cacheDuration);
} else {
delete cache[key];
}
};
next();
};
};
|
cacheManifest | lib/connect/middleware/cacheManifest.js |
Module dependencies.
|
var fs = require('fs'),
Utils = require('../utils'),
Url = require('url'),
Path = require('path');
|
Generate cache manifest for the given root , networks ,
and fallbacks .
param: String root
param: Array networks
param: Array fallbacks
return: Function
api: public
|
module.exports = function cacheManifest(root, networks, fallbacks) {
root = root || process.cwd();
var suffix = "";
if (networks) {
suffix += "\n\nNETWORK:\n" + networks.join("\n");
}
if (fallbacks) {
suffix += "\n\nFALLBACK:\n" +
fallbacks.map(function (second, first) {
return first + " " + second;
}).join("\n");
}
return function handle(req, res, next) {
if (Url.parse(req.url).pathname === "/cache.manifest") {
Utils.find(root, (/./), function (err, files) {
var latestMtime = 0;
files = files.map(function (entry) {
if (entry.mtime > latestMtime) {
latestMtime = entry.mtime;
}
return entry.path.substr(1);
});
var manifest = "CACHE MANIFEST\n"
+ "# " + latestMtime.toUTCString() + "\n"
+ files.join("\n")
+ suffix;
res.writeHead(200, {
"Content-Type": "text/cache-manifest",
"Last-Modified": latestMtime.toUTCString(),
"Content-Length": manifest.length
});
res.end(manifest);
});
return;
}
next();
};
};
|
conditionalGet | lib/connect/middleware/conditionalGet.js |
Conditional GET request support.
return: Function
api: public
|
module.exports = function conditionalGet(){
return function handle(req, res, next) {
if (!(req.method === "GET" &&
(req.headers["if-modified-since"] || req.headers["if-none-match"])
)) {
next();
return;
}
var since = req.headers["if-modified-since"],
oldEtag = req.headers["if-none-match"],
writeHead = res.writeHead,
write = res.write,
end = res.end;
since = since && Date.parse(since).valueOf();
res.writeHead = function (code, headers) {
var lastModified = headers["Last-Modified"],
etag = headers["Etag"];
lastModified = lastModified && Date.parse(lastModified).valueOf();
if (!(code === 200 &&
(lastModified === since || oldEtag === etag)
)) {
res.writeHead = writeHead;
res.writeHead(code, headers);
return;
}
res.write = function () {};
res.end = function () {
res.writeHead = writeHead;
res.write = write;
res.end = end;
var newHeaders = {};
headers.forEach(function (value, key) {
if (key.indexOf("Content") < 0) {
newHeaders[key] = value;
}
});
res.writeHead(304, newHeaders);
res.end();
};
};
next();
};
};
|
compiler | lib/connect/middleware/compiler.js |
Module dependencies.
|
var fs = require('fs'),
path = require('path');
|
Bundled compilers:
,P
|
var compilers = exports.compilers = {
sass: {
match: /\.css$/,
ext: '.sass',
compile: function(str, fn){
try {
var css = require('sass').render(str);
} catch (err) {
return fn(err);
}
fn(null, css);
}
},
less: {
match: /\.css$/,
ext: '.less',
compile: function(str, fn){
try {
require('less').render(str, fn);
} catch (err) {
fn(err);
}
}
}
};
|
Setup compiler.
Options
src Source directory, defaults to CWD.
dest Destination directory, defaults src .
enable Array of enabled compilers.
Compilers
sass Compiles cass to css
less Compiles less to css
param: Object options
api: public
|
module.exports = function compiler(options){
options = options || {};
var srcDir = process.connectEnv.compilerSrc || options.src || process.cwd(),
destDir = process.connectEnv.compilerDest || options.desc || srcDir,
enable = options.enable;
if (!enable || enable.length === 0) {
throw new Error(s "enable" option is not set, nothing will be compiled.');
}
return function(req, res, next){
for (var i = 0, len = enable.length; i < len; ++i) {
var name = enable[i],
compiler = compilers[name];
if (compiler.match.test(req.url)) {
var src = (srcDir + req.url).replace(compiler.match, compiler.ext),
dest = destDir + req.url;
fs.stat(src, function(err, srcStats){
if (err) {
if (err.errno === process.ENOENT) {
res.writeHead(404, { 'Content-Type': 'text/plain' });
res.end('Not Found');
} else {
next(err);
}
} else {
fs.stat(dest, function(err, destStats){
if (err) {
if (err.errno === process.ENOENT) {
compile();
} else {
next(err);
}
} else {
if (srcStats.mtime > destStats.mtime) {
compile();
} else {
next();
}
}
})
}
});
function compile() {
fs.readFile(src, 'utf8', function(err, str){
if (err) {
next(err);
} else {
compiler.compile(str, function(err, str){
if (err) {
next(err);
} else {
fs.writeFile(dest, str, 'utf8', function(err){
next(err);
});
}
});
}
});
}
return;
}
}
next();
};
};
|
cookieDecoder | lib/connect/middleware/cookieDecoder.js |
Module dependencies.
|
var utils = require('./../utils');
|
Parse Cookie header and populate req.cookies .
return: Function
api: public
|
module.exports = function(){
return function handle(req, res, next) {
var cookie = req.headers.cookie;
req.cookies = {};
if (cookie) {
process.nextTick(function(){
try {
req.cookies = utils.parseCookie(cookie);
delete req.headers.cookie;
} catch (err) {
}
next();
});
} else {
next();
}
};
};
|
errorHandler | lib/connect/middleware/errorHandler.js |
Module dependencies.
|
var utils = require('./../utils'),
sys = require('sys'),
fs = require('fs');
|
Setup error handler with the given options .
Options
showStack respond with both the error message and stack trace. Defaults to false
showMessage respond with the exception message only. Defaults to false
dumpExceptions dump exceptions to stderr (without terminating the process). Defaults to false
param: Object options
return: Function
api: public
|
module.exports = function errorHandler(options){
options = options || {};
var showStack = options.showStack,
showMessage = options.showMessage,
dumpExceptions = options.dumpExceptions;
if (process.connectEnv.showErrorStack !== undefined) {
showStack = op = utils.toBoolean(process.connectEnv.showErrorStack);
}
if (process.connectEnv.showErrorMessage !== undefined) {
showMessage = utils.toBoolean(process.connectEnv.showErrorMessage);
}
if (process.connectEnv.dumpExceptions !== undefined) {
dumpExceptions = utils.toBoolean(process.connectEnv.dumpExceptions);
}
return function(err, req, res, next){
if (dumpExceptions) {
sys.error(err.stack);
}
if (showStack) {
var accept = req.headers.accept || '';
if (accept.indexOf('html') !== -1) {
fs.readFile(__dirname + '/../public/style.css', function(e, style){
style = style.toString('ascii');
fs.readFile(__dirname + '/../public/error.html', function(e, html){
var stack = err.stack
.split('\n').slice(1)
.map(function(v){ return '' + v + ''; }).join('');
html = html
.toString('utf8')
.replace('{style}', style)
.replace('{stack}', stack)
.replace(/\{error\}/g, err.toString());
res.writeHead(500, { 'Content-Type': 'text/html' });
res.end(html);
});
});
} else if (accept.indexOf('json') !== -1) {
var json = JSON.stringify({ error: err });
res.writeHead(500, { 'Content-Type': 'application/json' });
res.end(json);
} else {
res.writeHead(500, { 'Content-Type': 'application/json' });
res.end(err.stack);
}
} else {
var body = showMessage
? err.toString()
: 'Internal Server Error';
res.writeHead(500, { 'Content-Type': 'text/plain' });
res.end(body);
}
};
};
|
flash | lib/connect/middleware/flash.js |
Module dependencies.
|
var utils = require('./../utils');
|
Provide req.flash() .
return: Function
api: public
|
module.exports = function flash(){
return function handle(req, res, next) {
|
Queue flash msg of the given type .
Examples
req.flash('info', 'email sent');
req.flash('error', 'email delivery failed');
req.flash('info', 'email re-sent');
// => 2
req.flash('info');
// => ['email sent', 'email re-sent']
req.flash('info');
// => []
req.flash();
// => { error: ['email delivery failed'], info: [] }
|
req.flash = function(type, msg){
var msgs = this.session.flash = this.session.flash || {};
if (type && msg) {
msg = utils.miniMarkdown(utils.htmlEscape(msg));
return (msgs[type] = msgs[type] || []).push(msg);
} else if (type) {
var arr = msgs[type];
delete msgs[type];
return arr || [];
} else {
this.session.flash = {};
return msgs;
}
};
next();
};
};
|
| lib/connect/middleware/format.js |
Module dependencies.
|
var connect = require('./../index'),
sys = require('sys');
|
Extract url “formats” aka extensions from the request
url, and assigns req.format .
Examples
// curl http://localhost:3000/users.json
handle: function(req, res, next){
switch (req.format) {
case 'json':
sys.puts(req.url);
// => "users"
// respond with json
break;
default:
// respond with your default format
}
}
return: Function
api: public
|
module.exports = function format(){
return function handle(req, res, next) {
if (/\.(\w+)($|#|\?)/.exec(req.url)) {
req.format = RegExp.$1;
req.url = req.url.replace('.' + req.format, '');
}
next();
};
};
|
gzip | lib/connect/middleware/gzip.js |
Module dependencies.
|
var child_process = require('child_process'),
sys = require('sys');
|
Provides gzip compression via the gzip executable.
return: Function
api: public
|
module.exports = function gzip(){
return function handle(req, res, next) {
var writeHead = res.writeHead,
write = res.write,
end = res.end;
res.writeHead = function (code, headers) {
var type = headers["Content-Type"],
accept = req.headers["accept-encoding"];
if (!(code === 200 && accept && accept.indexOf('gzip') >= 0
&& type && (/(text|javascript|json)/).test(type))) {
res.writeHead = writeHead;
res.writeHead(code, headers);
return;
}
headers["Content-Encoding"] = "gzip";
delete headers["Content-Length"];
var gzip = child_process.spawn("gzip", ["-9"]);
res.write = function (chunk, encoding) {
gzip.stdin.write(chunk, encoding);
};
res.end = function (chunk, encoding) {
if (chunk) {
res.write(chunk, encoding);
}
gzip.stdin.end();
};
gzip.stdout.addListener('data', function (chunk) {
write.call(res, chunk);
});
gzip.addListener("exit", function (code) {
res.write = write;
res.end = end;
res.end();
});
res.writeHead = writeHead;
res.writeHead(code, headers);
};
next();
};
};
|
jsonrpc | lib/connect/middleware/jsonrpc.js |
Module dependencies.
|
var sys = require('sys'),
parse = require('url').parse,
Buffer = require('buffer').Buffer,
http = require('http');
|
Export the setup() function.
|
exports = module.exports = jsonrpc;
|
JSON-RPC version.
|
var VERSION = exports.VERSION = '2.0';
|
JSON parse error.
|
var PARSE_ERROR = exports.PARSE_ERROR = -32700;
|
Invalid request due to invalid or missing properties. - **
|
var INVALID_REQUEST = exports.INVALID_REQUEST = -32600;
|
Service method does not exist. sing proper
|
var METHOD_NOT_FOUND = exports.METHOD_NOT_FOUND = -32601;
|
Invalid parameters.
|
var INVALID_PARAMS = exports.INVALID_PARAMS = -32602;
|
Internal JSON-RPC error.
|
var INTERNAL_ERROR = exports.INTERNAL_ERROR = -32603;
|
Default error messages.
|
var errorMessages = exports.errorMessages = {};
errorMessages[PARSE_ERROR] = 'Parse Error.';
errorMessages[INVALID_REQUEST] = 'Invalid Request.';
errorMessages[METHOD_NOT_FOUND] = 'Method Not Found.';
errorMessages[INVALID_PARAMS] = 'Invalid Params.';
errorMessages[INTERNAL_ERROR] = 'Internal Error.';
|
Accepts any number of objects, exposing their methods.
param: Object …
return: Function
api: public
f�Q
|
function jsonrpc(services) {
services = services || {};
for (var i = 0, len = arguments.length; i < len; ++i) {
arguments[i].forEach(function(val, key){
services[key] = val;
});
}
|
Handle JSON-RPC request.
param: Object rpc
param: Function respond
|
function handleRequest(rpc, respond){
if (validRequest(rpc)) {
var method = services[rpc.method];
if (typeof method === 'function') {
var params = [];
if (rpc.params instanceof Array) {
params = rpc.params;
} else if (typeof rpc.params === 'object') {
var names = method.toString().match(/\((.*?)\)/)[1].match(/[\w]+/g);
if (names) {
for (var i = 0, len = names.length; i < len; ++i) {
params.push(rpc.params[names[i]]);
}
} else {
return respond({ error: { code: INVALID_PARAMS, message: 'This service does not support named parameters.' }});
}
}
function reply(err, result){
if (err) {
if (typeof err === 'number') {
respond({
error: {
code: err
}
});
} else {
respond({
error: {
code: err.code || INTERNAL_ERROR,
message: err.message
}
});
}
} else {
respond({
result: result
});
}
}
method.apply(reply, params);
} else {
respond({ error: { code: METHOD_NOT_FOUND }});
}
} else {
respond({ error: { code: INVALID_REQUEST }});
}
}
return function handle(req, res, next) {
var me = this,
contentType = req.headers['content-type'] || '';
if (req.method === 'POST' && contentType === 'application/json') {
var data = '';
req.setEncoding('utf8');
req.addListener('data', function(chunk) { data += chunk; });
req.addListener('end', function() {
try {
var rpc = JSON.parse(data),
batch = rpc instanceof Array;
} catch (err) {
return respond(normalize(rpc, { error: { code: PARSE_ERROR }}));
}
|
Normalize response object.
|
function normalize(rpc, obj) {
obj.id = rpc && typeof rpc.id === 'number'
? rpc.id
: null;
obj.jsonrpc = VERSION;
if (obj.error && !obj.error.message) {
obj.error.message = errorMessages[obj.error.code];
}
return obj;
}
|
Respond with the given response object.
|
function respond(obj) {
var body = JSON.stringify(obj);
res.writeHead(200, {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(body)
});
res.end(body);
}
if (batch) {
var responses = [],
len = rpc.length,
pending = len;
for (var i = 0; i < len; ++i) {
(function(rpc){
handleRequest.call(me, rpc, function(obj){
responses.push(normalize(rpc, obj));
if (!--pending) {
respond(responses);
}
});
})(rpc[i]);
}
} else {
handleRequest.call(me, rpc, function(obj){
respond(normalize(rpc, obj));
});
}
});
} else {
next();
}
};
};
|
lint | lib/connect/middleware/lint.js |
Module dependencies.
|
var connect = require('./../index'),
sys = require('sys');
|
Setup lint for the given server .
return: Function
api: public
|
module.exports = function lint(server){
if (!server) {
throw new Error('lint "server" must be passed.');
}
if (process.connectEnv.name !== 'development') {
warn('"lint" middleware should never be enabled outside of the development environment');
}
checkStack(server.stack);
return function(req, res, next){
next();
}
};
|
logger | lib/connect/middleware/logger.js |
Log requests with the given options .
Options
format Format string, see below for tokens
stream Output stream, defaults to stdout
Tokens
:req[header] ex: :req[Accept]
:res[header] ex: :res[Content-Length]
:http-version
:response-time
:remote-addr
:date
:method
:url
:referrer
:user-agent
:status
return: Function
api: public
|
module.exports = function logger(options) {
options = options || {};
var format = process.connectEnv.logFormat || options.format,
stream = options.stream || process.stdout;
return function handle(req, res, next) {
var start = +new Date,
statusCode,
resHeaders,
writeHead = res.writeHead,
end = res.end,
url = req.url;
res.writeHead = function(code, headers){
res.writeHead = writeHead;
res.writeHead(code, headers);
res.statusCode = statusCode = code;
res.headers = resHeaders = headers;
};
if (format) {
res.end = function(chunk, encoding) {
res.end = end;
res.end(chunk, encoding);
res.responseTime = +new Date - start;
stream.write(format(format, req, res) + '\n', 'ascii');
};
} else {
res.end = function(chunk, encoding) {
res.end = end;
res.end(chunk, encoding);
stream.write((req.socket && req.socket.remoteAddress)
+ ' - - [' + (new Date).toUTCString() + ']'
+ ' "' + req.method + ' ' + url
+ ' HTTP/' + req.httpVersionMajor + '.' + req.httpVersionMinor + '" '
+ statusCode + ' ' + (resHeaders['Content-Length'] || '-')
+ ' "' + (req.headers['referer'] || req.headers['referrer'] || '')
+ '" "' + (req.headers['user-agent'] || '') + '"\n', 'ascii');
};
}
next();
};
};
|
methodOverride | lib/connect/middleware/methodOverride.js |
Module dependencies.
|
var queryString = require('querystring');
|
Valid http methods.
|
var methods = ['GET', 'POST', 'PUT', 'HEAD', 'DELETE', 'OPTIONS'];
|
Pass an optional key to use when checking for
a method override, othewise defaults to _method.
param: String key
return: Function
api: public
|
module.exports = function methodOverride(key){
key = key || "_method";
return function(req, res, next) {
if (typeof req.body === 'object' && key in req.body) {
var method = req.body[key].toUpperCase();
if (methods.indexOf(method) >= 0) {
req.method = method;
delete req.body[key];
}
}
next();
};
};
|
pubsub | lib/connect/middleware/pubsub.js |
Module dependencies.
|
var sys = require('sys');
|
Subscriber cache.
|
var cache = {};
|
redirect | lib/connect/middleware/redirect.js |
Module dependencies.
|
var connect = require('./../index'),
sys = require('sys');
|
Provide res.redirect() .
Examples
// Absolute
res.redirect('http://google.com');
// Relative + custom status
res.redirect('/foo', 301);
// Referr?er
res.redirect('back');
return: Function
api: public
`:
|
module.exports = function redirect(){
return function handle(req, res, next) {
var map = {
back: req.headers.referrer || req.headers.referer
};
res.redirect = function(url, code){
this.writeHead(code || 302, {
'Location': map[url] || url
});
this.end();
};
next();
};
};
|
repl | lib/connect/middleware/repl.js |
Module dependencies.
|
var net = require('net'),
repl = require('repl');
|
Start a REPL on the given unix domain socket path.
Options
-
sockect Unix domain socket path. Defaults to “/tmp/connect.sock”
-
prompt REPL prompt string. Defaults to “node> ”
Example
$ rlwrap telnet /tmp/connect.sock
|
module.exports = function repl(prompt, socket){
prompt = process.connectEnv.replPrompt || prompt || 'node> ';
socket = process.connectEnv.replSocket || socket || '/tmp/connect.sock';
net.createServer(function (stream) {
repl.start(prompt, stream);
}).listen(socket);
return function(req, res, next){
next();
}
};
|
responseTime | lib/connect/middleware/responseTime.js |
Responds with the X-Response-Time header in milliseconds.
return: Function
api: public
Q
|
module.exports = function responseTime(){
return function(req, res, next){
var start = new Date,
writeHead = res.writeHead;
res.writeHead = function(code, headers){
res.writeHead = writeHead;
headers['X-Response-Time'] = (new Date - start) + "ms";
res.writeHead(code, headers);
};
next();
};
};
|
router | lib/connect/middleware/router.js |
Module dependencies.
|
var parse = require('url').parse;
|
Provides Sinatra and Express like routing capabilities.
Examples
connect.router(function(app){
app.get('/user/:id', function(req, res, params){
// populates params.id
});
})
param: Function fn
return: Function
api: public
|
module.exports = function router(fn){
var routes;
if (fn) {
routes = {};
fn.call(this, {
post: method.call(this, 'post'),
get: method.call(this, 'get'),
put: method.call(this, 'put'),
del: method.call(this, 'del')
});
} else {
throw new Error('router provider requires a callback function');
}
function method(name) {
var self = this,
localRoutes = routes[name] = routes[name] || [];
return function(path, fn){
var keys = [];
path = path instanceof RegExp
? path
: normalizePath(path, keys);
localRoutes.push(fn, path, keys);
return self;
};
}
return function(req, res, next){
var self = this;
process.nextTick(function(){
var route;
if (route = match(req, routes)) {
req.params = req.params || {};
req.params.path = route._params;
route.call(self, req, res, route._params);
} else {
next();
}
});
};
}
|
memory | lib/connect/middleware/session/memory.js |
Module dependencies.
|
var sys = require('sys'),
utils = require('./../../utils'),
Store = require('./store').Store,
Session = require('./session').Session;
|
Initialize MemoryStore with the given options.
param: Object options
api: public
|
var MemoryStore = exports.MemoryStore = function MemoryStore(options) {
this.sessions = {};
options = options || {};
this.key = 'connect.sid';
this.reapInterval = options.reapInterval || 600000;
this.maxAge = options.maxAge || 14400000;
this.cookie = utils.merge({ path: '/', httpOnly: true }, options.cookie);
if (this.reapInterval !== -1) {
setInterval(function(self){
self.reap(self.maxAge);
}, this.reapInterval, this);
}
};
sys.inherits(MemoryStore, Store);
|
Destroy session for the given request.
|
MemoryStore.prototype.destroy = function(req, fn){
var key = this.fingerprint(req.session.id, req),
destroyed = key in this.sessions;
delete this.sessions[key];
fn && fn(null, destroyed);
};
|
Fetch Session for the given request.
|
MemoryStore.prototype.fetch = function(req, fn){
var sid = req.cookies[this.key],
key = this.fingerprint(sid, req);
if (sid && this.sessions[key]) {
fn(null, this.sessions[key]);
} else {
fn();
}
};
|
Commit the given request’s session.
|
MemoryStore.prototype.commit = function(req, fn){
var key = this.fingerprint(req.session.id, req);
this.sessions[key] = req.session;
fn && fn();
};
|
Clear all sessions.
param: Function fn
api: public
|
MemoryStore.prototype.clear = function(fn){
this.sessions = {};
fn && fn();
};
|
Fetch number of sessions.
param: Function fn
api: public
|
MemoryStore.prototype.length = function(fn){
fn(null, Object.keys(this.sessions).length);
};
|
session | lib/connect/middleware/session/session.js |
Module dependencies.
|
var utils = require('./../../utils');
|
Initialize Session with the given sid.
param: String sid
api: public
�dQ
|
var Session = exports.Session = function Session(sid) {
this.id = sid;
this.touch();
};
|
Update lastAccess timestamp.
|
Session.prototype.touch = function(){
this.lastAccess = +new Date;
};
|
store | lib/connect/middleware/session/store.js |
Module dependencies.
|
var Session = require('./session').Session,
utils = require('./../../utils');
|
Fetch session for the given request.
p><
|
Store.prototype.fetch = function(req, fn){
throw new Error(this.constructor.name + ' does not implement #fetch().');
};
|
Commit the given request’s session.
|
Store.prototype.commit = function(req, fn){
throw new Error(this.constructor.name + ' does not implement #commit().');
};
|
Clear all sessions.
param: Function fn
api: public
|
Store.prototype.clear = function(fn){
throw new Error(this.constructor.name + ' does not implement #clear().');
};
|
Destroy session for the given request.
|
Store.prototype.destroy = function(req, fn){
throw new Error(this.constructor.name + ' does not implement #destroy().');
};
|
Re-generate the given requests’s session.
|
Store.prototype.regenerate = function(req, fn){
this.destroy(req, function(){
req.session = req.sessionStore.createSession();
fn.apply(this, arguments);
});
};
|
Fetch number of sessions.
param: Function fn
api: public
tion
|
Store.prototype.length = function(fn){
throw new Error(this.constructor.name + ' does not implement #length().');
};
|
Create a new Session instance.
return: Session
api: public
|
Store.prototype.createSession = function(){
return new Session(utils.uid());
};
|
session | lib/connect/middleware/session.js |
Module dependencies.
|
var MemoryStore = require('./session/memory').MemoryStore,
utils = require('./../utils');
|
Setup session store with the given options .
Options
store Session store instance
fingerprint Custom fingerprint hashing function
param: Object options
return: Function
api: public
|
module.exports = function session(options){
options = options || {};
store = options.store || new MemoryStore;
store.fingerprint = options.fingerprint || function(sid, req){
return sid
+ req.socket.remoteAddress
+ (req.headers['user-agent'] || '');
};
return function(req, res, next){
req.sessionStore = store;
if (req.cookies) {
var writeHead = res.writeHead;
res.writeHead = function(status, headers){
headers = headers || {};
res.writeHead = writeHead;
store.commit(req);
store.cookie.expires = new Date(+new Date() + store.maxAge);
headers['Set-Cookie'] = utils.serializeCookie(store.key, req.session.id, store.cookie);
return res.writeHead(status, headers);
};
store.fetch(req, function(err, sess){
req.session = sess || store.createSession();
req.session.touch();
next(err);
});
} else {
next();
}
}
};
|
staticProvider | lib/connect/middleware/staticProvider.js |
Module dependencies.
|
var fs = require('fs'),
Url = require('url'),
Buffer = require('buffer').Buffer,
Path = require('path'),
utils = require('./../utils');
|
Browser cache lifetime of one hour.
|
var lifetime = 1000 * 60 * 60;
|
Static file server.
Options
root Root path from which to serve static files.
param: String root
return: Function
api: public
Q
|
module.exports = function staticProvider(root){
root = process.connectEnv.staticRoot || root || process.cwd();
return function handle(req, res, next) {
var url = Url.parse(req.url);
var pathname = url.pathname.replace(/\.\.+/g, '.'),
filename = Path.join(root, pathname);
if (filename[filename.length - 1] === "/") {
filename += "index.html";
}
var events = [];
function onData() {
events.push(["data"].concat(toArray(arguments)));
}
function onEnd() {
events.push(["end"].concat(toArray(arguments)));
}
req.addListener("data", onData);
req.addListener("end", onEnd);
fs.stat(filename, function (err, stat) {
req.removeListener("data", onData);
req.removeListener("end", onEnd);
if (err) {
if (err.errno === process.ENOENT) {
next();
for (var i = 0, len = events.length; i < len; ++i) {
req.emit.apply(req, events[i]);
}
return;
}
next(err);
return;
}
function onRead(err, data) {
if (err) {
next(err);
return;
}
if (typeof data === 'string') {
var b = new Buffer(data.length);
b.write(data, "binary");
data = b;
}
res.writeHead(200, {
"Content-Type": utils.mime.type(filename),
"Content-Length": data.length,
"Last-Modified": stat.mtime.toUTCString(),
"Cache-Control": "public max-age=" + 31536000
});
res.end(data);
}
if (process.version < "0.1.95") {
fs.readFile(filename, "binary", onRead);
} else {
fs.readFile(filename, onRead);
}
});
};
};
|
vhost | lib/connect/middleware/vhost.js |
Setup vhost for the given hostname and server .
Examples
connect.createServer(
connect.vhost('foo.com',
connect.createServer(...middleware...)
),
connect.vhost('bar.com',
connect.createServer(...middleware...)
)
);
param: String hostname
param: Server server
return: Function
api: public
|
module.exports = function vhost(hostname, server){
if (!hostname) {
throw new Error('vhost hostname required');
}
if (!server) {
throw new Error('vhost server required');
}
return function(req, res, next){
var host = req.headers.host.split(':')[0];
if (host === hostname) {
server.handle(req, res);
} else {
next();
}
};
};
|