mirror of
https://github.com/sstent/expressmongotest.git
synced 2026-03-19 11:25:55 +00:00
almost rebased
This commit is contained in:
10
chapter25/01_package.json
Normal file
10
chapter25/01_package.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"name": "application-name"
|
||||||
|
, "version": "0.0.1"
|
||||||
|
, "private": true
|
||||||
|
, "dependencies": {
|
||||||
|
"express": "2.5.11"
|
||||||
|
, "jade": ">= 0.0.1"
|
||||||
|
, "mongoose": ">=2.7.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
9
chapter25/02_user_schema.js
Normal file
9
chapter25/02_user_schema.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
var mongoose = require('mongoose');
|
||||||
|
|
||||||
|
var UserSchema = new mongoose.Schema({
|
||||||
|
username: String,
|
||||||
|
name: String,
|
||||||
|
password: String
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = UserSchema;
|
||||||
6
chapter25/03_user_model.js
Normal file
6
chapter25/03_user_model.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
var mongoose = require('mongoose');
|
||||||
|
var UserSchema = require('../schemas/user');
|
||||||
|
|
||||||
|
var User = mongoose.model('User', UserSchema);
|
||||||
|
|
||||||
|
module.exports = User;
|
||||||
16
chapter25/04_load_user_route_middleware_new_version.js
Normal file
16
chapter25/04_load_user_route_middleware_new_version.js
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
var User = require('../../data/models/user');
|
||||||
|
|
||||||
|
function loadUser(req, res, next) {
|
||||||
|
User.findOne({username: req.params.name}, function(err, user) {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
if (! user) {
|
||||||
|
return res.send('Not found', 404);
|
||||||
|
}
|
||||||
|
req.user = user;
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = loadUser;
|
||||||
56
chapter25/05_user_routes_new_version.js
Normal file
56
chapter25/05_user_routes_new_version.js
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* User Routes
|
||||||
|
*/
|
||||||
|
|
||||||
|
var User = require('../data/models/user');
|
||||||
|
var notLoggedIn = require('./middleware/not_logged_in');
|
||||||
|
var loadUser = require('./middleware/load_user');
|
||||||
|
var restrictUserToSelf = require('./middleware/restrict_user_to_self');
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = function(app) {
|
||||||
|
|
||||||
|
app.get('/users', function(req, res,next){
|
||||||
|
User.find({}, function(err, users) {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
res.render('users/index', {title: 'Users', users: users});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get('/users/new', notLoggedIn, function(req, res) {
|
||||||
|
res.render('users/new', {title: "New User"});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get('/users/:name', loadUser, function(req, res, next){
|
||||||
|
res.render('users/profile', {title: 'User profile', user: req.user});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post('/users', notLoggedIn, function(req, res, next) {
|
||||||
|
User.findOne({username: req.body.username}, function(err, user) {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
if (user) {
|
||||||
|
return res.send('Conflict', 409);
|
||||||
|
}
|
||||||
|
User.create(req.body, function(err) {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
res.redirect('/users');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.del('/users/:name', loadUser, restrictUserToSelf,
|
||||||
|
function(req, res, next) {
|
||||||
|
req.user.remove(function(err) {
|
||||||
|
if (err) { return next(err); }
|
||||||
|
res.redirect('/users');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
21
chapter25/06_user_list_with_paging.jade
Normal file
21
chapter25/06_user_list_with_paging.jade
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
h1 Users
|
||||||
|
|
||||||
|
p
|
||||||
|
a(href="/users/new") Create new profile
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ul
|
||||||
|
- for(var username in users) {
|
||||||
|
li
|
||||||
|
a(href="/users/" + encodeURIComponent(username))= users[username].name
|
||||||
|
- };
|
||||||
|
|
||||||
|
- if (page > 0) {
|
||||||
|
a(href="?page=" + (page - 1)) Previous
|
||||||
|
|
||||||
|
- }
|
||||||
|
|
||||||
|
a(href="?page=" + (page + 1)) Next
|
||||||
19
chapter25/07_user_list_with_paging_new_version.js
Normal file
19
chapter25/07_user_list_with_paging_new_version.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
h1 Users
|
||||||
|
|
||||||
|
p
|
||||||
|
a(href="/users/new") Create new profile
|
||||||
|
|
||||||
|
ul
|
||||||
|
- users.forEach(function(user) {
|
||||||
|
li
|
||||||
|
a(href="/users/" + encodeURIComponent(user.username))= user.name
|
||||||
|
- });
|
||||||
|
|
||||||
|
- if (page > 0) {
|
||||||
|
a(href="?page=" + (page - 1)) Previous
|
||||||
|
|
||||||
|
- }
|
||||||
|
|
||||||
|
- if (! lastPage) {
|
||||||
|
a(href="?page=" + (page + 1)) Next
|
||||||
|
- }
|
||||||
11
chapter25/08_package_new_version.json
Normal file
11
chapter25/08_package_new_version.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"name": "application-name"
|
||||||
|
, "version": "0.0.1"
|
||||||
|
, "private": true
|
||||||
|
, "dependencies": {
|
||||||
|
"express": "2.5.11"
|
||||||
|
, "jade": ">= 0.0.1"
|
||||||
|
, "mongoose": ">=2.7.0"
|
||||||
|
, "async": "0.1.22"
|
||||||
|
}
|
||||||
|
}
|
||||||
9
chapter25/09_user_schema_unique_index.js
Normal file
9
chapter25/09_user_schema_unique_index.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
var mongoose = require('mongoose');
|
||||||
|
|
||||||
|
var UserSchema = new mongoose.Schema({
|
||||||
|
username: {type: String, unique: true},
|
||||||
|
name: String,
|
||||||
|
password: String
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = UserSchema;
|
||||||
18
chapter25/10_user_schema_with_validated_email.js
Normal file
18
chapter25/10_user_schema_with_validated_email.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
var mongoose = require('mongoose');
|
||||||
|
|
||||||
|
// simple but incomplete email regexp:
|
||||||
|
var emailRegexp = /.+\@.+\..+/;
|
||||||
|
|
||||||
|
var UserSchema = new mongoose.Schema({
|
||||||
|
username: {type: String, unique: true},
|
||||||
|
name: String,
|
||||||
|
password: String,
|
||||||
|
email: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
match: emailRegexp
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = UserSchema;
|
||||||
22
chapter25/11_user_schema_with_enumerated_field.js
Normal file
22
chapter25/11_user_schema_with_enumerated_field.js
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
var mongoose = require('mongoose');
|
||||||
|
|
||||||
|
var emailRegexp = /.+\@.+\..+/;
|
||||||
|
|
||||||
|
var UserSchema = new mongoose.Schema({
|
||||||
|
username: {type: String, unique: true},
|
||||||
|
name: String,
|
||||||
|
password: String,
|
||||||
|
email: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
match: emailRegexp
|
||||||
|
},
|
||||||
|
gender: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
uppercase: true,
|
||||||
|
'enum': ['M', 'F']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = UserSchema;
|
||||||
23
chapter25/12_user_form_with_gender_field.jade
Normal file
23
chapter25/12_user_form_with_gender_field.jade
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
h1 New User
|
||||||
|
|
||||||
|
form(method="POST", action="/users")
|
||||||
|
p
|
||||||
|
label(for="username") Username<br />
|
||||||
|
input#username(name="username")
|
||||||
|
p
|
||||||
|
label(for="name") Name<br />
|
||||||
|
input#name(name="name")
|
||||||
|
p
|
||||||
|
label(for="email") Email<br />
|
||||||
|
input#email(name="email")
|
||||||
|
p
|
||||||
|
label(for="password") Password<br />
|
||||||
|
input#password(type="password", name="password")
|
||||||
|
p
|
||||||
|
label(for="gender") Gender<br />
|
||||||
|
input#gender(name="gender")
|
||||||
|
p
|
||||||
|
label(for="bio") Bio<br />
|
||||||
|
textarea#bio(name="bio")
|
||||||
|
p
|
||||||
|
input(type="submit", value="Create")
|
||||||
26
chapter25/13_user_form_with_birthday.jade
Normal file
26
chapter25/13_user_form_with_birthday.jade
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
h1 New User
|
||||||
|
|
||||||
|
form(method="POST", action="/users")
|
||||||
|
p
|
||||||
|
label(for="username") Username<br />
|
||||||
|
input#username(name="username")
|
||||||
|
p
|
||||||
|
label(for="name") Name<br />
|
||||||
|
input#name(name="name")
|
||||||
|
p
|
||||||
|
label(for="email") Email<br />
|
||||||
|
input#email(name="email")
|
||||||
|
p
|
||||||
|
label(for="password") Password<br />
|
||||||
|
input#password(type="password", name="password")
|
||||||
|
p
|
||||||
|
label(for="gender") Gender<br />
|
||||||
|
input#gender(name="gender")
|
||||||
|
p
|
||||||
|
label(for="birthday") Birthday<br />
|
||||||
|
input#birthday(name="birthday")
|
||||||
|
p
|
||||||
|
label(for="bio") Bio<br />
|
||||||
|
textarea#bio(name="bio")
|
||||||
|
p
|
||||||
|
input(type="submit", value="Create")
|
||||||
12
chapter25/14_package_with_request.json
Normal file
12
chapter25/14_package_with_request.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"name": "application-name"
|
||||||
|
, "version": "0.0.1"
|
||||||
|
, "private": true
|
||||||
|
, "dependencies": {
|
||||||
|
"express": "2.5.11"
|
||||||
|
, "jade": ">= 0.0.1"
|
||||||
|
, "mongoose": ">=2.7.0"
|
||||||
|
, "async": "0.1.22"
|
||||||
|
, "request": "2.10.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
24
chapter25/15_user_profile_with_virtual_attribute.jade
Normal file
24
chapter25/15_user_profile_with_virtual_attribute.jade
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
h1= user.name
|
||||||
|
|
||||||
|
h2 Bio
|
||||||
|
p= user.bio
|
||||||
|
|
||||||
|
h2 Email
|
||||||
|
p= user.email
|
||||||
|
|
||||||
|
h2 Gender
|
||||||
|
p= user.gender
|
||||||
|
|
||||||
|
h2 Birthday
|
||||||
|
p= user.birthday
|
||||||
|
|
||||||
|
- if (user.twitter) {
|
||||||
|
h2 Twitter
|
||||||
|
p
|
||||||
|
a(href= user.twitter_url)="@" + user.twitter
|
||||||
|
- }
|
||||||
|
|
||||||
|
|
||||||
|
form(action="/users/" + encodeURIComponent(user.username), method="POST")
|
||||||
|
input(name="_method", type="hidden", value="DELETE")
|
||||||
|
input(type="submit", value="Delete")
|
||||||
29
chapter25/16_user_form_with_virtual_attribute.jade
Normal file
29
chapter25/16_user_form_with_virtual_attribute.jade
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
h1 New User
|
||||||
|
|
||||||
|
form(method="POST", action="/users")
|
||||||
|
p
|
||||||
|
label(for="username") Username<br />
|
||||||
|
input#username(name="username")
|
||||||
|
p
|
||||||
|
label(for="full_name") Full name (first and last)<br />
|
||||||
|
input#full_name(name="full_name")
|
||||||
|
p
|
||||||
|
label(for="email") Email<br />
|
||||||
|
input#email(name="email")
|
||||||
|
p
|
||||||
|
label(for="password") Password<br />
|
||||||
|
input#password(type="password", name="password")
|
||||||
|
p
|
||||||
|
label(for="gender") Gender<br />
|
||||||
|
input#gender(name="gender")
|
||||||
|
p
|
||||||
|
label(for="birthday") Birthday<br />
|
||||||
|
input#birthday(name="birthday")
|
||||||
|
p
|
||||||
|
label(for="twitter") Twitter Handle<br />
|
||||||
|
input#twitter(name="twitter")
|
||||||
|
p
|
||||||
|
label(for="bio") Bio<br />
|
||||||
|
textarea#bio(name="bio")
|
||||||
|
p
|
||||||
|
input(type="submit", value="Create")
|
||||||
24
chapter25/17_user_profile_with_virtual_attribute.jade
Normal file
24
chapter25/17_user_profile_with_virtual_attribute.jade
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
h1= user.full_name
|
||||||
|
|
||||||
|
h2 Bio
|
||||||
|
p= user.bio
|
||||||
|
|
||||||
|
h2 Email
|
||||||
|
p= user.email
|
||||||
|
|
||||||
|
h2 Gender
|
||||||
|
p= user.gender
|
||||||
|
|
||||||
|
h2 Birthday
|
||||||
|
p= user.birthday
|
||||||
|
|
||||||
|
- if (user.twitter) {
|
||||||
|
h2 Twitter
|
||||||
|
p
|
||||||
|
a(href= user.twitter_url)="@" + user.twitter
|
||||||
|
- }
|
||||||
|
|
||||||
|
|
||||||
|
form(action="/users/" + encodeURIComponent(user.username), method="POST")
|
||||||
|
input(name="_method", type="hidden", value="DELETE")
|
||||||
|
input(type="submit", value="Delete")
|
||||||
19
chapter25/18_user_list_with_virtual_attribute.jade
Normal file
19
chapter25/18_user_list_with_virtual_attribute.jade
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
h1 Users
|
||||||
|
|
||||||
|
p
|
||||||
|
a(href="/users/new") Create new profile
|
||||||
|
|
||||||
|
ul
|
||||||
|
- users.forEach(function(user) {
|
||||||
|
li
|
||||||
|
a(href="/users/" + encodeURIComponent(user.username))= user.full_name
|
||||||
|
- });
|
||||||
|
|
||||||
|
- if (page > 0) {
|
||||||
|
a(href="?page=" + (page - 1)) Previous
|
||||||
|
|
||||||
|
- }
|
||||||
|
|
||||||
|
- if (! lastPage) {
|
||||||
|
a(href="?page=" + (page + 1)) Next
|
||||||
|
- }
|
||||||
20
chapter25/19_article_schema.js
Normal file
20
chapter25/19_article_schema.js
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
var Schema = require('mongoose').Schema;
|
||||||
|
|
||||||
|
var ArticleSchema = new Schema({
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
unique: true
|
||||||
|
},
|
||||||
|
body: String,
|
||||||
|
author: {
|
||||||
|
type: Schema.ObjectId,
|
||||||
|
ref: 'User',
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
created_at: {
|
||||||
|
type: Date,
|
||||||
|
'default': Date.now
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = ArticleSchema;
|
||||||
6
chapter25/20_article_model.js
Normal file
6
chapter25/20_article_model.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
var mongoose = require('mongoose');
|
||||||
|
var ArticleSchema = require('../schemas/article');
|
||||||
|
|
||||||
|
var Article = mongoose.model('Article', ArticleSchema);
|
||||||
|
|
||||||
|
module.exports = Article;
|
||||||
96
chapter25/21_article_routes.js
Normal file
96
chapter25/21_article_routes.js
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* Article Routes
|
||||||
|
*/
|
||||||
|
|
||||||
|
var async = require('async');
|
||||||
|
|
||||||
|
var Article = require('../data/models/article');
|
||||||
|
var notLoggedIn = require('./middleware/not_logged_in');
|
||||||
|
var loadArticle = require('./middleware/load_article');
|
||||||
|
var loggedIn = require('./middleware/logged_in');
|
||||||
|
|
||||||
|
var maxArticlesPerPage = 5;
|
||||||
|
|
||||||
|
module.exports = function(app) {
|
||||||
|
|
||||||
|
app.get('/articles', function(req, res, next){
|
||||||
|
var page = req.query.page && parseInt(req.query.page, 10) || 0;
|
||||||
|
async.parallel([
|
||||||
|
|
||||||
|
function(next) {
|
||||||
|
Article.count(next);
|
||||||
|
},
|
||||||
|
|
||||||
|
function(next) {
|
||||||
|
Article.find({})
|
||||||
|
.sort('title', 1)
|
||||||
|
.skip(page * maxArticlesPerPage)
|
||||||
|
.limit(maxArticlesPerPage)
|
||||||
|
.exec(next);
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
// final callback
|
||||||
|
function(err, results) {
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
var count = results[0];
|
||||||
|
var articles = results[1];
|
||||||
|
|
||||||
|
var lastPage = (page + 1) * maxArticlesPerPage >= count;
|
||||||
|
|
||||||
|
res.render('articles/index', {
|
||||||
|
title: 'Articles',
|
||||||
|
articles: articles,
|
||||||
|
page: page,
|
||||||
|
lastPage: lastPage
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get('/articles/new', loggedIn, function(req, res) {
|
||||||
|
res.render('Articles/new', {title: "New Article"});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get('/articles/:title', loadArticle, function(req, res, next){
|
||||||
|
res.render('articles/article', {title: req.article.title,
|
||||||
|
article: req.article});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post('/articles', loggedIn, function(req, res, next) {
|
||||||
|
var article = req.body;
|
||||||
|
article.author = req.session.user._id;
|
||||||
|
Article.create(article, function(err) {
|
||||||
|
if (err) {
|
||||||
|
if (err.code === 11000) {
|
||||||
|
res.send('Conflict', 409);
|
||||||
|
} else {
|
||||||
|
if (err.name === 'ValidationError') {
|
||||||
|
return res.send(Object.keys(err.errors).map(function(errField) {
|
||||||
|
return err.errors[errField].message;
|
||||||
|
}).join('. '), 406);
|
||||||
|
} else {
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
res.redirect('/articles');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.del('/articles/:title', loggedIn, loadArticle, function(req, res, next) {
|
||||||
|
req.article.remove(function(err) {
|
||||||
|
if (err) { return next(err); }
|
||||||
|
res.redirect('/articles');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
18
chapter25/22_load_article_middleware.js
Normal file
18
chapter25/22_load_article_middleware.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
var Article = require('../../data/models/article');
|
||||||
|
|
||||||
|
function loadArticle(req, res, next) {
|
||||||
|
Article.findOne({title: req.params.title})
|
||||||
|
.populate('author')
|
||||||
|
.exec(function(err, article) {
|
||||||
|
if (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
if (! article) {
|
||||||
|
return res.send('Not found', 404);
|
||||||
|
}
|
||||||
|
req.article = article;
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = loadArticle;
|
||||||
13
chapter25/23_article_detail.jade
Normal file
13
chapter25/23_article_detail.jade
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
h1= article.title
|
||||||
|
|
||||||
|
div!= article.body
|
||||||
|
|
||||||
|
hr
|
||||||
|
|
||||||
|
p
|
||||||
|
span Author:
|
||||||
|
|
||||||
|
a(href="/users/" + encodeURIComponent(article.author.username))= article.author.full_name
|
||||||
|
|
||||||
|
p
|
||||||
|
a(href="/articles") Back to all articles
|
||||||
9
chapter25/24_logged_in_middleware.js
Normal file
9
chapter25/24_logged_in_middleware.js
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
function loggedIn(req, res, next) {
|
||||||
|
if (! req.session.user) {
|
||||||
|
res.send('Forbidden. Please log in first.', 403);
|
||||||
|
} else {
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = loggedIn;
|
||||||
19
chapter25/25_article_list.jade
Normal file
19
chapter25/25_article_list.jade
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
h1 Articles
|
||||||
|
|
||||||
|
p
|
||||||
|
a(href="/articles/new") Create new article
|
||||||
|
|
||||||
|
ul
|
||||||
|
- articles.forEach(function(article) {
|
||||||
|
li
|
||||||
|
a(href="/articles/" + encodeURIComponent(article.title))= article.title
|
||||||
|
- });
|
||||||
|
|
||||||
|
- if (page > 0) {
|
||||||
|
a(href="?page=" + (page - 1)) Previous
|
||||||
|
|
||||||
|
- }
|
||||||
|
|
||||||
|
- if (! lastPage) {
|
||||||
|
a(href="?page=" + (page + 1)) Next
|
||||||
|
- }
|
||||||
11
chapter25/26_article_creation_form.jade
Normal file
11
chapter25/26_article_creation_form.jade
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
h1 New Article
|
||||||
|
|
||||||
|
form(method="POST", action="/articles")
|
||||||
|
p
|
||||||
|
label(for="title") Title<br />
|
||||||
|
input#title(name="title")
|
||||||
|
p
|
||||||
|
label(for="body") Body<br />
|
||||||
|
textarea#body(name="body")
|
||||||
|
p
|
||||||
|
input(type="submit", value="Create")
|
||||||
5
chapter25/27_article_list_partial.jade
Normal file
5
chapter25/27_article_list_partial.jade
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
ul
|
||||||
|
- articles.forEach(function(article) {
|
||||||
|
li
|
||||||
|
a(href="/articles/" + encodeURIComponent(article.title))= article.title
|
||||||
|
- });
|
||||||
15
chapter25/28_article_list_new_version.jade
Normal file
15
chapter25/28_article_list_new_version.jade
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
h1 Articles
|
||||||
|
|
||||||
|
p
|
||||||
|
a(href="/articles/new") Create new article
|
||||||
|
|
||||||
|
p!= partial('articles/list', {articles: articles})
|
||||||
|
|
||||||
|
- if (page > 0) {
|
||||||
|
a(href="?page=" + (page - 1)) Previous
|
||||||
|
|
||||||
|
- }
|
||||||
|
|
||||||
|
- if (! lastPage) {
|
||||||
|
a(href="?page=" + (page + 1)) Next
|
||||||
|
- }
|
||||||
44
test/app.js
Normal file
44
test/app.js
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var express = require('express')
|
||||||
|
, routes = require('./routes');
|
||||||
|
var async = require('async');
|
||||||
|
var app = module.exports = express.createServer();
|
||||||
|
|
||||||
|
// Configuration
|
||||||
|
|
||||||
|
app.configure(function(){
|
||||||
|
app.set('views', __dirname + '/views');
|
||||||
|
app.set('view engine', 'jade');
|
||||||
|
app.use(express.bodyParser());
|
||||||
|
app.use(express.methodOverride());
|
||||||
|
app.use(express.cookieParser('my secret string'));
|
||||||
|
app.use(express.session({
|
||||||
|
secret: 'my secret string',
|
||||||
|
maxAge: 3600000
|
||||||
|
}));
|
||||||
|
app.use(app.router);
|
||||||
|
app.use(express.static(__dirname + '/public'));
|
||||||
|
});
|
||||||
|
|
||||||
|
app.configure('development', function(){
|
||||||
|
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
|
||||||
|
});
|
||||||
|
|
||||||
|
app.configure('production', function(){
|
||||||
|
app.use(express.errorHandler());
|
||||||
|
});
|
||||||
|
|
||||||
|
// Routes
|
||||||
|
|
||||||
|
require('./routes/index')(app);
|
||||||
|
require('./routes/users')(app);
|
||||||
|
require('./routes/session')(app);
|
||||||
|
|
||||||
|
|
||||||
|
app.listen(3000, function(){
|
||||||
|
console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);
|
||||||
|
});
|
||||||
6
test/data/models/user.js
Normal file
6
test/data/models/user.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
var mongoose = require('mongoose');
|
||||||
|
var UserSchema = require('../schemas/user');
|
||||||
|
|
||||||
|
var User = mongoose.model('User', UserSchema);
|
||||||
|
|
||||||
|
module.exports = User;
|
||||||
24
test/data/users.json
Normal file
24
test/data/users.json
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
|
||||||
|
"frank": {
|
||||||
|
"username": "frank",
|
||||||
|
"name": "Frank Sinatra",
|
||||||
|
"bio": "Singer",
|
||||||
|
"password": "password"
|
||||||
|
},
|
||||||
|
|
||||||
|
"jobim": {
|
||||||
|
"username": "jobim",
|
||||||
|
"name": "Antonio Carlos Jobim",
|
||||||
|
"bio": "Composer",
|
||||||
|
"password": "password"
|
||||||
|
},
|
||||||
|
|
||||||
|
"fred": {
|
||||||
|
"username": "fred",
|
||||||
|
"name": "Fred Astaire",
|
||||||
|
"bio": "Dancer and Actor",
|
||||||
|
"password": "password"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
15
test/node_modules/.bin/express
generated
vendored
Normal file
15
test/node_modules/.bin/express
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
basedir=`dirname "$0"`
|
||||||
|
|
||||||
|
case `uname` in
|
||||||
|
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ -x "$basedir/node" ]; then
|
||||||
|
"$basedir/node" "$basedir/../express/bin/express" "$@"
|
||||||
|
ret=$?
|
||||||
|
else
|
||||||
|
node "$basedir/../express/bin/express" "$@"
|
||||||
|
ret=$?
|
||||||
|
fi
|
||||||
|
exit $ret
|
||||||
6
test/node_modules/.bin/express.cmd
generated
vendored
Normal file
6
test/node_modules/.bin/express.cmd
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
:: Created by npm, please don't edit manually.
|
||||||
|
@IF EXIST "%~dp0\node.exe" (
|
||||||
|
"%~dp0\node.exe" "%~dp0\..\express\bin\express" %*
|
||||||
|
) ELSE (
|
||||||
|
node "%~dp0\..\express\bin\express" %*
|
||||||
|
)
|
||||||
15
test/node_modules/.bin/jade
generated
vendored
Normal file
15
test/node_modules/.bin/jade
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
basedir=`dirname "$0"`
|
||||||
|
|
||||||
|
case `uname` in
|
||||||
|
*CYGWIN*) basedir=`cygpath -w "$basedir"`;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ -x "$basedir/node" ]; then
|
||||||
|
"$basedir/node" "$basedir/../jade/bin/jade" "$@"
|
||||||
|
ret=$?
|
||||||
|
else
|
||||||
|
node "$basedir/../jade/bin/jade" "$@"
|
||||||
|
ret=$?
|
||||||
|
fi
|
||||||
|
exit $ret
|
||||||
6
test/node_modules/.bin/jade.cmd
generated
vendored
Normal file
6
test/node_modules/.bin/jade.cmd
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
:: Created by npm, please don't edit manually.
|
||||||
|
@IF EXIST "%~dp0\node.exe" (
|
||||||
|
"%~dp0\node.exe" "%~dp0\..\jade\bin\jade" %*
|
||||||
|
) ELSE (
|
||||||
|
node "%~dp0\..\jade\bin\jade" %*
|
||||||
|
)
|
||||||
9
test/node_modules/async/.gitmodules
generated
vendored
Normal file
9
test/node_modules/async/.gitmodules
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
[submodule "deps/nodeunit"]
|
||||||
|
path = deps/nodeunit
|
||||||
|
url = git://github.com/caolan/nodeunit.git
|
||||||
|
[submodule "deps/UglifyJS"]
|
||||||
|
path = deps/UglifyJS
|
||||||
|
url = https://github.com/mishoo/UglifyJS.git
|
||||||
|
[submodule "deps/nodelint"]
|
||||||
|
path = deps/nodelint
|
||||||
|
url = https://github.com/tav/nodelint.git
|
||||||
4
test/node_modules/async/.npmignore
generated
vendored
Normal file
4
test/node_modules/async/.npmignore
generated
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
deps
|
||||||
|
dist
|
||||||
|
test
|
||||||
|
nodelint.cfg
|
||||||
19
test/node_modules/async/LICENSE
generated
vendored
Normal file
19
test/node_modules/async/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
Copyright (c) 2010 Caolan McMahon
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
25
test/node_modules/async/Makefile
generated
vendored
Normal file
25
test/node_modules/async/Makefile
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
PACKAGE = asyncjs
|
||||||
|
NODEJS = $(if $(shell test -f /usr/bin/nodejs && echo "true"),nodejs,node)
|
||||||
|
CWD := $(shell pwd)
|
||||||
|
NODEUNIT = $(CWD)/node_modules/nodeunit/bin/nodeunit
|
||||||
|
UGLIFY = $(CWD)/node_modules/uglify-js/bin/uglifyjs
|
||||||
|
NODELINT = $(CWD)/node_modules/nodelint/nodelint
|
||||||
|
|
||||||
|
BUILDDIR = dist
|
||||||
|
|
||||||
|
all: clean test build
|
||||||
|
|
||||||
|
build: $(wildcard lib/*.js)
|
||||||
|
mkdir -p $(BUILDDIR)
|
||||||
|
$(UGLIFY) lib/async.js > $(BUILDDIR)/async.min.js
|
||||||
|
|
||||||
|
test:
|
||||||
|
$(NODEUNIT) test
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(BUILDDIR)
|
||||||
|
|
||||||
|
lint:
|
||||||
|
$(NODELINT) --config nodelint.cfg lib/async.js
|
||||||
|
|
||||||
|
.PHONY: test build all
|
||||||
1021
test/node_modules/async/README.md
generated
vendored
Normal file
1021
test/node_modules/async/README.md
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3
test/node_modules/async/index.js
generated
vendored
Normal file
3
test/node_modules/async/index.js
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
// This file is just added for convenience so this repository can be
|
||||||
|
// directly checked out into a project's deps folder
|
||||||
|
module.exports = require('./lib/async');
|
||||||
692
test/node_modules/async/lib/async.js
generated
vendored
Normal file
692
test/node_modules/async/lib/async.js
generated
vendored
Normal file
@@ -0,0 +1,692 @@
|
|||||||
|
/*global setTimeout: false, console: false */
|
||||||
|
(function () {
|
||||||
|
|
||||||
|
var async = {};
|
||||||
|
|
||||||
|
// global on the server, window in the browser
|
||||||
|
var root = this,
|
||||||
|
previous_async = root.async;
|
||||||
|
|
||||||
|
if (typeof module !== 'undefined' && module.exports) {
|
||||||
|
module.exports = async;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
root.async = async;
|
||||||
|
}
|
||||||
|
|
||||||
|
async.noConflict = function () {
|
||||||
|
root.async = previous_async;
|
||||||
|
return async;
|
||||||
|
};
|
||||||
|
|
||||||
|
//// cross-browser compatiblity functions ////
|
||||||
|
|
||||||
|
var _forEach = function (arr, iterator) {
|
||||||
|
if (arr.forEach) {
|
||||||
|
return arr.forEach(iterator);
|
||||||
|
}
|
||||||
|
for (var i = 0; i < arr.length; i += 1) {
|
||||||
|
iterator(arr[i], i, arr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var _map = function (arr, iterator) {
|
||||||
|
if (arr.map) {
|
||||||
|
return arr.map(iterator);
|
||||||
|
}
|
||||||
|
var results = [];
|
||||||
|
_forEach(arr, function (x, i, a) {
|
||||||
|
results.push(iterator(x, i, a));
|
||||||
|
});
|
||||||
|
return results;
|
||||||
|
};
|
||||||
|
|
||||||
|
var _reduce = function (arr, iterator, memo) {
|
||||||
|
if (arr.reduce) {
|
||||||
|
return arr.reduce(iterator, memo);
|
||||||
|
}
|
||||||
|
_forEach(arr, function (x, i, a) {
|
||||||
|
memo = iterator(memo, x, i, a);
|
||||||
|
});
|
||||||
|
return memo;
|
||||||
|
};
|
||||||
|
|
||||||
|
var _keys = function (obj) {
|
||||||
|
if (Object.keys) {
|
||||||
|
return Object.keys(obj);
|
||||||
|
}
|
||||||
|
var keys = [];
|
||||||
|
for (var k in obj) {
|
||||||
|
if (obj.hasOwnProperty(k)) {
|
||||||
|
keys.push(k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return keys;
|
||||||
|
};
|
||||||
|
|
||||||
|
//// exported async module functions ////
|
||||||
|
|
||||||
|
//// nextTick implementation with browser-compatible fallback ////
|
||||||
|
if (typeof process === 'undefined' || !(process.nextTick)) {
|
||||||
|
async.nextTick = function (fn) {
|
||||||
|
setTimeout(fn, 0);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
async.nextTick = process.nextTick;
|
||||||
|
}
|
||||||
|
|
||||||
|
async.forEach = function (arr, iterator, callback) {
|
||||||
|
callback = callback || function () {};
|
||||||
|
if (!arr.length) {
|
||||||
|
return callback();
|
||||||
|
}
|
||||||
|
var completed = 0;
|
||||||
|
_forEach(arr, function (x) {
|
||||||
|
iterator(x, function (err) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
callback = function () {};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
completed += 1;
|
||||||
|
if (completed === arr.length) {
|
||||||
|
callback(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
async.forEachSeries = function (arr, iterator, callback) {
|
||||||
|
callback = callback || function () {};
|
||||||
|
if (!arr.length) {
|
||||||
|
return callback();
|
||||||
|
}
|
||||||
|
var completed = 0;
|
||||||
|
var iterate = function () {
|
||||||
|
iterator(arr[completed], function (err) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
callback = function () {};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
completed += 1;
|
||||||
|
if (completed === arr.length) {
|
||||||
|
callback(null);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
iterate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
iterate();
|
||||||
|
};
|
||||||
|
|
||||||
|
async.forEachLimit = function (arr, limit, iterator, callback) {
|
||||||
|
callback = callback || function () {};
|
||||||
|
if (!arr.length || limit <= 0) {
|
||||||
|
return callback();
|
||||||
|
}
|
||||||
|
var completed = 0;
|
||||||
|
var started = 0;
|
||||||
|
var running = 0;
|
||||||
|
|
||||||
|
(function replenish () {
|
||||||
|
if (completed === arr.length) {
|
||||||
|
return callback();
|
||||||
|
}
|
||||||
|
|
||||||
|
while (running < limit && started < arr.length) {
|
||||||
|
started += 1;
|
||||||
|
running += 1;
|
||||||
|
iterator(arr[started - 1], function (err) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
callback = function () {};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
completed += 1;
|
||||||
|
running -= 1;
|
||||||
|
if (completed === arr.length) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
replenish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var doParallel = function (fn) {
|
||||||
|
return function () {
|
||||||
|
var args = Array.prototype.slice.call(arguments);
|
||||||
|
return fn.apply(null, [async.forEach].concat(args));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
var doSeries = function (fn) {
|
||||||
|
return function () {
|
||||||
|
var args = Array.prototype.slice.call(arguments);
|
||||||
|
return fn.apply(null, [async.forEachSeries].concat(args));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
var _asyncMap = function (eachfn, arr, iterator, callback) {
|
||||||
|
var results = [];
|
||||||
|
arr = _map(arr, function (x, i) {
|
||||||
|
return {index: i, value: x};
|
||||||
|
});
|
||||||
|
eachfn(arr, function (x, callback) {
|
||||||
|
iterator(x.value, function (err, v) {
|
||||||
|
results[x.index] = v;
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
}, function (err) {
|
||||||
|
callback(err, results);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
async.map = doParallel(_asyncMap);
|
||||||
|
async.mapSeries = doSeries(_asyncMap);
|
||||||
|
|
||||||
|
|
||||||
|
// reduce only has a series version, as doing reduce in parallel won't
|
||||||
|
// work in many situations.
|
||||||
|
async.reduce = function (arr, memo, iterator, callback) {
|
||||||
|
async.forEachSeries(arr, function (x, callback) {
|
||||||
|
iterator(memo, x, function (err, v) {
|
||||||
|
memo = v;
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
}, function (err) {
|
||||||
|
callback(err, memo);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// inject alias
|
||||||
|
async.inject = async.reduce;
|
||||||
|
// foldl alias
|
||||||
|
async.foldl = async.reduce;
|
||||||
|
|
||||||
|
async.reduceRight = function (arr, memo, iterator, callback) {
|
||||||
|
var reversed = _map(arr, function (x) {
|
||||||
|
return x;
|
||||||
|
}).reverse();
|
||||||
|
async.reduce(reversed, memo, iterator, callback);
|
||||||
|
};
|
||||||
|
// foldr alias
|
||||||
|
async.foldr = async.reduceRight;
|
||||||
|
|
||||||
|
var _filter = function (eachfn, arr, iterator, callback) {
|
||||||
|
var results = [];
|
||||||
|
arr = _map(arr, function (x, i) {
|
||||||
|
return {index: i, value: x};
|
||||||
|
});
|
||||||
|
eachfn(arr, function (x, callback) {
|
||||||
|
iterator(x.value, function (v) {
|
||||||
|
if (v) {
|
||||||
|
results.push(x);
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
}, function (err) {
|
||||||
|
callback(_map(results.sort(function (a, b) {
|
||||||
|
return a.index - b.index;
|
||||||
|
}), function (x) {
|
||||||
|
return x.value;
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
async.filter = doParallel(_filter);
|
||||||
|
async.filterSeries = doSeries(_filter);
|
||||||
|
// select alias
|
||||||
|
async.select = async.filter;
|
||||||
|
async.selectSeries = async.filterSeries;
|
||||||
|
|
||||||
|
var _reject = function (eachfn, arr, iterator, callback) {
|
||||||
|
var results = [];
|
||||||
|
arr = _map(arr, function (x, i) {
|
||||||
|
return {index: i, value: x};
|
||||||
|
});
|
||||||
|
eachfn(arr, function (x, callback) {
|
||||||
|
iterator(x.value, function (v) {
|
||||||
|
if (!v) {
|
||||||
|
results.push(x);
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
}, function (err) {
|
||||||
|
callback(_map(results.sort(function (a, b) {
|
||||||
|
return a.index - b.index;
|
||||||
|
}), function (x) {
|
||||||
|
return x.value;
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
async.reject = doParallel(_reject);
|
||||||
|
async.rejectSeries = doSeries(_reject);
|
||||||
|
|
||||||
|
var _detect = function (eachfn, arr, iterator, main_callback) {
|
||||||
|
eachfn(arr, function (x, callback) {
|
||||||
|
iterator(x, function (result) {
|
||||||
|
if (result) {
|
||||||
|
main_callback(x);
|
||||||
|
main_callback = function () {};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, function (err) {
|
||||||
|
main_callback();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
async.detect = doParallel(_detect);
|
||||||
|
async.detectSeries = doSeries(_detect);
|
||||||
|
|
||||||
|
async.some = function (arr, iterator, main_callback) {
|
||||||
|
async.forEach(arr, function (x, callback) {
|
||||||
|
iterator(x, function (v) {
|
||||||
|
if (v) {
|
||||||
|
main_callback(true);
|
||||||
|
main_callback = function () {};
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
}, function (err) {
|
||||||
|
main_callback(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// any alias
|
||||||
|
async.any = async.some;
|
||||||
|
|
||||||
|
async.every = function (arr, iterator, main_callback) {
|
||||||
|
async.forEach(arr, function (x, callback) {
|
||||||
|
iterator(x, function (v) {
|
||||||
|
if (!v) {
|
||||||
|
main_callback(false);
|
||||||
|
main_callback = function () {};
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
}, function (err) {
|
||||||
|
main_callback(true);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// all alias
|
||||||
|
async.all = async.every;
|
||||||
|
|
||||||
|
async.sortBy = function (arr, iterator, callback) {
|
||||||
|
async.map(arr, function (x, callback) {
|
||||||
|
iterator(x, function (err, criteria) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
callback(null, {value: x, criteria: criteria});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, function (err, results) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var fn = function (left, right) {
|
||||||
|
var a = left.criteria, b = right.criteria;
|
||||||
|
return a < b ? -1 : a > b ? 1 : 0;
|
||||||
|
};
|
||||||
|
callback(null, _map(results.sort(fn), function (x) {
|
||||||
|
return x.value;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
async.auto = function (tasks, callback) {
|
||||||
|
callback = callback || function () {};
|
||||||
|
var keys = _keys(tasks);
|
||||||
|
if (!keys.length) {
|
||||||
|
return callback(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
var results = {};
|
||||||
|
|
||||||
|
var listeners = [];
|
||||||
|
var addListener = function (fn) {
|
||||||
|
listeners.unshift(fn);
|
||||||
|
};
|
||||||
|
var removeListener = function (fn) {
|
||||||
|
for (var i = 0; i < listeners.length; i += 1) {
|
||||||
|
if (listeners[i] === fn) {
|
||||||
|
listeners.splice(i, 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var taskComplete = function () {
|
||||||
|
_forEach(listeners.slice(0), function (fn) {
|
||||||
|
fn();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
addListener(function () {
|
||||||
|
if (_keys(results).length === keys.length) {
|
||||||
|
callback(null, results);
|
||||||
|
callback = function () {};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_forEach(keys, function (k) {
|
||||||
|
var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k];
|
||||||
|
var taskCallback = function (err) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
// stop subsequent errors hitting callback multiple times
|
||||||
|
callback = function () {};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var args = Array.prototype.slice.call(arguments, 1);
|
||||||
|
if (args.length <= 1) {
|
||||||
|
args = args[0];
|
||||||
|
}
|
||||||
|
results[k] = args;
|
||||||
|
taskComplete();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var requires = task.slice(0, Math.abs(task.length - 1)) || [];
|
||||||
|
var ready = function () {
|
||||||
|
return _reduce(requires, function (a, x) {
|
||||||
|
return (a && results.hasOwnProperty(x));
|
||||||
|
}, true) && !results.hasOwnProperty(k);
|
||||||
|
};
|
||||||
|
if (ready()) {
|
||||||
|
task[task.length - 1](taskCallback, results);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var listener = function () {
|
||||||
|
if (ready()) {
|
||||||
|
removeListener(listener);
|
||||||
|
task[task.length - 1](taskCallback, results);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
addListener(listener);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
async.waterfall = function (tasks, callback) {
|
||||||
|
callback = callback || function () {};
|
||||||
|
if (!tasks.length) {
|
||||||
|
return callback();
|
||||||
|
}
|
||||||
|
var wrapIterator = function (iterator) {
|
||||||
|
return function (err) {
|
||||||
|
if (err) {
|
||||||
|
callback(err);
|
||||||
|
callback = function () {};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var args = Array.prototype.slice.call(arguments, 1);
|
||||||
|
var next = iterator.next();
|
||||||
|
if (next) {
|
||||||
|
args.push(wrapIterator(next));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
args.push(callback);
|
||||||
|
}
|
||||||
|
async.nextTick(function () {
|
||||||
|
iterator.apply(null, args);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
wrapIterator(async.iterator(tasks))();
|
||||||
|
};
|
||||||
|
|
||||||
|
async.parallel = function (tasks, callback) {
|
||||||
|
callback = callback || function () {};
|
||||||
|
if (tasks.constructor === Array) {
|
||||||
|
async.map(tasks, function (fn, callback) {
|
||||||
|
if (fn) {
|
||||||
|
fn(function (err) {
|
||||||
|
var args = Array.prototype.slice.call(arguments, 1);
|
||||||
|
if (args.length <= 1) {
|
||||||
|
args = args[0];
|
||||||
|
}
|
||||||
|
callback.call(null, err, args);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, callback);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var results = {};
|
||||||
|
async.forEach(_keys(tasks), function (k, callback) {
|
||||||
|
tasks[k](function (err) {
|
||||||
|
var args = Array.prototype.slice.call(arguments, 1);
|
||||||
|
if (args.length <= 1) {
|
||||||
|
args = args[0];
|
||||||
|
}
|
||||||
|
results[k] = args;
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
}, function (err) {
|
||||||
|
callback(err, results);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
async.series = function (tasks, callback) {
|
||||||
|
callback = callback || function () {};
|
||||||
|
if (tasks.constructor === Array) {
|
||||||
|
async.mapSeries(tasks, function (fn, callback) {
|
||||||
|
if (fn) {
|
||||||
|
fn(function (err) {
|
||||||
|
var args = Array.prototype.slice.call(arguments, 1);
|
||||||
|
if (args.length <= 1) {
|
||||||
|
args = args[0];
|
||||||
|
}
|
||||||
|
callback.call(null, err, args);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, callback);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var results = {};
|
||||||
|
async.forEachSeries(_keys(tasks), function (k, callback) {
|
||||||
|
tasks[k](function (err) {
|
||||||
|
var args = Array.prototype.slice.call(arguments, 1);
|
||||||
|
if (args.length <= 1) {
|
||||||
|
args = args[0];
|
||||||
|
}
|
||||||
|
results[k] = args;
|
||||||
|
callback(err);
|
||||||
|
});
|
||||||
|
}, function (err) {
|
||||||
|
callback(err, results);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
async.iterator = function (tasks) {
|
||||||
|
var makeCallback = function (index) {
|
||||||
|
var fn = function () {
|
||||||
|
if (tasks.length) {
|
||||||
|
tasks[index].apply(null, arguments);
|
||||||
|
}
|
||||||
|
return fn.next();
|
||||||
|
};
|
||||||
|
fn.next = function () {
|
||||||
|
return (index < tasks.length - 1) ? makeCallback(index + 1): null;
|
||||||
|
};
|
||||||
|
return fn;
|
||||||
|
};
|
||||||
|
return makeCallback(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
async.apply = function (fn) {
|
||||||
|
var args = Array.prototype.slice.call(arguments, 1);
|
||||||
|
return function () {
|
||||||
|
return fn.apply(
|
||||||
|
null, args.concat(Array.prototype.slice.call(arguments))
|
||||||
|
);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
var _concat = function (eachfn, arr, fn, callback) {
|
||||||
|
var r = [];
|
||||||
|
eachfn(arr, function (x, cb) {
|
||||||
|
fn(x, function (err, y) {
|
||||||
|
r = r.concat(y || []);
|
||||||
|
cb(err);
|
||||||
|
});
|
||||||
|
}, function (err) {
|
||||||
|
callback(err, r);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
async.concat = doParallel(_concat);
|
||||||
|
async.concatSeries = doSeries(_concat);
|
||||||
|
|
||||||
|
async.whilst = function (test, iterator, callback) {
|
||||||
|
if (test()) {
|
||||||
|
iterator(function (err) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
async.whilst(test, iterator, callback);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
async.until = function (test, iterator, callback) {
|
||||||
|
if (!test()) {
|
||||||
|
iterator(function (err) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
async.until(test, iterator, callback);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
async.queue = function (worker, concurrency) {
|
||||||
|
var workers = 0;
|
||||||
|
var q = {
|
||||||
|
tasks: [],
|
||||||
|
concurrency: concurrency,
|
||||||
|
saturated: null,
|
||||||
|
empty: null,
|
||||||
|
drain: null,
|
||||||
|
push: function (data, callback) {
|
||||||
|
if(data.constructor !== Array) {
|
||||||
|
data = [data];
|
||||||
|
}
|
||||||
|
_forEach(data, function(task) {
|
||||||
|
q.tasks.push({
|
||||||
|
data: task,
|
||||||
|
callback: typeof callback === 'function' ? callback : null
|
||||||
|
});
|
||||||
|
if (q.saturated && q.tasks.length == concurrency) {
|
||||||
|
q.saturated();
|
||||||
|
}
|
||||||
|
async.nextTick(q.process);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
process: function () {
|
||||||
|
if (workers < q.concurrency && q.tasks.length) {
|
||||||
|
var task = q.tasks.shift();
|
||||||
|
if(q.empty && q.tasks.length == 0) q.empty();
|
||||||
|
workers += 1;
|
||||||
|
worker(task.data, function () {
|
||||||
|
workers -= 1;
|
||||||
|
if (task.callback) {
|
||||||
|
task.callback.apply(task, arguments);
|
||||||
|
}
|
||||||
|
if(q.drain && q.tasks.length + workers == 0) q.drain();
|
||||||
|
q.process();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
length: function () {
|
||||||
|
return q.tasks.length;
|
||||||
|
},
|
||||||
|
running: function () {
|
||||||
|
return workers;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return q;
|
||||||
|
};
|
||||||
|
|
||||||
|
var _console_fn = function (name) {
|
||||||
|
return function (fn) {
|
||||||
|
var args = Array.prototype.slice.call(arguments, 1);
|
||||||
|
fn.apply(null, args.concat([function (err) {
|
||||||
|
var args = Array.prototype.slice.call(arguments, 1);
|
||||||
|
if (typeof console !== 'undefined') {
|
||||||
|
if (err) {
|
||||||
|
if (console.error) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (console[name]) {
|
||||||
|
_forEach(args, function (x) {
|
||||||
|
console[name](x);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}]));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
async.log = _console_fn('log');
|
||||||
|
async.dir = _console_fn('dir');
|
||||||
|
/*async.info = _console_fn('info');
|
||||||
|
async.warn = _console_fn('warn');
|
||||||
|
async.error = _console_fn('error');*/
|
||||||
|
|
||||||
|
async.memoize = function (fn, hasher) {
|
||||||
|
var memo = {};
|
||||||
|
var queues = {};
|
||||||
|
hasher = hasher || function (x) {
|
||||||
|
return x;
|
||||||
|
};
|
||||||
|
var memoized = function () {
|
||||||
|
var args = Array.prototype.slice.call(arguments);
|
||||||
|
var callback = args.pop();
|
||||||
|
var key = hasher.apply(null, args);
|
||||||
|
if (key in memo) {
|
||||||
|
callback.apply(null, memo[key]);
|
||||||
|
}
|
||||||
|
else if (key in queues) {
|
||||||
|
queues[key].push(callback);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
queues[key] = [callback];
|
||||||
|
fn.apply(null, args.concat([function () {
|
||||||
|
memo[key] = arguments;
|
||||||
|
var q = queues[key];
|
||||||
|
delete queues[key];
|
||||||
|
for (var i = 0, l = q.length; i < l; i++) {
|
||||||
|
q[i].apply(null, arguments);
|
||||||
|
}
|
||||||
|
}]));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
memoized.unmemoized = fn;
|
||||||
|
return memoized;
|
||||||
|
};
|
||||||
|
|
||||||
|
async.unmemoize = function (fn) {
|
||||||
|
return function () {
|
||||||
|
return (fn.unmemoized || fn).apply(null, arguments);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}());
|
||||||
34
test/node_modules/async/package.json
generated
vendored
Normal file
34
test/node_modules/async/package.json
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
7
test/node_modules/express/.npmignore
generated
vendored
Normal file
7
test/node_modules/express/.npmignore
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
.git*
|
||||||
|
docs/
|
||||||
|
examples/
|
||||||
|
support/
|
||||||
|
test/
|
||||||
|
testing.js
|
||||||
|
.DS_Store
|
||||||
823
test/node_modules/express/History.md
generated
vendored
Normal file
823
test/node_modules/express/History.md
generated
vendored
Normal file
@@ -0,0 +1,823 @@
|
|||||||
|
|
||||||
|
2.5.11 / 2012-06-29
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Fixed backport of req.protocol
|
||||||
|
|
||||||
|
2.5.10 / 2012-06-15
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Remove annoying engines field from package.json
|
||||||
|
* Backport support for trusting X-Forwarded-Proto
|
||||||
|
* use version of `package.json` for `express` command
|
||||||
|
|
||||||
|
2.5.9/ 2012-04-02
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added support for PURGE request method [pbuyle]
|
||||||
|
* Fixed `express(1)` generated app `app.address()` before `listening` [mmalecki]
|
||||||
|
|
||||||
|
2.5.8 / 2012-02-08
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Update mkdirp dep. Closes #991
|
||||||
|
|
||||||
|
2.5.7 / 2012-02-06
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Fixed `app.all` duplicate DELETE requests [mscdex]
|
||||||
|
|
||||||
|
2.5.6 / 2012-01-13
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Updated hamljs dev dep. Closes #953
|
||||||
|
|
||||||
|
2.5.5 / 2012-01-08
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Fixed: set `filename` on cached templates [matthewleon]
|
||||||
|
|
||||||
|
2.5.4 / 2012-01-02
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Fixed `express(1)` eol on 0.4.x. Closes #947
|
||||||
|
|
||||||
|
2.5.3 / 2011-12-30
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Fixed `req.is()` when a charset is present
|
||||||
|
|
||||||
|
2.5.2 / 2011-12-10
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Fixed: express(1) LF -> CRLF for windows
|
||||||
|
|
||||||
|
2.5.1 / 2011-11-17
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Changed: updated connect to 1.8.x
|
||||||
|
* Removed sass.js support from express(1)
|
||||||
|
|
||||||
|
2.5.0 / 2011-10-24
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added ./routes dir for generated app by default
|
||||||
|
* Added npm install reminder to express(1) app gen
|
||||||
|
* Added 0.5.x support
|
||||||
|
* Removed `make test-cov` since it wont work with node 0.5.x
|
||||||
|
* Fixed express(1) public dir for windows. Closes #866
|
||||||
|
|
||||||
|
2.4.7 / 2011-10-05
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added mkdirp to express(1). Closes #795
|
||||||
|
* Added simple _json-config_ example
|
||||||
|
* Added shorthand for the parsed request's pathname via `req.path`
|
||||||
|
* Changed connect dep to 1.7.x to fix npm issue...
|
||||||
|
* Fixed `res.redirect()` __HEAD__ support. [reported by xerox]
|
||||||
|
* Fixed `req.flash()`, only escape args
|
||||||
|
* Fixed absolute path checking on windows. Closes #829 [reported by andrewpmckenzie]
|
||||||
|
|
||||||
|
2.4.6 / 2011-08-22
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Fixed multiple param callback regression. Closes #824 [reported by TroyGoode]
|
||||||
|
|
||||||
|
2.4.5 / 2011-08-19
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added support for routes to handle errors. Closes #809
|
||||||
|
* Added `app.routes.all()`. Closes #803
|
||||||
|
* Added "basepath" setting to work in conjunction with reverse proxies etc.
|
||||||
|
* Refactored `Route` to use a single array of callbacks
|
||||||
|
* Added support for multiple callbacks for `app.param()`. Closes #801
|
||||||
|
Closes #805
|
||||||
|
* Changed: removed .call(self) for route callbacks
|
||||||
|
* Dependency: `qs >= 0.3.1`
|
||||||
|
* Fixed `res.redirect()` on windows due to `join()` usage. Closes #808
|
||||||
|
|
||||||
|
2.4.4 / 2011-08-05
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Fixed `res.header()` intention of a set, even when `undefined`
|
||||||
|
* Fixed `*`, value no longer required
|
||||||
|
* Fixed `res.send(204)` support. Closes #771
|
||||||
|
|
||||||
|
2.4.3 / 2011-07-14
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added docs for `status` option special-case. Closes #739
|
||||||
|
* Fixed `options.filename`, exposing the view path to template engines
|
||||||
|
|
||||||
|
2.4.2. / 2011-07-06
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Revert "removed jsonp stripping" for XSS
|
||||||
|
|
||||||
|
2.4.1 / 2011-07-06
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added `res.json()` JSONP support. Closes #737
|
||||||
|
* Added _extending-templates_ example. Closes #730
|
||||||
|
* Added "strict routing" setting for trailing slashes
|
||||||
|
* Added support for multiple envs in `app.configure()` calls. Closes #735
|
||||||
|
* Changed: `res.send()` using `res.json()`
|
||||||
|
* Changed: when cookie `path === null` don't default it
|
||||||
|
* Changed; default cookie path to "home" setting. Closes #731
|
||||||
|
* Removed _pids/logs_ creation from express(1)
|
||||||
|
|
||||||
|
2.4.0 / 2011-06-28
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added chainable `res.status(code)`
|
||||||
|
* Added `res.json()`, an explicit version of `res.send(obj)`
|
||||||
|
* Added simple web-service example
|
||||||
|
|
||||||
|
2.3.12 / 2011-06-22
|
||||||
|
==================
|
||||||
|
|
||||||
|
* \#express is now on freenode! come join!
|
||||||
|
* Added `req.get(field, param)`
|
||||||
|
* Added links to Japanese documentation, thanks @hideyukisaito!
|
||||||
|
* Added; the `express(1)` generated app outputs the env
|
||||||
|
* Added `content-negotiation` example
|
||||||
|
* Dependency: connect >= 1.5.1 < 2.0.0
|
||||||
|
* Fixed view layout bug. Closes #720
|
||||||
|
* Fixed; ignore body on 304. Closes #701
|
||||||
|
|
||||||
|
2.3.11 / 2011-06-04
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added `npm test`
|
||||||
|
* Removed generation of dummy test file from `express(1)`
|
||||||
|
* Fixed; `express(1)` adds express as a dep
|
||||||
|
* Fixed; prune on `prepublish`
|
||||||
|
|
||||||
|
2.3.10 / 2011-05-27
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added `req.route`, exposing the current route
|
||||||
|
* Added _package.json_ generation support to `express(1)`
|
||||||
|
* Fixed call to `app.param()` function for optional params. Closes #682
|
||||||
|
|
||||||
|
2.3.9 / 2011-05-25
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Fixed bug-ish with `../' in `res.partial()` calls
|
||||||
|
|
||||||
|
2.3.8 / 2011-05-24
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Fixed `app.options()`
|
||||||
|
|
||||||
|
2.3.7 / 2011-05-23
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added route `Collection`, ex: `app.get('/user/:id').remove();`
|
||||||
|
* Added support for `app.param(fn)` to define param logic
|
||||||
|
* Removed `app.param()` support for callback with return value
|
||||||
|
* Removed module.parent check from express(1) generated app. Closes #670
|
||||||
|
* Refactored router. Closes #639
|
||||||
|
|
||||||
|
2.3.6 / 2011-05-20
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Changed; using devDependencies instead of git submodules
|
||||||
|
* Fixed redis session example
|
||||||
|
* Fixed markdown example
|
||||||
|
* Fixed view caching, should not be enabled in development
|
||||||
|
|
||||||
|
2.3.5 / 2011-05-20
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added export `.view` as alias for `.View`
|
||||||
|
|
||||||
|
2.3.4 / 2011-05-08
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added `./examples/say`
|
||||||
|
* Fixed `res.sendfile()` bug preventing the transfer of files with spaces
|
||||||
|
|
||||||
|
2.3.3 / 2011-05-03
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added "case sensitive routes" option.
|
||||||
|
* Changed; split methods supported per rfc [slaskis]
|
||||||
|
* Fixed route-specific middleware when using the same callback function several times
|
||||||
|
|
||||||
|
2.3.2 / 2011-04-27
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Fixed view hints
|
||||||
|
|
||||||
|
2.3.1 / 2011-04-26
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added `app.match()` as `app.match.all()`
|
||||||
|
* Added `app.lookup()` as `app.lookup.all()`
|
||||||
|
* Added `app.remove()` for `app.remove.all()`
|
||||||
|
* Added `app.remove.VERB()`
|
||||||
|
* Fixed template caching collision issue. Closes #644
|
||||||
|
* Moved router over from connect and started refactor
|
||||||
|
|
||||||
|
2.3.0 / 2011-04-25
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added options support to `res.clearCookie()`
|
||||||
|
* Added `res.helpers()` as alias of `res.locals()`
|
||||||
|
* Added; json defaults to UTF-8 with `res.send()`. Closes #632. [Daniel * Dependency `connect >= 1.4.0`
|
||||||
|
* Changed; auto set Content-Type in res.attachement [Aaron Heckmann]
|
||||||
|
* Renamed "cache views" to "view cache". Closes #628
|
||||||
|
* Fixed caching of views when using several apps. Closes #637
|
||||||
|
* Fixed gotcha invoking `app.param()` callbacks once per route middleware.
|
||||||
|
Closes #638
|
||||||
|
* Fixed partial lookup precedence. Closes #631
|
||||||
|
Shaw]
|
||||||
|
|
||||||
|
2.2.2 / 2011-04-12
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added second callback support for `res.download()` connection errors
|
||||||
|
* Fixed `filename` option passing to template engine
|
||||||
|
|
||||||
|
2.2.1 / 2011-04-04
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added `layout(path)` helper to change the layout within a view. Closes #610
|
||||||
|
* Fixed `partial()` collection object support.
|
||||||
|
Previously only anything with `.length` would work.
|
||||||
|
When `.length` is present one must still be aware of holes,
|
||||||
|
however now `{ collection: {foo: 'bar'}}` is valid, exposes
|
||||||
|
`keyInCollection` and `keysInCollection`.
|
||||||
|
|
||||||
|
* Performance improved with better view caching
|
||||||
|
* Removed `request` and `response` locals
|
||||||
|
* Changed; errorHandler page title is now `Express` instead of `Connect`
|
||||||
|
|
||||||
|
2.2.0 / 2011-03-30
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added `app.lookup.VERB()`, ex `app.lookup.put('/user/:id')`. Closes #606
|
||||||
|
* Added `app.match.VERB()`, ex `app.match.put('/user/12')`. Closes #606
|
||||||
|
* Added `app.VERB(path)` as alias of `app.lookup.VERB()`.
|
||||||
|
* Dependency `connect >= 1.2.0`
|
||||||
|
|
||||||
|
2.1.1 / 2011-03-29
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added; expose `err.view` object when failing to locate a view
|
||||||
|
* Fixed `res.partial()` call `next(err)` when no callback is given [reported by aheckmann]
|
||||||
|
* Fixed; `res.send(undefined)` responds with 204 [aheckmann]
|
||||||
|
|
||||||
|
2.1.0 / 2011-03-24
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added `<root>/_?<name>` partial lookup support. Closes #447
|
||||||
|
* Added `request`, `response`, and `app` local variables
|
||||||
|
* Added `settings` local variable, containing the app's settings
|
||||||
|
* Added `req.flash()` exception if `req.session` is not available
|
||||||
|
* Added `res.send(bool)` support (json response)
|
||||||
|
* Fixed stylus example for latest version
|
||||||
|
* Fixed; wrap try/catch around `res.render()`
|
||||||
|
|
||||||
|
2.0.0 / 2011-03-17
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Fixed up index view path alternative.
|
||||||
|
* Changed; `res.locals()` without object returns the locals
|
||||||
|
|
||||||
|
2.0.0rc3 / 2011-03-17
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added `res.locals(obj)` to compliment `res.local(key, val)`
|
||||||
|
* Added `res.partial()` callback support
|
||||||
|
* Fixed recursive error reporting issue in `res.render()`
|
||||||
|
|
||||||
|
2.0.0rc2 / 2011-03-17
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Changed; `partial()` "locals" are now optional
|
||||||
|
* Fixed `SlowBuffer` support. Closes #584 [reported by tyrda01]
|
||||||
|
* Fixed .filename view engine option [reported by drudge]
|
||||||
|
* Fixed blog example
|
||||||
|
* Fixed `{req,res}.app` reference when mounting [Ben Weaver]
|
||||||
|
|
||||||
|
2.0.0rc / 2011-03-14
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Fixed; expose `HTTPSServer` constructor
|
||||||
|
* Fixed express(1) default test charset. Closes #579 [reported by secoif]
|
||||||
|
* Fixed; default charset to utf-8 instead of utf8 for lame IE [reported by NickP]
|
||||||
|
|
||||||
|
2.0.0beta3 / 2011-03-09
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added support for `res.contentType()` literal
|
||||||
|
The original `res.contentType('.json')`,
|
||||||
|
`res.contentType('application/json')`, and `res.contentType('json')`
|
||||||
|
will work now.
|
||||||
|
* Added `res.render()` status option support back
|
||||||
|
* Added charset option for `res.render()`
|
||||||
|
* Added `.charset` support (via connect 1.0.4)
|
||||||
|
* Added view resolution hints when in development and a lookup fails
|
||||||
|
* Added layout lookup support relative to the page view.
|
||||||
|
For example while rendering `./views/user/index.jade` if you create
|
||||||
|
`./views/user/layout.jade` it will be used in favour of the root layout.
|
||||||
|
* Fixed `res.redirect()`. RFC states absolute url [reported by unlink]
|
||||||
|
* Fixed; default `res.send()` string charset to utf8
|
||||||
|
* Removed `Partial` constructor (not currently used)
|
||||||
|
|
||||||
|
2.0.0beta2 / 2011-03-07
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added res.render() `.locals` support back to aid in migration process
|
||||||
|
* Fixed flash example
|
||||||
|
|
||||||
|
2.0.0beta / 2011-03-03
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added HTTPS support
|
||||||
|
* Added `res.cookie()` maxAge support
|
||||||
|
* Added `req.header()` _Referrer_ / _Referer_ special-case, either works
|
||||||
|
* Added mount support for `res.redirect()`, now respects the mount-point
|
||||||
|
* Added `union()` util, taking place of `merge(clone())` combo
|
||||||
|
* Added stylus support to express(1) generated app
|
||||||
|
* Added secret to session middleware used in examples and generated app
|
||||||
|
* Added `res.local(name, val)` for progressive view locals
|
||||||
|
* Added default param support to `req.param(name, default)`
|
||||||
|
* Added `app.disabled()` and `app.enabled()`
|
||||||
|
* Added `app.register()` support for omitting leading ".", either works
|
||||||
|
* Added `res.partial()`, using the same interface as `partial()` within a view. Closes #539
|
||||||
|
* Added `app.param()` to map route params to async/sync logic
|
||||||
|
* Added; aliased `app.helpers()` as `app.locals()`. Closes #481
|
||||||
|
* Added extname with no leading "." support to `res.contentType()`
|
||||||
|
* Added `cache views` setting, defaulting to enabled in "production" env
|
||||||
|
* Added index file partial resolution, eg: partial('user') may try _views/user/index.jade_.
|
||||||
|
* Added `req.accepts()` support for extensions
|
||||||
|
* Changed; `res.download()` and `res.sendfile()` now utilize Connect's
|
||||||
|
static file server `connect.static.send()`.
|
||||||
|
* Changed; replaced `connect.utils.mime()` with npm _mime_ module
|
||||||
|
* Changed; allow `req.query` to be pre-defined (via middleware or other parent
|
||||||
|
* Changed view partial resolution, now relative to parent view
|
||||||
|
* Changed view engine signature. no longer `engine.render(str, options, callback)`, now `engine.compile(str, options) -> Function`, the returned function accepts `fn(locals)`.
|
||||||
|
* Fixed `req.param()` bug returning Array.prototype methods. Closes #552
|
||||||
|
* Fixed; using `Stream#pipe()` instead of `sys.pump()` in `res.sendfile()`
|
||||||
|
* Fixed; using _qs_ module instead of _querystring_
|
||||||
|
* Fixed; strip unsafe chars from jsonp callbacks
|
||||||
|
* Removed "stream threshold" setting
|
||||||
|
|
||||||
|
1.0.8 / 2011-03-01
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Allow `req.query` to be pre-defined (via middleware or other parent app)
|
||||||
|
* "connect": ">= 0.5.0 < 1.0.0". Closes #547
|
||||||
|
* Removed the long deprecated __EXPRESS_ENV__ support
|
||||||
|
|
||||||
|
1.0.7 / 2011-02-07
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Fixed `render()` setting inheritance.
|
||||||
|
Mounted apps would not inherit "view engine"
|
||||||
|
|
||||||
|
1.0.6 / 2011-02-07
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Fixed `view engine` setting bug when period is in dirname
|
||||||
|
|
||||||
|
1.0.5 / 2011-02-05
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added secret to generated app `session()` call
|
||||||
|
|
||||||
|
1.0.4 / 2011-02-05
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added `qs` dependency to _package.json_
|
||||||
|
* Fixed namespaced `require()`s for latest connect support
|
||||||
|
|
||||||
|
1.0.3 / 2011-01-13
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Remove unsafe characters from JSONP callback names [Ryan Grove]
|
||||||
|
|
||||||
|
1.0.2 / 2011-01-10
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Removed nested require, using `connect.router`
|
||||||
|
|
||||||
|
1.0.1 / 2010-12-29
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Fixed for middleware stacked via `createServer()`
|
||||||
|
previously the `foo` middleware passed to `createServer(foo)`
|
||||||
|
would not have access to Express methods such as `res.send()`
|
||||||
|
or props like `req.query` etc.
|
||||||
|
|
||||||
|
1.0.0 / 2010-11-16
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added; deduce partial object names from the last segment.
|
||||||
|
For example by default `partial('forum/post', postObject)` will
|
||||||
|
give you the _post_ object, providing a meaningful default.
|
||||||
|
* Added http status code string representation to `res.redirect()` body
|
||||||
|
* Added; `res.redirect()` supporting _text/plain_ and _text/html_ via __Accept__.
|
||||||
|
* Added `req.is()` to aid in content negotiation
|
||||||
|
* Added partial local inheritance [suggested by masylum]. Closes #102
|
||||||
|
providing access to parent template locals.
|
||||||
|
* Added _-s, --session[s]_ flag to express(1) to add session related middleware
|
||||||
|
* Added _--template_ flag to express(1) to specify the
|
||||||
|
template engine to use.
|
||||||
|
* Added _--css_ flag to express(1) to specify the
|
||||||
|
stylesheet engine to use (or just plain css by default).
|
||||||
|
* Added `app.all()` support [thanks aheckmann]
|
||||||
|
* Added partial direct object support.
|
||||||
|
You may now `partial('user', user)` providing the "user" local,
|
||||||
|
vs previously `partial('user', { object: user })`.
|
||||||
|
* Added _route-separation_ example since many people question ways
|
||||||
|
to do this with CommonJS modules. Also view the _blog_ example for
|
||||||
|
an alternative.
|
||||||
|
* Performance; caching view path derived partial object names
|
||||||
|
* Fixed partial local inheritance precedence. [reported by Nick Poulden] Closes #454
|
||||||
|
* Fixed jsonp support; _text/javascript_ as per mailinglist discussion
|
||||||
|
|
||||||
|
1.0.0rc4 / 2010-10-14
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added _NODE_ENV_ support, _EXPRESS_ENV_ is deprecated and will be removed in 1.0.0
|
||||||
|
* Added route-middleware support (very helpful, see the [docs](http://expressjs.com/guide.html#Route-Middleware))
|
||||||
|
* Added _jsonp callback_ setting to enable/disable jsonp autowrapping [Dav Glass]
|
||||||
|
* Added callback query check on response.send to autowrap JSON objects for simple webservice implementations [Dav Glass]
|
||||||
|
* Added `partial()` support for array-like collections. Closes #434
|
||||||
|
* Added support for swappable querystring parsers
|
||||||
|
* Added session usage docs. Closes #443
|
||||||
|
* Added dynamic helper caching. Closes #439 [suggested by maritz]
|
||||||
|
* Added authentication example
|
||||||
|
* Added basic Range support to `res.sendfile()` (and `res.download()` etc)
|
||||||
|
* Changed; `express(1)` generated app using 2 spaces instead of 4
|
||||||
|
* Default env to "development" again [aheckmann]
|
||||||
|
* Removed _context_ option is no more, use "scope"
|
||||||
|
* Fixed; exposing _./support_ libs to examples so they can run without installs
|
||||||
|
* Fixed mvc example
|
||||||
|
|
||||||
|
1.0.0rc3 / 2010-09-20
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added confirmation for `express(1)` app generation. Closes #391
|
||||||
|
* Added extending of flash formatters via `app.flashFormatters`
|
||||||
|
* Added flash formatter support. Closes #411
|
||||||
|
* Added streaming support to `res.sendfile()` using `sys.pump()` when >= "stream threshold"
|
||||||
|
* Added _stream threshold_ setting for `res.sendfile()`
|
||||||
|
* Added `res.send()` __HEAD__ support
|
||||||
|
* Added `res.clearCookie()`
|
||||||
|
* Added `res.cookie()`
|
||||||
|
* Added `res.render()` headers option
|
||||||
|
* Added `res.redirect()` response bodies
|
||||||
|
* Added `res.render()` status option support. Closes #425 [thanks aheckmann]
|
||||||
|
* Fixed `res.sendfile()` responding with 403 on malicious path
|
||||||
|
* Fixed `res.download()` bug; when an error occurs remove _Content-Disposition_
|
||||||
|
* Fixed; mounted apps settings now inherit from parent app [aheckmann]
|
||||||
|
* Fixed; stripping Content-Length / Content-Type when 204
|
||||||
|
* Fixed `res.send()` 204. Closes #419
|
||||||
|
* Fixed multiple _Set-Cookie_ headers via `res.header()`. Closes #402
|
||||||
|
* Fixed bug messing with error handlers when `listenFD()` is called instead of `listen()`. [thanks guillermo]
|
||||||
|
|
||||||
|
|
||||||
|
1.0.0rc2 / 2010-08-17
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added `app.register()` for template engine mapping. Closes #390
|
||||||
|
* Added `res.render()` callback support as second argument (no options)
|
||||||
|
* Added callback support to `res.download()`
|
||||||
|
* Added callback support for `res.sendfile()`
|
||||||
|
* Added support for middleware access via `express.middlewareName()` vs `connect.middlewareName()`
|
||||||
|
* Added "partials" setting to docs
|
||||||
|
* Added default expresso tests to `express(1)` generated app. Closes #384
|
||||||
|
* Fixed `res.sendfile()` error handling, defer via `next()`
|
||||||
|
* Fixed `res.render()` callback when a layout is used [thanks guillermo]
|
||||||
|
* Fixed; `make install` creating ~/.node_libraries when not present
|
||||||
|
* Fixed issue preventing error handlers from being defined anywhere. Closes #387
|
||||||
|
|
||||||
|
1.0.0rc / 2010-07-28
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added mounted hook. Closes #369
|
||||||
|
* Added connect dependency to _package.json_
|
||||||
|
|
||||||
|
* Removed "reload views" setting and support code
|
||||||
|
development env never caches, production always caches.
|
||||||
|
|
||||||
|
* Removed _param_ in route callbacks, signature is now
|
||||||
|
simply (req, res, next), previously (req, res, params, next).
|
||||||
|
Use _req.params_ for path captures, _req.query_ for GET params.
|
||||||
|
|
||||||
|
* Fixed "home" setting
|
||||||
|
* Fixed middleware/router precedence issue. Closes #366
|
||||||
|
* Fixed; _configure()_ callbacks called immediately. Closes #368
|
||||||
|
|
||||||
|
1.0.0beta2 / 2010-07-23
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added more examples
|
||||||
|
* Added; exporting `Server` constructor
|
||||||
|
* Added `Server#helpers()` for view locals
|
||||||
|
* Added `Server#dynamicHelpers()` for dynamic view locals. Closes #349
|
||||||
|
* Added support for absolute view paths
|
||||||
|
* Added; _home_ setting defaults to `Server#route` for mounted apps. Closes #363
|
||||||
|
* Added Guillermo Rauch to the contributor list
|
||||||
|
* Added support for "as" for non-collection partials. Closes #341
|
||||||
|
* Fixed _install.sh_, ensuring _~/.node_libraries_ exists. Closes #362 [thanks jf]
|
||||||
|
* Fixed `res.render()` exceptions, now passed to `next()` when no callback is given [thanks guillermo]
|
||||||
|
* Fixed instanceof `Array` checks, now `Array.isArray()`
|
||||||
|
* Fixed express(1) expansion of public dirs. Closes #348
|
||||||
|
* Fixed middleware precedence. Closes #345
|
||||||
|
* Fixed view watcher, now async [thanks aheckmann]
|
||||||
|
|
||||||
|
1.0.0beta / 2010-07-15
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Re-write
|
||||||
|
- much faster
|
||||||
|
- much lighter
|
||||||
|
- Check [ExpressJS.com](http://expressjs.com) for migration guide and updated docs
|
||||||
|
|
||||||
|
0.14.0 / 2010-06-15
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Utilize relative requires
|
||||||
|
* Added Static bufferSize option [aheckmann]
|
||||||
|
* Fixed caching of view and partial subdirectories [aheckmann]
|
||||||
|
* Fixed mime.type() comments now that ".ext" is not supported
|
||||||
|
* Updated haml submodule
|
||||||
|
* Updated class submodule
|
||||||
|
* Removed bin/express
|
||||||
|
|
||||||
|
0.13.0 / 2010-06-01
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added node v0.1.97 compatibility
|
||||||
|
* Added support for deleting cookies via Request#cookie('key', null)
|
||||||
|
* Updated haml submodule
|
||||||
|
* Fixed not-found page, now using using charset utf-8
|
||||||
|
* Fixed show-exceptions page, now using using charset utf-8
|
||||||
|
* Fixed view support due to fs.readFile Buffers
|
||||||
|
* Changed; mime.type() no longer accepts ".type" due to node extname() changes
|
||||||
|
|
||||||
|
0.12.0 / 2010-05-22
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added node v0.1.96 compatibility
|
||||||
|
* Added view `helpers` export which act as additional local variables
|
||||||
|
* Updated haml submodule
|
||||||
|
* Changed ETag; removed inode, modified time only
|
||||||
|
* Fixed LF to CRLF for setting multiple cookies
|
||||||
|
* Fixed cookie complation; values are now urlencoded
|
||||||
|
* Fixed cookies parsing; accepts quoted values and url escaped cookies
|
||||||
|
|
||||||
|
0.11.0 / 2010-05-06
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added support for layouts using different engines
|
||||||
|
- this.render('page.html.haml', { layout: 'super-cool-layout.html.ejs' })
|
||||||
|
- this.render('page.html.haml', { layout: 'foo' }) // assumes 'foo.html.haml'
|
||||||
|
- this.render('page.html.haml', { layout: false }) // no layout
|
||||||
|
* Updated ext submodule
|
||||||
|
* Updated haml submodule
|
||||||
|
* Fixed EJS partial support by passing along the context. Issue #307
|
||||||
|
|
||||||
|
0.10.1 / 2010-05-03
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Fixed binary uploads.
|
||||||
|
|
||||||
|
0.10.0 / 2010-04-30
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added charset support via Request#charset (automatically assigned to 'UTF-8' when respond()'s
|
||||||
|
encoding is set to 'utf8' or 'utf-8'.
|
||||||
|
* Added "encoding" option to Request#render(). Closes #299
|
||||||
|
* Added "dump exceptions" setting, which is enabled by default.
|
||||||
|
* Added simple ejs template engine support
|
||||||
|
* Added error reponse support for text/plain, application/json. Closes #297
|
||||||
|
* Added callback function param to Request#error()
|
||||||
|
* Added Request#sendHead()
|
||||||
|
* Added Request#stream()
|
||||||
|
* Added support for Request#respond(304, null) for empty response bodies
|
||||||
|
* Added ETag support to Request#sendfile()
|
||||||
|
* Added options to Request#sendfile(), passed to fs.createReadStream()
|
||||||
|
* Added filename arg to Request#download()
|
||||||
|
* Performance enhanced due to pre-reversing plugins so that plugins.reverse() is not called on each request
|
||||||
|
* Performance enhanced by preventing several calls to toLowerCase() in Router#match()
|
||||||
|
* Changed; Request#sendfile() now streams
|
||||||
|
* Changed; Renamed Request#halt() to Request#respond(). Closes #289
|
||||||
|
* Changed; Using sys.inspect() instead of JSON.encode() for error output
|
||||||
|
* Changed; run() returns the http.Server instance. Closes #298
|
||||||
|
* Changed; Defaulting Server#host to null (INADDR_ANY)
|
||||||
|
* Changed; Logger "common" format scale of 0.4f
|
||||||
|
* Removed Logger "request" format
|
||||||
|
* Fixed; Catching ENOENT in view caching, preventing error when "views/partials" is not found
|
||||||
|
* Fixed several issues with http client
|
||||||
|
* Fixed Logger Content-Length output
|
||||||
|
* Fixed bug preventing Opera from retaining the generated session id. Closes #292
|
||||||
|
|
||||||
|
0.9.0 / 2010-04-14
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added DSL level error() route support
|
||||||
|
* Added DSL level notFound() route support
|
||||||
|
* Added Request#error()
|
||||||
|
* Added Request#notFound()
|
||||||
|
* Added Request#render() callback function. Closes #258
|
||||||
|
* Added "max upload size" setting
|
||||||
|
* Added "magic" variables to collection partials (\_\_index\_\_, \_\_length\_\_, \_\_isFirst\_\_, \_\_isLast\_\_). Closes #254
|
||||||
|
* Added [haml.js](http://github.com/visionmedia/haml.js) submodule; removed haml-js
|
||||||
|
* Added callback function support to Request#halt() as 3rd/4th arg
|
||||||
|
* Added preprocessing of route param wildcards using param(). Closes #251
|
||||||
|
* Added view partial support (with collections etc)
|
||||||
|
* Fixed bug preventing falsey params (such as ?page=0). Closes #286
|
||||||
|
* Fixed setting of multiple cookies. Closes #199
|
||||||
|
* Changed; view naming convention is now NAME.TYPE.ENGINE (for example page.html.haml)
|
||||||
|
* Changed; session cookie is now httpOnly
|
||||||
|
* Changed; Request is no longer global
|
||||||
|
* Changed; Event is no longer global
|
||||||
|
* Changed; "sys" module is no longer global
|
||||||
|
* Changed; moved Request#download to Static plugin where it belongs
|
||||||
|
* Changed; Request instance created before body parsing. Closes #262
|
||||||
|
* Changed; Pre-caching views in memory when "cache view contents" is enabled. Closes #253
|
||||||
|
* Changed; Pre-caching view partials in memory when "cache view partials" is enabled
|
||||||
|
* Updated support to node --version 0.1.90
|
||||||
|
* Updated dependencies
|
||||||
|
* Removed set("session cookie") in favour of use(Session, { cookie: { ... }})
|
||||||
|
* Removed utils.mixin(); use Object#mergeDeep()
|
||||||
|
|
||||||
|
0.8.0 / 2010-03-19
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added coffeescript example app. Closes #242
|
||||||
|
* Changed; cache api now async friendly. Closes #240
|
||||||
|
* Removed deprecated 'express/static' support. Use 'express/plugins/static'
|
||||||
|
|
||||||
|
0.7.6 / 2010-03-19
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added Request#isXHR. Closes #229
|
||||||
|
* Added `make install` (for the executable)
|
||||||
|
* Added `express` executable for setting up simple app templates
|
||||||
|
* Added "GET /public/*" to Static plugin, defaulting to <root>/public
|
||||||
|
* Added Static plugin
|
||||||
|
* Fixed; Request#render() only calls cache.get() once
|
||||||
|
* Fixed; Namespacing View caches with "view:"
|
||||||
|
* Fixed; Namespacing Static caches with "static:"
|
||||||
|
* Fixed; Both example apps now use the Static plugin
|
||||||
|
* Fixed set("views"). Closes #239
|
||||||
|
* Fixed missing space for combined log format
|
||||||
|
* Deprecated Request#sendfile() and 'express/static'
|
||||||
|
* Removed Server#running
|
||||||
|
|
||||||
|
0.7.5 / 2010-03-16
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added Request#flash() support without args, now returns all flashes
|
||||||
|
* Updated ext submodule
|
||||||
|
|
||||||
|
0.7.4 / 2010-03-16
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Fixed session reaper
|
||||||
|
* Changed; class.js replacing js-oo Class implementation (quite a bit faster, no browser cruft)
|
||||||
|
|
||||||
|
0.7.3 / 2010-03-16
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added package.json
|
||||||
|
* Fixed requiring of haml / sass due to kiwi removal
|
||||||
|
|
||||||
|
0.7.2 / 2010-03-16
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Fixed GIT submodules (HAH!)
|
||||||
|
|
||||||
|
0.7.1 / 2010-03-16
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Changed; Express now using submodules again until a PM is adopted
|
||||||
|
* Changed; chat example using millisecond conversions from ext
|
||||||
|
|
||||||
|
0.7.0 / 2010-03-15
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added Request#pass() support (finds the next matching route, or the given path)
|
||||||
|
* Added Logger plugin (default "common" format replaces CommonLogger)
|
||||||
|
* Removed Profiler plugin
|
||||||
|
* Removed CommonLogger plugin
|
||||||
|
|
||||||
|
0.6.0 / 2010-03-11
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added seed.yml for kiwi package management support
|
||||||
|
* Added HTTP client query string support when method is GET. Closes #205
|
||||||
|
|
||||||
|
* Added support for arbitrary view engines.
|
||||||
|
For example "foo.engine.html" will now require('engine'),
|
||||||
|
the exports from this module are cached after the first require().
|
||||||
|
|
||||||
|
* Added async plugin support
|
||||||
|
|
||||||
|
* Removed usage of RESTful route funcs as http client
|
||||||
|
get() etc, use http.get() and friends
|
||||||
|
|
||||||
|
* Removed custom exceptions
|
||||||
|
|
||||||
|
0.5.0 / 2010-03-10
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added ext dependency (library of js extensions)
|
||||||
|
* Removed extname() / basename() utils. Use path module
|
||||||
|
* Removed toArray() util. Use arguments.values
|
||||||
|
* Removed escapeRegexp() util. Use RegExp.escape()
|
||||||
|
* Removed process.mixin() dependency. Use utils.mixin()
|
||||||
|
* Removed Collection
|
||||||
|
* Removed ElementCollection
|
||||||
|
* Shameless self promotion of ebook "Advanced JavaScript" (http://dev-mag.com) ;)
|
||||||
|
|
||||||
|
0.4.0 / 2010-02-11
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added flash() example to sample upload app
|
||||||
|
* Added high level restful http client module (express/http)
|
||||||
|
* Changed; RESTful route functions double as HTTP clients. Closes #69
|
||||||
|
* Changed; throwing error when routes are added at runtime
|
||||||
|
* Changed; defaulting render() context to the current Request. Closes #197
|
||||||
|
* Updated haml submodule
|
||||||
|
|
||||||
|
0.3.0 / 2010-02-11
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Updated haml / sass submodules. Closes #200
|
||||||
|
* Added flash message support. Closes #64
|
||||||
|
* Added accepts() now allows multiple args. fixes #117
|
||||||
|
* Added support for plugins to halt. Closes #189
|
||||||
|
* Added alternate layout support. Closes #119
|
||||||
|
* Removed Route#run(). Closes #188
|
||||||
|
* Fixed broken specs due to use(Cookie) missing
|
||||||
|
|
||||||
|
0.2.1 / 2010-02-05
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added "plot" format option for Profiler (for gnuplot processing)
|
||||||
|
* Added request number to Profiler plugin
|
||||||
|
* Fixed binary encoding for multi-part file uploads, was previously defaulting to UTF8
|
||||||
|
* Fixed issue with routes not firing when not files are present. Closes #184
|
||||||
|
* Fixed process.Promise -> events.Promise
|
||||||
|
|
||||||
|
0.2.0 / 2010-02-03
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added parseParam() support for name[] etc. (allows for file inputs with "multiple" attr) Closes #180
|
||||||
|
* Added Both Cache and Session option "reapInterval" may be "reapEvery". Closes #174
|
||||||
|
* Added expiration support to cache api with reaper. Closes #133
|
||||||
|
* Added cache Store.Memory#reap()
|
||||||
|
* Added Cache; cache api now uses first class Cache instances
|
||||||
|
* Added abstract session Store. Closes #172
|
||||||
|
* Changed; cache Memory.Store#get() utilizing Collection
|
||||||
|
* Renamed MemoryStore -> Store.Memory
|
||||||
|
* Fixed use() of the same plugin several time will always use latest options. Closes #176
|
||||||
|
|
||||||
|
0.1.0 / 2010-02-03
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Changed; Hooks (before / after) pass request as arg as well as evaluated in their context
|
||||||
|
* Updated node support to 0.1.27 Closes #169
|
||||||
|
* Updated dirname(__filename) -> __dirname
|
||||||
|
* Updated libxmljs support to v0.2.0
|
||||||
|
* Added session support with memory store / reaping
|
||||||
|
* Added quick uid() helper
|
||||||
|
* Added multi-part upload support
|
||||||
|
* Added Sass.js support / submodule
|
||||||
|
* Added production env caching view contents and static files
|
||||||
|
* Added static file caching. Closes #136
|
||||||
|
* Added cache plugin with memory stores
|
||||||
|
* Added support to StaticFile so that it works with non-textual files.
|
||||||
|
* Removed dirname() helper
|
||||||
|
* Removed several globals (now their modules must be required)
|
||||||
|
|
||||||
|
0.0.2 / 2010-01-10
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Added view benchmarks; currently haml vs ejs
|
||||||
|
* Added Request#attachment() specs. Closes #116
|
||||||
|
* Added use of node's parseQuery() util. Closes #123
|
||||||
|
* Added `make init` for submodules
|
||||||
|
* Updated Haml
|
||||||
|
* Updated sample chat app to show messages on load
|
||||||
|
* Updated libxmljs parseString -> parseHtmlString
|
||||||
|
* Fixed `make init` to work with older versions of git
|
||||||
|
* Fixed specs can now run independant specs for those who cant build deps. Closes #127
|
||||||
|
* Fixed issues introduced by the node url module changes. Closes 126.
|
||||||
|
* Fixed two assertions failing due to Collection#keys() returning strings
|
||||||
|
* Fixed faulty Collection#toArray() spec due to keys() returning strings
|
||||||
|
* Fixed `make test` now builds libxmljs.node before testing
|
||||||
|
|
||||||
|
0.0.1 / 2010-01-03
|
||||||
|
==================
|
||||||
|
|
||||||
|
* Initial release
|
||||||
22
test/node_modules/express/LICENSE
generated
vendored
Normal file
22
test/node_modules/express/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
(The MIT License)
|
||||||
|
|
||||||
|
Copyright (c) 2009-2011 TJ Holowaychuk <tj@vision-media.ca>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
'Software'), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
29
test/node_modules/express/Makefile
generated
vendored
Normal file
29
test/node_modules/express/Makefile
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
|
||||||
|
DOCS = $(shell find docs/*.md)
|
||||||
|
HTMLDOCS = $(DOCS:.md=.html)
|
||||||
|
TESTS = $(shell find test/*.test.js)
|
||||||
|
|
||||||
|
test:
|
||||||
|
@NODE_ENV=test ./node_modules/.bin/expresso $(TESTS)
|
||||||
|
|
||||||
|
docs: $(HTMLDOCS)
|
||||||
|
@ echo "... generating TOC"
|
||||||
|
@./support/toc.js docs/guide.html
|
||||||
|
|
||||||
|
%.html: %.md
|
||||||
|
@echo "... $< -> $@"
|
||||||
|
@markdown $< \
|
||||||
|
| cat docs/layout/head.html - docs/layout/foot.html \
|
||||||
|
> $@
|
||||||
|
|
||||||
|
site:
|
||||||
|
rm -fr /tmp/docs \
|
||||||
|
&& cp -fr docs /tmp/docs \
|
||||||
|
&& git checkout gh-pages \
|
||||||
|
&& cp -fr /tmp/docs/* . \
|
||||||
|
&& echo "done"
|
||||||
|
|
||||||
|
docclean:
|
||||||
|
rm -f docs/*.{1,html}
|
||||||
|
|
||||||
|
.PHONY: site test docs docclean
|
||||||
145
test/node_modules/express/Readme.md
generated
vendored
Normal file
145
test/node_modules/express/Readme.md
generated
vendored
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
|
||||||
|
# Express
|
||||||
|
|
||||||
|
Insanely fast (and small) server-side JavaScript web development framework
|
||||||
|
built on [node](http://nodejs.org) and [Connect](http://github.com/senchalabs/connect).
|
||||||
|
|
||||||
|
var app = express.createServer();
|
||||||
|
|
||||||
|
app.get('/', function(req, res){
|
||||||
|
res.send('Hello World');
|
||||||
|
});
|
||||||
|
|
||||||
|
app.listen(3000);
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
$ npm install express
|
||||||
|
|
||||||
|
or to access the `express(1)` executable install globally:
|
||||||
|
|
||||||
|
$ npm install -g express
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
The quickest way to get started with express is to utilize the executable `express(1)` to generate an application as shown below:
|
||||||
|
|
||||||
|
Create the app:
|
||||||
|
|
||||||
|
$ npm install -g express
|
||||||
|
$ express /tmp/foo && cd /tmp/foo
|
||||||
|
|
||||||
|
Install dependencies:
|
||||||
|
|
||||||
|
$ npm install -d
|
||||||
|
|
||||||
|
Start the server:
|
||||||
|
|
||||||
|
$ node app.js
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
* Robust routing
|
||||||
|
* Redirection helpers
|
||||||
|
* Dynamic view helpers
|
||||||
|
* Content negotiation
|
||||||
|
* Focus on high performance
|
||||||
|
* View rendering and partials support
|
||||||
|
* Environment based configuration
|
||||||
|
* Session based flash notifications
|
||||||
|
* Built on [Connect](http://github.com/senchalabs/connect)
|
||||||
|
* High test coverage
|
||||||
|
* Executable for generating applications quickly
|
||||||
|
* Application level view options
|
||||||
|
|
||||||
|
Via Connect:
|
||||||
|
|
||||||
|
* Session support
|
||||||
|
* Cache API
|
||||||
|
* Mime helpers
|
||||||
|
* ETag support
|
||||||
|
* Persistent flash notifications
|
||||||
|
* Cookie support
|
||||||
|
* JSON-RPC
|
||||||
|
* Logging
|
||||||
|
* and _much_ more!
|
||||||
|
|
||||||
|
## Contributors
|
||||||
|
|
||||||
|
The following are the major contributors of Express (in no specific order).
|
||||||
|
|
||||||
|
* TJ Holowaychuk ([visionmedia](http://github.com/visionmedia))
|
||||||
|
* Ciaran Jessup ([ciaranj](http://github.com/ciaranj))
|
||||||
|
* Aaron Heckmann ([aheckmann](http://github.com/aheckmann))
|
||||||
|
* Guillermo Rauch ([guille](http://github.com/guille))
|
||||||
|
|
||||||
|
## More Information
|
||||||
|
|
||||||
|
* #express on freenode
|
||||||
|
* [express-expose](http://github.com/visionmedia/express-expose) expose objects, functions, modules and more to client-side js with ease
|
||||||
|
* [express-configure](http://github.com/visionmedia/express-configuration) async configuration support
|
||||||
|
* [express-messages](http://github.com/visionmedia/express-messages) flash notification rendering helper
|
||||||
|
* [express-namespace](http://github.com/visionmedia/express-namespace) namespaced route support
|
||||||
|
* [express-params](https://github.com/visionmedia/express-params) param pre-condition functions
|
||||||
|
* [express-mongoose](https://github.com/LearnBoost/express-mongoose) plugin for easy rendering of Mongoose async Query results
|
||||||
|
* Follow [tjholowaychuk](http://twitter.com/tjholowaychuk) on twitter for updates
|
||||||
|
* [Google Group](http://groups.google.com/group/express-js) for discussion
|
||||||
|
* Visit the [Wiki](http://github.com/visionmedia/express/wiki)
|
||||||
|
* [日本語ドキュメンテーション](http://hideyukisaito.com/doc/expressjs/) by [hideyukisaito](https://github.com/hideyukisaito)
|
||||||
|
* Screencast - [Introduction](http://bit.ly/eRYu0O)
|
||||||
|
* Screencast - [View Partials](http://bit.ly/dU13Fx)
|
||||||
|
* Screencast - [Route Specific Middleware](http://bit.ly/hX4IaH)
|
||||||
|
* Screencast - [Route Path Placeholder Preconditions](http://bit.ly/eNqmVs)
|
||||||
|
|
||||||
|
## Node Compatibility
|
||||||
|
|
||||||
|
Express 1.x is compatible with node 0.2.x and connect < 1.0.
|
||||||
|
|
||||||
|
Express 2.x is compatible with node 0.4.x or 0.6.x, and connect 1.x
|
||||||
|
|
||||||
|
Express 3.x (master) will be compatible with node 0.6.x and connect 2.x
|
||||||
|
|
||||||
|
## Viewing Examples
|
||||||
|
|
||||||
|
First install the dev dependencies to install all the example / test suite deps:
|
||||||
|
|
||||||
|
$ npm install
|
||||||
|
|
||||||
|
then run whichever tests you want:
|
||||||
|
|
||||||
|
$ node examples/jade/app.js
|
||||||
|
|
||||||
|
## Running Tests
|
||||||
|
|
||||||
|
To run the test suite first invoke the following command within the repo, installing the development dependencies:
|
||||||
|
|
||||||
|
$ npm install
|
||||||
|
|
||||||
|
then run the tests:
|
||||||
|
|
||||||
|
$ make test
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
(The MIT License)
|
||||||
|
|
||||||
|
Copyright (c) 2009-2011 TJ Holowaychuk <tj@vision-media.ca>
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
'Software'), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
423
test/node_modules/express/bin/express
generated
vendored
Normal file
423
test/node_modules/express/bin/express
generated
vendored
Normal file
@@ -0,0 +1,423 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var fs = require('fs')
|
||||||
|
, os = require('os')
|
||||||
|
, exec = require('child_process').exec
|
||||||
|
, mkdirp = require('mkdirp');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Package information.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var pkg = JSON.parse(fs.readFileSync(__dirname + '/../package.json'));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Framework version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var version = pkg.version;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add session support.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var sessions = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CSS engine to utilize.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var cssEngine;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* End-of-line code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var eol = os.platform
|
||||||
|
? ('win32' == os.platform() ? '\r\n' : '\n')
|
||||||
|
: '\n';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Template engine to utilize.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var templateEngine = 'jade';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Usage documentation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var usage = ''
|
||||||
|
+ '\n'
|
||||||
|
+ ' Usage: express [options] [path]\n'
|
||||||
|
+ '\n'
|
||||||
|
+ ' Options:\n'
|
||||||
|
+ ' -s, --sessions add session support\n'
|
||||||
|
+ ' -t, --template <engine> add template <engine> support (jade|ejs). default=jade\n'
|
||||||
|
+ ' -c, --css <engine> add stylesheet <engine> support (stylus). default=plain css\n'
|
||||||
|
+ ' -v, --version output framework version\n'
|
||||||
|
+ ' -h, --help output help information\n'
|
||||||
|
;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Routes index template.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var index = [
|
||||||
|
''
|
||||||
|
, '/*'
|
||||||
|
, ' * GET home page.'
|
||||||
|
, ' */'
|
||||||
|
, ''
|
||||||
|
, 'exports.index = function(req, res){'
|
||||||
|
, ' res.render(\'index\', { title: \'Express\' })'
|
||||||
|
, '};'
|
||||||
|
].join(eol);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jade layout template.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var jadeLayout = [
|
||||||
|
'!!!'
|
||||||
|
, 'html'
|
||||||
|
, ' head'
|
||||||
|
, ' title= title'
|
||||||
|
, ' link(rel=\'stylesheet\', href=\'/stylesheets/style.css\')'
|
||||||
|
, ' body!= body'
|
||||||
|
].join(eol);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jade index template.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var jadeIndex = [
|
||||||
|
'h1= title'
|
||||||
|
, 'p Welcome to #{title}'
|
||||||
|
].join(eol);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EJS layout template.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var ejsLayout = [
|
||||||
|
'<!DOCTYPE html>'
|
||||||
|
, '<html>'
|
||||||
|
, ' <head>'
|
||||||
|
, ' <title><%= title %></title>'
|
||||||
|
, ' <link rel=\'stylesheet\' href=\'/stylesheets/style.css\' />'
|
||||||
|
, ' </head>'
|
||||||
|
, ' <body>'
|
||||||
|
, ' <%- body %>'
|
||||||
|
, ' </body>'
|
||||||
|
, '</html>'
|
||||||
|
].join(eol);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* EJS index template.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var ejsIndex = [
|
||||||
|
'<h1><%= title %></h1>'
|
||||||
|
, '<p>Welcome to <%= title %></p>'
|
||||||
|
].join(eol);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default css template.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var css = [
|
||||||
|
'body {'
|
||||||
|
, ' padding: 50px;'
|
||||||
|
, ' font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;'
|
||||||
|
, '}'
|
||||||
|
, ''
|
||||||
|
, 'a {'
|
||||||
|
, ' color: #00B7FF;'
|
||||||
|
, '}'
|
||||||
|
].join(eol);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default stylus template.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var stylus = [
|
||||||
|
'body'
|
||||||
|
, ' padding: 50px'
|
||||||
|
, ' font: 14px "Lucida Grande", Helvetica, Arial, sans-serif'
|
||||||
|
, 'a'
|
||||||
|
, ' color: #00B7FF'
|
||||||
|
].join(eol);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* App template.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var app = [
|
||||||
|
''
|
||||||
|
, '/**'
|
||||||
|
, ' * Module dependencies.'
|
||||||
|
, ' */'
|
||||||
|
, ''
|
||||||
|
, 'var express = require(\'express\')'
|
||||||
|
, ' , routes = require(\'./routes\');'
|
||||||
|
, ''
|
||||||
|
, 'var app = module.exports = express.createServer();'
|
||||||
|
, ''
|
||||||
|
, '// Configuration'
|
||||||
|
, ''
|
||||||
|
, 'app.configure(function(){'
|
||||||
|
, ' app.set(\'views\', __dirname + \'/views\');'
|
||||||
|
, ' app.set(\'view engine\', \':TEMPLATE\');'
|
||||||
|
, ' app.use(express.bodyParser());'
|
||||||
|
, ' app.use(express.methodOverride());{sess}{css}'
|
||||||
|
, ' app.use(app.router);'
|
||||||
|
, ' app.use(express.static(__dirname + \'/public\'));'
|
||||||
|
, '});'
|
||||||
|
, ''
|
||||||
|
, 'app.configure(\'development\', function(){'
|
||||||
|
, ' app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));'
|
||||||
|
, '});'
|
||||||
|
, ''
|
||||||
|
, 'app.configure(\'production\', function(){'
|
||||||
|
, ' app.use(express.errorHandler());'
|
||||||
|
, '});'
|
||||||
|
, ''
|
||||||
|
, '// Routes'
|
||||||
|
, ''
|
||||||
|
, 'app.get(\'/\', routes.index);'
|
||||||
|
, ''
|
||||||
|
, 'app.listen(3000, function(){'
|
||||||
|
, ' console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);'
|
||||||
|
, '});'
|
||||||
|
, ''
|
||||||
|
].join(eol);
|
||||||
|
|
||||||
|
// Parse arguments
|
||||||
|
|
||||||
|
var args = process.argv.slice(2)
|
||||||
|
, path = '.';
|
||||||
|
|
||||||
|
while (args.length) {
|
||||||
|
var arg = args.shift();
|
||||||
|
switch (arg) {
|
||||||
|
case '-h':
|
||||||
|
case '--help':
|
||||||
|
abort(usage);
|
||||||
|
break;
|
||||||
|
case '-v':
|
||||||
|
case '--version':
|
||||||
|
abort(version);
|
||||||
|
break;
|
||||||
|
case '-s':
|
||||||
|
case '--session':
|
||||||
|
case '--sessions':
|
||||||
|
sessions = true;
|
||||||
|
break;
|
||||||
|
case '-c':
|
||||||
|
case '--css':
|
||||||
|
args.length
|
||||||
|
? (cssEngine = args.shift())
|
||||||
|
: abort('--css requires an argument');
|
||||||
|
break;
|
||||||
|
case '-t':
|
||||||
|
case '--template':
|
||||||
|
args.length
|
||||||
|
? (templateEngine = args.shift())
|
||||||
|
: abort('--template requires an argument');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
path = arg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate application
|
||||||
|
|
||||||
|
(function createApplication(path) {
|
||||||
|
emptyDirectory(path, function(empty){
|
||||||
|
if (empty) {
|
||||||
|
createApplicationAt(path);
|
||||||
|
} else {
|
||||||
|
confirm('destination is not empty, continue? ', function(ok){
|
||||||
|
if (ok) {
|
||||||
|
process.stdin.destroy();
|
||||||
|
createApplicationAt(path);
|
||||||
|
} else {
|
||||||
|
abort('aborting');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})(path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create application at the given directory `path`.
|
||||||
|
*
|
||||||
|
* @param {String} path
|
||||||
|
*/
|
||||||
|
|
||||||
|
function createApplicationAt(path) {
|
||||||
|
console.log();
|
||||||
|
process.on('exit', function(){
|
||||||
|
console.log();
|
||||||
|
console.log(' dont forget to install dependencies:');
|
||||||
|
console.log(' $ cd %s && npm install', path);
|
||||||
|
console.log();
|
||||||
|
});
|
||||||
|
|
||||||
|
mkdir(path, function(){
|
||||||
|
mkdir(path + '/public');
|
||||||
|
mkdir(path + '/public/javascripts');
|
||||||
|
mkdir(path + '/public/images');
|
||||||
|
mkdir(path + '/public/stylesheets', function(){
|
||||||
|
switch (cssEngine) {
|
||||||
|
case 'stylus':
|
||||||
|
write(path + '/public/stylesheets/style.styl', stylus);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
write(path + '/public/stylesheets/style.css', css);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mkdir(path + '/routes', function(){
|
||||||
|
write(path + '/routes/index.js', index);
|
||||||
|
});
|
||||||
|
|
||||||
|
mkdir(path + '/views', function(){
|
||||||
|
switch (templateEngine) {
|
||||||
|
case 'ejs':
|
||||||
|
write(path + '/views/layout.ejs', ejsLayout);
|
||||||
|
write(path + '/views/index.ejs', ejsIndex);
|
||||||
|
break;
|
||||||
|
case 'jade':
|
||||||
|
write(path + '/views/layout.jade', jadeLayout);
|
||||||
|
write(path + '/views/index.jade', jadeIndex);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// CSS Engine support
|
||||||
|
switch (cssEngine) {
|
||||||
|
case 'stylus':
|
||||||
|
app = app.replace('{css}', eol + ' app.use(require(\'stylus\').middleware({ src: __dirname + \'/public\' }));');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
app = app.replace('{css}', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Session support
|
||||||
|
app = app.replace('{sess}', sessions
|
||||||
|
? eol + ' app.use(express.cookieParser());' + eol + ' app.use(express.session({ secret: \'your secret here\' }));'
|
||||||
|
: '');
|
||||||
|
|
||||||
|
// Template support
|
||||||
|
app = app.replace(':TEMPLATE', templateEngine);
|
||||||
|
|
||||||
|
// package.json
|
||||||
|
var json = '{' + eol;
|
||||||
|
json += ' "name": "application-name"' + eol;
|
||||||
|
json += ' , "version": "0.0.1"' + eol;
|
||||||
|
json += ' , "private": true' + eol;
|
||||||
|
json += ' , "dependencies": {' + eol;
|
||||||
|
json += ' "express": "' + version + '"' + eol;
|
||||||
|
if (cssEngine) json += ' , "' + cssEngine + '": ">= 0.0.1"' + eol;
|
||||||
|
if (templateEngine) json += ' , "' + templateEngine + '": ">= 0.0.1"' + eol;
|
||||||
|
json += ' }' + eol;
|
||||||
|
json += '}';
|
||||||
|
|
||||||
|
|
||||||
|
write(path + '/package.json', json);
|
||||||
|
write(path + '/app.js', app);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the given directory `path` is empty.
|
||||||
|
*
|
||||||
|
* @param {String} path
|
||||||
|
* @param {Function} fn
|
||||||
|
*/
|
||||||
|
|
||||||
|
function emptyDirectory(path, fn) {
|
||||||
|
fs.readdir(path, function(err, files){
|
||||||
|
if (err && 'ENOENT' != err.code) throw err;
|
||||||
|
fn(!files || !files.length);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* echo str > path.
|
||||||
|
*
|
||||||
|
* @param {String} path
|
||||||
|
* @param {String} str
|
||||||
|
*/
|
||||||
|
|
||||||
|
function write(path, str) {
|
||||||
|
fs.writeFile(path, str);
|
||||||
|
console.log(' \x1b[36mcreate\x1b[0m : ' + path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prompt confirmation with the given `msg`.
|
||||||
|
*
|
||||||
|
* @param {String} msg
|
||||||
|
* @param {Function} fn
|
||||||
|
*/
|
||||||
|
|
||||||
|
function confirm(msg, fn) {
|
||||||
|
prompt(msg, function(val){
|
||||||
|
fn(/^ *y(es)?/i.test(val));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prompt input with the given `msg` and callback `fn`.
|
||||||
|
*
|
||||||
|
* @param {String} msg
|
||||||
|
* @param {Function} fn
|
||||||
|
*/
|
||||||
|
|
||||||
|
function prompt(msg, fn) {
|
||||||
|
// prompt
|
||||||
|
if (' ' == msg[msg.length - 1]) {
|
||||||
|
process.stdout.write(msg);
|
||||||
|
} else {
|
||||||
|
console.log(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// stdin
|
||||||
|
process.stdin.setEncoding('ascii');
|
||||||
|
process.stdin.once('data', function(data){
|
||||||
|
fn(data);
|
||||||
|
}).resume();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mkdir -p.
|
||||||
|
*
|
||||||
|
* @param {String} path
|
||||||
|
* @param {Function} fn
|
||||||
|
*/
|
||||||
|
|
||||||
|
function mkdir(path, fn) {
|
||||||
|
mkdirp(path, 0755, function(err){
|
||||||
|
if (err) throw err;
|
||||||
|
console.log(' \033[36mcreate\033[0m : ' + path);
|
||||||
|
fn && fn();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exit with the given `str`.
|
||||||
|
*
|
||||||
|
* @param {String} str
|
||||||
|
*/
|
||||||
|
|
||||||
|
function abort(str) {
|
||||||
|
console.error(str);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
2
test/node_modules/express/index.js
generated
vendored
Normal file
2
test/node_modules/express/index.js
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
module.exports = require('./lib/express');
|
||||||
79
test/node_modules/express/lib/express.js
generated
vendored
Normal file
79
test/node_modules/express/lib/express.js
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Express
|
||||||
|
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var connect = require('connect')
|
||||||
|
, HTTPSServer = require('./https')
|
||||||
|
, HTTPServer = require('./http')
|
||||||
|
, Route = require('./router/route')
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-export connect auto-loaders.
|
||||||
|
*
|
||||||
|
* This prevents the need to `require('connect')` in order
|
||||||
|
* to access core middleware, so for example `express.logger()` instead
|
||||||
|
* of `require('connect').logger()`.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var exports = module.exports = connect.middleware;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Framework version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.version = '2.5.11';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shortcut for `new Server(...)`.
|
||||||
|
*
|
||||||
|
* @param {Function} ...
|
||||||
|
* @return {Server}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.createServer = function(options){
|
||||||
|
if ('object' == typeof options) {
|
||||||
|
return new HTTPSServer(options, Array.prototype.slice.call(arguments, 1));
|
||||||
|
} else {
|
||||||
|
return new HTTPServer(Array.prototype.slice.call(arguments));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expose constructors.
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.HTTPServer = HTTPServer;
|
||||||
|
exports.HTTPSServer = HTTPSServer;
|
||||||
|
exports.Route = Route;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* View extensions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.View =
|
||||||
|
exports.view = require('./view');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Response extensions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
require('./response');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request extensions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
require('./request');
|
||||||
|
|
||||||
|
// Error handler title
|
||||||
|
|
||||||
|
exports.errorHandler.title = 'Express';
|
||||||
|
|
||||||
582
test/node_modules/express/lib/http.js
generated
vendored
Normal file
582
test/node_modules/express/lib/http.js
generated
vendored
Normal file
@@ -0,0 +1,582 @@
|
|||||||
|
/*!
|
||||||
|
* Express - HTTPServer
|
||||||
|
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var qs = require('qs')
|
||||||
|
, connect = require('connect')
|
||||||
|
, router = require('./router')
|
||||||
|
, Router = require('./router')
|
||||||
|
, view = require('./view')
|
||||||
|
, toArray = require('./utils').toArray
|
||||||
|
, methods = router.methods.concat('del', 'all')
|
||||||
|
, url = require('url')
|
||||||
|
, utils = connect.utils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expose `HTTPServer`.
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports = module.exports = HTTPServer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server proto.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var app = HTTPServer.prototype;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a new `HTTPServer` with optional `middleware`.
|
||||||
|
*
|
||||||
|
* @param {Array} middleware
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
function HTTPServer(middleware){
|
||||||
|
connect.HTTPServer.call(this, []);
|
||||||
|
this.init(middleware);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inherit from `connect.HTTPServer`.
|
||||||
|
*/
|
||||||
|
|
||||||
|
app.__proto__ = connect.HTTPServer.prototype;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the server.
|
||||||
|
*
|
||||||
|
* @param {Array} middleware
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
app.init = function(middleware){
|
||||||
|
var self = this;
|
||||||
|
this.cache = {};
|
||||||
|
this.settings = {};
|
||||||
|
this.redirects = {};
|
||||||
|
this.isCallbacks = {};
|
||||||
|
this._locals = {};
|
||||||
|
this.dynamicViewHelpers = {};
|
||||||
|
this.errorHandlers = [];
|
||||||
|
|
||||||
|
this.set('env', process.env.NODE_ENV || 'development');
|
||||||
|
|
||||||
|
// expose objects to each other
|
||||||
|
this.use(function(req, res, next){
|
||||||
|
req.query = req.query || {};
|
||||||
|
res.setHeader('X-Powered-By', 'Express');
|
||||||
|
req.app = res.app = self;
|
||||||
|
req.res = res;
|
||||||
|
res.req = req;
|
||||||
|
req.next = next;
|
||||||
|
// assign req.query
|
||||||
|
if (req.url.indexOf('?') > 0) {
|
||||||
|
var query = url.parse(req.url).query;
|
||||||
|
req.query = qs.parse(query);
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
// apply middleware
|
||||||
|
if (middleware) middleware.forEach(self.use.bind(self));
|
||||||
|
|
||||||
|
// router
|
||||||
|
this.routes = new Router(this);
|
||||||
|
this.__defineGetter__('router', function(){
|
||||||
|
this.__usedRouter = true;
|
||||||
|
return self.routes.middleware;
|
||||||
|
});
|
||||||
|
|
||||||
|
// default locals
|
||||||
|
this.locals({
|
||||||
|
settings: this.settings
|
||||||
|
, app: this
|
||||||
|
});
|
||||||
|
|
||||||
|
// default development configuration
|
||||||
|
this.configure('development', function(){
|
||||||
|
this.enable('hints');
|
||||||
|
});
|
||||||
|
|
||||||
|
// default production configuration
|
||||||
|
this.configure('production', function(){
|
||||||
|
this.enable('view cache');
|
||||||
|
});
|
||||||
|
|
||||||
|
// register error handlers on "listening"
|
||||||
|
// so that they disregard definition position.
|
||||||
|
this.on('listening', this.registerErrorHandlers.bind(this));
|
||||||
|
|
||||||
|
// route manipulation methods
|
||||||
|
methods.forEach(function(method){
|
||||||
|
self.lookup[method] = function(path){
|
||||||
|
return self.routes.lookup(method, path);
|
||||||
|
};
|
||||||
|
|
||||||
|
self.match[method] = function(path){
|
||||||
|
return self.routes.match(method, path);
|
||||||
|
};
|
||||||
|
|
||||||
|
self.remove[method] = function(path){
|
||||||
|
return self.routes.lookup(method, path).remove();
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// del -> delete
|
||||||
|
self.lookup.del = self.lookup.delete;
|
||||||
|
self.match.del = self.match.delete;
|
||||||
|
self.remove.del = self.remove.delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove routes matching the given `path`.
|
||||||
|
*
|
||||||
|
* @param {Route} path
|
||||||
|
* @return {Boolean}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
app.remove = function(path){
|
||||||
|
return this.routes.lookup('all', path).remove();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lookup routes defined with a path
|
||||||
|
* equivalent to `path`.
|
||||||
|
*
|
||||||
|
* @param {Stirng} path
|
||||||
|
* @return {Array}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
app.lookup = function(path){
|
||||||
|
return this.routes.lookup('all', path);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lookup routes matching the given `url`.
|
||||||
|
*
|
||||||
|
* @param {Stirng} url
|
||||||
|
* @return {Array}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
app.match = function(url){
|
||||||
|
return this.routes.match('all', url);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When using the vhost() middleware register error handlers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
app.onvhost = function(){
|
||||||
|
this.registerErrorHandlers();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register error handlers.
|
||||||
|
*
|
||||||
|
* @return {Server} for chaining
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
app.registerErrorHandlers = function(){
|
||||||
|
this.errorHandlers.forEach(function(fn){
|
||||||
|
this.use(function(err, req, res, next){
|
||||||
|
fn.apply(this, arguments);
|
||||||
|
});
|
||||||
|
}, this);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Proxy `connect.HTTPServer#use()` to apply settings to
|
||||||
|
* mounted applications.
|
||||||
|
*
|
||||||
|
* @param {String|Function|Server} route
|
||||||
|
* @param {Function|Server} middleware
|
||||||
|
* @return {Server} for chaining
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
app.use = function(route, middleware){
|
||||||
|
var app, base, handle;
|
||||||
|
|
||||||
|
if ('string' != typeof route) {
|
||||||
|
middleware = route, route = '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
// express app
|
||||||
|
if (middleware.handle && middleware.set) app = middleware;
|
||||||
|
|
||||||
|
// restore .app property on req and res
|
||||||
|
if (app) {
|
||||||
|
app.route = route;
|
||||||
|
middleware = function(req, res, next) {
|
||||||
|
var orig = req.app;
|
||||||
|
app.handle(req, res, function(err){
|
||||||
|
req.app = res.app = orig;
|
||||||
|
next(err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
connect.HTTPServer.prototype.use.call(this, route, middleware);
|
||||||
|
|
||||||
|
// mounted an app, invoke the hook
|
||||||
|
// and adjust some settings
|
||||||
|
if (app) {
|
||||||
|
base = this.set('basepath') || this.route;
|
||||||
|
if ('/' == base) base = '';
|
||||||
|
base = base + (app.set('basepath') || app.route);
|
||||||
|
app.set('basepath', base);
|
||||||
|
app.parent = this;
|
||||||
|
if (app.__mounted) app.__mounted.call(app, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign a callback `fn` which is called
|
||||||
|
* when this `Server` is passed to `Server#use()`.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
* var app = express.createServer()
|
||||||
|
* , blog = express.createServer();
|
||||||
|
*
|
||||||
|
* blog.mounted(function(parent){
|
||||||
|
* // parent is app
|
||||||
|
* // "this" is blog
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* app.use(blog);
|
||||||
|
*
|
||||||
|
* @param {Function} fn
|
||||||
|
* @return {Server} for chaining
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
app.mounted = function(fn){
|
||||||
|
this.__mounted = fn;
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See: view.register.
|
||||||
|
*
|
||||||
|
* @return {Server} for chaining
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
app.register = function(){
|
||||||
|
view.register.apply(this, arguments);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the given view helpers `obj`. This method
|
||||||
|
* can be called several times to apply additional helpers.
|
||||||
|
*
|
||||||
|
* @param {Object} obj
|
||||||
|
* @return {Server} for chaining
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
app.helpers =
|
||||||
|
app.locals = function(obj){
|
||||||
|
utils.merge(this._locals, obj);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the given dynamic view helpers `obj`. This method
|
||||||
|
* can be called several times to apply additional helpers.
|
||||||
|
*
|
||||||
|
* @param {Object} obj
|
||||||
|
* @return {Server} for chaining
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
app.dynamicHelpers = function(obj){
|
||||||
|
utils.merge(this.dynamicViewHelpers, obj);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map the given param placeholder `name`(s) to the given callback(s).
|
||||||
|
*
|
||||||
|
* Param mapping is used to provide pre-conditions to routes
|
||||||
|
* which us normalized placeholders. This callback has the same
|
||||||
|
* signature as regular middleware, for example below when ":userId"
|
||||||
|
* is used this function will be invoked in an attempt to load the user.
|
||||||
|
*
|
||||||
|
* app.param('userId', function(req, res, next, id){
|
||||||
|
* User.find(id, function(err, user){
|
||||||
|
* if (err) {
|
||||||
|
* next(err);
|
||||||
|
* } else if (user) {
|
||||||
|
* req.user = user;
|
||||||
|
* next();
|
||||||
|
* } else {
|
||||||
|
* next(new Error('failed to load user'));
|
||||||
|
* }
|
||||||
|
* });
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* Passing a single function allows you to map logic
|
||||||
|
* to the values passed to `app.param()`, for example
|
||||||
|
* this is useful to provide coercion support in a concise manner.
|
||||||
|
*
|
||||||
|
* The following example maps regular expressions to param values
|
||||||
|
* ensuring that they match, otherwise passing control to the next
|
||||||
|
* route:
|
||||||
|
*
|
||||||
|
* app.param(function(name, regexp){
|
||||||
|
* if (regexp instanceof RegExp) {
|
||||||
|
* return function(req, res, next, val){
|
||||||
|
* var captures;
|
||||||
|
* if (captures = regexp.exec(String(val))) {
|
||||||
|
* req.params[name] = captures;
|
||||||
|
* next();
|
||||||
|
* } else {
|
||||||
|
* next('route');
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* We can now use it as shown below, where "/commit/:commit" expects
|
||||||
|
* that the value for ":commit" is at 5 or more digits. The capture
|
||||||
|
* groups are then available as `req.params.commit` as we defined
|
||||||
|
* in the function above.
|
||||||
|
*
|
||||||
|
* app.param('commit', /^\d{5,}$/);
|
||||||
|
*
|
||||||
|
* For more of this useful functionality take a look
|
||||||
|
* at [express-params](http://github.com/visionmedia/express-params).
|
||||||
|
*
|
||||||
|
* @param {String|Array|Function} name
|
||||||
|
* @param {Function} fn
|
||||||
|
* @return {Server} for chaining
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
app.param = function(name, fn){
|
||||||
|
var self = this
|
||||||
|
, fns = [].slice.call(arguments, 1);
|
||||||
|
|
||||||
|
// array
|
||||||
|
if (Array.isArray(name)) {
|
||||||
|
name.forEach(function(name){
|
||||||
|
fns.forEach(function(fn){
|
||||||
|
self.param(name, fn);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// param logic
|
||||||
|
} else if ('function' == typeof name) {
|
||||||
|
this.routes.param(name);
|
||||||
|
// single
|
||||||
|
} else {
|
||||||
|
if (':' == name[0]) name = name.substr(1);
|
||||||
|
fns.forEach(function(fn){
|
||||||
|
self.routes.param(name, fn);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign a custom exception handler callback `fn`.
|
||||||
|
* These handlers are always _last_ in the middleware stack.
|
||||||
|
*
|
||||||
|
* @param {Function} fn
|
||||||
|
* @return {Server} for chaining
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
app.error = function(fn){
|
||||||
|
this.errorHandlers.push(fn);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the given callback `fn` for the given `type`.
|
||||||
|
*
|
||||||
|
* @param {String} type
|
||||||
|
* @param {Function} fn
|
||||||
|
* @return {Server} for chaining
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
app.is = function(type, fn){
|
||||||
|
if (!fn) return this.isCallbacks[type];
|
||||||
|
this.isCallbacks[type] = fn;
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign `setting` to `val`, or return `setting`'s value.
|
||||||
|
* Mounted servers inherit their parent server's settings.
|
||||||
|
*
|
||||||
|
* @param {String} setting
|
||||||
|
* @param {String} val
|
||||||
|
* @return {Server|Mixed} for chaining, or the setting value
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
app.set = function(setting, val){
|
||||||
|
if (val === undefined) {
|
||||||
|
if (this.settings.hasOwnProperty(setting)) {
|
||||||
|
return this.settings[setting];
|
||||||
|
} else if (this.parent) {
|
||||||
|
return this.parent.set(setting);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.settings[setting] = val;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if `setting` is enabled.
|
||||||
|
*
|
||||||
|
* @param {String} setting
|
||||||
|
* @return {Boolean}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
app.enabled = function(setting){
|
||||||
|
return !!this.set(setting);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if `setting` is disabled.
|
||||||
|
*
|
||||||
|
* @param {String} setting
|
||||||
|
* @return {Boolean}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
app.disabled = function(setting){
|
||||||
|
return !this.set(setting);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable `setting`.
|
||||||
|
*
|
||||||
|
* @param {String} setting
|
||||||
|
* @return {Server} for chaining
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
app.enable = function(setting){
|
||||||
|
return this.set(setting, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable `setting`.
|
||||||
|
*
|
||||||
|
* @param {String} setting
|
||||||
|
* @return {Server} for chaining
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
app.disable = function(setting){
|
||||||
|
return this.set(setting, false);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redirect `key` to `url`.
|
||||||
|
*
|
||||||
|
* @param {String} key
|
||||||
|
* @param {String} url
|
||||||
|
* @return {Server} for chaining
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
app.redirect = function(key, url){
|
||||||
|
this.redirects[key] = url;
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure callback for zero or more envs,
|
||||||
|
* when no env is specified that callback will
|
||||||
|
* be invoked for all environments. Any combination
|
||||||
|
* can be used multiple times, in any order desired.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
* app.configure(function(){
|
||||||
|
* // executed for all envs
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* app.configure('stage', function(){
|
||||||
|
* // executed staging env
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* app.configure('stage', 'production', function(){
|
||||||
|
* // executed for stage and production
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* @param {String} env...
|
||||||
|
* @param {Function} fn
|
||||||
|
* @return {Server} for chaining
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
app.configure = function(env, fn){
|
||||||
|
var envs = 'all'
|
||||||
|
, args = toArray(arguments);
|
||||||
|
fn = args.pop();
|
||||||
|
if (args.length) envs = args;
|
||||||
|
if ('all' == envs || ~envs.indexOf(this.settings.env)) fn.call(this);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delegate `.VERB(...)` calls to `.route(VERB, ...)`.
|
||||||
|
*/
|
||||||
|
|
||||||
|
methods.forEach(function(method){
|
||||||
|
app[method] = function(path){
|
||||||
|
if (1 == arguments.length) return this.routes.lookup(method, path);
|
||||||
|
var args = [method].concat(toArray(arguments));
|
||||||
|
if (!this.__usedRouter) this.use(this.router);
|
||||||
|
return this.routes._route.apply(this.routes, args);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Special-cased "all" method, applying the given route `path`,
|
||||||
|
* middleware, and callback to _every_ HTTP method.
|
||||||
|
*
|
||||||
|
* @param {String} path
|
||||||
|
* @param {Function} ...
|
||||||
|
* @return {Server} for chaining
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
app.all = function(path){
|
||||||
|
var args = arguments;
|
||||||
|
if (1 == args.length) return this.routes.lookup('all', path);
|
||||||
|
methods.forEach(function(method){
|
||||||
|
if ('all' == method || 'del' == method) return;
|
||||||
|
app[method].apply(this, args);
|
||||||
|
}, this);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
// del -> delete alias
|
||||||
|
|
||||||
|
app.del = app.delete;
|
||||||
|
|
||||||
52
test/node_modules/express/lib/https.js
generated
vendored
Normal file
52
test/node_modules/express/lib/https.js
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Express - HTTPSServer
|
||||||
|
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var connect = require('connect')
|
||||||
|
, HTTPServer = require('./http')
|
||||||
|
, https = require('https');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expose `HTTPSServer`.
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports = module.exports = HTTPSServer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server proto.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var app = HTTPSServer.prototype;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a new `HTTPSServer` with the
|
||||||
|
* given `options`, and optional `middleware`.
|
||||||
|
*
|
||||||
|
* @param {Object} options
|
||||||
|
* @param {Array} middleware
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
function HTTPSServer(options, middleware){
|
||||||
|
connect.HTTPSServer.call(this, options, []);
|
||||||
|
this.init(middleware);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inherit from `connect.HTTPSServer`.
|
||||||
|
*/
|
||||||
|
|
||||||
|
app.__proto__ = connect.HTTPSServer.prototype;
|
||||||
|
|
||||||
|
// mixin HTTPServer methods
|
||||||
|
|
||||||
|
Object.keys(HTTPServer.prototype).forEach(function(method){
|
||||||
|
app[method] = HTTPServer.prototype[method];
|
||||||
|
});
|
||||||
357
test/node_modules/express/lib/request.js
generated
vendored
Normal file
357
test/node_modules/express/lib/request.js
generated
vendored
Normal file
@@ -0,0 +1,357 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Express - request
|
||||||
|
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var http = require('http')
|
||||||
|
, req = http.IncomingMessage.prototype
|
||||||
|
, utils = require('./utils')
|
||||||
|
, parse = require('url').parse
|
||||||
|
, mime = require('mime');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default flash formatters.
|
||||||
|
*
|
||||||
|
* @type Object
|
||||||
|
*/
|
||||||
|
|
||||||
|
var flashFormatters = exports.flashFormatters = {
|
||||||
|
s: function(val){
|
||||||
|
return String(val);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return request header or optional default.
|
||||||
|
*
|
||||||
|
* The `Referrer` header field is special-cased,
|
||||||
|
* both `Referrer` and `Referer` will yield are
|
||||||
|
* interchangeable.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
* req.header('Content-Type');
|
||||||
|
* // => "text/plain"
|
||||||
|
*
|
||||||
|
* req.header('content-type');
|
||||||
|
* // => "text/plain"
|
||||||
|
*
|
||||||
|
* req.header('Accept');
|
||||||
|
* // => undefined
|
||||||
|
*
|
||||||
|
* req.header('Accept', 'text/html');
|
||||||
|
* // => "text/html"
|
||||||
|
*
|
||||||
|
* @param {String} name
|
||||||
|
* @param {String} defaultValue
|
||||||
|
* @return {String}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
req.header = function(name, defaultValue){
|
||||||
|
switch (name = name.toLowerCase()) {
|
||||||
|
case 'referer':
|
||||||
|
case 'referrer':
|
||||||
|
return this.headers.referrer
|
||||||
|
|| this.headers.referer
|
||||||
|
|| defaultValue;
|
||||||
|
default:
|
||||||
|
return this.headers[name] || defaultValue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get `field`'s `param` value, defaulting to ''.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
* req.get('content-disposition', 'filename');
|
||||||
|
* // => "something.png"
|
||||||
|
*
|
||||||
|
* @param {String} field
|
||||||
|
* @param {String} param
|
||||||
|
* @return {String}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
req.get = function(field, param){
|
||||||
|
var val = this.header(field);
|
||||||
|
if (!val) return '';
|
||||||
|
var regexp = new RegExp(param + ' *= *(?:"([^"]+)"|([^;]+))', 'i');
|
||||||
|
if (!regexp.exec(val)) return '';
|
||||||
|
return RegExp.$1 || RegExp.$2;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Short-hand for `require('url').parse(req.url).pathname`.
|
||||||
|
*
|
||||||
|
* @return {String}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
req.__defineGetter__('path', function(){
|
||||||
|
return parse(this.url).pathname;
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the _Accept_ header is present, and includes the given `type`.
|
||||||
|
*
|
||||||
|
* When the _Accept_ header is not present `true` is returned. Otherwise
|
||||||
|
* the given `type` is matched by an exact match, and then subtypes. You
|
||||||
|
* may pass the subtype such as "html" which is then converted internally
|
||||||
|
* to "text/html" using the mime lookup table.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
* // Accept: text/html
|
||||||
|
* req.accepts('html');
|
||||||
|
* // => true
|
||||||
|
*
|
||||||
|
* // Accept: text/*; application/json
|
||||||
|
* req.accepts('html');
|
||||||
|
* req.accepts('text/html');
|
||||||
|
* req.accepts('text/plain');
|
||||||
|
* req.accepts('application/json');
|
||||||
|
* // => true
|
||||||
|
*
|
||||||
|
* req.accepts('image/png');
|
||||||
|
* req.accepts('png');
|
||||||
|
* // => false
|
||||||
|
*
|
||||||
|
* @param {String} type
|
||||||
|
* @return {Boolean}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
req.accepts = function(type){
|
||||||
|
var accept = this.header('Accept');
|
||||||
|
|
||||||
|
// normalize extensions ".json" -> "json"
|
||||||
|
if (type && '.' == type[0]) type = type.substr(1);
|
||||||
|
|
||||||
|
// when Accept does not exist, or contains '*/*' return true
|
||||||
|
if (!accept || ~accept.indexOf('*/*')) {
|
||||||
|
return true;
|
||||||
|
} else if (type) {
|
||||||
|
// allow "html" vs "text/html" etc
|
||||||
|
if (!~type.indexOf('/')) type = mime.lookup(type);
|
||||||
|
|
||||||
|
// check if we have a direct match
|
||||||
|
if (~accept.indexOf(type)) return true;
|
||||||
|
|
||||||
|
// check if we have type/*
|
||||||
|
type = type.split('/')[0] + '/*';
|
||||||
|
return !!~accept.indexOf(type);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the value of param `name` when present or `defaultValue`.
|
||||||
|
*
|
||||||
|
* - Checks route placeholders, ex: _/user/:id_
|
||||||
|
* - Checks query string params, ex: ?id=12
|
||||||
|
* - Checks urlencoded body params, ex: id=12
|
||||||
|
*
|
||||||
|
* To utilize urlencoded request bodies, `req.body`
|
||||||
|
* should be an object. This can be done by using
|
||||||
|
* the `connect.bodyParser` middleware.
|
||||||
|
*
|
||||||
|
* @param {String} name
|
||||||
|
* @param {Mixed} defaultValue
|
||||||
|
* @return {String}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
req.param = function(name, defaultValue){
|
||||||
|
// route params like /user/:id
|
||||||
|
if (this.params && this.params.hasOwnProperty(name) && undefined !== this.params[name]) {
|
||||||
|
return this.params[name];
|
||||||
|
}
|
||||||
|
// query string params
|
||||||
|
if (undefined !== this.query[name]) {
|
||||||
|
return this.query[name];
|
||||||
|
}
|
||||||
|
// request body params via connect.bodyParser
|
||||||
|
if (this.body && undefined !== this.body[name]) {
|
||||||
|
return this.body[name];
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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: [] }
|
||||||
|
*
|
||||||
|
* Formatting:
|
||||||
|
*
|
||||||
|
* Flash notifications also support arbitrary formatting support.
|
||||||
|
* For example you may pass variable arguments to `req.flash()`
|
||||||
|
* and use the %s specifier to be replaced by the associated argument:
|
||||||
|
*
|
||||||
|
* req.flash('info', 'email has been sent to %s.', userName);
|
||||||
|
*
|
||||||
|
* To add custom formatters use the `exports.flashFormatters` object.
|
||||||
|
*
|
||||||
|
* @param {String} type
|
||||||
|
* @param {String} msg
|
||||||
|
* @return {Array|Object|Number}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
req.flash = function(type, msg){
|
||||||
|
if (this.session === undefined) throw Error('req.flash() requires sessions');
|
||||||
|
var msgs = this.session.flash = this.session.flash || {};
|
||||||
|
if (type && msg) {
|
||||||
|
var i = 2
|
||||||
|
, args = arguments
|
||||||
|
, formatters = this.app.flashFormatters || {};
|
||||||
|
formatters.__proto__ = flashFormatters;
|
||||||
|
msg = utils.miniMarkdown(msg);
|
||||||
|
msg = msg.replace(/%([a-zA-Z])/g, function(_, format){
|
||||||
|
var formatter = formatters[format];
|
||||||
|
if (formatter) return formatter(utils.escape(args[i++]));
|
||||||
|
});
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the incoming request contains the "Content-Type"
|
||||||
|
* header field, and it contains the give mime `type`.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
* // With Content-Type: text/html; charset=utf-8
|
||||||
|
* req.is('html');
|
||||||
|
* req.is('text/html');
|
||||||
|
* // => true
|
||||||
|
*
|
||||||
|
* // When Content-Type is application/json
|
||||||
|
* req.is('json');
|
||||||
|
* req.is('application/json');
|
||||||
|
* // => true
|
||||||
|
*
|
||||||
|
* req.is('html');
|
||||||
|
* // => false
|
||||||
|
*
|
||||||
|
* Ad-hoc callbacks can also be registered with Express, to perform
|
||||||
|
* assertions again the request, for example if we need an expressive
|
||||||
|
* way to check if our incoming request is an image, we can register "an image"
|
||||||
|
* callback:
|
||||||
|
*
|
||||||
|
* app.is('an image', function(req){
|
||||||
|
* return 0 == req.headers['content-type'].indexOf('image');
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* Now within our route callbacks, we can use to to assert content types
|
||||||
|
* such as "image/jpeg", "image/png", etc.
|
||||||
|
*
|
||||||
|
* app.post('/image/upload', function(req, res, next){
|
||||||
|
* if (req.is('an image')) {
|
||||||
|
* // do something
|
||||||
|
* } else {
|
||||||
|
* next();
|
||||||
|
* }
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* @param {String} type
|
||||||
|
* @return {Boolean}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
req.is = function(type){
|
||||||
|
var fn = this.app.is(type);
|
||||||
|
if (fn) return fn(this);
|
||||||
|
var ct = this.headers['content-type'];
|
||||||
|
if (!ct) return false;
|
||||||
|
ct = ct.split(';')[0];
|
||||||
|
if (!~type.indexOf('/')) type = mime.lookup(type);
|
||||||
|
if (~type.indexOf('*')) {
|
||||||
|
type = type.split('/');
|
||||||
|
ct = ct.split('/');
|
||||||
|
if ('*' == type[0] && type[1] == ct[1]) return true;
|
||||||
|
if ('*' == type[1] && type[0] == ct[0]) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return !! ~ct.indexOf(type);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Callback for isXMLHttpRequest / xhr
|
||||||
|
|
||||||
|
function isxhr() {
|
||||||
|
return this.header('X-Requested-With', '').toLowerCase() === 'xmlhttprequest';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the request was an _XMLHttpRequest_.
|
||||||
|
*
|
||||||
|
* @return {Boolean}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
req.__defineGetter__('isXMLHttpRequest', isxhr);
|
||||||
|
req.__defineGetter__('xhr', isxhr);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the protocol string "http" or "https"
|
||||||
|
* when requested with TLS. When the "trust proxy"
|
||||||
|
* setting is enabled the "X-Forwarded-Proto" header
|
||||||
|
* field will be trusted. If you're running behind
|
||||||
|
* a reverse proxy that supplies https for you this
|
||||||
|
* may be enabled.
|
||||||
|
*
|
||||||
|
* @return {String}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
req.__defineGetter__('protocol', function(){
|
||||||
|
var trustProxy = this.app.set('trust proxy');
|
||||||
|
return this.connection.encrypted
|
||||||
|
? 'https'
|
||||||
|
: trustProxy
|
||||||
|
? (this.header('X-Forwarded-Proto') || 'http')
|
||||||
|
: 'http';
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Short-hand for:
|
||||||
|
*
|
||||||
|
* req.protocol == 'https'
|
||||||
|
*
|
||||||
|
* @return {Boolean}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
req.__defineGetter__('secure', function(){
|
||||||
|
return 'https' == this.protocol;
|
||||||
|
});
|
||||||
459
test/node_modules/express/lib/response.js
generated
vendored
Normal file
459
test/node_modules/express/lib/response.js
generated
vendored
Normal file
@@ -0,0 +1,459 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Express - response
|
||||||
|
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var fs = require('fs')
|
||||||
|
, http = require('http')
|
||||||
|
, path = require('path')
|
||||||
|
, connect = require('connect')
|
||||||
|
, utils = connect.utils
|
||||||
|
, parseRange = require('./utils').parseRange
|
||||||
|
, res = http.ServerResponse.prototype
|
||||||
|
, send = connect.static.send
|
||||||
|
, mime = require('mime')
|
||||||
|
, basename = path.basename
|
||||||
|
, join = path.join;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a response with the given `body` and optional `headers` and `status` code.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
* res.send();
|
||||||
|
* res.send(new Buffer('wahoo'));
|
||||||
|
* res.send({ some: 'json' });
|
||||||
|
* res.send('<p>some html</p>');
|
||||||
|
* res.send('Sorry, cant find that', 404);
|
||||||
|
* res.send('text', { 'Content-Type': 'text/plain' }, 201);
|
||||||
|
* res.send(404);
|
||||||
|
*
|
||||||
|
* @param {String|Object|Number|Buffer} body or status
|
||||||
|
* @param {Object|Number} headers or status
|
||||||
|
* @param {Number} status
|
||||||
|
* @return {ServerResponse}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
res.send = function(body, headers, status){
|
||||||
|
// allow status as second arg
|
||||||
|
if ('number' == typeof headers) {
|
||||||
|
status = headers,
|
||||||
|
headers = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// default status
|
||||||
|
status = status || this.statusCode;
|
||||||
|
|
||||||
|
// allow 0 args as 204
|
||||||
|
if (!arguments.length || undefined === body) status = 204;
|
||||||
|
|
||||||
|
// determine content type
|
||||||
|
switch (typeof body) {
|
||||||
|
case 'number':
|
||||||
|
if (!this.header('Content-Type')) {
|
||||||
|
this.contentType('.txt');
|
||||||
|
}
|
||||||
|
body = http.STATUS_CODES[status = body];
|
||||||
|
break;
|
||||||
|
case 'string':
|
||||||
|
if (!this.header('Content-Type')) {
|
||||||
|
this.charset = this.charset || 'utf-8';
|
||||||
|
this.contentType('.html');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'boolean':
|
||||||
|
case 'object':
|
||||||
|
if (Buffer.isBuffer(body)) {
|
||||||
|
if (!this.header('Content-Type')) {
|
||||||
|
this.contentType('.bin');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return this.json(body, headers, status);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// populate Content-Length
|
||||||
|
if (undefined !== body && !this.header('Content-Length')) {
|
||||||
|
this.header('Content-Length', Buffer.isBuffer(body)
|
||||||
|
? body.length
|
||||||
|
: Buffer.byteLength(body));
|
||||||
|
}
|
||||||
|
|
||||||
|
// merge headers passed
|
||||||
|
if (headers) {
|
||||||
|
var fields = Object.keys(headers);
|
||||||
|
for (var i = 0, len = fields.length; i < len; ++i) {
|
||||||
|
var field = fields[i];
|
||||||
|
this.header(field, headers[field]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// strip irrelevant headers
|
||||||
|
if (204 == status || 304 == status) {
|
||||||
|
this.removeHeader('Content-Type');
|
||||||
|
this.removeHeader('Content-Length');
|
||||||
|
body = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// respond
|
||||||
|
this.statusCode = status;
|
||||||
|
this.end('HEAD' == this.req.method ? null : body);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send JSON response with `obj`, optional `headers`, and optional `status`.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
* res.json(null);
|
||||||
|
* res.json({ user: 'tj' });
|
||||||
|
* res.json('oh noes!', 500);
|
||||||
|
* res.json('I dont have that', 404);
|
||||||
|
*
|
||||||
|
* @param {Mixed} obj
|
||||||
|
* @param {Object|Number} headers or status
|
||||||
|
* @param {Number} status
|
||||||
|
* @return {ServerResponse}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
res.json = function(obj, headers, status){
|
||||||
|
var body = JSON.stringify(obj)
|
||||||
|
, callback = this.req.query.callback
|
||||||
|
, jsonp = this.app.enabled('jsonp callback');
|
||||||
|
|
||||||
|
this.charset = this.charset || 'utf-8';
|
||||||
|
this.header('Content-Type', 'application/json');
|
||||||
|
|
||||||
|
if (callback && jsonp) {
|
||||||
|
this.header('Content-Type', 'text/javascript');
|
||||||
|
body = callback.replace(/[^\w$.]/g, '') + '(' + body + ');';
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.send(body, headers, status);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set status `code`.
|
||||||
|
*
|
||||||
|
* @param {Number} code
|
||||||
|
* @return {ServerResponse}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
res.status = function(code){
|
||||||
|
this.statusCode = code;
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transfer the file at the given `path`. Automatically sets
|
||||||
|
* the _Content-Type_ response header field. `next()` is called
|
||||||
|
* when `path` is a directory, or when an error occurs.
|
||||||
|
*
|
||||||
|
* Options:
|
||||||
|
*
|
||||||
|
* - `maxAge` defaulting to 0
|
||||||
|
* - `root` root directory for relative filenames
|
||||||
|
*
|
||||||
|
* @param {String} path
|
||||||
|
* @param {Object|Function} options or fn
|
||||||
|
* @param {Function} fn
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
res.sendfile = function(path, options, fn){
|
||||||
|
var next = this.req.next;
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
// support function as second arg
|
||||||
|
if ('function' == typeof options) {
|
||||||
|
fn = options;
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
options.path = encodeURIComponent(path);
|
||||||
|
options.callback = fn;
|
||||||
|
send(this.req, this, next, options);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set _Content-Type_ response header passed through `mime.lookup()`.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
* var filename = 'path/to/image.png';
|
||||||
|
* res.contentType(filename);
|
||||||
|
* // res.headers['Content-Type'] is now "image/png"
|
||||||
|
*
|
||||||
|
* res.contentType('.html');
|
||||||
|
* res.contentType('html');
|
||||||
|
* res.contentType('json');
|
||||||
|
* res.contentType('png');
|
||||||
|
*
|
||||||
|
* @param {String} type
|
||||||
|
* @return {String} the resolved mime type
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
res.contentType = function(type){
|
||||||
|
return this.header('Content-Type', mime.lookup(type));
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set _Content-Disposition_ header to _attachment_ with optional `filename`.
|
||||||
|
*
|
||||||
|
* @param {String} filename
|
||||||
|
* @return {ServerResponse}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
res.attachment = function(filename){
|
||||||
|
if (filename) this.contentType(filename);
|
||||||
|
this.header('Content-Disposition', filename
|
||||||
|
? 'attachment; filename="' + basename(filename) + '"'
|
||||||
|
: 'attachment');
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transfer the file at the given `path`, with optional
|
||||||
|
* `filename` as an attachment and optional callback `fn(err)`,
|
||||||
|
* and optional `fn2(err)` which is invoked when an error has
|
||||||
|
* occurred after header has been sent.
|
||||||
|
*
|
||||||
|
* @param {String} path
|
||||||
|
* @param {String|Function} filename or fn
|
||||||
|
* @param {Function} fn
|
||||||
|
* @param {Function} fn2
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
res.download = function(path, filename, fn, fn2){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
// support callback as second arg
|
||||||
|
if ('function' == typeof filename) {
|
||||||
|
fn2 = fn;
|
||||||
|
fn = filename;
|
||||||
|
filename = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// transfer the file
|
||||||
|
this.attachment(filename || path).sendfile(path, function(err){
|
||||||
|
var sentHeader = self._header;
|
||||||
|
if (err) {
|
||||||
|
if (!sentHeader) self.removeHeader('Content-Disposition');
|
||||||
|
if (sentHeader) {
|
||||||
|
fn2 && fn2(err);
|
||||||
|
} else if (fn) {
|
||||||
|
fn(err);
|
||||||
|
} else {
|
||||||
|
self.req.next(err);
|
||||||
|
}
|
||||||
|
} else if (fn) {
|
||||||
|
fn();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set or get response header `name` with optional `val`.
|
||||||
|
*
|
||||||
|
* @param {String} name
|
||||||
|
* @param {String} val
|
||||||
|
* @return {ServerResponse} for chaining
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
res.header = function(name, val){
|
||||||
|
if (1 == arguments.length) return this.getHeader(name);
|
||||||
|
this.setHeader(name, val);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear cookie `name`.
|
||||||
|
*
|
||||||
|
* @param {String} name
|
||||||
|
* @param {Object} options
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
res.clearCookie = function(name, options){
|
||||||
|
var opts = { expires: new Date(1) };
|
||||||
|
this.cookie(name, '', options
|
||||||
|
? utils.merge(options, opts)
|
||||||
|
: opts);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set cookie `name` to `val`, with the given `options`.
|
||||||
|
*
|
||||||
|
* Options:
|
||||||
|
*
|
||||||
|
* - `maxAge` max-age in milliseconds, converted to `expires`
|
||||||
|
* - `path` defaults to the "basepath" setting which is typically "/"
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
* // "Remember Me" for 15 minutes
|
||||||
|
* res.cookie('rememberme', '1', { expires: new Date(Date.now() + 900000), httpOnly: true });
|
||||||
|
*
|
||||||
|
* // save as above
|
||||||
|
* res.cookie('rememberme', '1', { maxAge: 900000, httpOnly: true })
|
||||||
|
*
|
||||||
|
* @param {String} name
|
||||||
|
* @param {String} val
|
||||||
|
* @param {Options} options
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
res.cookie = function(name, val, options){
|
||||||
|
options = options || {};
|
||||||
|
if ('maxAge' in options) options.expires = new Date(Date.now() + options.maxAge);
|
||||||
|
if (undefined === options.path) options.path = this.app.set('basepath');
|
||||||
|
var cookie = utils.serializeCookie(name, val, options);
|
||||||
|
this.header('Set-Cookie', cookie);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redirect to the given `url` with optional response `status`
|
||||||
|
* defauling to 302.
|
||||||
|
*
|
||||||
|
* The given `url` can also be the name of a mapped url, for
|
||||||
|
* example by default express supports "back" which redirects
|
||||||
|
* to the _Referrer_ or _Referer_ headers or the application's
|
||||||
|
* "basepath" setting. Express also supports "basepath" out of the box,
|
||||||
|
* which can be set via `app.set('basepath', '/blog');`, and defaults
|
||||||
|
* to '/'.
|
||||||
|
*
|
||||||
|
* Redirect Mapping:
|
||||||
|
*
|
||||||
|
* To extend the redirect mapping capabilities that Express provides,
|
||||||
|
* we may use the `app.redirect()` method:
|
||||||
|
*
|
||||||
|
* app.redirect('google', 'http://google.com');
|
||||||
|
*
|
||||||
|
* Now in a route we may call:
|
||||||
|
*
|
||||||
|
* res.redirect('google');
|
||||||
|
*
|
||||||
|
* We may also map dynamic redirects:
|
||||||
|
*
|
||||||
|
* app.redirect('comments', function(req, res){
|
||||||
|
* return '/post/' + req.params.id + '/comments';
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* So now we may do the following, and the redirect will dynamically adjust to
|
||||||
|
* the context of the request. If we called this route with _GET /post/12_ our
|
||||||
|
* redirect _Location_ would be _/post/12/comments_.
|
||||||
|
*
|
||||||
|
* app.get('/post/:id', function(req, res){
|
||||||
|
* res.redirect('comments');
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* Unless an absolute `url` is given, the app's mount-point
|
||||||
|
* will be respected. For example if we redirect to `/posts`,
|
||||||
|
* and our app is mounted at `/blog` we will redirect to `/blog/posts`.
|
||||||
|
*
|
||||||
|
* @param {String} url
|
||||||
|
* @param {Number} code
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
res.redirect = function(url, status){
|
||||||
|
var app = this.app
|
||||||
|
, req = this.req
|
||||||
|
, base = app.set('basepath') || app.route
|
||||||
|
, status = status || 302
|
||||||
|
, head = 'HEAD' == req.method
|
||||||
|
, body;
|
||||||
|
|
||||||
|
// Setup redirect map
|
||||||
|
var map = {
|
||||||
|
back: req.header('Referrer', base)
|
||||||
|
, home: base
|
||||||
|
};
|
||||||
|
|
||||||
|
// Support custom redirect map
|
||||||
|
map.__proto__ = app.redirects;
|
||||||
|
|
||||||
|
// Attempt mapped redirect
|
||||||
|
var mapped = 'function' == typeof map[url]
|
||||||
|
? map[url](req, this)
|
||||||
|
: map[url];
|
||||||
|
|
||||||
|
// Perform redirect
|
||||||
|
url = mapped || url;
|
||||||
|
|
||||||
|
// Relative
|
||||||
|
if (!~url.indexOf('://')) {
|
||||||
|
// Respect mount-point
|
||||||
|
if ('/' != base && 0 != url.indexOf(base)) url = base + url;
|
||||||
|
|
||||||
|
// Absolute
|
||||||
|
var host = req.headers.host;
|
||||||
|
url = req.protocol + '://' + host + url;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Support text/{plain,html} by default
|
||||||
|
if (req.accepts('html')) {
|
||||||
|
body = '<p>' + http.STATUS_CODES[status] + '. Redirecting to <a href="' + url + '">' + url + '</a></p>';
|
||||||
|
this.header('Content-Type', 'text/html');
|
||||||
|
} else {
|
||||||
|
body = http.STATUS_CODES[status] + '. Redirecting to ' + url;
|
||||||
|
this.header('Content-Type', 'text/plain');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Respond
|
||||||
|
this.statusCode = status;
|
||||||
|
this.header('Location', url);
|
||||||
|
this.end(head ? null : body);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign the view local variable `name` to `val` or return the
|
||||||
|
* local previously assigned to `name`.
|
||||||
|
*
|
||||||
|
* @param {String} name
|
||||||
|
* @param {Mixed} val
|
||||||
|
* @return {Mixed} val
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
res.local = function(name, val){
|
||||||
|
this._locals = this._locals || {};
|
||||||
|
return undefined === val
|
||||||
|
? this._locals[name]
|
||||||
|
: this._locals[name] = val;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign several locals with the given `obj`,
|
||||||
|
* or return the locals.
|
||||||
|
*
|
||||||
|
* @param {Object} obj
|
||||||
|
* @return {Object|Undefined}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
res.locals =
|
||||||
|
res.helpers = function(obj){
|
||||||
|
if (obj) {
|
||||||
|
for (var key in obj) {
|
||||||
|
this.local(key, obj[key]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return this._locals;
|
||||||
|
}
|
||||||
|
};
|
||||||
53
test/node_modules/express/lib/router/collection.js
generated
vendored
Normal file
53
test/node_modules/express/lib/router/collection.js
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Express - router - Collection
|
||||||
|
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expose `Collection`.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a new route `Collection`
|
||||||
|
* with the given `router`.
|
||||||
|
*
|
||||||
|
* @param {Router} router
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function Collection(router) {
|
||||||
|
Array.apply(this, arguments);
|
||||||
|
this.router = router;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inherit from `Array.prototype`.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Collection.prototype.__proto__ = Array.prototype;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the routes in this collection.
|
||||||
|
*
|
||||||
|
* @return {Collection} of routes removed
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
Collection.prototype.remove = function(){
|
||||||
|
var router = this.router
|
||||||
|
, len = this.length
|
||||||
|
, ret = new Collection(this.router);
|
||||||
|
|
||||||
|
for (var i = 0; i < len; ++i) {
|
||||||
|
if (router.remove(this[i])) {
|
||||||
|
ret.push(this[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
398
test/node_modules/express/lib/router/index.js
generated
vendored
Normal file
398
test/node_modules/express/lib/router/index.js
generated
vendored
Normal file
@@ -0,0 +1,398 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Express - Router
|
||||||
|
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var Route = require('./route')
|
||||||
|
, Collection = require('./collection')
|
||||||
|
, utils = require('../utils')
|
||||||
|
, parse = require('url').parse
|
||||||
|
, toArray = utils.toArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expose `Router` constructor.
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports = module.exports = Router;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expose HTTP methods.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var methods = exports.methods = require('./methods');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a new `Router` with the given `app`.
|
||||||
|
*
|
||||||
|
* @param {express.HTTPServer} app
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function Router(app) {
|
||||||
|
var self = this;
|
||||||
|
this.app = app;
|
||||||
|
this.routes = {};
|
||||||
|
this.params = {};
|
||||||
|
this._params = [];
|
||||||
|
|
||||||
|
this.middleware = function(req, res, next){
|
||||||
|
self._dispatch(req, res, next);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a param callback `fn` for the given `name`.
|
||||||
|
*
|
||||||
|
* @param {String|Function} name
|
||||||
|
* @param {Function} fn
|
||||||
|
* @return {Router} for chaining
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
Router.prototype.param = function(name, fn){
|
||||||
|
// param logic
|
||||||
|
if ('function' == typeof name) {
|
||||||
|
this._params.push(name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// apply param functions
|
||||||
|
var params = this._params
|
||||||
|
, len = params.length
|
||||||
|
, ret;
|
||||||
|
|
||||||
|
for (var i = 0; i < len; ++i) {
|
||||||
|
if (ret = params[i](name, fn)) {
|
||||||
|
fn = ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure we end up with a
|
||||||
|
// middleware function
|
||||||
|
if ('function' != typeof fn) {
|
||||||
|
throw new Error('invalid param() call for ' + name + ', got ' + fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
(this.params[name] = this.params[name] || []).push(fn);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a `Collection` of all routes defined.
|
||||||
|
*
|
||||||
|
* @return {Collection}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
Router.prototype.all = function(){
|
||||||
|
return this.find(function(){
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the given `route`, returns
|
||||||
|
* a bool indicating if the route was present
|
||||||
|
* or not.
|
||||||
|
*
|
||||||
|
* @param {Route} route
|
||||||
|
* @return {Boolean}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
Router.prototype.remove = function(route){
|
||||||
|
var routes = this.routes[route.method]
|
||||||
|
, len = routes.length;
|
||||||
|
|
||||||
|
for (var i = 0; i < len; ++i) {
|
||||||
|
if (route == routes[i]) {
|
||||||
|
routes.splice(i, 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return routes with route paths matching `path`.
|
||||||
|
*
|
||||||
|
* @param {String} method
|
||||||
|
* @param {String} path
|
||||||
|
* @return {Collection}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
Router.prototype.lookup = function(method, path){
|
||||||
|
return this.find(function(route){
|
||||||
|
return path == route.path
|
||||||
|
&& (route.method == method
|
||||||
|
|| method == 'all');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return routes with regexps that match the given `url`.
|
||||||
|
*
|
||||||
|
* @param {String} method
|
||||||
|
* @param {String} url
|
||||||
|
* @return {Collection}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
Router.prototype.match = function(method, url){
|
||||||
|
return this.find(function(route){
|
||||||
|
return route.match(url)
|
||||||
|
&& (route.method == method
|
||||||
|
|| method == 'all');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find routes based on the return value of `fn`
|
||||||
|
* which is invoked once per route.
|
||||||
|
*
|
||||||
|
* @param {Function} fn
|
||||||
|
* @return {Collection}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
Router.prototype.find = function(fn){
|
||||||
|
var len = methods.length
|
||||||
|
, ret = new Collection(this)
|
||||||
|
, method
|
||||||
|
, routes
|
||||||
|
, route;
|
||||||
|
|
||||||
|
for (var i = 0; i < len; ++i) {
|
||||||
|
method = methods[i];
|
||||||
|
routes = this.routes[method];
|
||||||
|
if (!routes) continue;
|
||||||
|
for (var j = 0, jlen = routes.length; j < jlen; ++j) {
|
||||||
|
route = routes[j];
|
||||||
|
if (fn(route)) ret.push(route);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Route dispatcher aka the route "middleware".
|
||||||
|
*
|
||||||
|
* @param {IncomingMessage} req
|
||||||
|
* @param {ServerResponse} res
|
||||||
|
* @param {Function} next
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
Router.prototype._dispatch = function(req, res, next){
|
||||||
|
var params = this.params
|
||||||
|
, self = this;
|
||||||
|
|
||||||
|
// route dispatch
|
||||||
|
(function pass(i, err){
|
||||||
|
var paramCallbacks
|
||||||
|
, paramIndex = 0
|
||||||
|
, paramVal
|
||||||
|
, route
|
||||||
|
, keys
|
||||||
|
, key
|
||||||
|
, ret;
|
||||||
|
|
||||||
|
// match next route
|
||||||
|
function nextRoute(err) {
|
||||||
|
pass(req._route_index + 1, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
// match route
|
||||||
|
req.route = route = self._match(req, i);
|
||||||
|
|
||||||
|
// implied OPTIONS
|
||||||
|
if (!route && 'OPTIONS' == req.method) return self._options(req, res);
|
||||||
|
|
||||||
|
// no route
|
||||||
|
if (!route) return next(err);
|
||||||
|
|
||||||
|
// we have a route
|
||||||
|
// start at param 0
|
||||||
|
req.params = route.params;
|
||||||
|
keys = route.keys;
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
// param callbacks
|
||||||
|
function param(err) {
|
||||||
|
paramIndex = 0;
|
||||||
|
key = keys[i++];
|
||||||
|
paramVal = key && req.params[key.name];
|
||||||
|
paramCallbacks = key && params[key.name];
|
||||||
|
|
||||||
|
try {
|
||||||
|
if ('route' == err) {
|
||||||
|
nextRoute();
|
||||||
|
} else if (err) {
|
||||||
|
i = 0;
|
||||||
|
callbacks(err);
|
||||||
|
} else if (paramCallbacks && undefined !== paramVal) {
|
||||||
|
paramCallback();
|
||||||
|
} else if (key) {
|
||||||
|
param();
|
||||||
|
} else {
|
||||||
|
i = 0;
|
||||||
|
callbacks();
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
param(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
param(err);
|
||||||
|
|
||||||
|
// single param callbacks
|
||||||
|
function paramCallback(err) {
|
||||||
|
var fn = paramCallbacks[paramIndex++];
|
||||||
|
if (err || !fn) return param(err);
|
||||||
|
fn(req, res, paramCallback, paramVal, key.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// invoke route callbacks
|
||||||
|
function callbacks(err) {
|
||||||
|
var fn = route.callbacks[i++];
|
||||||
|
try {
|
||||||
|
if ('route' == err) {
|
||||||
|
nextRoute();
|
||||||
|
} else if (err && fn) {
|
||||||
|
if (fn.length < 4) return callbacks(err);
|
||||||
|
fn(err, req, res, callbacks);
|
||||||
|
} else if (fn) {
|
||||||
|
fn(req, res, callbacks);
|
||||||
|
} else {
|
||||||
|
nextRoute(err);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
callbacks(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Respond to __OPTIONS__ method.
|
||||||
|
*
|
||||||
|
* @param {IncomingMessage} req
|
||||||
|
* @param {ServerResponse} res
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
Router.prototype._options = function(req, res){
|
||||||
|
var path = parse(req.url).pathname
|
||||||
|
, body = this._optionsFor(path).join(',');
|
||||||
|
res.send(body, { Allow: body });
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an array of HTTP verbs or "options" for `path`.
|
||||||
|
*
|
||||||
|
* @param {String} path
|
||||||
|
* @return {Array}
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
Router.prototype._optionsFor = function(path){
|
||||||
|
var self = this;
|
||||||
|
return methods.filter(function(method){
|
||||||
|
var routes = self.routes[method];
|
||||||
|
if (!routes || 'options' == method) return;
|
||||||
|
for (var i = 0, len = routes.length; i < len; ++i) {
|
||||||
|
if (routes[i].match(path)) return true;
|
||||||
|
}
|
||||||
|
}).map(function(method){
|
||||||
|
return method.toUpperCase();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to match a route for `req`
|
||||||
|
* starting from offset `i`.
|
||||||
|
*
|
||||||
|
* @param {IncomingMessage} req
|
||||||
|
* @param {Number} i
|
||||||
|
* @return {Route}
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
Router.prototype._match = function(req, i){
|
||||||
|
var method = req.method.toLowerCase()
|
||||||
|
, url = parse(req.url)
|
||||||
|
, path = url.pathname
|
||||||
|
, routes = this.routes
|
||||||
|
, captures
|
||||||
|
, route
|
||||||
|
, keys;
|
||||||
|
|
||||||
|
// pass HEAD to GET routes
|
||||||
|
if ('head' == method) method = 'get';
|
||||||
|
|
||||||
|
// routes for this method
|
||||||
|
if (routes = routes[method]) {
|
||||||
|
|
||||||
|
// matching routes
|
||||||
|
for (var len = routes.length; i < len; ++i) {
|
||||||
|
route = routes[i];
|
||||||
|
if (captures = route.match(path)) {
|
||||||
|
keys = route.keys;
|
||||||
|
route.params = [];
|
||||||
|
|
||||||
|
// params from capture groups
|
||||||
|
for (var j = 1, jlen = captures.length; j < jlen; ++j) {
|
||||||
|
var key = keys[j-1]
|
||||||
|
, val = 'string' == typeof captures[j]
|
||||||
|
? decodeURIComponent(captures[j])
|
||||||
|
: captures[j];
|
||||||
|
if (key) {
|
||||||
|
route.params[key.name] = val;
|
||||||
|
} else {
|
||||||
|
route.params.push(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// all done
|
||||||
|
req._route_index = i;
|
||||||
|
return route;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Route `method`, `path`, and one or more callbacks.
|
||||||
|
*
|
||||||
|
* @param {String} method
|
||||||
|
* @param {String} path
|
||||||
|
* @param {Function} callback...
|
||||||
|
* @return {Router} for chaining
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
Router.prototype._route = function(method, path, callbacks){
|
||||||
|
var app = this.app
|
||||||
|
, callbacks = utils.flatten(toArray(arguments, 2));
|
||||||
|
|
||||||
|
// ensure path was given
|
||||||
|
if (!path) throw new Error('app.' + method + '() requires a path');
|
||||||
|
|
||||||
|
// create the route
|
||||||
|
var route = new Route(method, path, callbacks, {
|
||||||
|
sensitive: app.enabled('case sensitive routes')
|
||||||
|
, strict: app.enabled('strict routing')
|
||||||
|
});
|
||||||
|
|
||||||
|
// add it
|
||||||
|
(this.routes[method] = this.routes[method] || [])
|
||||||
|
.push(route);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
79
test/node_modules/express/lib/router/methods.js
generated
vendored
Normal file
79
test/node_modules/express/lib/router/methods.js
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Express - router - methods
|
||||||
|
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hypertext Transfer Protocol -- HTTP/1.1
|
||||||
|
* http://www.ietf.org/rfc/rfc2616.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
var RFC2616 = ['OPTIONS', 'GET', 'POST', 'PUT', 'DELETE', 'TRACE', 'CONNECT'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTTP Extensions for Distributed Authoring -- WEBDAV
|
||||||
|
* http://www.ietf.org/rfc/rfc2518.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
var RFC2518 = ['PROPFIND', 'PROPPATCH', 'MKCOL', 'COPY', 'MOVE', 'LOCK', 'UNLOCK'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Versioning Extensions to WebDAV
|
||||||
|
* http://www.ietf.org/rfc/rfc3253.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
var RFC3253 = ['VERSION-CONTROL', 'REPORT', 'CHECKOUT', 'CHECKIN', 'UNCHECKOUT', 'MKWORKSPACE', 'UPDATE', 'LABEL', 'MERGE', 'BASELINE-CONTROL', 'MKACTIVITY'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ordered Collections Protocol (WebDAV)
|
||||||
|
* http://www.ietf.org/rfc/rfc3648.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
var RFC3648 = ['ORDERPATCH'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Web Distributed Authoring and Versioning (WebDAV) Access Control Protocol
|
||||||
|
* http://www.ietf.org/rfc/rfc3744.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
var RFC3744 = ['ACL'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Web Distributed Authoring and Versioning (WebDAV) SEARCH
|
||||||
|
* http://www.ietf.org/rfc/rfc5323.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
var RFC5323 = ['SEARCH'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PATCH Method for HTTP
|
||||||
|
* http://www.ietf.org/rfc/rfc5789.txt
|
||||||
|
*/
|
||||||
|
|
||||||
|
var RFC5789 = ['PATCH'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PURGE Method for caching reverse-proxy
|
||||||
|
* http://wiki.squid-cache.org/SquidFaq/OperatingSquid#How_can_I_purge_an_object_from_my_cache.3F
|
||||||
|
* https://www.varnish-cache.org/docs/trunk/tutorial/purging.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
var CACHE_PURGE = ['PURGE'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expose the methods.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = [].concat(
|
||||||
|
RFC2616
|
||||||
|
, RFC2518
|
||||||
|
, RFC3253
|
||||||
|
, RFC3648
|
||||||
|
, RFC3744
|
||||||
|
, RFC5323
|
||||||
|
, RFC5789
|
||||||
|
, CACHE_PURGE).map(function(method){
|
||||||
|
return method.toLowerCase();
|
||||||
|
});
|
||||||
88
test/node_modules/express/lib/router/route.js
generated
vendored
Normal file
88
test/node_modules/express/lib/router/route.js
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Express - router - Route
|
||||||
|
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expose `Route`.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = Route;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize `Route` with the given HTTP `method`, `path`,
|
||||||
|
* and an array of `callbacks` and `options`.
|
||||||
|
*
|
||||||
|
* Options:
|
||||||
|
*
|
||||||
|
* - `sensitive` enable case-sensitive routes
|
||||||
|
* - `strict` enable strict matching for trailing slashes
|
||||||
|
*
|
||||||
|
* @param {String} method
|
||||||
|
* @param {String} path
|
||||||
|
* @param {Array} callbacks
|
||||||
|
* @param {Object} options.
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function Route(method, path, callbacks, options) {
|
||||||
|
options = options || {};
|
||||||
|
this.path = path;
|
||||||
|
this.method = method;
|
||||||
|
this.callbacks = callbacks;
|
||||||
|
this.regexp = normalize(path
|
||||||
|
, this.keys = []
|
||||||
|
, options.sensitive
|
||||||
|
, options.strict);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if this route matches `path` and return captures made.
|
||||||
|
*
|
||||||
|
* @param {String} path
|
||||||
|
* @return {Array}
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
Route.prototype.match = function(path){
|
||||||
|
return this.regexp.exec(path);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize the given path string,
|
||||||
|
* returning a regular expression.
|
||||||
|
*
|
||||||
|
* An empty array should be passed,
|
||||||
|
* which will contain the placeholder
|
||||||
|
* key names. For example "/user/:id" will
|
||||||
|
* then contain ["id"].
|
||||||
|
*
|
||||||
|
* @param {String|RegExp} path
|
||||||
|
* @param {Array} keys
|
||||||
|
* @param {Boolean} sensitive
|
||||||
|
* @param {Boolean} strict
|
||||||
|
* @return {RegExp}
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function normalize(path, keys, sensitive, strict) {
|
||||||
|
if (path instanceof RegExp) return path;
|
||||||
|
path = path
|
||||||
|
.concat(strict ? '' : '/?')
|
||||||
|
.replace(/\/\(/g, '(?:/')
|
||||||
|
.replace(/(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?/g, function(_, slash, format, key, capture, optional){
|
||||||
|
keys.push({ name: key, optional: !! optional });
|
||||||
|
slash = slash || '';
|
||||||
|
return ''
|
||||||
|
+ (optional ? '' : slash)
|
||||||
|
+ '(?:'
|
||||||
|
+ (optional ? slash : '')
|
||||||
|
+ (format || '') + (capture || (format && '([^/.]+?)' || '([^/]+?)')) + ')'
|
||||||
|
+ (optional || '');
|
||||||
|
})
|
||||||
|
.replace(/([\/.])/g, '\\$1')
|
||||||
|
.replace(/\*/g, '(.*)');
|
||||||
|
return new RegExp('^' + path + '$', sensitive ? '' : 'i');
|
||||||
|
}
|
||||||
152
test/node_modules/express/lib/utils.js
generated
vendored
Normal file
152
test/node_modules/express/lib/utils.js
generated
vendored
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Express - Utils
|
||||||
|
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if `path` looks absolute.
|
||||||
|
*
|
||||||
|
* @param {String} path
|
||||||
|
* @return {Boolean}
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.isAbsolute = function(path){
|
||||||
|
if ('/' == path[0]) return true;
|
||||||
|
if (':' == path[1] && '\\' == path[2]) return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge object `b` with `a` giving precedence to
|
||||||
|
* values in object `a`.
|
||||||
|
*
|
||||||
|
* @param {Object} a
|
||||||
|
* @param {Object} b
|
||||||
|
* @return {Object} a
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.union = function(a, b){
|
||||||
|
if (a && b) {
|
||||||
|
var keys = Object.keys(b)
|
||||||
|
, len = keys.length
|
||||||
|
, key;
|
||||||
|
for (var i = 0; i < len; ++i) {
|
||||||
|
key = keys[i];
|
||||||
|
if (!a.hasOwnProperty(key)) {
|
||||||
|
a[key] = b[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flatten the given `arr`.
|
||||||
|
*
|
||||||
|
* @param {Array} arr
|
||||||
|
* @return {Array}
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.flatten = function(arr, ret){
|
||||||
|
var ret = ret || []
|
||||||
|
, len = arr.length;
|
||||||
|
for (var i = 0; i < len; ++i) {
|
||||||
|
if (Array.isArray(arr[i])) {
|
||||||
|
exports.flatten(arr[i], ret);
|
||||||
|
} else {
|
||||||
|
ret.push(arr[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse mini markdown implementation.
|
||||||
|
* The following conversions are supported,
|
||||||
|
* primarily for the "flash" middleware:
|
||||||
|
*
|
||||||
|
* _foo_ or *foo* become <em>foo</em>
|
||||||
|
* __foo__ or **foo** become <strong>foo</strong>
|
||||||
|
* [A](B) becomes <a href="B">A</a>
|
||||||
|
*
|
||||||
|
* @param {String} str
|
||||||
|
* @return {String}
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.miniMarkdown = function(str){
|
||||||
|
return String(str)
|
||||||
|
.replace(/(__|\*\*)(.*?)\1/g, '<strong>$2</strong>')
|
||||||
|
.replace(/(_|\*)(.*?)\1/g, '<em>$2</em>')
|
||||||
|
.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2">$1</a>');
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escape special characters in the given string of html.
|
||||||
|
*
|
||||||
|
* @param {String} html
|
||||||
|
* @return {String}
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.escape = function(html) {
|
||||||
|
return String(html)
|
||||||
|
.replace(/&/g, '&')
|
||||||
|
.replace(/"/g, '"')
|
||||||
|
.replace(/</g, '<')
|
||||||
|
.replace(/>/g, '>');
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse "Range" header `str` relative to the given file `size`.
|
||||||
|
*
|
||||||
|
* @param {Number} size
|
||||||
|
* @param {String} str
|
||||||
|
* @return {Array}
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.parseRange = function(size, str){
|
||||||
|
var valid = true;
|
||||||
|
var arr = str.substr(6).split(',').map(function(range){
|
||||||
|
var range = range.split('-')
|
||||||
|
, start = parseInt(range[0], 10)
|
||||||
|
, end = parseInt(range[1], 10);
|
||||||
|
|
||||||
|
// -500
|
||||||
|
if (isNaN(start)) {
|
||||||
|
start = size - end;
|
||||||
|
end = size - 1;
|
||||||
|
// 500-
|
||||||
|
} else if (isNaN(end)) {
|
||||||
|
end = size - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invalid
|
||||||
|
if (isNaN(start) || isNaN(end) || start > end) valid = false;
|
||||||
|
|
||||||
|
return { start: start, end: end };
|
||||||
|
});
|
||||||
|
return valid ? arr : undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fast alternative to `Array.prototype.slice.call()`.
|
||||||
|
*
|
||||||
|
* @param {Arguments} args
|
||||||
|
* @param {Number} n
|
||||||
|
* @return {Array}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.toArray = function(args, i){
|
||||||
|
var arr = []
|
||||||
|
, len = args.length
|
||||||
|
, i = i || 0;
|
||||||
|
for (; i < len; ++i) arr.push(args[i]);
|
||||||
|
return arr;
|
||||||
|
};
|
||||||
460
test/node_modules/express/lib/view.js
generated
vendored
Normal file
460
test/node_modules/express/lib/view.js
generated
vendored
Normal file
@@ -0,0 +1,460 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Express - view
|
||||||
|
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var path = require('path')
|
||||||
|
, extname = path.extname
|
||||||
|
, dirname = path.dirname
|
||||||
|
, basename = path.basename
|
||||||
|
, utils = require('connect').utils
|
||||||
|
, View = require('./view/view')
|
||||||
|
, partial = require('./view/partial')
|
||||||
|
, union = require('./utils').union
|
||||||
|
, merge = utils.merge
|
||||||
|
, http = require('http')
|
||||||
|
, res = http.ServerResponse.prototype;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expose constructors.
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports = module.exports = View;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export template engine registrar.
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.register = View.register;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lookup and compile `view` with cache support by supplying
|
||||||
|
* both the `cache` object and `cid` string,
|
||||||
|
* followed by `options` passed to `exports.lookup()`.
|
||||||
|
*
|
||||||
|
* @param {String} view
|
||||||
|
* @param {Object} cache
|
||||||
|
* @param {Object} cid
|
||||||
|
* @param {Object} options
|
||||||
|
* @return {View}
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.compile = function(view, cache, cid, options){
|
||||||
|
if (cache && cid && cache[cid]){
|
||||||
|
options.filename = cache[cid].path;
|
||||||
|
return cache[cid];
|
||||||
|
}
|
||||||
|
|
||||||
|
// lookup
|
||||||
|
view = exports.lookup(view, options);
|
||||||
|
|
||||||
|
// hints
|
||||||
|
if (!view.exists) {
|
||||||
|
if (options.hint) hintAtViewPaths(view.original, options);
|
||||||
|
var err = new Error('failed to locate view "' + view.original.view + '"');
|
||||||
|
err.view = view.original;
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
|
||||||
|
// compile
|
||||||
|
options.filename = view.path;
|
||||||
|
view.fn = view.templateEngine.compile(view.contents, options);
|
||||||
|
cache[cid] = view;
|
||||||
|
|
||||||
|
return view;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lookup `view`, returning an instanceof `View`.
|
||||||
|
*
|
||||||
|
* Options:
|
||||||
|
*
|
||||||
|
* - `root` root directory path
|
||||||
|
* - `defaultEngine` default template engine
|
||||||
|
* - `parentView` parent `View` object
|
||||||
|
* - `cache` cache object
|
||||||
|
* - `cacheid` optional cache id
|
||||||
|
*
|
||||||
|
* Lookup:
|
||||||
|
*
|
||||||
|
* - partial `_<name>`
|
||||||
|
* - any `<name>/index`
|
||||||
|
* - non-layout `../<name>/index`
|
||||||
|
* - any `<root>/<name>`
|
||||||
|
* - partial `<root>/_<name>`
|
||||||
|
*
|
||||||
|
* @param {String} view
|
||||||
|
* @param {Object} options
|
||||||
|
* @return {View}
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.lookup = function(view, options){
|
||||||
|
var orig = view = new View(view, options)
|
||||||
|
, partial = options.isPartial
|
||||||
|
, layout = options.isLayout;
|
||||||
|
|
||||||
|
// Try _ prefix ex: ./views/_<name>.jade
|
||||||
|
// taking precedence over the direct path
|
||||||
|
if (partial) {
|
||||||
|
view = new View(orig.prefixPath, options);
|
||||||
|
if (!view.exists) view = orig;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try index ex: ./views/user/index.jade
|
||||||
|
if (!layout && !view.exists) view = new View(orig.indexPath, options);
|
||||||
|
|
||||||
|
// Try ../<name>/index ex: ../user/index.jade
|
||||||
|
// when calling partial('user') within the same dir
|
||||||
|
if (!layout && !view.exists) view = new View(orig.upIndexPath, options);
|
||||||
|
|
||||||
|
// Try root ex: <root>/user.jade
|
||||||
|
if (!view.exists) view = new View(orig.rootPath, options);
|
||||||
|
|
||||||
|
// Try root _ prefix ex: <root>/_user.jade
|
||||||
|
if (!view.exists && partial) view = new View(view.prefixPath, options);
|
||||||
|
|
||||||
|
view.original = orig;
|
||||||
|
return view;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Partial render helper.
|
||||||
|
*
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function renderPartial(res, view, options, parentLocals, parent){
|
||||||
|
var collection, object, locals;
|
||||||
|
|
||||||
|
if (options) {
|
||||||
|
// collection
|
||||||
|
if (options.collection) {
|
||||||
|
collection = options.collection;
|
||||||
|
delete options.collection;
|
||||||
|
} else if ('length' in options) {
|
||||||
|
collection = options;
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// locals
|
||||||
|
if (options.locals) {
|
||||||
|
locals = options.locals;
|
||||||
|
delete options.locals;
|
||||||
|
}
|
||||||
|
|
||||||
|
// object
|
||||||
|
if ('Object' != options.constructor.name) {
|
||||||
|
object = options;
|
||||||
|
options = {};
|
||||||
|
} else if (undefined != options.object) {
|
||||||
|
object = options.object;
|
||||||
|
delete options.object;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inherit locals from parent
|
||||||
|
union(options, parentLocals);
|
||||||
|
|
||||||
|
// Merge locals
|
||||||
|
if (locals) merge(options, locals);
|
||||||
|
|
||||||
|
// Partials dont need layouts
|
||||||
|
options.isPartial = true;
|
||||||
|
options.layout = false;
|
||||||
|
|
||||||
|
// Deduce name from view path
|
||||||
|
var name = options.as || partial.resolveObjectName(view);
|
||||||
|
|
||||||
|
// Render partial
|
||||||
|
function render(){
|
||||||
|
if (object) {
|
||||||
|
if ('string' == typeof name) {
|
||||||
|
options[name] = object;
|
||||||
|
} else if (name === global) {
|
||||||
|
merge(options, object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res.render(view, options, null, parent, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Collection support
|
||||||
|
if (collection) {
|
||||||
|
var len = collection.length
|
||||||
|
, buf = ''
|
||||||
|
, keys
|
||||||
|
, key
|
||||||
|
, val;
|
||||||
|
|
||||||
|
options.collectionLength = len;
|
||||||
|
|
||||||
|
if ('number' == typeof len || Array.isArray(collection)) {
|
||||||
|
for (var i = 0; i < len; ++i) {
|
||||||
|
val = collection[i];
|
||||||
|
options.firstInCollection = i == 0;
|
||||||
|
options.indexInCollection = i;
|
||||||
|
options.lastInCollection = i == len - 1;
|
||||||
|
object = val;
|
||||||
|
buf += render();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
keys = Object.keys(collection);
|
||||||
|
len = keys.length;
|
||||||
|
options.collectionLength = len;
|
||||||
|
options.collectionKeys = keys;
|
||||||
|
for (var i = 0; i < len; ++i) {
|
||||||
|
key = keys[i];
|
||||||
|
val = collection[key];
|
||||||
|
options.keyInCollection = key;
|
||||||
|
options.firstInCollection = i == 0;
|
||||||
|
options.indexInCollection = i;
|
||||||
|
options.lastInCollection = i == len - 1;
|
||||||
|
object = val;
|
||||||
|
buf += render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
} else {
|
||||||
|
return render();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render `view` partial with the given `options`. Optionally a
|
||||||
|
* callback `fn(err, str)` may be passed instead of writing to
|
||||||
|
* the socket.
|
||||||
|
*
|
||||||
|
* Options:
|
||||||
|
*
|
||||||
|
* - `object` Single object with name derived from the view (unless `as` is present)
|
||||||
|
*
|
||||||
|
* - `as` Variable name for each `collection` value, defaults to the view name.
|
||||||
|
* * as: 'something' will add the `something` local variable
|
||||||
|
* * as: this will use the collection value as the template context
|
||||||
|
* * as: global will merge the collection value's properties with `locals`
|
||||||
|
*
|
||||||
|
* - `collection` Array of objects, the name is derived from the view name itself.
|
||||||
|
* For example _video.html_ will have a object _video_ available to it.
|
||||||
|
*
|
||||||
|
* @param {String} view
|
||||||
|
* @param {Object|Array|Function} options, collection, callback, or object
|
||||||
|
* @param {Function} fn
|
||||||
|
* @return {String}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
res.partial = function(view, options, fn){
|
||||||
|
var app = this.app
|
||||||
|
, options = options || {}
|
||||||
|
, viewEngine = app.set('view engine')
|
||||||
|
, parent = {};
|
||||||
|
|
||||||
|
// accept callback as second argument
|
||||||
|
if ('function' == typeof options) {
|
||||||
|
fn = options;
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// root "views" option
|
||||||
|
parent.dirname = app.set('views') || process.cwd() + '/views';
|
||||||
|
|
||||||
|
// utilize "view engine" option
|
||||||
|
if (viewEngine) parent.engine = viewEngine;
|
||||||
|
|
||||||
|
// render the partial
|
||||||
|
try {
|
||||||
|
var str = renderPartial(this, view, options, null, parent);
|
||||||
|
} catch (err) {
|
||||||
|
if (fn) {
|
||||||
|
fn(err);
|
||||||
|
} else {
|
||||||
|
this.req.next(err);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// callback or transfer
|
||||||
|
if (fn) {
|
||||||
|
fn(null, str);
|
||||||
|
} else {
|
||||||
|
this.send(str);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render `view` with the given `options` and optional callback `fn`.
|
||||||
|
* When a callback function is given a response will _not_ be made
|
||||||
|
* automatically, however otherwise a response of _200_ and _text/html_ is given.
|
||||||
|
*
|
||||||
|
* Options:
|
||||||
|
*
|
||||||
|
* - `scope` Template evaluation context (the value of `this`)
|
||||||
|
* - `debug` Output debugging information
|
||||||
|
* - `status` Response status code
|
||||||
|
*
|
||||||
|
* @param {String} view
|
||||||
|
* @param {Object|Function} options or callback function
|
||||||
|
* @param {Function} fn
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
res.render = function(view, opts, fn, parent, sub){
|
||||||
|
// support callback function as second arg
|
||||||
|
if ('function' == typeof opts) {
|
||||||
|
fn = opts, opts = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return this._render(view, opts, fn, parent, sub);
|
||||||
|
} catch (err) {
|
||||||
|
// callback given
|
||||||
|
if (fn) {
|
||||||
|
fn(err);
|
||||||
|
// unwind to root call to prevent multiple callbacks
|
||||||
|
} else if (sub) {
|
||||||
|
throw err;
|
||||||
|
// root template, next(err)
|
||||||
|
} else {
|
||||||
|
this.req.next(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// private render()
|
||||||
|
|
||||||
|
res._render = function(view, opts, fn, parent, sub){
|
||||||
|
var options = {}
|
||||||
|
, self = this
|
||||||
|
, app = this.app
|
||||||
|
, helpers = app._locals
|
||||||
|
, dynamicHelpers = app.dynamicViewHelpers
|
||||||
|
, viewOptions = app.set('view options')
|
||||||
|
, root = app.set('views') || process.cwd() + '/views';
|
||||||
|
|
||||||
|
// cache id
|
||||||
|
var cid = app.enabled('view cache')
|
||||||
|
? view + (parent ? ':' + parent.path : '')
|
||||||
|
: false;
|
||||||
|
|
||||||
|
// merge "view options"
|
||||||
|
if (viewOptions) merge(options, viewOptions);
|
||||||
|
|
||||||
|
// merge res._locals
|
||||||
|
if (this._locals) merge(options, this._locals);
|
||||||
|
|
||||||
|
// merge render() options
|
||||||
|
if (opts) merge(options, opts);
|
||||||
|
|
||||||
|
// merge render() .locals
|
||||||
|
if (opts && opts.locals) merge(options, opts.locals);
|
||||||
|
|
||||||
|
// status support
|
||||||
|
if (options.status) this.statusCode = options.status;
|
||||||
|
|
||||||
|
// capture attempts
|
||||||
|
options.attempts = [];
|
||||||
|
|
||||||
|
var partial = options.isPartial
|
||||||
|
, layout = options.layout;
|
||||||
|
|
||||||
|
// Layout support
|
||||||
|
if (true === layout || undefined === layout) {
|
||||||
|
layout = 'layout';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default execution scope to a plain object
|
||||||
|
options.scope = options.scope || {};
|
||||||
|
|
||||||
|
// Populate view
|
||||||
|
options.parentView = parent;
|
||||||
|
|
||||||
|
// "views" setting
|
||||||
|
options.root = root;
|
||||||
|
|
||||||
|
// "view engine" setting
|
||||||
|
options.defaultEngine = app.set('view engine');
|
||||||
|
|
||||||
|
// charset option
|
||||||
|
if (options.charset) this.charset = options.charset;
|
||||||
|
|
||||||
|
// Dynamic helper support
|
||||||
|
if (false !== options.dynamicHelpers) {
|
||||||
|
// cache
|
||||||
|
if (!this.__dynamicHelpers) {
|
||||||
|
this.__dynamicHelpers = {};
|
||||||
|
for (var key in dynamicHelpers) {
|
||||||
|
this.__dynamicHelpers[key] = dynamicHelpers[key].call(
|
||||||
|
this.app
|
||||||
|
, this.req
|
||||||
|
, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// apply
|
||||||
|
merge(options, this.__dynamicHelpers);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge view helpers
|
||||||
|
union(options, helpers);
|
||||||
|
|
||||||
|
// Always expose partial() as a local
|
||||||
|
options.partial = function(path, opts){
|
||||||
|
return renderPartial(self, path, opts, options, view);
|
||||||
|
};
|
||||||
|
|
||||||
|
// View lookup
|
||||||
|
options.hint = app.enabled('hints');
|
||||||
|
view = exports.compile(view, app.cache, cid, options);
|
||||||
|
|
||||||
|
// layout helper
|
||||||
|
options.layout = function(path){
|
||||||
|
layout = path;
|
||||||
|
};
|
||||||
|
|
||||||
|
// render
|
||||||
|
var str = view.fn.call(options.scope, options);
|
||||||
|
|
||||||
|
// layout expected
|
||||||
|
if (layout) {
|
||||||
|
options.isLayout = true;
|
||||||
|
options.layout = false;
|
||||||
|
options.body = str;
|
||||||
|
this.render(layout, options, fn, view, true);
|
||||||
|
// partial return
|
||||||
|
} else if (partial) {
|
||||||
|
return str;
|
||||||
|
// render complete, and
|
||||||
|
// callback given
|
||||||
|
} else if (fn) {
|
||||||
|
fn(null, str);
|
||||||
|
// respond
|
||||||
|
} else {
|
||||||
|
this.send(str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hint at view path resolution, outputting the
|
||||||
|
* paths that Express has tried.
|
||||||
|
*
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function hintAtViewPaths(view, options) {
|
||||||
|
console.error();
|
||||||
|
console.error('failed to locate view "' + view.view + '", tried:');
|
||||||
|
options.attempts.forEach(function(path){
|
||||||
|
console.error(' - %s', path);
|
||||||
|
});
|
||||||
|
console.error();
|
||||||
|
}
|
||||||
40
test/node_modules/express/lib/view/partial.js
generated
vendored
Normal file
40
test/node_modules/express/lib/view/partial.js
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Express - view - Partial
|
||||||
|
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Memory cache.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var cache = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve partial object name from the view path.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
* "user.ejs" becomes "user"
|
||||||
|
* "forum thread.ejs" becomes "forumThread"
|
||||||
|
* "forum/thread/post.ejs" becomes "post"
|
||||||
|
* "blog-post.ejs" becomes "blogPost"
|
||||||
|
*
|
||||||
|
* @return {String}
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.resolveObjectName = function(view){
|
||||||
|
return cache[view] || (cache[view] = view
|
||||||
|
.split('/')
|
||||||
|
.slice(-1)[0]
|
||||||
|
.split('.')[0]
|
||||||
|
.replace(/^_/, '')
|
||||||
|
.replace(/[^a-zA-Z0-9 ]+/g, ' ')
|
||||||
|
.split(/ +/).map(function(word, i){
|
||||||
|
return i
|
||||||
|
? word[0].toUpperCase() + word.substr(1)
|
||||||
|
: word;
|
||||||
|
}).join(''));
|
||||||
|
};
|
||||||
210
test/node_modules/express/lib/view/view.js
generated
vendored
Normal file
210
test/node_modules/express/lib/view/view.js
generated
vendored
Normal file
@@ -0,0 +1,210 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Express - View
|
||||||
|
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var path = require('path')
|
||||||
|
, utils = require('../utils')
|
||||||
|
, extname = path.extname
|
||||||
|
, dirname = path.dirname
|
||||||
|
, basename = path.basename
|
||||||
|
, fs = require('fs')
|
||||||
|
, stat = fs.statSync;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expose `View`.
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports = module.exports = View;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Require cache.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var cache = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a new `View` with the given `view` path and `options`.
|
||||||
|
*
|
||||||
|
* @param {String} view
|
||||||
|
* @param {Object} options
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function View(view, options) {
|
||||||
|
options = options || {};
|
||||||
|
this.view = view;
|
||||||
|
this.root = options.root;
|
||||||
|
this.relative = false !== options.relative;
|
||||||
|
this.defaultEngine = options.defaultEngine;
|
||||||
|
this.parent = options.parentView;
|
||||||
|
this.basename = basename(view);
|
||||||
|
this.engine = this.resolveEngine();
|
||||||
|
this.extension = '.' + this.engine;
|
||||||
|
this.name = this.basename.replace(this.extension, '');
|
||||||
|
this.path = this.resolvePath();
|
||||||
|
this.dirname = dirname(this.path);
|
||||||
|
if (options.attempts) {
|
||||||
|
if (!~options.attempts.indexOf(this.path))
|
||||||
|
options.attempts.push(this.path);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the view path exists.
|
||||||
|
*
|
||||||
|
* @return {Boolean}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
View.prototype.__defineGetter__('exists', function(){
|
||||||
|
try {
|
||||||
|
stat(this.path);
|
||||||
|
return true;
|
||||||
|
} catch (err) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve view engine.
|
||||||
|
*
|
||||||
|
* @return {String}
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
View.prototype.resolveEngine = function(){
|
||||||
|
// Explicit
|
||||||
|
if (~this.basename.indexOf('.')) return extname(this.basename).substr(1);
|
||||||
|
// Inherit from parent
|
||||||
|
if (this.parent) return this.parent.engine;
|
||||||
|
// Default
|
||||||
|
return this.defaultEngine;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve view path.
|
||||||
|
*
|
||||||
|
* @return {String}
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
View.prototype.resolvePath = function(){
|
||||||
|
var path = this.view;
|
||||||
|
// Implicit engine
|
||||||
|
if (!~this.basename.indexOf('.')) path += this.extension;
|
||||||
|
// Absolute
|
||||||
|
if (utils.isAbsolute(path)) return path;
|
||||||
|
// Relative to parent
|
||||||
|
if (this.relative && this.parent) return this.parent.dirname + '/' + path;
|
||||||
|
// Relative to root
|
||||||
|
return this.root
|
||||||
|
? this.root + '/' + path
|
||||||
|
: path;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get view contents. This is a one-time hit, so we
|
||||||
|
* can afford to be sync.
|
||||||
|
*
|
||||||
|
* @return {String}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
View.prototype.__defineGetter__('contents', function(){
|
||||||
|
return fs.readFileSync(this.path, 'utf8');
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get template engine api, cache exports to reduce
|
||||||
|
* require() calls.
|
||||||
|
*
|
||||||
|
* @return {Object}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
View.prototype.__defineGetter__('templateEngine', function(){
|
||||||
|
var ext = this.extension;
|
||||||
|
return cache[ext] || (cache[ext] = require(this.engine));
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return root path alternative.
|
||||||
|
*
|
||||||
|
* @return {String}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
View.prototype.__defineGetter__('rootPath', function(){
|
||||||
|
this.relative = false;
|
||||||
|
return this.resolvePath();
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return index path alternative.
|
||||||
|
*
|
||||||
|
* @return {String}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
View.prototype.__defineGetter__('indexPath', function(){
|
||||||
|
return this.dirname
|
||||||
|
+ '/' + this.basename.replace(this.extension, '')
|
||||||
|
+ '/index' + this.extension;
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return ../<name>/index path alternative.
|
||||||
|
*
|
||||||
|
* @return {String}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
View.prototype.__defineGetter__('upIndexPath', function(){
|
||||||
|
return this.dirname + '/../' + this.name + '/index' + this.extension;
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return _ prefix path alternative
|
||||||
|
*
|
||||||
|
* @return {String}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
View.prototype.__defineGetter__('prefixPath', function(){
|
||||||
|
return this.dirname + '/_' + this.basename;
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the given template engine `exports`
|
||||||
|
* as `ext`. For example we may wish to map ".html"
|
||||||
|
* files to jade:
|
||||||
|
*
|
||||||
|
* app.register('.html', require('jade'));
|
||||||
|
*
|
||||||
|
* or
|
||||||
|
*
|
||||||
|
* app.register('html', require('jade'));
|
||||||
|
*
|
||||||
|
* This is also useful for libraries that may not
|
||||||
|
* match extensions correctly. For example my haml.js
|
||||||
|
* library is installed from npm as "hamljs" so instead
|
||||||
|
* of layout.hamljs, we can register the engine as ".haml":
|
||||||
|
*
|
||||||
|
* app.register('.haml', require('haml-js'));
|
||||||
|
*
|
||||||
|
* @param {String} ext
|
||||||
|
* @param {Object} obj
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.register = function(ext, exports) {
|
||||||
|
if ('.' != ext[0]) ext = '.' + ext;
|
||||||
|
cache[ext] = exports;
|
||||||
|
};
|
||||||
11
test/node_modules/express/node_modules/connect/.npmignore
generated
vendored
Normal file
11
test/node_modules/express/node_modules/connect/.npmignore
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
*.markdown
|
||||||
|
*.md
|
||||||
|
.git*
|
||||||
|
Makefile
|
||||||
|
benchmarks/
|
||||||
|
docs/
|
||||||
|
examples/
|
||||||
|
install.sh
|
||||||
|
support/
|
||||||
|
test/
|
||||||
|
.DS_Store
|
||||||
24
test/node_modules/express/node_modules/connect/LICENSE
generated
vendored
Normal file
24
test/node_modules/express/node_modules/connect/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
(The MIT License)
|
||||||
|
|
||||||
|
Copyright (c) 2010 Sencha Inc.
|
||||||
|
Copyright (c) 2011 LearnBoost
|
||||||
|
Copyright (c) 2011 TJ Holowaychuk
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
'Software'), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
2
test/node_modules/express/node_modules/connect/index.js
generated
vendored
Normal file
2
test/node_modules/express/node_modules/connect/index.js
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
module.exports = require('./lib/connect');
|
||||||
81
test/node_modules/express/node_modules/connect/lib/cache.js
generated
vendored
Normal file
81
test/node_modules/express/node_modules/connect/lib/cache.js
generated
vendored
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Connect - Cache
|
||||||
|
* Copyright(c) 2011 Sencha Inc.
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expose `Cache`.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = Cache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LRU cache store.
|
||||||
|
*
|
||||||
|
* @param {Number} limit
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function Cache(limit) {
|
||||||
|
this.store = {};
|
||||||
|
this.keys = [];
|
||||||
|
this.limit = limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Touch `key`, promoting the object.
|
||||||
|
*
|
||||||
|
* @param {String} key
|
||||||
|
* @param {Number} i
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
Cache.prototype.touch = function(key, i){
|
||||||
|
this.keys.splice(i,1);
|
||||||
|
this.keys.push(key);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove `key`.
|
||||||
|
*
|
||||||
|
* @param {String} key
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
Cache.prototype.remove = function(key){
|
||||||
|
delete this.store[key];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the object stored for `key`.
|
||||||
|
*
|
||||||
|
* @param {String} key
|
||||||
|
* @return {Array}
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
Cache.prototype.get = function(key){
|
||||||
|
return this.store[key];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a cache `key`.
|
||||||
|
*
|
||||||
|
* @param {String} key
|
||||||
|
* @return {Array}
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
Cache.prototype.add = function(key){
|
||||||
|
// initialize store
|
||||||
|
var len = this.keys.push(key);
|
||||||
|
|
||||||
|
// limit reached, invalid LRU
|
||||||
|
if (len > this.limit) this.remove(this.keys.shift());
|
||||||
|
|
||||||
|
var arr = this.store[key] = [];
|
||||||
|
arr.createdAt = new Date;
|
||||||
|
return arr;
|
||||||
|
};
|
||||||
106
test/node_modules/express/node_modules/connect/lib/connect.js
generated
vendored
Normal file
106
test/node_modules/express/node_modules/connect/lib/connect.js
generated
vendored
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Connect
|
||||||
|
* Copyright(c) 2010 Sencha Inc.
|
||||||
|
* Copyright(c) 2011 TJ Holowaychuk
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var HTTPServer = require('./http').Server
|
||||||
|
, HTTPSServer = require('./https').Server
|
||||||
|
, fs = require('fs');
|
||||||
|
|
||||||
|
// node patches
|
||||||
|
|
||||||
|
require('./patch');
|
||||||
|
|
||||||
|
// expose createServer() as the module
|
||||||
|
|
||||||
|
exports = module.exports = createServer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Framework version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.version = '1.9.2';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a new `connect.HTTPServer` with the middleware
|
||||||
|
* passed to this function. When an object is passed _first_,
|
||||||
|
* we assume these are the tls options, and return a `connect.HTTPSServer`.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
* An example HTTP server, accepting several middleware.
|
||||||
|
*
|
||||||
|
* var server = connect.createServer(
|
||||||
|
* connect.logger()
|
||||||
|
* , connect.static(__dirname + '/public')
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* An HTTPS server, utilizing the same middleware as above.
|
||||||
|
*
|
||||||
|
* var server = connect.createServer(
|
||||||
|
* { key: key, cert: cert }
|
||||||
|
* , connect.logger()
|
||||||
|
* , connect.static(__dirname + '/public')
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* Alternatively with connect 1.0 we may omit `createServer()`.
|
||||||
|
*
|
||||||
|
* connect(
|
||||||
|
* connect.logger()
|
||||||
|
* , connect.static(__dirname + '/public')
|
||||||
|
* ).listen(3000);
|
||||||
|
*
|
||||||
|
* @param {Object|Function} ...
|
||||||
|
* @return {Server}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
function createServer() {
|
||||||
|
if ('object' == typeof arguments[0]) {
|
||||||
|
return new HTTPSServer(arguments[0], Array.prototype.slice.call(arguments, 1));
|
||||||
|
} else {
|
||||||
|
return new HTTPServer(Array.prototype.slice.call(arguments));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// support connect.createServer()
|
||||||
|
|
||||||
|
exports.createServer = createServer;
|
||||||
|
|
||||||
|
// auto-load getters
|
||||||
|
|
||||||
|
exports.middleware = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-load bundled middleware with getters.
|
||||||
|
*/
|
||||||
|
|
||||||
|
fs.readdirSync(__dirname + '/middleware').forEach(function(filename){
|
||||||
|
if (/\.js$/.test(filename)) {
|
||||||
|
var name = filename.substr(0, filename.lastIndexOf('.'));
|
||||||
|
exports.middleware.__defineGetter__(name, function(){
|
||||||
|
return require('./middleware/' + name);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// expose utils
|
||||||
|
|
||||||
|
exports.utils = require('./utils');
|
||||||
|
|
||||||
|
// expose getters as first-class exports
|
||||||
|
|
||||||
|
exports.utils.merge(exports, exports.middleware);
|
||||||
|
|
||||||
|
// expose constructors
|
||||||
|
|
||||||
|
exports.HTTPServer = HTTPServer;
|
||||||
|
exports.HTTPSServer = HTTPSServer;
|
||||||
|
|
||||||
218
test/node_modules/express/node_modules/connect/lib/http.js
generated
vendored
Normal file
218
test/node_modules/express/node_modules/connect/lib/http.js
generated
vendored
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Connect - HTTPServer
|
||||||
|
* Copyright(c) 2010 Sencha Inc.
|
||||||
|
* Copyright(c) 2011 TJ Holowaychuk
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var http = require('http')
|
||||||
|
, parse = require('url').parse
|
||||||
|
, assert = require('assert')
|
||||||
|
, utils = require('./utils');
|
||||||
|
|
||||||
|
// environment
|
||||||
|
|
||||||
|
var env = process.env.NODE_ENV || 'development';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a new `Server` with the given `middleware`.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
* var server = connect.createServer(
|
||||||
|
* connect.favicon()
|
||||||
|
* , connect.logger()
|
||||||
|
* , connect.static(__dirname + '/public')
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* @params {Array} middleware
|
||||||
|
* @return {Server}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
var Server = exports.Server = function HTTPServer(middleware) {
|
||||||
|
this.stack = [];
|
||||||
|
middleware.forEach(function(fn){
|
||||||
|
this.use(fn);
|
||||||
|
}, this);
|
||||||
|
http.Server.call(this, this.handle);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inherit from `http.Server.prototype`.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Server.prototype.__proto__ = http.Server.prototype;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utilize the given middleware `handle` to the given `route`,
|
||||||
|
* defaulting to _/_. This "route" is the mount-point for the
|
||||||
|
* middleware, when given a value other than _/_ the middleware
|
||||||
|
* is only effective when that segment is present in the request's
|
||||||
|
* pathname.
|
||||||
|
*
|
||||||
|
* For example if we were to mount a function at _/admin_, it would
|
||||||
|
* be invoked on _/admin_, and _/admin/settings_, however it would
|
||||||
|
* not be invoked for _/_, or _/posts_.
|
||||||
|
*
|
||||||
|
* This is effectively the same as passing middleware to `connect.createServer()`,
|
||||||
|
* however provides a progressive api.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
* var server = connect.createServer();
|
||||||
|
* server.use(connect.favicon());
|
||||||
|
* server.use(connect.logger());
|
||||||
|
* server.use(connect.static(__dirname + '/public'));
|
||||||
|
*
|
||||||
|
* If we wanted to prefix static files with _/public_, we could
|
||||||
|
* "mount" the `static()` middleware:
|
||||||
|
*
|
||||||
|
* server.use('/public', connect.static(__dirname + '/public'));
|
||||||
|
*
|
||||||
|
* This api is chainable, meaning the following is valid:
|
||||||
|
*
|
||||||
|
* connect.createServer()
|
||||||
|
* .use(connect.favicon())
|
||||||
|
* .use(connect.logger())
|
||||||
|
* .use(connect.static(__dirname + '/public'))
|
||||||
|
* .listen(3000);
|
||||||
|
*
|
||||||
|
* @param {String|Function} route or handle
|
||||||
|
* @param {Function} handle
|
||||||
|
* @return {Server}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
Server.prototype.use = function(route, handle){
|
||||||
|
this.route = '/';
|
||||||
|
|
||||||
|
// default route to '/'
|
||||||
|
if ('string' != typeof route) {
|
||||||
|
handle = route;
|
||||||
|
route = '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
// wrap sub-apps
|
||||||
|
if ('function' == typeof handle.handle) {
|
||||||
|
var server = handle;
|
||||||
|
server.route = route;
|
||||||
|
handle = function(req, res, next) {
|
||||||
|
server.handle(req, res, next);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// wrap vanilla http.Servers
|
||||||
|
if (handle instanceof http.Server) {
|
||||||
|
handle = handle.listeners('request')[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// normalize route to not trail with slash
|
||||||
|
if ('/' == route[route.length - 1]) {
|
||||||
|
route = route.substr(0, route.length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the middleware
|
||||||
|
this.stack.push({ route: route, handle: handle });
|
||||||
|
|
||||||
|
// allow chaining
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle server requests, punting them down
|
||||||
|
* the middleware stack.
|
||||||
|
*
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
Server.prototype.handle = function(req, res, out) {
|
||||||
|
var writeHead = res.writeHead
|
||||||
|
, stack = this.stack
|
||||||
|
, removed = ''
|
||||||
|
, index = 0;
|
||||||
|
|
||||||
|
function next(err) {
|
||||||
|
var layer, path, c;
|
||||||
|
req.url = removed + req.url;
|
||||||
|
req.originalUrl = req.originalUrl || req.url;
|
||||||
|
removed = '';
|
||||||
|
|
||||||
|
layer = stack[index++];
|
||||||
|
|
||||||
|
// all done
|
||||||
|
if (!layer || res.headerSent) {
|
||||||
|
// but wait! we have a parent
|
||||||
|
if (out) return out(err);
|
||||||
|
|
||||||
|
// error
|
||||||
|
if (err) {
|
||||||
|
var msg = 'production' == env
|
||||||
|
? 'Internal Server Error'
|
||||||
|
: err.stack || err.toString();
|
||||||
|
|
||||||
|
// output to stderr in a non-test env
|
||||||
|
if ('test' != env) console.error(err.stack || err.toString());
|
||||||
|
|
||||||
|
// unable to respond
|
||||||
|
if (res.headerSent) return req.socket.destroy();
|
||||||
|
|
||||||
|
res.statusCode = 500;
|
||||||
|
res.setHeader('Content-Type', 'text/plain');
|
||||||
|
if ('HEAD' == req.method) return res.end();
|
||||||
|
res.end(msg);
|
||||||
|
} else {
|
||||||
|
res.statusCode = 404;
|
||||||
|
res.setHeader('Content-Type', 'text/plain');
|
||||||
|
if ('HEAD' == req.method) return res.end();
|
||||||
|
res.end('Cannot ' + req.method + ' ' + utils.escape(req.originalUrl));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
path = parse(req.url).pathname;
|
||||||
|
if (undefined == path) path = '/';
|
||||||
|
|
||||||
|
// skip this layer if the route doesn't match.
|
||||||
|
if (0 != path.indexOf(layer.route)) return next(err);
|
||||||
|
|
||||||
|
c = path[layer.route.length];
|
||||||
|
if (c && '/' != c && '.' != c) return next(err);
|
||||||
|
|
||||||
|
// Call the layer handler
|
||||||
|
// Trim off the part of the url that matches the route
|
||||||
|
removed = layer.route;
|
||||||
|
req.url = req.url.substr(removed.length);
|
||||||
|
|
||||||
|
// Ensure leading slash
|
||||||
|
if ('/' != req.url[0]) req.url = '/' + req.url;
|
||||||
|
|
||||||
|
var arity = layer.handle.length;
|
||||||
|
if (err) {
|
||||||
|
if (arity === 4) {
|
||||||
|
layer.handle(err, req, res, next);
|
||||||
|
} else {
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
} else if (arity < 4) {
|
||||||
|
layer.handle(req, res, next);
|
||||||
|
} else {
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
if (e instanceof assert.AssertionError) {
|
||||||
|
console.error(e.stack + '\n');
|
||||||
|
next(e);
|
||||||
|
} else {
|
||||||
|
next(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
};
|
||||||
47
test/node_modules/express/node_modules/connect/lib/https.js
generated
vendored
Normal file
47
test/node_modules/express/node_modules/connect/lib/https.js
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Connect - HTTPServer
|
||||||
|
* Copyright(c) 2010 Sencha Inc.
|
||||||
|
* Copyright(c) 2011 TJ Holowaychuk
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var HTTPServer = require('./http').Server
|
||||||
|
, https = require('https');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a new `Server` with the given
|
||||||
|
*`options` and `middleware`. The HTTPS api
|
||||||
|
* is identical to the [HTTP](http.html) server,
|
||||||
|
* however TLS `options` must be provided before
|
||||||
|
* passing in the optional middleware.
|
||||||
|
*
|
||||||
|
* @params {Object} options
|
||||||
|
* @params {Array} middleawre
|
||||||
|
* @return {Server}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
var Server = exports.Server = function HTTPSServer(options, middleware) {
|
||||||
|
this.stack = [];
|
||||||
|
middleware.forEach(function(fn){
|
||||||
|
this.use(fn);
|
||||||
|
}, this);
|
||||||
|
https.Server.call(this, options, this.handle);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inherit from `http.Server.prototype`.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Server.prototype.__proto__ = https.Server.prototype;
|
||||||
|
|
||||||
|
// mixin HTTPServer methods
|
||||||
|
|
||||||
|
Object.keys(HTTPServer.prototype).forEach(function(method){
|
||||||
|
Server.prototype[method] = HTTPServer.prototype[method];
|
||||||
|
});
|
||||||
46
test/node_modules/express/node_modules/connect/lib/index.js
generated
vendored
Normal file
46
test/node_modules/express/node_modules/connect/lib/index.js
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
* # Connect
|
||||||
|
*
|
||||||
|
* Connect is a middleware framework for node,
|
||||||
|
* shipping with over 11 bundled middleware and a rich choice of
|
||||||
|
* [3rd-party middleware](https://github.com/senchalabs/connect/wiki).
|
||||||
|
*
|
||||||
|
* Installation:
|
||||||
|
*
|
||||||
|
* $ npm install connect
|
||||||
|
*
|
||||||
|
* API:
|
||||||
|
*
|
||||||
|
* - [connect](connect.html) general
|
||||||
|
* - [http](http.html) http server
|
||||||
|
* - [https](https.html) https server
|
||||||
|
*
|
||||||
|
* Middleware:
|
||||||
|
*
|
||||||
|
* - [logger](middleware-logger.html) request logger with custom format support
|
||||||
|
* - [csrf](middleware-csrf.html) Cross-site request forgery protection
|
||||||
|
* - [basicAuth](middleware-basicAuth.html) basic http authentication
|
||||||
|
* - [bodyParser](middleware-bodyParser.html) extensible request body parser
|
||||||
|
* - [cookieParser](middleware-cookieParser.html) cookie parser
|
||||||
|
* - [session](middleware-session.html) session management support with bundled [MemoryStore](middleware-session-memory.html)
|
||||||
|
* - [compiler](middleware-compiler.html) static asset compiler (sass, less, coffee-script, etc)
|
||||||
|
* - [methodOverride](middleware-methodOverride.html) faux HTTP method support
|
||||||
|
* - [responseTime](middleware-responseTime.html) calculates response-time and exposes via X-Response-Time
|
||||||
|
* - [router](middleware-router.html) provides rich Sinatra / Express-like routing
|
||||||
|
* - [staticCache](middleware-staticCache.html) memory cache layer for the static() middleware
|
||||||
|
* - [static](middleware-static.html) streaming static file server supporting `Range` and more
|
||||||
|
* - [directory](middleware-directory.html) directory listing middleware
|
||||||
|
* - [vhost](middleware-vhost.html) virtual host sub-domain mapping middleware
|
||||||
|
* - [favicon](middleware-favicon.html) efficient favicon server (with default icon)
|
||||||
|
* - [limit](middleware-limit.html) limit the bytesize of request bodies
|
||||||
|
* - [profiler](middleware-profiler.html) request profiler reporting response-time, memory usage, etc
|
||||||
|
* - [query](middleware-query.html) automatic querystring parser, populating `req.query`
|
||||||
|
* - [errorHandler](middleware-errorHandler.html) flexible error handler
|
||||||
|
*
|
||||||
|
* Internals:
|
||||||
|
*
|
||||||
|
* - connect [utilities](utils.html)
|
||||||
|
* - node monkey [patches](patch.html)
|
||||||
|
*
|
||||||
|
*/
|
||||||
93
test/node_modules/express/node_modules/connect/lib/middleware/basicAuth.js
generated
vendored
Normal file
93
test/node_modules/express/node_modules/connect/lib/middleware/basicAuth.js
generated
vendored
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Connect - basicAuth
|
||||||
|
* Copyright(c) 2010 Sencha Inc.
|
||||||
|
* Copyright(c) 2011 TJ Holowaychuk
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var utils = require('../utils')
|
||||||
|
, unauthorized = utils.unauthorized
|
||||||
|
, badRequest = utils.badRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enfore basic authentication by providing a `callback(user, pass)`,
|
||||||
|
* which must return `true` in order to gain access. Alternatively an async
|
||||||
|
* method is provided as well, invoking `callback(user, pass, callback)`. Populates
|
||||||
|
* `req.remoteUser`. The final alternative is simply passing username / password
|
||||||
|
* strings.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
* connect(connect.basicAuth('username', 'password'));
|
||||||
|
*
|
||||||
|
* connect(
|
||||||
|
* connect.basicAuth(function(user, pass){
|
||||||
|
* return 'tj' == user & 'wahoo' == pass;
|
||||||
|
* })
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* connect(
|
||||||
|
* connect.basicAuth(function(user, pass, fn){
|
||||||
|
* User.authenticate({ user: user, pass: pass }, fn);
|
||||||
|
* })
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* @param {Function|String} callback or username
|
||||||
|
* @param {String} realm
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
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.remoteUser) return next();
|
||||||
|
if (!authorization) return unauthorized(res, realm);
|
||||||
|
|
||||||
|
var parts = authorization.split(' ')
|
||||||
|
, scheme = parts[0]
|
||||||
|
, credentials = new Buffer(parts[1], 'base64').toString().split(':');
|
||||||
|
|
||||||
|
if ('Basic' != scheme) return badRequest(res);
|
||||||
|
|
||||||
|
// async
|
||||||
|
if (callback.length >= 3) {
|
||||||
|
var pause = utils.pause(req);
|
||||||
|
callback(credentials[0], credentials[1], function(err, user){
|
||||||
|
if (err || !user) return unauthorized(res, realm);
|
||||||
|
req.remoteUser = user;
|
||||||
|
next();
|
||||||
|
pause.resume();
|
||||||
|
});
|
||||||
|
// sync
|
||||||
|
} else {
|
||||||
|
if (callback(credentials[0], credentials[1])) {
|
||||||
|
req.remoteUser = credentials[0];
|
||||||
|
next();
|
||||||
|
} else {
|
||||||
|
unauthorized(res, realm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
196
test/node_modules/express/node_modules/connect/lib/middleware/bodyParser.js
generated
vendored
Normal file
196
test/node_modules/express/node_modules/connect/lib/middleware/bodyParser.js
generated
vendored
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Connect - bodyParser
|
||||||
|
* Copyright(c) 2010 Sencha Inc.
|
||||||
|
* Copyright(c) 2011 TJ Holowaychuk
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var qs = require('qs')
|
||||||
|
, formidable = require('formidable');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract the mime type from the given request's
|
||||||
|
* _Content-Type_ header.
|
||||||
|
*
|
||||||
|
* @param {IncomingMessage} req
|
||||||
|
* @return {String}
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function mime(req) {
|
||||||
|
var str = req.headers['content-type'] || '';
|
||||||
|
return str.split(';')[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse request bodies.
|
||||||
|
*
|
||||||
|
* By default _application/json_, _application/x-www-form-urlencoded_,
|
||||||
|
* and _multipart/form-data_ are supported, however you may map `connect.bodyParser.parse[contentType]`
|
||||||
|
* to a function receiving `(req, options, callback)`.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
* connect.createServer(
|
||||||
|
* connect.bodyParser()
|
||||||
|
* , function(req, res) {
|
||||||
|
* res.end('viewing user ' + req.body.user.name);
|
||||||
|
* }
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* $ curl -d 'user[name]=tj' http://localhost/
|
||||||
|
* $ curl -d '{"user":{"name":"tj"}}' -H "Content-Type: application/json" http://localhost/
|
||||||
|
*
|
||||||
|
* Multipart req.files:
|
||||||
|
*
|
||||||
|
* As a security measure files are stored in a separate object, stored
|
||||||
|
* as `req.files`. This prevents attacks that may potentially alter
|
||||||
|
* filenames, and depending on the application gain access to restricted files.
|
||||||
|
*
|
||||||
|
* Multipart configuration:
|
||||||
|
*
|
||||||
|
* The `options` passed are provided to each parser function.
|
||||||
|
* The _multipart/form-data_ parser merges these with formidable's
|
||||||
|
* IncomingForm object, allowing you to tweak the upload directory,
|
||||||
|
* size limits, etc. For example you may wish to retain the file extension
|
||||||
|
* and change the upload directory:
|
||||||
|
*
|
||||||
|
* server.use(bodyParser({ uploadDir: '/www/mysite.com/uploads' }));
|
||||||
|
*
|
||||||
|
* View [node-formidable](https://github.com/felixge/node-formidable) for more information.
|
||||||
|
*
|
||||||
|
* If you wish to use formidable directly within your app, and do not
|
||||||
|
* desire this behaviour for multipart requests simply remove the
|
||||||
|
* parser:
|
||||||
|
*
|
||||||
|
* delete connect.bodyParser.parse['multipart/form-data'];
|
||||||
|
*
|
||||||
|
* Or
|
||||||
|
*
|
||||||
|
* delete express.bodyParser.parse['multipart/form-data'];
|
||||||
|
*
|
||||||
|
* @param {Object} options
|
||||||
|
* @return {Function}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports = module.exports = function bodyParser(options){
|
||||||
|
options = options || {};
|
||||||
|
return function bodyParser(req, res, next) {
|
||||||
|
if (req.body) return next();
|
||||||
|
req.body = {};
|
||||||
|
|
||||||
|
if ('GET' == req.method || 'HEAD' == req.method) return next();
|
||||||
|
var parser = exports.parse[mime(req)];
|
||||||
|
if (parser) {
|
||||||
|
parser(req, options, next);
|
||||||
|
} else {
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parsers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.parse = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse application/x-www-form-urlencoded.
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.parse['application/x-www-form-urlencoded'] = function(req, options, fn){
|
||||||
|
var buf = '';
|
||||||
|
req.setEncoding('utf8');
|
||||||
|
req.on('data', function(chunk){ buf += chunk });
|
||||||
|
req.on('end', function(){
|
||||||
|
try {
|
||||||
|
req.body = buf.length
|
||||||
|
? qs.parse(buf)
|
||||||
|
: {};
|
||||||
|
fn();
|
||||||
|
} catch (err){
|
||||||
|
fn(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse application/json.
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.parse['application/json'] = function(req, options, fn){
|
||||||
|
var buf = '';
|
||||||
|
req.setEncoding('utf8');
|
||||||
|
req.on('data', function(chunk){ buf += chunk });
|
||||||
|
req.on('end', function(){
|
||||||
|
try {
|
||||||
|
req.body = buf.length
|
||||||
|
? JSON.parse(buf)
|
||||||
|
: {};
|
||||||
|
fn();
|
||||||
|
} catch (err){
|
||||||
|
fn(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse multipart/form-data.
|
||||||
|
*
|
||||||
|
* TODO: make multiple support optional
|
||||||
|
* TODO: revisit "error" flag if it's a formidable bug
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.parse['multipart/form-data'] = function(req, options, fn){
|
||||||
|
var form = new formidable.IncomingForm
|
||||||
|
, data = {}
|
||||||
|
, files = {}
|
||||||
|
, done;
|
||||||
|
|
||||||
|
Object.keys(options).forEach(function(key){
|
||||||
|
form[key] = options[key];
|
||||||
|
});
|
||||||
|
|
||||||
|
function ondata(name, val, data){
|
||||||
|
if (Array.isArray(data[name])) {
|
||||||
|
data[name].push(val);
|
||||||
|
} else if (data[name]) {
|
||||||
|
data[name] = [data[name], val];
|
||||||
|
} else {
|
||||||
|
data[name] = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
form.on('field', function(name, val){
|
||||||
|
ondata(name, val, data);
|
||||||
|
});
|
||||||
|
|
||||||
|
form.on('file', function(name, val){
|
||||||
|
ondata(name, val, files);
|
||||||
|
});
|
||||||
|
|
||||||
|
form.on('error', function(err){
|
||||||
|
fn(err);
|
||||||
|
done = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
form.on('end', function(){
|
||||||
|
if (done) return;
|
||||||
|
try {
|
||||||
|
req.body = qs.parse(data);
|
||||||
|
req.files = qs.parse(files);
|
||||||
|
fn();
|
||||||
|
} catch (err) {
|
||||||
|
fn(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
form.parse(req);
|
||||||
|
};
|
||||||
163
test/node_modules/express/node_modules/connect/lib/middleware/compiler.js
generated
vendored
Normal file
163
test/node_modules/express/node_modules/connect/lib/middleware/compiler.js
generated
vendored
Normal file
@@ -0,0 +1,163 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Connect - compiler
|
||||||
|
* Copyright(c) 2010 Sencha Inc.
|
||||||
|
* Copyright(c) 2011 TJ Holowaychuk
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var fs = require('fs')
|
||||||
|
, path = require('path')
|
||||||
|
, parse = require('url').parse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Require cache.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var cache = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup compiler.
|
||||||
|
*
|
||||||
|
* Options:
|
||||||
|
*
|
||||||
|
* - `src` Source directory, defaults to **CWD**.
|
||||||
|
* - `dest` Destination directory, defaults `src`.
|
||||||
|
* - `enable` Array of enabled compilers.
|
||||||
|
*
|
||||||
|
* Compilers:
|
||||||
|
*
|
||||||
|
* - `sass` Compiles sass to css
|
||||||
|
* - `less` Compiles less to css
|
||||||
|
* - `coffeescript` Compiles coffee to js
|
||||||
|
*
|
||||||
|
* @param {Object} options
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports = module.exports = function compiler(options){
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
var srcDir = options.src || process.cwd()
|
||||||
|
, destDir = options.dest || srcDir
|
||||||
|
, enable = options.enable;
|
||||||
|
|
||||||
|
if (!enable || enable.length === 0) {
|
||||||
|
throw new Error('compiler\'s "enable" option is not set, nothing will be compiled.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return function compiler(req, res, next){
|
||||||
|
if ('GET' != req.method) return next();
|
||||||
|
var pathname = parse(req.url).pathname;
|
||||||
|
for (var i = 0, len = enable.length; i < len; ++i) {
|
||||||
|
var name = enable[i]
|
||||||
|
, compiler = compilers[name];
|
||||||
|
if (compiler.match.test(pathname)) {
|
||||||
|
var src = (srcDir + pathname).replace(compiler.match, compiler.ext)
|
||||||
|
, dest = destDir + pathname;
|
||||||
|
|
||||||
|
// Compare mtimes
|
||||||
|
fs.stat(src, function(err, srcStats){
|
||||||
|
if (err) {
|
||||||
|
if ('ENOENT' == err.code) {
|
||||||
|
next();
|
||||||
|
} else {
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fs.stat(dest, function(err, destStats){
|
||||||
|
if (err) {
|
||||||
|
// Oh snap! it does not exist, compile it
|
||||||
|
if ('ENOENT' == err.code) {
|
||||||
|
compile();
|
||||||
|
} else {
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Source has changed, compile it
|
||||||
|
if (srcStats.mtime > destStats.mtime) {
|
||||||
|
compile();
|
||||||
|
} else {
|
||||||
|
// Defer file serving
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Compile to the destination
|
||||||
|
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();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bundled compilers:
|
||||||
|
*
|
||||||
|
* - [sass](http://github.com/visionmedia/sass.js) to _css_
|
||||||
|
* - [less](http://github.com/cloudhead/less.js) to _css_
|
||||||
|
* - [coffee](http://github.com/jashkenas/coffee-script) to _js_
|
||||||
|
*/
|
||||||
|
|
||||||
|
var compilers = exports.compilers = {
|
||||||
|
sass: {
|
||||||
|
match: /\.css$/,
|
||||||
|
ext: '.sass',
|
||||||
|
compile: function(str, fn){
|
||||||
|
var sass = cache.sass || (cache.sass = require('sass'));
|
||||||
|
try {
|
||||||
|
fn(null, sass.render(str));
|
||||||
|
} catch (err) {
|
||||||
|
fn(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
less: {
|
||||||
|
match: /\.css$/,
|
||||||
|
ext: '.less',
|
||||||
|
compile: function(str, fn){
|
||||||
|
var less = cache.less || (cache.less = require('less'));
|
||||||
|
try {
|
||||||
|
less.render(str, fn);
|
||||||
|
} catch (err) {
|
||||||
|
fn(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
coffeescript: {
|
||||||
|
match: /\.js$/,
|
||||||
|
ext: '.coffee',
|
||||||
|
compile: function(str, fn){
|
||||||
|
var coffee = cache.coffee || (cache.coffee = require('coffee-script'));
|
||||||
|
try {
|
||||||
|
fn(null, coffee.compile(str));
|
||||||
|
} catch (err) {
|
||||||
|
fn(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
146
test/node_modules/express/node_modules/connect/lib/middleware/compress.js
generated
vendored
Normal file
146
test/node_modules/express/node_modules/connect/lib/middleware/compress.js
generated
vendored
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Connect - compress
|
||||||
|
* Copyright(c) 2010 Sencha Inc.
|
||||||
|
* Copyright(c) 2011 TJ Holowaychuk
|
||||||
|
* Copyright(c) 2012 Nebojsa Sabovic
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var zlib = require('zlib');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Supported content-encoding methods.
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.methods = {
|
||||||
|
gzip: zlib.createGzip
|
||||||
|
, deflate: zlib.createDeflate
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default filter function.
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.filter = function(req, res){
|
||||||
|
var type = res.getHeader('Content-Type') || '';
|
||||||
|
return type.match(/json|text|javascript/);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compress:
|
||||||
|
*
|
||||||
|
* Compress response data with gzip/deflate.
|
||||||
|
*
|
||||||
|
* Filter:
|
||||||
|
*
|
||||||
|
* A `filter` callback function may be passed to
|
||||||
|
* replace the default logic of:
|
||||||
|
*
|
||||||
|
* exports.filter = function(req, res){
|
||||||
|
* var type = res.getHeader('Content-Type') || '';
|
||||||
|
* return type.match(/json|text|javascript/);
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* Options:
|
||||||
|
*
|
||||||
|
* All remaining options are passed to the gzip/deflate
|
||||||
|
* creation functions. Consult node's docs for additional details.
|
||||||
|
*
|
||||||
|
* - `chunkSize` (default: 16*1024)
|
||||||
|
* - `windowBits`
|
||||||
|
* - `level`: 0-9 where 0 is no compression, and 9 is slow but best compression
|
||||||
|
* - `memLevel`: 1-9 low is slower but uses less memory, high is fast but uses more
|
||||||
|
* - `strategy`: compression strategy
|
||||||
|
*
|
||||||
|
* @param {Object} options
|
||||||
|
* @return {Function}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
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
|
||||||
|
, writeHead = res.writeHead
|
||||||
|
, end = res.end
|
||||||
|
, stream
|
||||||
|
, method;
|
||||||
|
|
||||||
|
// vary
|
||||||
|
res.setHeader('Vary', 'Accept-Encoding');
|
||||||
|
|
||||||
|
// proxy
|
||||||
|
|
||||||
|
res.write = function(chunk, encoding){
|
||||||
|
if (!this._header) this._implicitHeader();
|
||||||
|
return stream
|
||||||
|
? stream.write(chunk, encoding)
|
||||||
|
: write.call(this, chunk, encoding);
|
||||||
|
};
|
||||||
|
|
||||||
|
res.end = function(chunk, encoding){
|
||||||
|
if (!this._header) {
|
||||||
|
this._implicitHeader();
|
||||||
|
}
|
||||||
|
if (chunk) this.write(chunk, encoding);
|
||||||
|
return stream
|
||||||
|
? stream.end()
|
||||||
|
: end.call(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
res.writeHead = function(){
|
||||||
|
res.writeHead = writeHead;
|
||||||
|
|
||||||
|
// default request filter, SHOULD use identity, head
|
||||||
|
if (filter(req, res) && accept && 'HEAD' != req.method) {
|
||||||
|
// default to gzip
|
||||||
|
if ('*' == accept.trim()) {
|
||||||
|
method = 'gzip';
|
||||||
|
} else {
|
||||||
|
for (var i = 0, len = names.length; i < len; ++i) {
|
||||||
|
if (~accept.indexOf(names[i])) {
|
||||||
|
method = names[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// compression method
|
||||||
|
if (method) {
|
||||||
|
// compression stream
|
||||||
|
stream = exports.methods[method](options);
|
||||||
|
|
||||||
|
// header fields
|
||||||
|
res.setHeader('Content-Encoding', method);
|
||||||
|
res.removeHeader('Content-Length');
|
||||||
|
// WARNING: We do not strip content-length out of passed-in headers
|
||||||
|
|
||||||
|
// compression
|
||||||
|
stream.on('data', function(chunk){
|
||||||
|
write.call(res, chunk);
|
||||||
|
});
|
||||||
|
|
||||||
|
stream.on('end', function(){
|
||||||
|
end.call(res);
|
||||||
|
});
|
||||||
|
|
||||||
|
stream.on('drain', function() {
|
||||||
|
res.emit('drain');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res.writeHead.apply(this, arguments);
|
||||||
|
};
|
||||||
|
|
||||||
|
next();
|
||||||
|
};
|
||||||
|
}
|
||||||
46
test/node_modules/express/node_modules/connect/lib/middleware/cookieParser.js
generated
vendored
Normal file
46
test/node_modules/express/node_modules/connect/lib/middleware/cookieParser.js
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Connect - cookieParser
|
||||||
|
* Copyright(c) 2010 Sencha Inc.
|
||||||
|
* Copyright(c) 2011 TJ Holowaychuk
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var utils = require('./../utils');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse _Cookie_ header and populate `req.cookies`
|
||||||
|
* with an object keyed by the cookie names.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
* connect.createServer(
|
||||||
|
* connect.cookieParser()
|
||||||
|
* , function(req, res, next){
|
||||||
|
* res.end(JSON.stringify(req.cookies));
|
||||||
|
* }
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* @return {Function}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = function cookieParser(){
|
||||||
|
return function cookieParser(req, res, next) {
|
||||||
|
var cookie = req.headers.cookie;
|
||||||
|
if (req.cookies) return next();
|
||||||
|
req.cookies = {};
|
||||||
|
if (cookie) {
|
||||||
|
try {
|
||||||
|
req.cookies = utils.parseCookie(cookie);
|
||||||
|
} catch (err) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
};
|
||||||
|
};
|
||||||
105
test/node_modules/express/node_modules/connect/lib/middleware/csrf.js
generated
vendored
Normal file
105
test/node_modules/express/node_modules/connect/lib/middleware/csrf.js
generated
vendored
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Connect - csrf
|
||||||
|
* Copyright(c) 2011 Sencha Inc.
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var utils = require('../utils')
|
||||||
|
, crypto = require('crypto');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CRSF protection middleware.
|
||||||
|
*
|
||||||
|
* By default this middleware generates a token named "_csrf"
|
||||||
|
* which should be added to requests which mutate
|
||||||
|
* state, within a hidden form field, query-string etc. This
|
||||||
|
* token is validated against the visitor's `req.session._csrf`
|
||||||
|
* property which is re-generated per request.
|
||||||
|
*
|
||||||
|
* The default `value` function checks `req.body` generated
|
||||||
|
* by the `bodyParser()` middleware, `req.query` generated
|
||||||
|
* by `query()`, and the "X-CSRF-Token" header field.
|
||||||
|
*
|
||||||
|
* This middleware requires session support, thus should be added
|
||||||
|
* somewhere _below_ `session()` and `cookieParser()`.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
* var form = '\n\
|
||||||
|
* <form action="/" method="post">\n\
|
||||||
|
* <input type="hidden" name="_csrf" value="{token}" />\n\
|
||||||
|
* <input type="text" name="user[name]" value="{user}" />\n\
|
||||||
|
* <input type="password" name="user[pass]" />\n\
|
||||||
|
* <input type="submit" value="Login" />\n\
|
||||||
|
* </form>\n\
|
||||||
|
* ';
|
||||||
|
*
|
||||||
|
* connect(
|
||||||
|
* connect.cookieParser()
|
||||||
|
* , connect.session({ secret: 'keyboard cat' })
|
||||||
|
* , connect.bodyParser()
|
||||||
|
* , connect.csrf()
|
||||||
|
*
|
||||||
|
* , function(req, res, next){
|
||||||
|
* if ('POST' != req.method) return next();
|
||||||
|
* req.session.user = req.body.user;
|
||||||
|
* next();
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* , function(req, res){
|
||||||
|
* res.setHeader('Content-Type', 'text/html');
|
||||||
|
* var body = form
|
||||||
|
* .replace('{token}', req.session._csrf)
|
||||||
|
* .replace('{user}', req.session.user && req.session.user.name || '');
|
||||||
|
* res.end(body);
|
||||||
|
* }
|
||||||
|
* ).listen(3000);
|
||||||
|
*
|
||||||
|
* Options:
|
||||||
|
*
|
||||||
|
* - `value` a function accepting the request, returning the token
|
||||||
|
*
|
||||||
|
* @param {Object} options
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = function csrf(options) {
|
||||||
|
var options = options || {}
|
||||||
|
, value = options.value || defaultValue;
|
||||||
|
|
||||||
|
return function(req, res, next){
|
||||||
|
// generate CSRF token
|
||||||
|
var token = req.session._csrf || (req.session._csrf = utils.uid(24));
|
||||||
|
|
||||||
|
// ignore GET (for now)
|
||||||
|
if ('GET' == req.method || 'HEAD' == req.method || 'OPTIONS' == req.method) return next();
|
||||||
|
|
||||||
|
// determine value
|
||||||
|
var val = value(req);
|
||||||
|
|
||||||
|
// check
|
||||||
|
if (val != token) return utils.forbidden(res);
|
||||||
|
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default value function, checking the `req.body`
|
||||||
|
* and `req.query` for the CSRF token.
|
||||||
|
*
|
||||||
|
* @param {IncomingMessage} req
|
||||||
|
* @return {String}
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function defaultValue(req) {
|
||||||
|
return (req.body && req.body._csrf)
|
||||||
|
|| (req.query && req.query._csrf)
|
||||||
|
|| (req.headers['x-csrf-token']);
|
||||||
|
}
|
||||||
222
test/node_modules/express/node_modules/connect/lib/middleware/directory.js
generated
vendored
Normal file
222
test/node_modules/express/node_modules/connect/lib/middleware/directory.js
generated
vendored
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Connect - directory
|
||||||
|
* Copyright(c) 2011 Sencha Inc.
|
||||||
|
* Copyright(c) 2011 TJ Holowaychuk
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
// TODO: icon / style for directories
|
||||||
|
// TODO: arrow key navigation
|
||||||
|
// TODO: make icons extensible
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var fs = require('fs')
|
||||||
|
, parse = require('url').parse
|
||||||
|
, utils = require('../utils')
|
||||||
|
, path = require('path')
|
||||||
|
, normalize = path.normalize
|
||||||
|
, extname = path.extname
|
||||||
|
, join = path.join;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Icon cache.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var cache = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serve directory listings with the given `root` path.
|
||||||
|
*
|
||||||
|
* Options:
|
||||||
|
*
|
||||||
|
* - `hidden` display hidden (dot) files. Defaults to false.
|
||||||
|
* - `icons` display icons. Defaults to false.
|
||||||
|
* - `filter` Apply this filter function to files. Defaults to false.
|
||||||
|
*
|
||||||
|
* @param {String} root
|
||||||
|
* @param {Object} options
|
||||||
|
* @return {Function}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports = module.exports = function directory(root, options){
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
// root required
|
||||||
|
if (!root) throw new Error('directory() root path required');
|
||||||
|
var hidden = options.hidden
|
||||||
|
, icons = options.icons
|
||||||
|
, filter = options.filter
|
||||||
|
, root = normalize(root);
|
||||||
|
|
||||||
|
return function directory(req, res, next) {
|
||||||
|
var accept = req.headers.accept || 'text/plain'
|
||||||
|
, url = parse(req.url)
|
||||||
|
, dir = decodeURIComponent(url.pathname)
|
||||||
|
, path = normalize(join(root, dir))
|
||||||
|
, originalUrl = parse(req.originalUrl)
|
||||||
|
, originalDir = decodeURIComponent(originalUrl.pathname)
|
||||||
|
, showUp = path != root && path != root + '/';
|
||||||
|
|
||||||
|
// null byte(s)
|
||||||
|
if (~path.indexOf('\0')) return utils.badRequest(res);
|
||||||
|
|
||||||
|
// malicious path
|
||||||
|
if (0 != path.indexOf(root)) return utils.forbidden(res);
|
||||||
|
|
||||||
|
// check if we have a directory
|
||||||
|
fs.stat(path, function(err, stat){
|
||||||
|
if (err) return 'ENOENT' == err.code
|
||||||
|
? next()
|
||||||
|
: next(err);
|
||||||
|
|
||||||
|
if (!stat.isDirectory()) return next();
|
||||||
|
|
||||||
|
// fetch files
|
||||||
|
fs.readdir(path, function(err, files){
|
||||||
|
if (err) return next(err);
|
||||||
|
if (!hidden) files = removeHidden(files);
|
||||||
|
if (filter) files = files.filter(filter);
|
||||||
|
files.sort();
|
||||||
|
// content-negotiation
|
||||||
|
for (var key in exports) {
|
||||||
|
if (~accept.indexOf(key) || ~accept.indexOf('*/*')) {
|
||||||
|
exports[key](req, res, files, next, originalDir, showUp, icons);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
utils.notAcceptable(res);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Respond with text/html.
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.html = function(req, res, files, next, dir, showUp, icons){
|
||||||
|
fs.readFile(__dirname + '/../public/directory.html', 'utf8', function(err, str){
|
||||||
|
if (err) return next(err);
|
||||||
|
fs.readFile(__dirname + '/../public/style.css', 'utf8', function(err, style){
|
||||||
|
if (err) return next(err);
|
||||||
|
if (showUp) files.unshift('..');
|
||||||
|
str = str
|
||||||
|
.replace('{style}', style)
|
||||||
|
.replace('{files}', html(files, dir, icons))
|
||||||
|
.replace('{directory}', dir)
|
||||||
|
.replace('{linked-path}', htmlPath(dir));
|
||||||
|
res.setHeader('Content-Type', 'text/html');
|
||||||
|
res.setHeader('Content-Length', str.length);
|
||||||
|
res.end(str);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Respond with application/json.
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.json = function(req, res, files){
|
||||||
|
files = JSON.stringify(files);
|
||||||
|
res.setHeader('Content-Type', 'application/json');
|
||||||
|
res.setHeader('Content-Length', files.length);
|
||||||
|
res.end(files);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Respond with text/plain.
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.plain = function(req, res, files){
|
||||||
|
files = files.join('\n') + '\n';
|
||||||
|
res.setHeader('Content-Type', 'text/plain');
|
||||||
|
res.setHeader('Content-Length', files.length);
|
||||||
|
res.end(files);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map html `dir`, returning a linked path.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function htmlPath(dir) {
|
||||||
|
var curr = [];
|
||||||
|
return dir.split('/').map(function(part){
|
||||||
|
curr.push(part);
|
||||||
|
return '<a href="' + curr.join('/') + '">' + part + '</a>';
|
||||||
|
}).join(' / ');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map html `files`, returning an html unordered list.
|
||||||
|
*/
|
||||||
|
|
||||||
|
function html(files, dir, useIcons) {
|
||||||
|
return '<ul id="files">' + files.map(function(file){
|
||||||
|
var icon = ''
|
||||||
|
, classes = [];
|
||||||
|
|
||||||
|
if (useIcons && '..' != file) {
|
||||||
|
icon = icons[extname(file)] || icons.default;
|
||||||
|
icon = '<img src="data:image/png;base64,' + load(icon) + '" />';
|
||||||
|
classes.push('icon');
|
||||||
|
}
|
||||||
|
|
||||||
|
return '<li><a href="'
|
||||||
|
+ join(dir, file)
|
||||||
|
+ '" class="'
|
||||||
|
+ classes.join(' ') + '"'
|
||||||
|
+ ' title="' + file + '">'
|
||||||
|
+ icon + file + '</a></li>';
|
||||||
|
|
||||||
|
}).join('\n') + '</ul>';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load and cache the given `icon`.
|
||||||
|
*
|
||||||
|
* @param {String} icon
|
||||||
|
* @return {String}
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function load(icon) {
|
||||||
|
if (cache[icon]) return cache[icon];
|
||||||
|
return cache[icon] = fs.readFileSync(__dirname + '/../public/icons/' + icon, 'base64');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter "hidden" `files`, aka files
|
||||||
|
* beginning with a `.`.
|
||||||
|
*
|
||||||
|
* @param {Array} files
|
||||||
|
* @return {Array}
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function removeHidden(files) {
|
||||||
|
return files.filter(function(file){
|
||||||
|
return '.' != file[0];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Icon map.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var icons = {
|
||||||
|
'.js': 'page_white_code_red.png'
|
||||||
|
, '.c': 'page_white_c.png'
|
||||||
|
, '.h': 'page_white_h.png'
|
||||||
|
, '.cc': 'page_white_cplusplus.png'
|
||||||
|
, '.php': 'page_white_php.png'
|
||||||
|
, '.rb': 'page_white_ruby.png'
|
||||||
|
, '.cpp': 'page_white_cplusplus.png'
|
||||||
|
, '.swf': 'page_white_flash.png'
|
||||||
|
, '.pdf': 'page_white_acrobat.png'
|
||||||
|
, 'default': 'page_white.png'
|
||||||
|
};
|
||||||
100
test/node_modules/express/node_modules/connect/lib/middleware/errorHandler.js
generated
vendored
Normal file
100
test/node_modules/express/node_modules/connect/lib/middleware/errorHandler.js
generated
vendored
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
/*!
|
||||||
|
* Connect - errorHandler
|
||||||
|
* Copyright(c) 2010 Sencha Inc.
|
||||||
|
* Copyright(c) 2011 TJ Holowaychuk
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var utils = require('../utils')
|
||||||
|
, url = require('url')
|
||||||
|
, fs = require('fs');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flexible error handler, providing (_optional_) stack traces
|
||||||
|
* and error message responses for requests accepting text, html,
|
||||||
|
* or json.
|
||||||
|
*
|
||||||
|
* Options:
|
||||||
|
*
|
||||||
|
* - `showStack`, `stack` respond with both the error message and stack trace. Defaults to `false`
|
||||||
|
* - `showMessage`, `message`, respond with the exception message only. Defaults to `false`
|
||||||
|
* - `dumpExceptions`, `dump`, dump exceptions to stderr (without terminating the process). Defaults to `false`
|
||||||
|
*
|
||||||
|
* Text:
|
||||||
|
*
|
||||||
|
* By default, and when _text/plain_ is accepted a simple stack trace
|
||||||
|
* or error message will be returned.
|
||||||
|
*
|
||||||
|
* JSON:
|
||||||
|
*
|
||||||
|
* When _application/json_ is accepted, connect will respond with
|
||||||
|
* an object in the form of `{ "error": error }`.
|
||||||
|
*
|
||||||
|
* HTML:
|
||||||
|
*
|
||||||
|
* When accepted connect will output a nice html stack trace.
|
||||||
|
*
|
||||||
|
* @param {Object} options
|
||||||
|
* @return {Function}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports = module.exports = function errorHandler(options){
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
// defaults
|
||||||
|
var showStack = options.showStack || options.stack
|
||||||
|
, showMessage = options.showMessage || options.message
|
||||||
|
, dumpExceptions = options.dumpExceptions || options.dump
|
||||||
|
, formatUrl = options.formatUrl;
|
||||||
|
|
||||||
|
return function errorHandler(err, req, res, next){
|
||||||
|
res.statusCode = 500;
|
||||||
|
if (dumpExceptions) console.error(err.stack);
|
||||||
|
if (showStack) {
|
||||||
|
var accept = req.headers.accept || '';
|
||||||
|
// html
|
||||||
|
if (~accept.indexOf('html')) {
|
||||||
|
fs.readFile(__dirname + '/../public/style.css', 'utf8', function(e, style){
|
||||||
|
fs.readFile(__dirname + '/../public/error.html', 'utf8', function(e, html){
|
||||||
|
var stack = (err.stack || '')
|
||||||
|
.split('\n').slice(1)
|
||||||
|
.map(function(v){ return '<li>' + v + '</li>'; }).join('');
|
||||||
|
html = html
|
||||||
|
.replace('{style}', style)
|
||||||
|
.replace('{stack}', stack)
|
||||||
|
.replace('{title}', exports.title)
|
||||||
|
.replace(/\{error\}/g, utils.escape(err.toString()));
|
||||||
|
res.setHeader('Content-Type', 'text/html');
|
||||||
|
res.end(html);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// json
|
||||||
|
} else if (~accept.indexOf('json')) {
|
||||||
|
var json = JSON.stringify({ error: err });
|
||||||
|
res.setHeader('Content-Type', 'application/json');
|
||||||
|
res.end(json);
|
||||||
|
// plain text
|
||||||
|
} else {
|
||||||
|
res.writeHead(500, { 'Content-Type': 'text/plain' });
|
||||||
|
res.end(err.stack);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var body = showMessage
|
||||||
|
? err.toString()
|
||||||
|
: 'Internal Server Error';
|
||||||
|
res.setHeader('Content-Type', 'text/plain');
|
||||||
|
res.end(body);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Template title.
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.title = 'Connect';
|
||||||
76
test/node_modules/express/node_modules/connect/lib/middleware/favicon.js
generated
vendored
Normal file
76
test/node_modules/express/node_modules/connect/lib/middleware/favicon.js
generated
vendored
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Connect - favicon
|
||||||
|
* Copyright(c) 2010 Sencha Inc.
|
||||||
|
* Copyright(c) 2011 TJ Holowaychuk
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var fs = require('fs')
|
||||||
|
, utils = require('../utils');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Favicon cache.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var icon;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By default serves the connect favicon, or the favicon
|
||||||
|
* located by the given `path`.
|
||||||
|
*
|
||||||
|
* Options:
|
||||||
|
*
|
||||||
|
* - `maxAge` cache-control max-age directive, defaulting to 1 day
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
* connect.createServer(
|
||||||
|
* connect.favicon()
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* connect.createServer(
|
||||||
|
* connect.favicon(__dirname + '/public/favicon.ico')
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* @param {String} path
|
||||||
|
* @param {Object} options
|
||||||
|
* @return {Function}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = function favicon(path, options){
|
||||||
|
var options = options || {}
|
||||||
|
, path = path || __dirname + '/../public/favicon.ico'
|
||||||
|
, maxAge = options.maxAge || 86400000;
|
||||||
|
|
||||||
|
return function favicon(req, res, next){
|
||||||
|
if ('/favicon.ico' == req.url) {
|
||||||
|
if (icon) {
|
||||||
|
res.writeHead(200, icon.headers);
|
||||||
|
res.end(icon.body);
|
||||||
|
} else {
|
||||||
|
fs.readFile(path, function(err, buf){
|
||||||
|
if (err) return next(err);
|
||||||
|
icon = {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'image/x-icon'
|
||||||
|
, 'Content-Length': buf.length
|
||||||
|
, 'ETag': '"' + utils.md5(buf) + '"'
|
||||||
|
, 'Cache-Control': 'public, max-age=' + (maxAge / 1000)
|
||||||
|
},
|
||||||
|
body: buf
|
||||||
|
};
|
||||||
|
res.writeHead(200, icon.headers);
|
||||||
|
res.end(icon.body);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
80
test/node_modules/express/node_modules/connect/lib/middleware/limit.js
generated
vendored
Normal file
80
test/node_modules/express/node_modules/connect/lib/middleware/limit.js
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Connect - limit
|
||||||
|
* Copyright(c) 2011 TJ Holowaychuk
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Limit request bodies to the given size in `bytes`.
|
||||||
|
*
|
||||||
|
* A string representation of the bytesize may also be passed,
|
||||||
|
* for example "5mb", "200kb", "1gb", etc.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
* var server = connect(
|
||||||
|
* connect.limit('5.5mb')
|
||||||
|
* ).listen(3000);
|
||||||
|
*
|
||||||
|
* @param {Number|String} bytes
|
||||||
|
* @return {Function}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = function limit(bytes){
|
||||||
|
if ('string' == typeof bytes) bytes = parse(bytes);
|
||||||
|
if ('number' != typeof bytes) throw new Error('limit() bytes required');
|
||||||
|
return function limit(req, res, next){
|
||||||
|
var received = 0
|
||||||
|
, len = req.headers['content-length']
|
||||||
|
? parseInt(req.headers['content-length'], 10)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
// deny the request
|
||||||
|
function deny() {
|
||||||
|
req.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
// self-awareness
|
||||||
|
if (req._limit) return next();
|
||||||
|
req._limit = true;
|
||||||
|
|
||||||
|
// limit by content-length
|
||||||
|
if (len && len > bytes) {
|
||||||
|
res.statusCode = 413;
|
||||||
|
res.end('Request Entity Too Large');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// limit
|
||||||
|
req.on('data', function(chunk){
|
||||||
|
received += chunk.length;
|
||||||
|
if (received > bytes) deny();
|
||||||
|
});
|
||||||
|
|
||||||
|
next();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse byte `size` string.
|
||||||
|
*
|
||||||
|
* @param {String} size
|
||||||
|
* @return {Number}
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function parse(size) {
|
||||||
|
var parts = size.match(/^(\d+(?:\.\d+)?) *(kb|mb|gb)$/)
|
||||||
|
, n = parseFloat(parts[1])
|
||||||
|
, type = parts[2];
|
||||||
|
|
||||||
|
var map = {
|
||||||
|
kb: 1024
|
||||||
|
, mb: 1024 * 1024
|
||||||
|
, gb: 1024 * 1024 * 1024
|
||||||
|
};
|
||||||
|
|
||||||
|
return map[type] * n;
|
||||||
|
}
|
||||||
299
test/node_modules/express/node_modules/connect/lib/middleware/logger.js
generated
vendored
Normal file
299
test/node_modules/express/node_modules/connect/lib/middleware/logger.js
generated
vendored
Normal file
@@ -0,0 +1,299 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Connect - logger
|
||||||
|
* Copyright(c) 2010 Sencha Inc.
|
||||||
|
* Copyright(c) 2011 TJ Holowaychuk
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log buffer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var buf = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default log buffer duration.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var defaultBufferDuration = 1000;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log requests with the given `options` or a `format` string.
|
||||||
|
*
|
||||||
|
* Options:
|
||||||
|
*
|
||||||
|
* - `format` Format string, see below for tokens
|
||||||
|
* - `stream` Output stream, defaults to _stdout_
|
||||||
|
* - `buffer` Buffer duration, defaults to 1000ms when _true_
|
||||||
|
* - `immediate` Write log line on request instead of response (for response times)
|
||||||
|
*
|
||||||
|
* 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`
|
||||||
|
*
|
||||||
|
* Formats:
|
||||||
|
*
|
||||||
|
* Pre-defined formats that ship with connect:
|
||||||
|
*
|
||||||
|
* - `default` ':remote-addr - - [:date] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"'
|
||||||
|
* - `short` ':remote-addr - :method :url HTTP/:http-version :status :res[content-length] - :response-time ms'
|
||||||
|
* - `tiny` ':method :url :status :res[content-length] - :response-time ms'
|
||||||
|
* - `dev` concise output colored by response status for development use
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
* connect.logger() // default
|
||||||
|
* connect.logger('short')
|
||||||
|
* connect.logger('tiny')
|
||||||
|
* connect.logger('dev')
|
||||||
|
* connect.logger(':method :url - :referrer')
|
||||||
|
* connect.logger(':req[content-type] -> :res[content-type]')
|
||||||
|
* connect.logger(function(req, res){ return 'some format string' })
|
||||||
|
*
|
||||||
|
* Defining Tokens:
|
||||||
|
*
|
||||||
|
* To define a token, simply invoke `connect.logger.token()` with the
|
||||||
|
* name and a callback function. The value returned is then available
|
||||||
|
* as ":type" in this case.
|
||||||
|
*
|
||||||
|
* connect.logger.token('type', function(req, res){ return req.headers['content-type']; })
|
||||||
|
*
|
||||||
|
* Defining Formats:
|
||||||
|
*
|
||||||
|
* All default formats are defined this way, however it's public API as well:
|
||||||
|
*
|
||||||
|
* connect.logger.format('name', 'string or function')
|
||||||
|
*
|
||||||
|
* @param {String|Function|Object} format or options
|
||||||
|
* @return {Function}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports = module.exports = function logger(options) {
|
||||||
|
if ('object' == typeof options) {
|
||||||
|
options = options || {};
|
||||||
|
} else if (options) {
|
||||||
|
options = { format: options };
|
||||||
|
} else {
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// output on request instead of response
|
||||||
|
var immediate = options.immediate;
|
||||||
|
|
||||||
|
// format name
|
||||||
|
var fmt = exports[options.format] || options.format || exports.default;
|
||||||
|
|
||||||
|
// compile format
|
||||||
|
if ('function' != typeof fmt) fmt = compile(fmt);
|
||||||
|
|
||||||
|
// options
|
||||||
|
var stream = options.stream || process.stdout
|
||||||
|
, buffer = options.buffer;
|
||||||
|
|
||||||
|
// buffering support
|
||||||
|
if (buffer) {
|
||||||
|
var realStream = stream
|
||||||
|
, interval = 'number' == typeof buffer
|
||||||
|
? buffer
|
||||||
|
: defaultBufferDuration;
|
||||||
|
|
||||||
|
// flush interval
|
||||||
|
setInterval(function(){
|
||||||
|
if (buf.length) {
|
||||||
|
realStream.write(buf.join(''), 'ascii');
|
||||||
|
buf.length = 0;
|
||||||
|
}
|
||||||
|
}, interval);
|
||||||
|
|
||||||
|
// swap the stream
|
||||||
|
stream = {
|
||||||
|
write: function(str){
|
||||||
|
buf.push(str);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return function logger(req, res, next) {
|
||||||
|
req._startTime = new Date;
|
||||||
|
|
||||||
|
// mount safety
|
||||||
|
if (req._logging) return next();
|
||||||
|
|
||||||
|
// flag as logging
|
||||||
|
req._logging = true;
|
||||||
|
|
||||||
|
// immediate
|
||||||
|
if (immediate) {
|
||||||
|
var line = fmt(exports, req, res);
|
||||||
|
if (null == line) return;
|
||||||
|
stream.write(line + '\n', 'ascii');
|
||||||
|
} else {
|
||||||
|
// proxy end to output loggging
|
||||||
|
var end = res.end;
|
||||||
|
res.end = function(chunk, encoding){
|
||||||
|
res.end = end;
|
||||||
|
res.end(chunk, encoding);
|
||||||
|
var line = fmt(exports, req, res);
|
||||||
|
if (null == line) return;
|
||||||
|
stream.write(line + '\n', 'ascii');
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
next();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compile `fmt` into a function.
|
||||||
|
*
|
||||||
|
* @param {String} fmt
|
||||||
|
* @return {Function}
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function compile(fmt) {
|
||||||
|
fmt = fmt.replace(/"/g, '\\"');
|
||||||
|
var js = ' return "' + fmt.replace(/:([-\w]{2,})(?:\[([^\]]+)\])?/g, function(_, name, arg){
|
||||||
|
return '"\n + (tokens["' + name + '"](req, res, "' + arg + '") || "-") + "';
|
||||||
|
}) + '";'
|
||||||
|
return new Function('tokens, req, res', js);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define a token function with the given `name`,
|
||||||
|
* and callback `fn(req, res)`.
|
||||||
|
*
|
||||||
|
* @param {String} name
|
||||||
|
* @param {Function} fn
|
||||||
|
* @return {Object} exports for chaining
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.token = function(name, fn) {
|
||||||
|
exports[name] = fn;
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define a `fmt` with the given `name`.
|
||||||
|
*
|
||||||
|
* @param {String} name
|
||||||
|
* @param {String|Function} fmt
|
||||||
|
* @return {Object} exports for chaining
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.format = function(name, str){
|
||||||
|
exports[name] = str;
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
// default format
|
||||||
|
|
||||||
|
exports.format('default', ':remote-addr - - [:date] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"');
|
||||||
|
|
||||||
|
// short format
|
||||||
|
|
||||||
|
exports.format('short', ':remote-addr - :method :url HTTP/:http-version :status :res[content-length] - :response-time ms');
|
||||||
|
|
||||||
|
// tiny format
|
||||||
|
|
||||||
|
exports.format('tiny', ':method :url :status :res[content-length] - :response-time ms');
|
||||||
|
|
||||||
|
// dev (colored)
|
||||||
|
|
||||||
|
exports.format('dev', function(tokens, req, res){
|
||||||
|
var status = res.statusCode
|
||||||
|
, color = 32;
|
||||||
|
|
||||||
|
if (status >= 500) color = 31
|
||||||
|
else if (status >= 400) color = 33
|
||||||
|
else if (status >= 300) color = 36;
|
||||||
|
|
||||||
|
return '\033[90m' + req.method
|
||||||
|
+ ' ' + req.originalUrl + ' '
|
||||||
|
+ '\033[' + color + 'm' + res.statusCode
|
||||||
|
+ ' \033[90m'
|
||||||
|
+ (new Date - req._startTime)
|
||||||
|
+ 'ms\033[0m';
|
||||||
|
});
|
||||||
|
|
||||||
|
// request url
|
||||||
|
|
||||||
|
exports.token('url', function(req){
|
||||||
|
return req.originalUrl;
|
||||||
|
});
|
||||||
|
|
||||||
|
// request method
|
||||||
|
|
||||||
|
exports.token('method', function(req){
|
||||||
|
return req.method;
|
||||||
|
});
|
||||||
|
|
||||||
|
// response time in milliseconds
|
||||||
|
|
||||||
|
exports.token('response-time', function(req){
|
||||||
|
return new Date - req._startTime;
|
||||||
|
});
|
||||||
|
|
||||||
|
// UTC date
|
||||||
|
|
||||||
|
exports.token('date', function(){
|
||||||
|
return new Date().toUTCString();
|
||||||
|
});
|
||||||
|
|
||||||
|
// response status code
|
||||||
|
|
||||||
|
exports.token('status', function(req, res){
|
||||||
|
return res.statusCode;
|
||||||
|
});
|
||||||
|
|
||||||
|
// normalized referrer
|
||||||
|
|
||||||
|
exports.token('referrer', function(req){
|
||||||
|
return req.headers['referer'] || req.headers['referrer'];
|
||||||
|
});
|
||||||
|
|
||||||
|
// remote address
|
||||||
|
|
||||||
|
exports.token('remote-addr', function(req){
|
||||||
|
return req.socket && (req.socket.remoteAddress || (req.socket.socket && req.socket.socket.remoteAddress));
|
||||||
|
});
|
||||||
|
|
||||||
|
// HTTP version
|
||||||
|
|
||||||
|
exports.token('http-version', function(req){
|
||||||
|
return req.httpVersionMajor + '.' + req.httpVersionMinor;
|
||||||
|
});
|
||||||
|
|
||||||
|
// UA string
|
||||||
|
|
||||||
|
exports.token('user-agent', function(req){
|
||||||
|
return req.headers['user-agent'];
|
||||||
|
});
|
||||||
|
|
||||||
|
// request header
|
||||||
|
|
||||||
|
exports.token('req', function(req, res, field){
|
||||||
|
return req.headers[field.toLowerCase()];
|
||||||
|
});
|
||||||
|
|
||||||
|
// response header
|
||||||
|
|
||||||
|
exports.token('res', function(req, res, field){
|
||||||
|
return (res._headers || {})[field.toLowerCase()];
|
||||||
|
});
|
||||||
|
|
||||||
38
test/node_modules/express/node_modules/connect/lib/middleware/methodOverride.js
generated
vendored
Normal file
38
test/node_modules/express/node_modules/connect/lib/middleware/methodOverride.js
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Connect - methodOverride
|
||||||
|
* Copyright(c) 2010 Sencha Inc.
|
||||||
|
* Copyright(c) 2011 TJ Holowaychuk
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides faux HTTP method support.
|
||||||
|
*
|
||||||
|
* Pass an optional `key` to use when checking for
|
||||||
|
* a method override, othewise defaults to _\_method_.
|
||||||
|
* The original method is available via `req.originalMethod`.
|
||||||
|
*
|
||||||
|
* @param {String} key
|
||||||
|
* @return {Function}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = function methodOverride(key){
|
||||||
|
key = key || "_method";
|
||||||
|
return function methodOverride(req, res, next) {
|
||||||
|
req.originalMethod = req.originalMethod || req.method;
|
||||||
|
|
||||||
|
// req.body
|
||||||
|
if (req.body && key in req.body) {
|
||||||
|
req.method = req.body[key].toUpperCase();
|
||||||
|
delete req.body[key];
|
||||||
|
// check X-HTTP-Method-Override
|
||||||
|
} else if (req.headers['x-http-method-override']) {
|
||||||
|
req.method = req.headers['x-http-method-override'].toUpperCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
next();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
100
test/node_modules/express/node_modules/connect/lib/middleware/profiler.js
generated
vendored
Normal file
100
test/node_modules/express/node_modules/connect/lib/middleware/profiler.js
generated
vendored
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Connect - profiler
|
||||||
|
* Copyright(c) 2011 TJ Holowaychuk
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Profile the duration of a request.
|
||||||
|
*
|
||||||
|
* Typically this middleware should be utilized
|
||||||
|
* _above_ all others, as it proxies the `res.end()`
|
||||||
|
* method, being first allows it to encapsulate all
|
||||||
|
* other middleware.
|
||||||
|
*
|
||||||
|
* Example Output:
|
||||||
|
*
|
||||||
|
* GET /
|
||||||
|
* response time 2ms
|
||||||
|
* memory rss 52.00kb
|
||||||
|
* memory vsize 2.07mb
|
||||||
|
* heap before 3.76mb / 8.15mb
|
||||||
|
* heap after 3.80mb / 8.15mb
|
||||||
|
*
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = function profiler(){
|
||||||
|
return function(req, res, next){
|
||||||
|
var end = res.end
|
||||||
|
, start = snapshot();
|
||||||
|
|
||||||
|
// state snapshot
|
||||||
|
function snapshot() {
|
||||||
|
return {
|
||||||
|
mem: process.memoryUsage()
|
||||||
|
, time: new Date
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// proxy res.end()
|
||||||
|
res.end = function(data, encoding){
|
||||||
|
res.end = end;
|
||||||
|
res.end(data, encoding);
|
||||||
|
compare(req, start, snapshot())
|
||||||
|
};
|
||||||
|
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare `start` / `end` snapshots.
|
||||||
|
*
|
||||||
|
* @param {IncomingRequest} req
|
||||||
|
* @param {Object} start
|
||||||
|
* @param {Object} end
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function compare(req, start, end) {
|
||||||
|
console.log();
|
||||||
|
row(req.method, req.url);
|
||||||
|
row('response time:', (end.time - start.time) + 'ms');
|
||||||
|
row('memory rss:', formatBytes(end.mem.rss - start.mem.rss));
|
||||||
|
row('memory vsize:', formatBytes(end.mem.vsize - start.mem.vsize));
|
||||||
|
row('heap before:', formatBytes(start.mem.heapUsed) + ' / ' + formatBytes(start.mem.heapTotal));
|
||||||
|
row('heap after:', formatBytes(end.mem.heapUsed) + ' / ' + formatBytes(end.mem.heapTotal));
|
||||||
|
console.log();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Row helper
|
||||||
|
*
|
||||||
|
* @param {String} key
|
||||||
|
* @param {String} val
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function row(key, val) {
|
||||||
|
console.log(' \033[90m%s\033[0m \033[36m%s\033[0m', key, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format byte-size.
|
||||||
|
*
|
||||||
|
* @param {Number} bytes
|
||||||
|
* @return {String}
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function formatBytes(bytes) {
|
||||||
|
var kb = 1024
|
||||||
|
, mb = 1024 * kb
|
||||||
|
, gb = 1024 * mb;
|
||||||
|
if (bytes < kb) return bytes + 'b';
|
||||||
|
if (bytes < mb) return (bytes / kb).toFixed(2) + 'kb';
|
||||||
|
if (bytes < gb) return (bytes / mb).toFixed(2) + 'mb';
|
||||||
|
return (bytes / gb).toFixed(2) + 'gb';
|
||||||
|
};
|
||||||
40
test/node_modules/express/node_modules/connect/lib/middleware/query.js
generated
vendored
Normal file
40
test/node_modules/express/node_modules/connect/lib/middleware/query.js
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Connect - query
|
||||||
|
* Copyright(c) 2011 TJ Holowaychuk
|
||||||
|
* Copyright(c) 2011 Sencha Inc.
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var qs = require('qs')
|
||||||
|
, parse = require('url').parse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Automatically parse the query-string when available,
|
||||||
|
* populating the `req.query` object.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
* connect(
|
||||||
|
* connect.query()
|
||||||
|
* , function(req, res){
|
||||||
|
* res.end(JSON.stringify(req.query));
|
||||||
|
* }
|
||||||
|
* ).listen(3000);
|
||||||
|
*
|
||||||
|
* @return {Function}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = function query(){
|
||||||
|
return function query(req, res, next){
|
||||||
|
req.query = ~req.url.indexOf('?')
|
||||||
|
? qs.parse(parse(req.url).query)
|
||||||
|
: {};
|
||||||
|
next();
|
||||||
|
};
|
||||||
|
};
|
||||||
34
test/node_modules/express/node_modules/connect/lib/middleware/responseTime.js
generated
vendored
Normal file
34
test/node_modules/express/node_modules/connect/lib/middleware/responseTime.js
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Connect - responseTime
|
||||||
|
* Copyright(c) 2011 TJ Holowaychuk
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the `X-Response-Time` header displaying the response
|
||||||
|
* duration in milliseconds.
|
||||||
|
*
|
||||||
|
* @return {Function}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = function responseTime(){
|
||||||
|
return function(req, res, next){
|
||||||
|
var writeHead = res.writeHead
|
||||||
|
, start = new Date;
|
||||||
|
|
||||||
|
if (res._responseTime) return next();
|
||||||
|
res._responseTime = true;
|
||||||
|
|
||||||
|
// proxy writeHead to calculate duration
|
||||||
|
res.writeHead = function(status, headers){
|
||||||
|
var duration = new Date - start;
|
||||||
|
res.setHeader('X-Response-Time', duration + 'ms');
|
||||||
|
res.writeHead = writeHead;
|
||||||
|
res.writeHead(status, headers);
|
||||||
|
};
|
||||||
|
|
||||||
|
next();
|
||||||
|
};
|
||||||
|
};
|
||||||
379
test/node_modules/express/node_modules/connect/lib/middleware/router.js
generated
vendored
Normal file
379
test/node_modules/express/node_modules/connect/lib/middleware/router.js
generated
vendored
Normal file
@@ -0,0 +1,379 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Connect - router
|
||||||
|
* Copyright(c) 2010 Sencha Inc.
|
||||||
|
* Copyright(c) 2011 TJ Holowaychuk
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var utils = require('../utils')
|
||||||
|
, parse = require('url').parse;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expose router.
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports = module.exports = router;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Supported HTTP / WebDAV methods.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var _methods = exports.methods = [
|
||||||
|
'get'
|
||||||
|
, 'post'
|
||||||
|
, 'put'
|
||||||
|
, 'delete'
|
||||||
|
, 'connect'
|
||||||
|
, 'options'
|
||||||
|
, 'trace'
|
||||||
|
, 'copy'
|
||||||
|
, 'lock'
|
||||||
|
, 'mkcol'
|
||||||
|
, 'move'
|
||||||
|
, 'propfind'
|
||||||
|
, 'proppatch'
|
||||||
|
, 'unlock'
|
||||||
|
, 'report'
|
||||||
|
, 'mkactivity'
|
||||||
|
, 'checkout'
|
||||||
|
, 'merge'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides Sinatra and Express-like routing capabilities.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
* connect.router(function(app){
|
||||||
|
* app.get('/user/:id', function(req, res, next){
|
||||||
|
* // populates req.params.id
|
||||||
|
* });
|
||||||
|
* app.put('/user/:id', function(req, res, next){
|
||||||
|
* // populates req.params.id
|
||||||
|
* });
|
||||||
|
* })
|
||||||
|
*
|
||||||
|
* @param {Function} fn
|
||||||
|
* @return {Function}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
function router(fn){
|
||||||
|
var self = this
|
||||||
|
, methods = {}
|
||||||
|
, routes = {}
|
||||||
|
, params = {};
|
||||||
|
|
||||||
|
if (!fn) throw new Error('router provider requires a callback function');
|
||||||
|
|
||||||
|
// Generate method functions
|
||||||
|
_methods.forEach(function(method){
|
||||||
|
methods[method] = generateMethodFunction(method.toUpperCase());
|
||||||
|
});
|
||||||
|
|
||||||
|
// Alias del -> delete
|
||||||
|
methods.del = methods.delete;
|
||||||
|
|
||||||
|
// Apply callback to all methods
|
||||||
|
methods.all = function(){
|
||||||
|
var args = arguments;
|
||||||
|
_methods.forEach(function(name){
|
||||||
|
methods[name].apply(this, args);
|
||||||
|
});
|
||||||
|
return self;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Register param callback
|
||||||
|
methods.param = function(name, fn){
|
||||||
|
params[name] = fn;
|
||||||
|
};
|
||||||
|
|
||||||
|
fn.call(this, methods);
|
||||||
|
|
||||||
|
function generateMethodFunction(name) {
|
||||||
|
var localRoutes = routes[name] = routes[name] || [];
|
||||||
|
return function(path, fn){
|
||||||
|
var keys = []
|
||||||
|
, middleware = [];
|
||||||
|
|
||||||
|
// slice middleware
|
||||||
|
if (arguments.length > 2) {
|
||||||
|
middleware = Array.prototype.slice.call(arguments, 1, arguments.length);
|
||||||
|
fn = middleware.pop();
|
||||||
|
middleware = utils.flatten(middleware);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn.middleware = middleware;
|
||||||
|
|
||||||
|
if (!path) throw new Error(name + ' route requires a path');
|
||||||
|
if (!fn) throw new Error(name + ' route ' + path + ' requires a callback');
|
||||||
|
var regexp = path instanceof RegExp
|
||||||
|
? path
|
||||||
|
: normalizePath(path, keys);
|
||||||
|
localRoutes.push({
|
||||||
|
fn: fn
|
||||||
|
, path: regexp
|
||||||
|
, keys: keys
|
||||||
|
, orig: path
|
||||||
|
, method: name
|
||||||
|
});
|
||||||
|
return self;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function router(req, res, next){
|
||||||
|
var route
|
||||||
|
, self = this;
|
||||||
|
|
||||||
|
(function pass(i){
|
||||||
|
if (route = match(req, routes, i)) {
|
||||||
|
var i = 0
|
||||||
|
, keys = route.keys;
|
||||||
|
|
||||||
|
req.params = route.params;
|
||||||
|
|
||||||
|
// Param preconditions
|
||||||
|
(function param(err) {
|
||||||
|
try {
|
||||||
|
var key = keys[i++]
|
||||||
|
, val = req.params[key]
|
||||||
|
, fn = params[key];
|
||||||
|
|
||||||
|
if ('route' == err) {
|
||||||
|
pass(req._route_index + 1);
|
||||||
|
// Error
|
||||||
|
} else if (err) {
|
||||||
|
next(err);
|
||||||
|
// Param has callback
|
||||||
|
} else if (fn) {
|
||||||
|
// Return style
|
||||||
|
if (1 == fn.length) {
|
||||||
|
req.params[key] = fn(val);
|
||||||
|
param();
|
||||||
|
// Middleware style
|
||||||
|
} else {
|
||||||
|
fn(req, res, param, val);
|
||||||
|
}
|
||||||
|
// Finished processing params
|
||||||
|
} else if (!key) {
|
||||||
|
// route middleware
|
||||||
|
i = 0;
|
||||||
|
(function nextMiddleware(err){
|
||||||
|
var fn = route.middleware[i++];
|
||||||
|
if ('route' == err) {
|
||||||
|
pass(req._route_index + 1);
|
||||||
|
} else if (err) {
|
||||||
|
next(err);
|
||||||
|
} else if (fn) {
|
||||||
|
fn(req, res, nextMiddleware);
|
||||||
|
} else {
|
||||||
|
route.call(self, req, res, function(err){
|
||||||
|
if (err) {
|
||||||
|
next(err);
|
||||||
|
} else {
|
||||||
|
pass(req._route_index + 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
// More params
|
||||||
|
} else {
|
||||||
|
param();
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
next(err);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
} else if ('OPTIONS' == req.method) {
|
||||||
|
options(req, res, routes);
|
||||||
|
} else {
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
};
|
||||||
|
|
||||||
|
router.remove = function(path, method){
|
||||||
|
var fns = router.lookup(path, method);
|
||||||
|
fns.forEach(function(fn){
|
||||||
|
routes[fn.method].splice(fn.index, 1);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
router.lookup = function(path, method, ret){
|
||||||
|
ret = ret || [];
|
||||||
|
|
||||||
|
// method specific lookup
|
||||||
|
if (method) {
|
||||||
|
method = method.toUpperCase();
|
||||||
|
if (routes[method]) {
|
||||||
|
routes[method].forEach(function(route, i){
|
||||||
|
if (path == route.orig) {
|
||||||
|
var fn = route.fn;
|
||||||
|
fn.regexp = route.path;
|
||||||
|
fn.keys = route.keys;
|
||||||
|
fn.path = route.orig;
|
||||||
|
fn.method = route.method;
|
||||||
|
fn.index = i;
|
||||||
|
ret.push(fn);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// global lookup
|
||||||
|
} else {
|
||||||
|
_methods.forEach(function(method){
|
||||||
|
router.lookup(path, method, ret);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
router.match = function(url, method, ret){
|
||||||
|
var ret = ret || []
|
||||||
|
, i = 0
|
||||||
|
, fn
|
||||||
|
, req;
|
||||||
|
|
||||||
|
// method specific matches
|
||||||
|
if (method) {
|
||||||
|
method = method.toUpperCase();
|
||||||
|
req = { url: url, method: method };
|
||||||
|
while (fn = match(req, routes, i)) {
|
||||||
|
i = req._route_index + 1;
|
||||||
|
ret.push(fn);
|
||||||
|
}
|
||||||
|
// global matches
|
||||||
|
} else {
|
||||||
|
_methods.forEach(function(method){
|
||||||
|
router.match(url, method, ret);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
return router;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Respond to OPTIONS.
|
||||||
|
*
|
||||||
|
* @param {ServerRequest} req
|
||||||
|
* @param {ServerResponse} req
|
||||||
|
* @param {Array} routes
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function options(req, res, routes) {
|
||||||
|
var pathname = parse(req.url).pathname
|
||||||
|
, body = optionsFor(pathname, routes).join(',');
|
||||||
|
res.writeHead(200, {
|
||||||
|
'Content-Length': body.length
|
||||||
|
, 'Allow': body
|
||||||
|
});
|
||||||
|
res.end(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return OPTIONS array for the given `path`, matching `routes`.
|
||||||
|
*
|
||||||
|
* @param {String} path
|
||||||
|
* @param {Array} routes
|
||||||
|
* @return {Array}
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function optionsFor(path, routes) {
|
||||||
|
return _methods.filter(function(method){
|
||||||
|
var arr = routes[method.toUpperCase()];
|
||||||
|
for (var i = 0, len = arr.length; i < len; ++i) {
|
||||||
|
if (arr[i].path.test(path)) return true;
|
||||||
|
}
|
||||||
|
}).map(function(method){
|
||||||
|
return method.toUpperCase();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize the given path string,
|
||||||
|
* returning a regular expression.
|
||||||
|
*
|
||||||
|
* An empty array should be passed,
|
||||||
|
* which will contain the placeholder
|
||||||
|
* key names. For example "/user/:id" will
|
||||||
|
* then contain ["id"].
|
||||||
|
*
|
||||||
|
* @param {String} path
|
||||||
|
* @param {Array} keys
|
||||||
|
* @return {RegExp}
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function normalizePath(path, keys) {
|
||||||
|
path = path
|
||||||
|
.concat('/?')
|
||||||
|
.replace(/\/\(/g, '(?:/')
|
||||||
|
.replace(/(\/)?(\.)?:(\w+)(?:(\(.*?\)))?(\?)?/g, function(_, slash, format, key, capture, optional){
|
||||||
|
keys.push(key);
|
||||||
|
slash = slash || '';
|
||||||
|
return ''
|
||||||
|
+ (optional ? '' : slash)
|
||||||
|
+ '(?:'
|
||||||
|
+ (optional ? slash : '')
|
||||||
|
+ (format || '') + (capture || '([^/]+?)') + ')'
|
||||||
|
+ (optional || '');
|
||||||
|
})
|
||||||
|
.replace(/([\/.])/g, '\\$1')
|
||||||
|
.replace(/\*/g, '(.+)');
|
||||||
|
return new RegExp('^' + path + '$', 'i');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to match the given request to
|
||||||
|
* one of the routes. When successful
|
||||||
|
* a route function is returned.
|
||||||
|
*
|
||||||
|
* @param {ServerRequest} req
|
||||||
|
* @param {Object} routes
|
||||||
|
* @return {Function}
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function match(req, routes, i) {
|
||||||
|
var captures
|
||||||
|
, method = req.method
|
||||||
|
, i = i || 0;
|
||||||
|
if ('HEAD' == method) method = 'GET';
|
||||||
|
if (routes = routes[method]) {
|
||||||
|
var url = parse(req.url)
|
||||||
|
, pathname = url.pathname;
|
||||||
|
for (var len = routes.length; i < len; ++i) {
|
||||||
|
var route = routes[i]
|
||||||
|
, fn = route.fn
|
||||||
|
, path = route.path
|
||||||
|
, keys = fn.keys = route.keys;
|
||||||
|
if (captures = path.exec(pathname)) {
|
||||||
|
fn.method = method;
|
||||||
|
fn.params = [];
|
||||||
|
for (var j = 1, len = captures.length; j < len; ++j) {
|
||||||
|
var key = keys[j-1],
|
||||||
|
val = typeof captures[j] === 'string'
|
||||||
|
? decodeURIComponent(captures[j])
|
||||||
|
: captures[j];
|
||||||
|
if (key) {
|
||||||
|
fn.params[key] = val;
|
||||||
|
} else {
|
||||||
|
fn.params.push(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
req._route_index = i;
|
||||||
|
return fn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
345
test/node_modules/express/node_modules/connect/lib/middleware/session.js
generated
vendored
Normal file
345
test/node_modules/express/node_modules/connect/lib/middleware/session.js
generated
vendored
Normal file
@@ -0,0 +1,345 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* 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) {
|
||||||
|
return '';
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
126
test/node_modules/express/node_modules/connect/lib/middleware/session/cookie.js
generated
vendored
Normal file
126
test/node_modules/express/node_modules/connect/lib/middleware/session/cookie.js
generated
vendored
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Connect - session - Cookie
|
||||||
|
* Copyright(c) 2010 Sencha Inc.
|
||||||
|
* Copyright(c) 2011 TJ Holowaychuk
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var utils = require('../../utils');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a new `Cookie` with the given `options`.
|
||||||
|
*
|
||||||
|
* @param {Object} options
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
var Cookie = module.exports = function Cookie(options) {
|
||||||
|
this.path = '/';
|
||||||
|
this.httpOnly = true;
|
||||||
|
this.maxAge = 14400000;
|
||||||
|
if (options) utils.merge(this, options);
|
||||||
|
this.originalMaxAge = undefined == this.originalMaxAge
|
||||||
|
? this.maxAge
|
||||||
|
: this.originalMaxAge;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prototype.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Cookie.prototype = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set expires `date`.
|
||||||
|
*
|
||||||
|
* @param {Date} date
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
set expires(date) {
|
||||||
|
this._expires = date;
|
||||||
|
this.originalMaxAge = this.maxAge;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get expires `date`.
|
||||||
|
*
|
||||||
|
* @return {Date}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
get expires() {
|
||||||
|
return this._expires;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set expires via max-age in `ms`.
|
||||||
|
*
|
||||||
|
* @param {Number} ms
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
set maxAge(ms) {
|
||||||
|
this.expires = 'number' == typeof ms
|
||||||
|
? new Date(Date.now() + ms)
|
||||||
|
: ms;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get expires max-age in `ms`.
|
||||||
|
*
|
||||||
|
* @return {Number}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
get maxAge() {
|
||||||
|
return this.expires instanceof Date
|
||||||
|
? this.expires.valueOf() - Date.now()
|
||||||
|
: this.expires;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return cookie data object.
|
||||||
|
*
|
||||||
|
* @return {Object}
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
get data() {
|
||||||
|
return {
|
||||||
|
originalMaxAge: this.originalMaxAge
|
||||||
|
, expires: this._expires
|
||||||
|
, secure: this.secure
|
||||||
|
, httpOnly: this.httpOnly
|
||||||
|
, domain: this.domain
|
||||||
|
, path: this.path
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a serialized cookie string.
|
||||||
|
*
|
||||||
|
* @return {String}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
serialize: function(name, val){
|
||||||
|
return utils.serializeCookie(name, val, this.data);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return JSON representation of this cookie.
|
||||||
|
*
|
||||||
|
* @return {Object}
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
toJSON: function(){
|
||||||
|
return this.data;
|
||||||
|
}
|
||||||
|
};
|
||||||
131
test/node_modules/express/node_modules/connect/lib/middleware/session/memory.js
generated
vendored
Normal file
131
test/node_modules/express/node_modules/connect/lib/middleware/session/memory.js
generated
vendored
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Connect - session - MemoryStore
|
||||||
|
* Copyright(c) 2010 Sencha Inc.
|
||||||
|
* Copyright(c) 2011 TJ Holowaychuk
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var Store = require('./store')
|
||||||
|
, utils = require('../../utils')
|
||||||
|
, Session = require('./session');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a new `MemoryStore`.
|
||||||
|
*
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
var MemoryStore = module.exports = function MemoryStore() {
|
||||||
|
this.sessions = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inherit from `Store.prototype`.
|
||||||
|
*/
|
||||||
|
|
||||||
|
MemoryStore.prototype.__proto__ = Store.prototype;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to fetch session by the given `sid`.
|
||||||
|
*
|
||||||
|
* @param {String} sid
|
||||||
|
* @param {Function} fn
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
MemoryStore.prototype.get = function(sid, fn){
|
||||||
|
var self = this;
|
||||||
|
process.nextTick(function(){
|
||||||
|
var expires
|
||||||
|
, sess = self.sessions[sid];
|
||||||
|
if (sess) {
|
||||||
|
sess = JSON.parse(sess);
|
||||||
|
expires = 'string' == typeof sess.cookie.expires
|
||||||
|
? new Date(sess.cookie.expires)
|
||||||
|
: sess.cookie.expires;
|
||||||
|
if (!expires || new Date < expires) {
|
||||||
|
fn(null, sess);
|
||||||
|
} else {
|
||||||
|
self.destroy(sid, fn);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fn();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Commit the given `sess` object associated with the given `sid`.
|
||||||
|
*
|
||||||
|
* @param {String} sid
|
||||||
|
* @param {Session} sess
|
||||||
|
* @param {Function} fn
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
MemoryStore.prototype.set = function(sid, sess, fn){
|
||||||
|
var self = this;
|
||||||
|
process.nextTick(function(){
|
||||||
|
self.sessions[sid] = JSON.stringify(sess);
|
||||||
|
fn && fn();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy the session associated with the given `sid`.
|
||||||
|
*
|
||||||
|
* @param {String} sid
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
MemoryStore.prototype.destroy = function(sid, fn){
|
||||||
|
var self = this;
|
||||||
|
process.nextTick(function(){
|
||||||
|
delete self.sessions[sid];
|
||||||
|
fn && fn();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoke the given callback `fn` with all active sessions.
|
||||||
|
*
|
||||||
|
* @param {Function} fn
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
MemoryStore.prototype.all = function(fn){
|
||||||
|
var arr = []
|
||||||
|
, keys = Object.keys(this.sessions);
|
||||||
|
for (var i = 0, len = keys.length; i < len; ++i) {
|
||||||
|
arr.push(this.sessions[keys[i]]);
|
||||||
|
}
|
||||||
|
fn(null, arr);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
};
|
||||||
137
test/node_modules/express/node_modules/connect/lib/middleware/session/session.js
generated
vendored
Normal file
137
test/node_modules/express/node_modules/connect/lib/middleware/session/session.js
generated
vendored
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Connect - session - Session
|
||||||
|
* Copyright(c) 2010 Sencha Inc.
|
||||||
|
* Copyright(c) 2011 TJ Holowaychuk
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var utils = require('../../utils')
|
||||||
|
, Cookie = require('./cookie');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new `Session` with the given request and `data`.
|
||||||
|
*
|
||||||
|
* @param {IncomingRequest} req
|
||||||
|
* @param {Object} data
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
var Session = module.exports = function Session(req, data) {
|
||||||
|
Object.defineProperty(this, 'req', { value: req });
|
||||||
|
Object.defineProperty(this, 'id', { value: req.sessionID });
|
||||||
|
if ('object' == typeof data) {
|
||||||
|
utils.merge(this, data);
|
||||||
|
} else {
|
||||||
|
this.lastAccess = Date.now();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update `.lastAccess` timestamp,
|
||||||
|
* and reset `.cookie.maxAge` to prevent
|
||||||
|
* the cookie from expiring when the
|
||||||
|
* session is still active.
|
||||||
|
*
|
||||||
|
* @return {Session} for chaining
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
Session.prototype.touch = function(){
|
||||||
|
return this
|
||||||
|
.resetLastAccess()
|
||||||
|
.resetMaxAge();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update `.lastAccess` timestamp.
|
||||||
|
*
|
||||||
|
* @return {Session} for chaining
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
Session.prototype.resetLastAccess = function(){
|
||||||
|
this.lastAccess = Date.now();
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset `.maxAge` to `.originalMaxAge`.
|
||||||
|
*
|
||||||
|
* @return {Session} for chaining
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
Session.prototype.resetMaxAge = function(){
|
||||||
|
this.cookie.maxAge = this.cookie.originalMaxAge;
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the session data with optional callback `fn(err)`.
|
||||||
|
*
|
||||||
|
* @param {Function} fn
|
||||||
|
* @return {Session} for chaining
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
Session.prototype.save = function(fn){
|
||||||
|
this.req.sessionStore.set(this.id, this, fn || function(){});
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-loads the session data _without_ altering
|
||||||
|
* the maxAge or lastAccess properties. Invokes the
|
||||||
|
* callback `fn(err)`, after which time if no exception
|
||||||
|
* has occurred the `req.session` property will be
|
||||||
|
* a new `Session` object, although representing the
|
||||||
|
* same session.
|
||||||
|
*
|
||||||
|
* @param {Function} fn
|
||||||
|
* @return {Session} for chaining
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
Session.prototype.reload = function(fn){
|
||||||
|
var req = this.req
|
||||||
|
, store = this.req.sessionStore;
|
||||||
|
store.get(this.id, function(err, sess){
|
||||||
|
if (err) return fn(err);
|
||||||
|
if (!sess) return fn(new Error('failed to load session'));
|
||||||
|
store.createSession(req, sess);
|
||||||
|
fn();
|
||||||
|
});
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy `this` session.
|
||||||
|
*
|
||||||
|
* @param {Function} fn
|
||||||
|
* @return {Session} for chaining
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
Session.prototype.destroy = function(fn){
|
||||||
|
delete this.req.session;
|
||||||
|
this.req.sessionStore.destroy(this.id, fn);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Regenerate this request's session.
|
||||||
|
*
|
||||||
|
* @param {Function} fn
|
||||||
|
* @return {Session} for chaining
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
Session.prototype.regenerate = function(fn){
|
||||||
|
this.req.sessionStore.regenerate(this.req, fn);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
87
test/node_modules/express/node_modules/connect/lib/middleware/session/store.js
generated
vendored
Normal file
87
test/node_modules/express/node_modules/connect/lib/middleware/session/store.js
generated
vendored
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Connect - session - Store
|
||||||
|
* Copyright(c) 2010 Sencha Inc.
|
||||||
|
* Copyright(c) 2011 TJ Holowaychuk
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var EventEmitter = require('events').EventEmitter
|
||||||
|
, Session = require('./session')
|
||||||
|
, Cookie = require('./cookie')
|
||||||
|
, utils = require('../../utils');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize abstract `Store`.
|
||||||
|
*
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
var Store = module.exports = function Store(options){};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inherit from `EventEmitter.prototype`.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Store.prototype.__proto__ = EventEmitter.prototype;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-generate the given requests's session.
|
||||||
|
*
|
||||||
|
* @param {IncomingRequest} req
|
||||||
|
* @return {Function} fn
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
Store.prototype.regenerate = function(req, fn){
|
||||||
|
var self = this;
|
||||||
|
this.destroy(req.sessionID, function(err){
|
||||||
|
self.generate(req);
|
||||||
|
fn(err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load a `Session` instance via the given `sid`
|
||||||
|
* and invoke the callback `fn(err, sess)`.
|
||||||
|
*
|
||||||
|
* @param {String} sid
|
||||||
|
* @param {Function} fn
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
Store.prototype.load = function(sid, fn){
|
||||||
|
var self = this;
|
||||||
|
this.get(sid, function(err, sess){
|
||||||
|
if (err) return fn(err);
|
||||||
|
if (!sess) return fn();
|
||||||
|
var req = { sessionID: sid, sessionStore: self };
|
||||||
|
sess = self.createSession(req, sess, false);
|
||||||
|
fn(null, sess);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create session from JSON `sess` data.
|
||||||
|
*
|
||||||
|
* @param {IncomingRequest} req
|
||||||
|
* @param {Object} sess
|
||||||
|
* @return {Session}
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
Store.prototype.createSession = function(req, sess, update){
|
||||||
|
var expires = sess.cookie.expires
|
||||||
|
, orig = sess.cookie.originalMaxAge
|
||||||
|
, update = null == update ? true : false;
|
||||||
|
sess.cookie = new Cookie(sess.cookie);
|
||||||
|
if ('string' == typeof expires) sess.cookie.expires = new Date(expires);
|
||||||
|
sess.cookie.originalMaxAge = orig;
|
||||||
|
req.session = new Session(req, sess);
|
||||||
|
if (update) req.session.resetLastAccess();
|
||||||
|
return req.session;
|
||||||
|
};
|
||||||
225
test/node_modules/express/node_modules/connect/lib/middleware/static.js
generated
vendored
Normal file
225
test/node_modules/express/node_modules/connect/lib/middleware/static.js
generated
vendored
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Connect - staticProvider
|
||||||
|
* Copyright(c) 2010 Sencha Inc.
|
||||||
|
* Copyright(c) 2011 TJ Holowaychuk
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var fs = require('fs')
|
||||||
|
, path = require('path')
|
||||||
|
, join = path.join
|
||||||
|
, basename = path.basename
|
||||||
|
, normalize = path.normalize
|
||||||
|
, utils = require('../utils')
|
||||||
|
, Buffer = require('buffer').Buffer
|
||||||
|
, parse = require('url').parse
|
||||||
|
, mime = require('mime');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static file server with the given `root` path.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
* var oneDay = 86400000;
|
||||||
|
*
|
||||||
|
* connect(
|
||||||
|
* connect.static(__dirname + '/public')
|
||||||
|
* ).listen(3000);
|
||||||
|
*
|
||||||
|
* connect(
|
||||||
|
* connect.static(__dirname + '/public', { maxAge: oneDay })
|
||||||
|
* ).listen(3000);
|
||||||
|
*
|
||||||
|
* Options:
|
||||||
|
*
|
||||||
|
* - `maxAge` Browser cache maxAge in milliseconds. defaults to 0
|
||||||
|
* - `hidden` Allow transfer of hidden files. defaults to false
|
||||||
|
* - `redirect` Redirect to trailing "/" when the pathname is a dir
|
||||||
|
*
|
||||||
|
* @param {String} root
|
||||||
|
* @param {Object} options
|
||||||
|
* @return {Function}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports = module.exports = function static(root, options){
|
||||||
|
options = options || {};
|
||||||
|
|
||||||
|
// root required
|
||||||
|
if (!root) throw new Error('static() root path required');
|
||||||
|
options.root = root;
|
||||||
|
|
||||||
|
return function static(req, res, next) {
|
||||||
|
options.path = req.url;
|
||||||
|
options.getOnly = true;
|
||||||
|
send(req, res, next, options);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expose mime module.
|
||||||
|
*/
|
||||||
|
|
||||||
|
exports.mime = mime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Respond with 416 "Requested Range Not Satisfiable"
|
||||||
|
*
|
||||||
|
* @param {ServerResponse} res
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function invalidRange(res) {
|
||||||
|
var body = 'Requested Range Not Satisfiable';
|
||||||
|
res.setHeader('Content-Type', 'text/plain');
|
||||||
|
res.setHeader('Content-Length', body.length);
|
||||||
|
res.statusCode = 416;
|
||||||
|
res.end(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to tranfer the requseted file to `res`.
|
||||||
|
*
|
||||||
|
* @param {ServerRequest}
|
||||||
|
* @param {ServerResponse}
|
||||||
|
* @param {Function} next
|
||||||
|
* @param {Object} options
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
var send = exports.send = function(req, res, next, options){
|
||||||
|
options = options || {};
|
||||||
|
if (!options.path) throw new Error('path required');
|
||||||
|
|
||||||
|
// setup
|
||||||
|
var maxAge = options.maxAge || 0
|
||||||
|
, ranges = req.headers.range
|
||||||
|
, head = 'HEAD' == req.method
|
||||||
|
, get = 'GET' == req.method
|
||||||
|
, root = options.root ? normalize(options.root) : null
|
||||||
|
, redirect = false === options.redirect ? false : true
|
||||||
|
, getOnly = options.getOnly
|
||||||
|
, fn = options.callback
|
||||||
|
, hidden = options.hidden
|
||||||
|
, done;
|
||||||
|
|
||||||
|
// replace next() with callback when available
|
||||||
|
if (fn) next = fn;
|
||||||
|
|
||||||
|
// ignore non-GET requests
|
||||||
|
if (getOnly && !get && !head) return next();
|
||||||
|
|
||||||
|
// parse url
|
||||||
|
var url = parse(options.path)
|
||||||
|
, path = decodeURIComponent(url.pathname)
|
||||||
|
, type;
|
||||||
|
|
||||||
|
// null byte(s)
|
||||||
|
if (~path.indexOf('\0')) return utils.badRequest(res);
|
||||||
|
|
||||||
|
// when root is not given, consider .. malicious
|
||||||
|
if (!root && ~path.indexOf('..')) return utils.forbidden(res);
|
||||||
|
|
||||||
|
// join / normalize from optional root dir
|
||||||
|
path = normalize(join(root, path));
|
||||||
|
|
||||||
|
// malicious path
|
||||||
|
if (root && 0 != path.indexOf(root)) return fn
|
||||||
|
? fn(new Error('Forbidden'))
|
||||||
|
: utils.forbidden(res);
|
||||||
|
|
||||||
|
// index.html support
|
||||||
|
if (normalize('/') == path[path.length - 1]) path += 'index.html';
|
||||||
|
|
||||||
|
// "hidden" file
|
||||||
|
if (!hidden && '.' == basename(path)[0]) return next();
|
||||||
|
|
||||||
|
fs.stat(path, function(err, stat){
|
||||||
|
// mime type
|
||||||
|
type = mime.lookup(path);
|
||||||
|
|
||||||
|
// ignore ENOENT
|
||||||
|
if (err) {
|
||||||
|
if (fn) return fn(err);
|
||||||
|
return 'ENOENT' == err.code
|
||||||
|
? next()
|
||||||
|
: next(err);
|
||||||
|
// redirect directory in case index.html is present
|
||||||
|
} else if (stat.isDirectory()) {
|
||||||
|
if (!redirect) return next();
|
||||||
|
res.statusCode = 301;
|
||||||
|
res.setHeader('Location', url.pathname + '/');
|
||||||
|
res.end('Redirecting to ' + url.pathname + '/');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// header fields
|
||||||
|
if (!res.getHeader('Date')) res.setHeader('Date', new Date().toUTCString());
|
||||||
|
if (!res.getHeader('Cache-Control')) res.setHeader('Cache-Control', 'public, max-age=' + (maxAge / 1000));
|
||||||
|
if (!res.getHeader('Last-Modified')) res.setHeader('Last-Modified', stat.mtime.toUTCString());
|
||||||
|
if (!res.getHeader('ETag')) res.setHeader('ETag', utils.etag(stat));
|
||||||
|
if (!res.getHeader('content-type')) {
|
||||||
|
var charset = mime.charsets.lookup(type);
|
||||||
|
res.setHeader('Content-Type', type + (charset ? '; charset=' + charset : ''));
|
||||||
|
}
|
||||||
|
res.setHeader('Accept-Ranges', 'bytes');
|
||||||
|
|
||||||
|
// conditional GET support
|
||||||
|
if (utils.conditionalGET(req)) {
|
||||||
|
if (!utils.modified(req, res)) {
|
||||||
|
req.emit('static');
|
||||||
|
return utils.notModified(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var opts = {};
|
||||||
|
var chunkSize = stat.size;
|
||||||
|
|
||||||
|
// we have a Range request
|
||||||
|
if (ranges) {
|
||||||
|
ranges = utils.parseRange(stat.size, ranges);
|
||||||
|
// valid
|
||||||
|
if (ranges) {
|
||||||
|
// TODO: stream options
|
||||||
|
// TODO: multiple support
|
||||||
|
opts.start = ranges[0].start;
|
||||||
|
opts.end = ranges[0].end;
|
||||||
|
chunkSize = opts.end - opts.start + 1;
|
||||||
|
res.statusCode = 206;
|
||||||
|
res.setHeader('Content-Range', 'bytes '
|
||||||
|
+ opts.start
|
||||||
|
+ '-'
|
||||||
|
+ opts.end
|
||||||
|
+ '/'
|
||||||
|
+ stat.size);
|
||||||
|
// invalid
|
||||||
|
} else {
|
||||||
|
return fn
|
||||||
|
? fn(new Error('Requested Range Not Satisfiable'))
|
||||||
|
: invalidRange(res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res.setHeader('Content-Length', chunkSize);
|
||||||
|
|
||||||
|
// transfer
|
||||||
|
if (head) return res.end();
|
||||||
|
|
||||||
|
// stream
|
||||||
|
var stream = fs.createReadStream(path, opts);
|
||||||
|
req.emit('static', stream);
|
||||||
|
stream.pipe(res);
|
||||||
|
|
||||||
|
// callback
|
||||||
|
if (fn) {
|
||||||
|
function callback(err) { done || fn(err); done = true }
|
||||||
|
req.on('close', callback);
|
||||||
|
stream.on('end', callback);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
175
test/node_modules/express/node_modules/connect/lib/middleware/staticCache.js
generated
vendored
Normal file
175
test/node_modules/express/node_modules/connect/lib/middleware/staticCache.js
generated
vendored
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Connect - staticCache
|
||||||
|
* Copyright(c) 2011 Sencha Inc.
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var http = require('http')
|
||||||
|
, utils = require('../utils')
|
||||||
|
, Cache = require('../cache')
|
||||||
|
, url = require('url')
|
||||||
|
, fs = require('fs');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables a memory cache layer on top of
|
||||||
|
* the `static()` middleware, serving popular
|
||||||
|
* static files.
|
||||||
|
*
|
||||||
|
* By default a maximum of 128 objects are
|
||||||
|
* held in cache, with a max of 256k each,
|
||||||
|
* totalling ~32mb.
|
||||||
|
*
|
||||||
|
* A Least-Recently-Used (LRU) cache algo
|
||||||
|
* is implemented through the `Cache` object,
|
||||||
|
* simply rotating cache objects as they are
|
||||||
|
* hit. This means that increasingly popular
|
||||||
|
* objects maintain their positions while
|
||||||
|
* others get shoved out of the stack and
|
||||||
|
* garbage collected.
|
||||||
|
*
|
||||||
|
* Benchmarks:
|
||||||
|
*
|
||||||
|
* static(): 2700 rps
|
||||||
|
* node-static: 5300 rps
|
||||||
|
* static() + staticCache(): 7500 rps
|
||||||
|
*
|
||||||
|
* Options:
|
||||||
|
*
|
||||||
|
* - `maxObjects` max cache objects [128]
|
||||||
|
* - `maxLength` max cache object length 256kb
|
||||||
|
*
|
||||||
|
* @param {Type} name
|
||||||
|
* @return {Type}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
module.exports = function staticCache(options){
|
||||||
|
var options = options || {}
|
||||||
|
, cache = new Cache(options.maxObjects || 128)
|
||||||
|
, maxlen = options.maxLength || 1024 * 256;
|
||||||
|
|
||||||
|
return function staticCache(req, res, next){
|
||||||
|
var path = url.parse(req.url).pathname
|
||||||
|
, ranges = req.headers.range
|
||||||
|
, hit = cache.get(path)
|
||||||
|
, hitCC
|
||||||
|
, uaCC
|
||||||
|
, header
|
||||||
|
, age;
|
||||||
|
|
||||||
|
// cache static
|
||||||
|
req.on('static', function(stream){
|
||||||
|
var headers = res._headers
|
||||||
|
, cc = utils.parseCacheControl(headers['cache-control'] || '')
|
||||||
|
, contentLength = headers['content-length']
|
||||||
|
, hit;
|
||||||
|
|
||||||
|
// ignore larger files
|
||||||
|
if (!contentLength || contentLength > maxlen) return;
|
||||||
|
|
||||||
|
// dont cache items we shouldn't be
|
||||||
|
if ( cc['no-cache']
|
||||||
|
|| cc['no-store']
|
||||||
|
|| cc['private']
|
||||||
|
|| cc['must-revalidate']) return;
|
||||||
|
|
||||||
|
// if already in cache then validate
|
||||||
|
if (hit = cache.get(path)){
|
||||||
|
if (headers.etag == hit[0].etag) {
|
||||||
|
hit[0].date = new Date;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
cache.remove(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// validation notifiactions don't contain a steam
|
||||||
|
if (null == stream) return;
|
||||||
|
|
||||||
|
// add the cache object
|
||||||
|
var arr = cache.add(path);
|
||||||
|
arr.push(headers);
|
||||||
|
|
||||||
|
// store the chunks
|
||||||
|
stream.on('data', function(chunk){
|
||||||
|
arr.push(chunk);
|
||||||
|
});
|
||||||
|
|
||||||
|
// flag it as complete
|
||||||
|
stream.on('end', function(){
|
||||||
|
arr.complete = true;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// cache hit, doesnt support range requests
|
||||||
|
if (hit && hit.complete && !ranges) {
|
||||||
|
header = utils.merge({}, hit[0]);
|
||||||
|
header.Age = age = (new Date - new Date(header.date)) / 1000 | 0;
|
||||||
|
header.date = new Date().toUTCString();
|
||||||
|
|
||||||
|
// parse cache-controls
|
||||||
|
hitCC = utils.parseCacheControl(header['cache-control'] || '');
|
||||||
|
uaCC = utils.parseCacheControl(req.headers['cache-control'] || '');
|
||||||
|
|
||||||
|
// check if we must revalidate(bypass)
|
||||||
|
if (hitCC['no-cache'] || uaCC['no-cache']) return next();
|
||||||
|
|
||||||
|
// check freshness of entity
|
||||||
|
if (isStale(hitCC, age) || isStale(uaCC, age)) return next();
|
||||||
|
|
||||||
|
// conditional GET support
|
||||||
|
if (utils.conditionalGET(req)) {
|
||||||
|
if (!utils.modified(req, res, header)) {
|
||||||
|
header['content-length'] = 0;
|
||||||
|
res.writeHead(304, header);
|
||||||
|
return res.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// HEAD support
|
||||||
|
if ('HEAD' == req.method) {
|
||||||
|
header['content-length'] = 0;
|
||||||
|
res.writeHead(200, header);
|
||||||
|
return res.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
// respond with cache
|
||||||
|
res.writeHead(200, header);
|
||||||
|
|
||||||
|
// backpressure
|
||||||
|
function write(i) {
|
||||||
|
var buf = hit[i];
|
||||||
|
if (!buf) return res.end();
|
||||||
|
if (false === res.write(buf)) {
|
||||||
|
res.once('drain', function(){
|
||||||
|
write(++i);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
write(++i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return write(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if cache item is stale
|
||||||
|
*
|
||||||
|
* @param {Object} cc
|
||||||
|
* @param {Number} age
|
||||||
|
* @return {Boolean}
|
||||||
|
* @api private
|
||||||
|
*/
|
||||||
|
|
||||||
|
function isStale(cc, age) {
|
||||||
|
return cc['max-age'] && cc['max-age'] <= age;
|
||||||
|
}
|
||||||
44
test/node_modules/express/node_modules/connect/lib/middleware/vhost.js
generated
vendored
Normal file
44
test/node_modules/express/node_modules/connect/lib/middleware/vhost.js
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Connect - vhost
|
||||||
|
* Copyright(c) 2010 Sencha Inc.
|
||||||
|
* Copyright(c) 2011 TJ Holowaychuk
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup vhost for the given `hostname` and `server`.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
* connect(
|
||||||
|
* 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');
|
||||||
|
var regexp = new RegExp('^' + hostname.replace(/[*]/g, '(.*?)') + '$');
|
||||||
|
if (server.onvhost) server.onvhost(hostname);
|
||||||
|
return function vhost(req, res, next){
|
||||||
|
if (!req.headers.host) return next();
|
||||||
|
var host = req.headers.host.split(':')[0];
|
||||||
|
if (req.subdomains = regexp.exec(host)) {
|
||||||
|
req.subdomains = req.subdomains[0].split('.').slice(0, -1);
|
||||||
|
server.emit("request", req, res);
|
||||||
|
} else {
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
79
test/node_modules/express/node_modules/connect/lib/patch.js
generated
vendored
Normal file
79
test/node_modules/express/node_modules/connect/lib/patch.js
generated
vendored
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
|
||||||
|
/*!
|
||||||
|
* Connect
|
||||||
|
* Copyright(c) 2011 TJ Holowaychuk
|
||||||
|
* MIT Licensed
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module dependencies.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var http = require('http')
|
||||||
|
, res = http.OutgoingMessage.prototype;
|
||||||
|
|
||||||
|
// original setHeader()
|
||||||
|
|
||||||
|
var setHeader = res.setHeader;
|
||||||
|
|
||||||
|
// original _renderHeaders()
|
||||||
|
|
||||||
|
var _renderHeaders = res._renderHeaders;
|
||||||
|
|
||||||
|
if (res._hasConnectPatch) return;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide a public "header sent" flag
|
||||||
|
* until node does.
|
||||||
|
*
|
||||||
|
* @return {Boolean}
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
res.__defineGetter__('headerSent', function(){
|
||||||
|
return this._headerSent;
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set header `field` to `val`, special-casing
|
||||||
|
* the `Set-Cookie` field for multiple support.
|
||||||
|
*
|
||||||
|
* @param {String} field
|
||||||
|
* @param {String} val
|
||||||
|
* @api public
|
||||||
|
*/
|
||||||
|
|
||||||
|
res.setHeader = function(field, val){
|
||||||
|
var key = field.toLowerCase()
|
||||||
|
, prev;
|
||||||
|
|
||||||
|
// special-case Set-Cookie
|
||||||
|
if (this._headers && 'set-cookie' == key) {
|
||||||
|
if (prev = this.getHeader(field)) {
|
||||||
|
val = Array.isArray(prev)
|
||||||
|
? prev.concat(val)
|
||||||
|
: [prev, val];
|
||||||
|
}
|
||||||
|
// charset
|
||||||
|
} else if ('content-type' == key && this.charset) {
|
||||||
|
val += '; charset=' + this.charset;
|
||||||
|
}
|
||||||
|
|
||||||
|
return setHeader.call(this, field, val);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Proxy `res.end()` to expose a 'header' event,
|
||||||
|
* allowing arbitrary augmentation before the header
|
||||||
|
* fields are written to the socket.
|
||||||
|
*
|
||||||
|
* NOTE: this _only_ supports node's progressive header
|
||||||
|
* field API aka `res.setHeader()`.
|
||||||
|
*/
|
||||||
|
|
||||||
|
res._renderHeaders = function(){
|
||||||
|
this.emit('header');
|
||||||
|
return _renderHeaders.call(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
res._hasConnectPatch = true;
|
||||||
75
test/node_modules/express/node_modules/connect/lib/public/directory.html
generated
vendored
Normal file
75
test/node_modules/express/node_modules/connect/lib/public/directory.html
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>listing directory {directory}</title>
|
||||||
|
<style>{style}</style>
|
||||||
|
<script>
|
||||||
|
function $(id){
|
||||||
|
var el = 'string' == typeof id
|
||||||
|
? document.getElementById(id)
|
||||||
|
: id;
|
||||||
|
|
||||||
|
el.on = function(event, fn){
|
||||||
|
if ('content loaded' == event) event = 'DOMContentLoaded';
|
||||||
|
el.addEventListener(event, fn, false);
|
||||||
|
};
|
||||||
|
|
||||||
|
el.all = function(selector){
|
||||||
|
return $(el.querySelectorAll(selector));
|
||||||
|
};
|
||||||
|
|
||||||
|
el.each = function(fn){
|
||||||
|
for (var i = 0, len = el.length; i < len; ++i) {
|
||||||
|
fn($(el[i]), i);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
el.getClasses = function(){
|
||||||
|
return this.getAttribute('class').split(/\s+/);
|
||||||
|
};
|
||||||
|
|
||||||
|
el.addClass = function(name){
|
||||||
|
var classes = this.getAttribute('class');
|
||||||
|
el.setAttribute('class', classes
|
||||||
|
? classes + ' ' + name
|
||||||
|
: name);
|
||||||
|
};
|
||||||
|
|
||||||
|
el.removeClass = function(name){
|
||||||
|
var classes = this.getClasses().filter(function(curr){
|
||||||
|
return curr != name;
|
||||||
|
});
|
||||||
|
this.setAttribute('class', classes);
|
||||||
|
};
|
||||||
|
|
||||||
|
return el;
|
||||||
|
}
|
||||||
|
|
||||||
|
function search() {
|
||||||
|
var str = $('search').value
|
||||||
|
, links = $('files').all('a');
|
||||||
|
|
||||||
|
links.each(function(link){
|
||||||
|
var text = link.textContent;
|
||||||
|
|
||||||
|
if ('..' == text) return;
|
||||||
|
if (str.length && ~text.indexOf(str)) {
|
||||||
|
link.addClass('highlight');
|
||||||
|
} else {
|
||||||
|
link.removeClass('highlight');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$(window).on('content loaded', function(){
|
||||||
|
$('search').on('keyup', search);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body class="directory">
|
||||||
|
<input id="search" type="text" placeholder="Search" autocomplete="off" />
|
||||||
|
<div id="wrapper">
|
||||||
|
<h1>{linked-path}</h1>
|
||||||
|
{files}
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
13
test/node_modules/express/node_modules/connect/lib/public/error.html
generated
vendored
Normal file
13
test/node_modules/express/node_modules/connect/lib/public/error.html
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>{error}</title>
|
||||||
|
<style>{style}</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="wrapper">
|
||||||
|
<h1>{title}</h1>
|
||||||
|
<h2><em>500</em> {error}</h2>
|
||||||
|
<ul id="stacktrace">{stack}</ul>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
BIN
test/node_modules/express/node_modules/connect/lib/public/favicon.ico
generated
vendored
Normal file
BIN
test/node_modules/express/node_modules/connect/lib/public/favicon.ico
generated
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
BIN
test/node_modules/express/node_modules/connect/lib/public/icons/page.png
generated
vendored
Normal file
BIN
test/node_modules/express/node_modules/connect/lib/public/icons/page.png
generated
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 635 B |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user