Comparar commits
20 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| 658e064220 | |||
| 66b472e567 | |||
| 3d242a607e | |||
| bc68e5e7a3 | |||
| aa6858189c | |||
| 06fda62c9e | |||
| 5688ea650d | |||
| f5c4e9d612 | |||
| b9eda2a59d | |||
| 8c168b0971 | |||
| 9c20a50ee2 | |||
| eac666574e | |||
| e4c840f6b8 | |||
| 3afbcd0acf | |||
| 8f054dbcaf | |||
| ccc39e5aa2 | |||
| 53d4da2a9c | |||
| d9e7153fc9 | |||
| dc02b0d5ae | |||
| e0bc5711b8 |
@@ -1,4 +1,19 @@
|
||||
|
||||
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
|
||||
==================
|
||||
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ var fs = require('fs')
|
||||
* Framework version.
|
||||
*/
|
||||
|
||||
var version = '2.2.2';
|
||||
var version = '2.3.0';
|
||||
|
||||
/**
|
||||
* Add session support.
|
||||
|
||||
+1
-1
@@ -894,7 +894,7 @@ To parse incoming _Cookie_ headers, use the _cookieParser_ middleware, which pro
|
||||
// use req.cookies.rememberme
|
||||
});
|
||||
|
||||
### res.clearCookie(name)
|
||||
### res.clearCookie(name[, options])
|
||||
|
||||
Clear cookie _name_ by setting "expires" far in the past.
|
||||
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ var exports = module.exports = connect.middleware;
|
||||
* Framework version.
|
||||
*/
|
||||
|
||||
exports.version = '2.2.2';
|
||||
exports.version = '2.3.0';
|
||||
|
||||
/**
|
||||
* Shortcut for `new Server(...)`.
|
||||
|
||||
+7
-23
@@ -44,12 +44,13 @@ Server.prototype.__proto__ = connect.HTTPServer.prototype;
|
||||
|
||||
Server.prototype.init = function(middleware){
|
||||
var self = this;
|
||||
this.cache = {};
|
||||
this.match = {};
|
||||
this.lookup = {};
|
||||
this.settings = {};
|
||||
this.redirects = {};
|
||||
this.isCallbacks = {};
|
||||
this.viewHelpers = {};
|
||||
this._locals = {};
|
||||
this.dynamicViewHelpers = {};
|
||||
this.errorHandlers = [];
|
||||
|
||||
@@ -98,7 +99,7 @@ Server.prototype.init = function(middleware){
|
||||
|
||||
// default production configuration
|
||||
this.configure('production', function(){
|
||||
this.enable('cache views');
|
||||
this.enable('view cache');
|
||||
});
|
||||
|
||||
// register error handlers on "listening"
|
||||
@@ -241,7 +242,7 @@ Server.prototype.register = function(){
|
||||
|
||||
Server.prototype.helpers =
|
||||
Server.prototype.locals = function(obj){
|
||||
utils.merge(this.viewHelpers, obj);
|
||||
utils.merge(this._locals, obj);
|
||||
return this;
|
||||
};
|
||||
|
||||
@@ -450,7 +451,7 @@ Server.prototype.configure = function(env, fn){
|
||||
// Generate routing methods
|
||||
|
||||
function generateMethod(method){
|
||||
Server.prototype[method] = function(path, fn){
|
||||
Server.prototype[method] = function(path){
|
||||
var self = this;
|
||||
|
||||
// Lookup
|
||||
@@ -461,27 +462,10 @@ function generateMethod(method){
|
||||
}
|
||||
|
||||
// Ensure router is mounted
|
||||
if (!this.__usedRouter) {
|
||||
this.use(this.router);
|
||||
}
|
||||
|
||||
// Route specific middleware support
|
||||
if (arguments.length > 2) {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
fn = args.pop();
|
||||
(function stack(middleware){
|
||||
middleware.forEach(function(fn){
|
||||
if (Array.isArray(fn)) {
|
||||
stack(fn);
|
||||
} else {
|
||||
self[method](path, fn);
|
||||
}
|
||||
});
|
||||
})(args);
|
||||
}
|
||||
if (!this.__usedRouter) this.use(this.router);
|
||||
|
||||
// Generate the route
|
||||
this.routes[method](path, fn);
|
||||
this.routes[method].apply(this, arguments);
|
||||
return this;
|
||||
};
|
||||
return arguments.callee;
|
||||
|
||||
+12
-4
@@ -75,10 +75,12 @@ res.send = function(body, headers, status){
|
||||
}
|
||||
} else {
|
||||
if (!this.header('Content-Type')) {
|
||||
this.charset = this.charset || 'utf-8';
|
||||
this.contentType('.json');
|
||||
}
|
||||
body = JSON.stringify(body);
|
||||
if (this.req.query.callback && this.app.set('jsonp callback')) {
|
||||
this.charset = this.charset || 'utf-8';
|
||||
this.header('Content-Type', 'text/javascript');
|
||||
body = this.req.query.callback.replace(/[^\w$.]/g, '') + '(' + body + ');';
|
||||
}
|
||||
@@ -176,6 +178,7 @@ res.contentType = function(type){
|
||||
*/
|
||||
|
||||
res.attachment = function(filename){
|
||||
if (filename) this.contentType(filename);
|
||||
this.header('Content-Disposition', filename
|
||||
? 'attachment; filename="' + path.basename(filename) + '"'
|
||||
: 'attachment');
|
||||
@@ -211,7 +214,7 @@ res.download = function(path, filename, fn, fn2){
|
||||
if (err) {
|
||||
if (!sentHeader) self.removeHeader('Content-Disposition');
|
||||
if (sentHeader) {
|
||||
if (fn2) fn2(err);
|
||||
fn2 && fn2(err);
|
||||
} else if (fn) {
|
||||
fn(err);
|
||||
} else {
|
||||
@@ -245,11 +248,15 @@ res.header = function(name, val){
|
||||
* Clear cookie `name`.
|
||||
*
|
||||
* @param {String} name
|
||||
* @param {Object} options
|
||||
* @api public
|
||||
*/
|
||||
|
||||
res.clearCookie = function(name){
|
||||
this.cookie(name, '', { expires: new Date(1) });
|
||||
res.clearCookie = function(name, options){
|
||||
var opts = { expires: new Date(1) };
|
||||
this.cookie(name, '', options
|
||||
? utils.merge(options, opts)
|
||||
: opts);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -404,7 +411,8 @@ res.local = function(name, val){
|
||||
* @api public
|
||||
*/
|
||||
|
||||
res.locals = function(obj){
|
||||
res.locals =
|
||||
res.helpers = function(obj){
|
||||
if (obj) {
|
||||
for (var key in obj) {
|
||||
this.local(key, obj[key]);
|
||||
|
||||
+9
-14
@@ -21,14 +21,6 @@ var path = require('path')
|
||||
, http = require('http')
|
||||
, res = http.ServerResponse.prototype;
|
||||
|
||||
/**
|
||||
* Memory cache.
|
||||
*
|
||||
* @type Object
|
||||
*/
|
||||
|
||||
var cache = {};
|
||||
|
||||
/**
|
||||
* Expose constructors.
|
||||
*/
|
||||
@@ -261,10 +253,10 @@ res._render = function(view, opts, fn, parent, sub){
|
||||
var options = {}
|
||||
, self = this
|
||||
, app = this.app
|
||||
, helpers = app.viewHelpers
|
||||
, helpers = app._locals
|
||||
, dynamicHelpers = app.dynamicViewHelpers
|
||||
, viewOptions = app.set('view options')
|
||||
, cacheViews = app.set('cache views')
|
||||
, cacheViews = app.enabled('view cache')
|
||||
, root = app.set('views') || process.cwd() + '/views';
|
||||
|
||||
// merge "view options"
|
||||
@@ -331,15 +323,18 @@ res._render = function(view, opts, fn, parent, sub){
|
||||
};
|
||||
|
||||
// cached view
|
||||
if (cache[view]) {
|
||||
view = cache[view];
|
||||
if (app.cache[view]) {
|
||||
view = app.cache[view];
|
||||
options.filename = view.path;
|
||||
// resolve view
|
||||
} else {
|
||||
var orig = view = new View(view, options);
|
||||
|
||||
// Try _ prefix ex: ./views/_<name>.jade
|
||||
if (!view.exists) view = new View(orig.prefixPath, options);
|
||||
if (partial) {
|
||||
view = new View(orig.prefixPath, options);
|
||||
if (!view.exists) view = orig;
|
||||
}
|
||||
|
||||
// Try index ex: ./views/user/index.jade
|
||||
if (!view.exists) view = new View(orig.indexPath, options);
|
||||
@@ -365,7 +360,7 @@ res._render = function(view, opts, fn, parent, sub){
|
||||
options.filename = view.path;
|
||||
var engine = view.templateEngine;
|
||||
view.fn = engine.compile(view.contents, options)
|
||||
if (cacheViews) cache[orig.view] = view;
|
||||
if (cacheViews) app.cache[orig.view] = view;
|
||||
}
|
||||
|
||||
// layout helper
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "express",
|
||||
"description": "Sinatra inspired web development framework",
|
||||
"version": "2.2.2",
|
||||
"version": "2.3.0",
|
||||
"author": "TJ Holowaychuk <tj@vision-media.ca>",
|
||||
"contributors": [
|
||||
{ "name": "TJ Holowaychuk", "email": "tj@vision-media.ca" },
|
||||
@@ -10,7 +10,7 @@
|
||||
{ "name": "Guillermo Rauch", "email": "rauchg@gmail.com" }
|
||||
],
|
||||
"dependencies": {
|
||||
"connect": ">= 1.3.0 < 2.0.0",
|
||||
"connect": ">= 1.4.0 < 2.0.0",
|
||||
"mime": ">= 0.0.1",
|
||||
"qs": ">= 0.0.6"
|
||||
},
|
||||
|
||||
+1
-1
Submodule support/connect updated: 4b5a36540b...af32d828a3
+17
-3
@@ -435,8 +435,9 @@ module.exports = {
|
||||
);
|
||||
},
|
||||
|
||||
'test route middleware': function(){
|
||||
var app = express.createServer();
|
||||
'test route middleware': function(beforeExit){
|
||||
var app = express.createServer()
|
||||
, calls = 0;
|
||||
|
||||
function allow(role) {
|
||||
return function(req, res, next) {
|
||||
@@ -460,6 +461,11 @@ module.exports = {
|
||||
}
|
||||
}
|
||||
|
||||
app.param('user', function(req, res, next, user){
|
||||
++calls;
|
||||
next();
|
||||
});
|
||||
|
||||
app.get('/xxx', allow('member'), restrictAge(18), function(req, res){
|
||||
res.send(200);
|
||||
});
|
||||
@@ -471,8 +477,12 @@ module.exports = {
|
||||
app.get('/tobi', [allow('member')], [[restrictAge(18)]], function(req, res){
|
||||
res.send(200);
|
||||
});
|
||||
|
||||
app.get('/user/:user', [allow('member')], [[restrictAge(18)]], function(req, res){
|
||||
res.send(200);
|
||||
});
|
||||
|
||||
['xxx', 'booze', 'tobi'].forEach(function(thing){
|
||||
['xxx', 'booze', 'tobi', 'user/tj'].forEach(function(thing){
|
||||
assert.response(app,
|
||||
{ url: '/' + thing },
|
||||
{ body: 'Unauthorized', status: 401 });
|
||||
@@ -483,6 +493,10 @@ module.exports = {
|
||||
{ url: '/' + thing, headers: { 'X-Role': 'member', 'X-Age': 18 }},
|
||||
{ body: 'OK', status: 200 });
|
||||
});
|
||||
|
||||
beforeExit(function(){
|
||||
calls.should.equal(3);
|
||||
});
|
||||
},
|
||||
|
||||
'test named capture groups': function(){
|
||||
|
||||
externo
+1
@@ -0,0 +1 @@
|
||||
p two
|
||||
externo
+1
@@ -0,0 +1 @@
|
||||
p one
|
||||
+12
-10
@@ -61,7 +61,7 @@ module.exports = {
|
||||
assert.response(app,
|
||||
{ url: '/bool' },
|
||||
{ body: 'true'
|
||||
, headers: { 'Content-Type': 'application/json' }});
|
||||
, headers: { 'Content-Type': 'application/json; charset=utf-8' }});
|
||||
|
||||
assert.response(app,
|
||||
{ url: '/html' },
|
||||
@@ -76,7 +76,7 @@ module.exports = {
|
||||
{ body: '{"foo":"bar"}'
|
||||
, status: 201
|
||||
, headers: {
|
||||
'Content-Type': 'application/json'
|
||||
'Content-Type': 'application/json; charset=utf-8'
|
||||
, 'X-Foo': 'baz'
|
||||
}});
|
||||
|
||||
@@ -85,7 +85,7 @@ module.exports = {
|
||||
{ body: 'test({"foo":"bar"});'
|
||||
, status: 201
|
||||
, headers: {
|
||||
'Content-Type': 'text/javascript'
|
||||
'Content-Type': 'text/javascript; charset=utf-8'
|
||||
, 'X-Foo': 'baz'
|
||||
}});
|
||||
|
||||
@@ -93,7 +93,7 @@ module.exports = {
|
||||
{ url: '/jsonp?callback=baz' },
|
||||
{ body: 'baz({"foo":"bar"});'
|
||||
, status: 201, headers: {
|
||||
'Content-Type': 'text/javascript'
|
||||
'Content-Type': 'text/javascript; charset=utf-8'
|
||||
, 'X-Foo': 'baz'
|
||||
}});
|
||||
|
||||
@@ -102,7 +102,7 @@ module.exports = {
|
||||
{ body: 'invalid({"foo":"bar"});'
|
||||
, status: 201
|
||||
, headers: {
|
||||
'Content-Type': 'text/javascript'
|
||||
'Content-Type': 'text/javascript; charset=utf-8'
|
||||
, 'X-Foo': 'baz'
|
||||
}});
|
||||
|
||||
@@ -111,7 +111,7 @@ module.exports = {
|
||||
{ body: '{"foo":"bar"}'
|
||||
, status: 201
|
||||
, headers: {
|
||||
'Content-Type': 'application/json'
|
||||
'Content-Type': 'application/json; charset=utf-8'
|
||||
, 'X-Foo': 'baz'
|
||||
}});
|
||||
|
||||
@@ -207,12 +207,14 @@ module.exports = {
|
||||
assert.response(app,
|
||||
{ url: '/javascripts/jquery.js' },
|
||||
{ body: 'whatever'
|
||||
, headers: { 'Content-Disposition': 'attachment; filename="jquery.js"' }});
|
||||
, headers: { 'Content-Type': 'application/javascript'
|
||||
, 'Content-Disposition': 'attachment; filename="jquery.js"' }});
|
||||
|
||||
assert.response(app,
|
||||
{ url: '/style.css' },
|
||||
{ body: 'some stylezzz'
|
||||
, headers: { 'Content-Disposition': 'attachment' }});
|
||||
, headers: { 'Content-Type': 'text/html; charset=utf-8'
|
||||
, 'Content-Disposition': 'attachment' }});
|
||||
},
|
||||
|
||||
'test #redirect()': function(){
|
||||
@@ -568,7 +570,7 @@ module.exports = {
|
||||
var app = express.createServer();
|
||||
|
||||
app.get('/', function(req, res){
|
||||
res.clearCookie('rememberme');
|
||||
res.clearCookie('rememberme', { path: '/foo' });
|
||||
res.redirect('/');
|
||||
});
|
||||
|
||||
@@ -576,7 +578,7 @@ module.exports = {
|
||||
{ url: '/' },
|
||||
function(res){
|
||||
res.headers['set-cookie']
|
||||
.should.eql(['rememberme=; expires=Thu, 01 Jan 1970 00:00:00 GMT']);
|
||||
.should.eql(['rememberme=; path=/foo; expires=Thu, 01 Jan 1970 00:00:00 GMT']);
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@@ -657,6 +657,14 @@ module.exports = {
|
||||
assert.response(app,
|
||||
{ url: '/error' },
|
||||
{ status: 500 });
|
||||
|
||||
app.get('/underscore', function(req, res, next){
|
||||
res.partial('foobar');
|
||||
});
|
||||
|
||||
assert.response(app,
|
||||
{ url: '/underscore' },
|
||||
{ body: '<p>two</p>' });
|
||||
},
|
||||
|
||||
'test #partial() with several calls': function(){
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário