mirror of
https://github.com/expressjs/express.git
synced 2026-02-26 18:57:43 +00:00
Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e3e7d0def6 | ||
|
|
585039f487 | ||
|
|
de4bc808a4 | ||
|
|
1515d53f55 | ||
|
|
c92c10d8ff | ||
|
|
bc81e7441c | ||
|
|
78b874e881 | ||
|
|
5c50e3a58c | ||
|
|
508e8cc64e | ||
|
|
5c962ba27b | ||
|
|
9bcb46848b | ||
|
|
4363b20186 | ||
|
|
77645bcc93 | ||
|
|
b0a66fe6c9 | ||
|
|
e8dd0a1267 | ||
|
|
9dd7b7b63a | ||
|
|
ba80b7ba97 | ||
|
|
45bb4aff09 | ||
|
|
bb14a86e17 | ||
|
|
1773681ef8 | ||
|
|
2ac612f14d | ||
|
|
20570fc80d | ||
|
|
92c1c953dc | ||
|
|
8b372b3faa | ||
|
|
da3a743c1b | ||
|
|
09c9537381 | ||
|
|
9cf1800731 | ||
|
|
0d0fd347ab | ||
|
|
5cf8023dc3 |
36
History.md
36
History.md
@@ -1,4 +1,40 @@
|
||||
|
||||
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
|
||||
==================
|
||||
|
||||
|
||||
60
bin/express
60
bin/express
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
var fs = require('fs')
|
||||
, os = require('os')
|
||||
, exec = require('child_process').exec
|
||||
, mkdirp = require('mkdirp');
|
||||
|
||||
@@ -12,7 +13,7 @@ var fs = require('fs')
|
||||
* Framework version.
|
||||
*/
|
||||
|
||||
var version = '2.5.2';
|
||||
var version = '2.5.8';
|
||||
|
||||
/**
|
||||
* Add session support.
|
||||
@@ -26,6 +27,14 @@ var sessions = false;
|
||||
|
||||
var cssEngine;
|
||||
|
||||
/**
|
||||
* End-of-line code.
|
||||
*/
|
||||
|
||||
var eol = os.platform
|
||||
? ('win32' == os.platform() ? '\r\n' : '\n')
|
||||
: '\n';
|
||||
|
||||
/**
|
||||
* Template engine to utilize.
|
||||
*/
|
||||
@@ -61,7 +70,7 @@ var index = [
|
||||
, 'exports.index = function(req, res){'
|
||||
, ' res.render(\'index\', { title: \'Express\' })'
|
||||
, '};'
|
||||
].join('\r\n');
|
||||
].join(eol);
|
||||
|
||||
/**
|
||||
* Jade layout template.
|
||||
@@ -74,7 +83,7 @@ var jadeLayout = [
|
||||
, ' title= title'
|
||||
, ' link(rel=\'stylesheet\', href=\'/stylesheets/style.css\')'
|
||||
, ' body!= body'
|
||||
].join('\r\n');
|
||||
].join(eol);
|
||||
|
||||
/**
|
||||
* Jade index template.
|
||||
@@ -83,7 +92,7 @@ var jadeLayout = [
|
||||
var jadeIndex = [
|
||||
'h1= title'
|
||||
, 'p Welcome to #{title}'
|
||||
].join('\r\n');
|
||||
].join(eol);
|
||||
|
||||
/**
|
||||
* EJS layout template.
|
||||
@@ -100,7 +109,7 @@ var ejsLayout = [
|
||||
, ' <%- body %>'
|
||||
, ' </body>'
|
||||
, '</html>'
|
||||
].join('\r\n');
|
||||
].join(eol);
|
||||
|
||||
/**
|
||||
* EJS index template.
|
||||
@@ -109,7 +118,7 @@ var ejsLayout = [
|
||||
var ejsIndex = [
|
||||
'<h1><%= title %></h1>'
|
||||
, '<p>Welcome to <%= title %></p>'
|
||||
].join('\r\n');
|
||||
].join(eol);
|
||||
|
||||
/**
|
||||
* Default css template.
|
||||
@@ -124,7 +133,7 @@ var css = [
|
||||
, 'a {'
|
||||
, ' color: #00B7FF;'
|
||||
, '}'
|
||||
].join('\r\n');
|
||||
].join(eol);
|
||||
|
||||
/**
|
||||
* Default stylus template.
|
||||
@@ -136,7 +145,7 @@ var stylus = [
|
||||
, ' font: 14px "Lucida Grande", Helvetica, Arial, sans-serif'
|
||||
, 'a'
|
||||
, ' color: #00B7FF'
|
||||
].join('\r\n');
|
||||
].join(eol);
|
||||
|
||||
/**
|
||||
* App template.
|
||||
@@ -149,7 +158,7 @@ var app = [
|
||||
, ' */'
|
||||
, ''
|
||||
, 'var express = require(\'express\')'
|
||||
, ' , routes = require(\'./routes\')'
|
||||
, ' , routes = require(\'./routes\');'
|
||||
, ''
|
||||
, 'var app = module.exports = express.createServer();'
|
||||
, ''
|
||||
@@ -165,21 +174,22 @@ var app = [
|
||||
, '});'
|
||||
, ''
|
||||
, 'app.configure(\'development\', function(){'
|
||||
, ' app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); '
|
||||
, ' app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));'
|
||||
, '});'
|
||||
, ''
|
||||
, 'app.configure(\'production\', function(){'
|
||||
, ' app.use(express.errorHandler()); '
|
||||
, ' app.use(express.errorHandler());'
|
||||
, '});'
|
||||
, ''
|
||||
, '// Routes'
|
||||
, ''
|
||||
, 'app.get(\'/\', routes.index);'
|
||||
, ''
|
||||
, 'app.listen(3000);'
|
||||
, 'console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);'
|
||||
, 'app.listen(3000, function(){'
|
||||
, ' console.log("Express server listening on port %d in %s mode", app.address().port, app.settings.env);'
|
||||
, '});'
|
||||
, ''
|
||||
].join('\r\n');
|
||||
].join(eol);
|
||||
|
||||
// Parse arguments
|
||||
|
||||
@@ -287,7 +297,7 @@ function createApplicationAt(path) {
|
||||
// CSS Engine support
|
||||
switch (cssEngine) {
|
||||
case 'stylus':
|
||||
app = app.replace('{css}', '\r\n app.use(require(\'stylus\').middleware({ src: __dirname + \'/public\' }));');
|
||||
app = app.replace('{css}', eol + ' app.use(require(\'stylus\').middleware({ src: __dirname + \'/public\' }));');
|
||||
break;
|
||||
default:
|
||||
app = app.replace('{css}', '');
|
||||
@@ -295,22 +305,22 @@ function createApplicationAt(path) {
|
||||
|
||||
// Session support
|
||||
app = app.replace('{sess}', sessions
|
||||
? '\r\n app.use(express.cookieParser());\r\n app.use(express.session({ secret: \'your secret here\' }));'
|
||||
? 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 = '{\r\n';
|
||||
json += ' "name": "application-name"\r\n';
|
||||
json += ' , "version": "0.0.1"\r\n';
|
||||
json += ' , "private": true\r\n';
|
||||
json += ' , "dependencies": {\r\n';
|
||||
json += ' "express": "' + version + '"\r\n';
|
||||
if (cssEngine) json += ' , "' + cssEngine + '": ">= 0.0.1"\r\n';
|
||||
if (templateEngine) json += ' , "' + templateEngine + '": ">= 0.0.1"\r\n';
|
||||
json += ' }\r\n';
|
||||
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 += '}';
|
||||
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ var exports = module.exports = connect.middleware;
|
||||
* Framework version.
|
||||
*/
|
||||
|
||||
exports.version = '2.5.2';
|
||||
exports.version = '2.5.9';
|
||||
|
||||
/**
|
||||
* Shortcut for `new Server(...)`.
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
/*!
|
||||
* Express - HTTPServer
|
||||
* Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
|
||||
@@ -571,7 +570,7 @@ app.all = function(path){
|
||||
var args = arguments;
|
||||
if (1 == args.length) return this.routes.lookup('all', path);
|
||||
methods.forEach(function(method){
|
||||
if ('all' == method) return;
|
||||
if ('all' == method || 'del' == method) return;
|
||||
app[method].apply(this, args);
|
||||
}, this);
|
||||
return this;
|
||||
|
||||
@@ -135,8 +135,8 @@ req.accepts = function(type){
|
||||
// normalize extensions ".json" -> "json"
|
||||
if (type && '.' == type[0]) type = type.substr(1);
|
||||
|
||||
// when Accept does not exist, or is '*/*' return true
|
||||
if (!accept || '*/*' == accept) {
|
||||
// when Accept does not exist, or contains '*/*' return true
|
||||
if (!accept || ~accept.indexOf('*/*')) {
|
||||
return true;
|
||||
} else if (type) {
|
||||
// allow "html" vs "text/html" etc
|
||||
@@ -292,16 +292,18 @@ req.flash = function(type, msg){
|
||||
req.is = function(type){
|
||||
var fn = this.app.is(type);
|
||||
if (fn) return fn(this);
|
||||
var contentType = this.headers['content-type'];
|
||||
if (!contentType) return;
|
||||
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('/')
|
||||
contentType = contentType.split('/');
|
||||
if ('*' == type[0] && type[1] == contentType[1]) return true;
|
||||
if ('*' == type[1] && type[0] == contentType[0]) return true;
|
||||
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 !! ~contentType.indexOf(type);
|
||||
return !! ~ct.indexOf(type);
|
||||
};
|
||||
|
||||
// Callback for isXMLHttpRequest / xhr
|
||||
|
||||
@@ -54,6 +54,14 @@ var RFC5323 = ['SEARCH'];
|
||||
|
||||
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.
|
||||
*/
|
||||
@@ -65,6 +73,7 @@ module.exports = [].concat(
|
||||
, RFC3648
|
||||
, RFC3744
|
||||
, RFC5323
|
||||
, RFC5789).map(function(method){
|
||||
, RFC5789
|
||||
, CACHE_PURGE).map(function(method){
|
||||
return method.toLowerCase();
|
||||
});
|
||||
|
||||
35
lib/view.js
35
lib/view.js
@@ -47,7 +47,10 @@ exports.register = View.register;
|
||||
*/
|
||||
|
||||
exports.compile = function(view, cache, cid, options){
|
||||
if (cache && cid && cache[cid]) return cache[cid];
|
||||
if (cache && cid && cache[cid]){
|
||||
options.filename = cache[cid].path;
|
||||
return cache[cid];
|
||||
}
|
||||
|
||||
// lookup
|
||||
view = exports.lookup(view, options);
|
||||
@@ -58,13 +61,13 @@ exports.compile = function(view, cache, cid, 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;
|
||||
};
|
||||
|
||||
@@ -81,11 +84,11 @@ exports.compile = function(view, cache, cid, options){
|
||||
*
|
||||
* Lookup:
|
||||
*
|
||||
* - partial `_<name>`
|
||||
* - any `<name>/index`
|
||||
* - non-layout `../<name>/index`
|
||||
* - any `<root>/<name>`
|
||||
* - partial `<root>/_<name>`
|
||||
* - partial `_<name>`
|
||||
* - any `<name>/index`
|
||||
* - non-layout `../<name>/index`
|
||||
* - any `<root>/<name>`
|
||||
* - partial `<root>/_<name>`
|
||||
*
|
||||
* @param {String} view
|
||||
* @param {Object} options
|
||||
@@ -161,7 +164,7 @@ function renderPartial(res, view, options, parentLocals, parent){
|
||||
|
||||
// Inherit locals from parent
|
||||
union(options, parentLocals);
|
||||
|
||||
|
||||
// Merge locals
|
||||
if (locals) merge(options, locals);
|
||||
|
||||
@@ -202,7 +205,7 @@ function renderPartial(res, view, options, parentLocals, parent){
|
||||
options.lastInCollection = i == len - 1;
|
||||
object = val;
|
||||
buf += render();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
keys = Object.keys(collection);
|
||||
len = keys.length;
|
||||
@@ -227,20 +230,20 @@ function renderPartial(res, view, options, parentLocals, parent){
|
||||
};
|
||||
|
||||
/**
|
||||
* Render `view` partial with the given `options`. Optionally a
|
||||
* 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)
|
||||
* - `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.
|
||||
* - `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
|
||||
@@ -294,7 +297,7 @@ res.partial = function(view, options, fn){
|
||||
* 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
|
||||
@@ -430,7 +433,7 @@ res._render = function(view, opts, fn, parent, sub){
|
||||
// partial return
|
||||
} else if (partial) {
|
||||
return str;
|
||||
// render complete, and
|
||||
// render complete, and
|
||||
// callback given
|
||||
} else if (fn) {
|
||||
fn(null, str);
|
||||
@@ -454,4 +457,4 @@ function hintAtViewPaths(view, options) {
|
||||
console.error(' - %s', path);
|
||||
});
|
||||
console.error();
|
||||
}
|
||||
}
|
||||
|
||||
12
package.json
12
package.json
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "express",
|
||||
"description": "Sinatra inspired web development framework",
|
||||
"version": "2.5.2",
|
||||
"version": "2.5.9",
|
||||
"author": "TJ Holowaychuk <tj@vision-media.ca>",
|
||||
"contributors": [
|
||||
{ "name": "TJ Holowaychuk", "email": "tj@vision-media.ca" },
|
||||
@@ -10,16 +10,16 @@
|
||||
{ "name": "Guillermo Rauch", "email": "rauchg@gmail.com" }
|
||||
],
|
||||
"dependencies": {
|
||||
"connect": "1.8.x",
|
||||
"mime": ">= 0.0.1",
|
||||
"qs": ">= 0.3.1",
|
||||
"mkdirp": "0.0.7"
|
||||
"connect": "1.x",
|
||||
"mime": "1.2.4",
|
||||
"qs": "0.4.x",
|
||||
"mkdirp": "0.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"connect-form": "0.2.1",
|
||||
"ejs": "0.4.2",
|
||||
"expresso": "0.9.2",
|
||||
"hamljs": "0.5.1",
|
||||
"hamljs": "0.6.x",
|
||||
"jade": "0.16.2",
|
||||
"stylus": "0.13.0",
|
||||
"should": "0.3.2",
|
||||
|
||||
@@ -821,5 +821,25 @@ module.exports = {
|
||||
assert.response(app,
|
||||
{ url: '/1/2/3' },
|
||||
{ body: '["1","2","3"]' });
|
||||
},
|
||||
|
||||
'test app.all for multiple deletes': function(beforeExit){
|
||||
var app = express.createServer();
|
||||
|
||||
var deletes = 0;
|
||||
|
||||
app.all('*', function(req, res, next){
|
||||
if (req.method === 'DELETE')
|
||||
deletes++;
|
||||
next();
|
||||
});
|
||||
|
||||
assert.response(app,
|
||||
{ url: '/', method: 'DELETE' },
|
||||
{ status: 404 });
|
||||
|
||||
beforeExit(function(){
|
||||
deletes.should.eql(1);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var express = require('express')
|
||||
var express = require('../')
|
||||
, connect = require('connect')
|
||||
, assert = require('assert')
|
||||
, should = require('should')
|
||||
|
||||
Reference in New Issue
Block a user