add new style middleware support through @jonathanong's koa-compose patch
This commit is contained in:
parent
a9ae563051
commit
2d35cdff50
4 changed files with 124 additions and 182 deletions
|
@ -9,20 +9,16 @@ var n = parseInt(process.env.MW || '1', 10);
|
||||||
console.log(' %s middleware', n);
|
console.log(' %s middleware', n);
|
||||||
|
|
||||||
while (n--) {
|
while (n--) {
|
||||||
app.use(function(next){
|
app.use(function *(next){
|
||||||
return function *(){
|
yield next;
|
||||||
yield next;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
var body = new Buffer('Hello World');
|
var body = new Buffer('Hello World');
|
||||||
|
|
||||||
app.use(function(next){
|
app.use(function *(next){
|
||||||
return function *(){
|
yield next;
|
||||||
yield next;
|
this.body = body;
|
||||||
this.body = body;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
app.listen(3333);
|
app.listen(3333);
|
||||||
|
|
|
@ -126,15 +126,13 @@ app.context = function(obj){
|
||||||
|
|
||||||
app.callback = function(){
|
app.callback = function(){
|
||||||
var mw = [respond].concat(this.middleware);
|
var mw = [respond].concat(this.middleware);
|
||||||
var fn = compose(mw)(downstream);
|
var gen = compose(mw);
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
return function(req, res){
|
return function(req, res){
|
||||||
var ctx = new self.Context(self, req, res);
|
var ctx = new self.Context(self, req, res);
|
||||||
|
|
||||||
co.call(ctx, function *(){
|
co.call(ctx, gen)(function(err){
|
||||||
yield fn;
|
|
||||||
})(function(err){
|
|
||||||
if (err) ctx.onerror(err);
|
if (err) ctx.onerror(err);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -157,68 +155,58 @@ app.onerror = function(err){
|
||||||
* Response middleware.
|
* Response middleware.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function respond(next){
|
function *respond(next){
|
||||||
return function *respond(){
|
this.status = 200;
|
||||||
this.status = 200;
|
if (this.app.poweredBy) this.set('X-Powered-By', 'koa');
|
||||||
if (this.app.poweredBy) this.set('X-Powered-By', 'koa');
|
|
||||||
|
|
||||||
yield next;
|
yield next;
|
||||||
|
|
||||||
var app = this.app;
|
var app = this.app;
|
||||||
var res = this.res;
|
var res = this.res;
|
||||||
var body = this.body;
|
var body = this.body;
|
||||||
var head = 'HEAD' == this.method;
|
var head = 'HEAD' == this.method;
|
||||||
var noContent = 204 == this.status || 304 == this.status;
|
var noContent = 204 == this.status || 304 == this.status;
|
||||||
|
|
||||||
// 404
|
// 404
|
||||||
if (null == body && 200 == this.status) {
|
if (null == body && 200 == this.status) {
|
||||||
this.status = 404;
|
this.status = 404;
|
||||||
}
|
|
||||||
|
|
||||||
// ignore body
|
|
||||||
if (noContent) return res.end();
|
|
||||||
|
|
||||||
// status body
|
|
||||||
if (null == body) {
|
|
||||||
this.type = 'text';
|
|
||||||
body = http.STATUS_CODES[this.status];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Buffer body
|
|
||||||
if (Buffer.isBuffer(body)) {
|
|
||||||
if (head) return res.end();
|
|
||||||
return res.end(body);
|
|
||||||
}
|
|
||||||
|
|
||||||
// string body
|
|
||||||
if ('string' == typeof body) {
|
|
||||||
if (head) return res.end();
|
|
||||||
return res.end(body);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stream body
|
|
||||||
if (body instanceof Stream) {
|
|
||||||
if (!~body.listeners('error').indexOf(this.onerror)) body.on('error', this.onerror);
|
|
||||||
if (head) return res.end();
|
|
||||||
return body.pipe(res);
|
|
||||||
}
|
|
||||||
|
|
||||||
// body: json
|
|
||||||
body = JSON.stringify(body, null, this.app.jsonSpaces);
|
|
||||||
this.length = Buffer.byteLength(body);
|
|
||||||
if (head) return res.end();
|
|
||||||
res.end(body);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ignore body
|
||||||
|
if (noContent) return res.end();
|
||||||
|
|
||||||
|
// status body
|
||||||
|
if (null == body) {
|
||||||
|
this.type = 'text';
|
||||||
|
body = http.STATUS_CODES[this.status];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Buffer body
|
||||||
|
if (Buffer.isBuffer(body)) {
|
||||||
|
if (head) return res.end();
|
||||||
|
return res.end(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
// string body
|
||||||
|
if ('string' == typeof body) {
|
||||||
|
if (head) return res.end();
|
||||||
|
return res.end(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stream body
|
||||||
|
if (body instanceof Stream) {
|
||||||
|
if (!~body.listeners('error').indexOf(this.onerror)) body.on('error', this.onerror);
|
||||||
|
if (head) return res.end();
|
||||||
|
return body.pipe(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
// body: json
|
||||||
|
body = JSON.stringify(body, null, this.app.jsonSpaces);
|
||||||
|
this.length = Buffer.byteLength(body);
|
||||||
|
if (head) return res.end();
|
||||||
|
res.end(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Default downstream middleware.
|
|
||||||
*
|
|
||||||
* @api private
|
|
||||||
*/
|
|
||||||
|
|
||||||
function *downstream(){}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new `Context` constructor.
|
* Create a new `Context` constructor.
|
||||||
*
|
*
|
||||||
|
|
|
@ -21,12 +21,12 @@
|
||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"co": "2.0.0",
|
"co": "2.2.0",
|
||||||
"debug": "*",
|
"debug": "*",
|
||||||
"mime": "1.2.10",
|
"mime": "1.2.10",
|
||||||
"fresh": "0.2.0",
|
"fresh": "0.2.0",
|
||||||
"negotiator": "0.2.7",
|
"negotiator": "0.2.7",
|
||||||
"koa-compose": "1.0.0",
|
"koa-compose": "2.0.0",
|
||||||
"cookies": "~0.3.6"
|
"cookies": "~0.3.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
@ -10,28 +10,22 @@ describe('app.use(fn)', function(){
|
||||||
var app = koa();
|
var app = koa();
|
||||||
var calls = [];
|
var calls = [];
|
||||||
|
|
||||||
app.use(function(next){
|
app.use(function *(next){
|
||||||
return function *(){
|
calls.push(1);
|
||||||
calls.push(1);
|
yield next;
|
||||||
yield next;
|
calls.push(6);
|
||||||
calls.push(6);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
app.use(function(next){
|
app.use(function *(next){
|
||||||
return function *(){
|
calls.push(2);
|
||||||
calls.push(2);
|
yield next;
|
||||||
yield next;
|
calls.push(5);
|
||||||
calls.push(5);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
app.use(function(next){
|
app.use(function *(next){
|
||||||
return function *(){
|
calls.push(3);
|
||||||
calls.push(3);
|
yield next;
|
||||||
yield next;
|
calls.push(4);
|
||||||
calls.push(4);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var server = app.listen();
|
var server = app.listen();
|
||||||
|
@ -51,10 +45,8 @@ describe('app.respond', function(){
|
||||||
it('should not respond with the body', function(done){
|
it('should not respond with the body', function(done){
|
||||||
var app = koa();
|
var app = koa();
|
||||||
|
|
||||||
app.use(function(next){
|
app.use(function *(){
|
||||||
return function *(){
|
this.body = 'Hello';
|
||||||
this.body = 'Hello';
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var server = app.listen();
|
var server = app.listen();
|
||||||
|
@ -87,10 +79,8 @@ describe('app.respond', function(){
|
||||||
it('should respond with the associated status message', function(done){
|
it('should respond with the associated status message', function(done){
|
||||||
var app = koa();
|
var app = koa();
|
||||||
|
|
||||||
app.use(function(next){
|
app.use(function *(){
|
||||||
return function *(){
|
this.status = 400;
|
||||||
this.status = 400;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var server = app.listen();
|
var server = app.listen();
|
||||||
|
@ -106,10 +96,8 @@ describe('app.respond', function(){
|
||||||
it('should respond', function(done){
|
it('should respond', function(done){
|
||||||
var app = koa();
|
var app = koa();
|
||||||
|
|
||||||
app.use(function(next){
|
app.use(function *(){
|
||||||
return function *(){
|
this.body = 'Hello';
|
||||||
this.body = 'Hello';
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var server = app.listen();
|
var server = app.listen();
|
||||||
|
@ -124,10 +112,8 @@ describe('app.respond', function(){
|
||||||
it('should respond', function(done){
|
it('should respond', function(done){
|
||||||
var app = koa();
|
var app = koa();
|
||||||
|
|
||||||
app.use(function(next){
|
app.use(function *(){
|
||||||
return function *(){
|
this.body = new Buffer('Hello');
|
||||||
this.body = new Buffer('Hello');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var server = app.listen();
|
var server = app.listen();
|
||||||
|
@ -142,11 +128,9 @@ describe('app.respond', function(){
|
||||||
it('should respond', function(done){
|
it('should respond', function(done){
|
||||||
var app = koa();
|
var app = koa();
|
||||||
|
|
||||||
app.use(function(next){
|
app.use(function *(){
|
||||||
return function *(){
|
this.body = fs.createReadStream('package.json');
|
||||||
this.body = fs.createReadStream('package.json');
|
this.set('Content-Type', 'application/json');
|
||||||
this.set('Content-Type', 'application/json');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var server = app.listen();
|
var server = app.listen();
|
||||||
|
@ -165,11 +149,9 @@ describe('app.respond', function(){
|
||||||
it('should handle errors', function(done){
|
it('should handle errors', function(done){
|
||||||
var app = koa();
|
var app = koa();
|
||||||
|
|
||||||
app.use(function(next){
|
app.use(function *(){
|
||||||
return function *(){
|
this.set('Content-Type', 'application/json');
|
||||||
this.set('Content-Type', 'application/json');
|
this.body = fs.createReadStream('does not exist');
|
||||||
this.body = fs.createReadStream('does not exist');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var server = app.listen();
|
var server = app.listen();
|
||||||
|
@ -186,10 +168,8 @@ describe('app.respond', function(){
|
||||||
it('should respond with json', function(done){
|
it('should respond with json', function(done){
|
||||||
var app = koa();
|
var app = koa();
|
||||||
|
|
||||||
app.use(function(next){
|
app.use(function *(){
|
||||||
return function *(){
|
this.body = { hello: 'world' };
|
||||||
this.body = { hello: 'world' };
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var server = app.listen();
|
var server = app.listen();
|
||||||
|
@ -206,10 +186,8 @@ describe('app.respond', function(){
|
||||||
|
|
||||||
app.jsonSpaces = 0;
|
app.jsonSpaces = 0;
|
||||||
|
|
||||||
app.use(function(next){
|
app.use(function *(){
|
||||||
return function *(){
|
this.body = { hello: 'world' };
|
||||||
this.body = { hello: 'world' };
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var server = app.listen();
|
var server = app.listen();
|
||||||
|
@ -226,10 +204,8 @@ describe('app.respond', function(){
|
||||||
it('should emit "error" on the app', function(done){
|
it('should emit "error" on the app', function(done){
|
||||||
var app = koa();
|
var app = koa();
|
||||||
|
|
||||||
app.use(function(next){
|
app.use(function *(){
|
||||||
return function *(){
|
throw new Error('boom');
|
||||||
throw new Error('boom');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
app.on('error', function(err){
|
app.on('error', function(err){
|
||||||
|
@ -246,13 +222,11 @@ describe('app.respond', function(){
|
||||||
it('should expose the message', function(done){
|
it('should expose the message', function(done){
|
||||||
var app = koa();
|
var app = koa();
|
||||||
|
|
||||||
app.use(function(next){
|
app.use(function *(){
|
||||||
return function *(){
|
var err = new Error('sorry!');
|
||||||
var err = new Error('sorry!');
|
err.status = 403;
|
||||||
err.status = 403;
|
err.expose = true;
|
||||||
err.expose = true;
|
throw err;
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
request(app.listen())
|
request(app.listen())
|
||||||
|
@ -266,12 +240,10 @@ describe('app.respond', function(){
|
||||||
it('should respond with .status', function(done){
|
it('should respond with .status', function(done){
|
||||||
var app = koa();
|
var app = koa();
|
||||||
|
|
||||||
app.use(function(next){
|
app.use(function *(){
|
||||||
return function *(){
|
var err = new Error('s3 explodes');
|
||||||
var err = new Error('s3 explodes');
|
err.status = 403;
|
||||||
err.status = 403;
|
throw err;
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
request(app.listen())
|
request(app.listen())
|
||||||
|
@ -284,10 +256,8 @@ describe('app.respond', function(){
|
||||||
it('should respond with 500', function(done){
|
it('should respond with 500', function(done){
|
||||||
var app = koa();
|
var app = koa();
|
||||||
|
|
||||||
app.use(function(next){
|
app.use(function *(){
|
||||||
return function *(){
|
throw new Error('boom!');
|
||||||
throw new Error('boom!');
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var server = app.listen();
|
var server = app.listen();
|
||||||
|
@ -301,23 +271,19 @@ describe('app.respond', function(){
|
||||||
it('should be catchable', function(done){
|
it('should be catchable', function(done){
|
||||||
var app = koa();
|
var app = koa();
|
||||||
|
|
||||||
app.use(function(next){
|
app.use(function *(next){
|
||||||
return function *(){
|
try {
|
||||||
try {
|
yield next;
|
||||||
yield next;
|
this.body = 'Hello';
|
||||||
this.body = 'Hello';
|
} catch (err) {
|
||||||
} catch (err) {
|
error = err;
|
||||||
error = err;
|
this.body = 'Got error';
|
||||||
this.body = 'Got error';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
app.use(function(next){
|
app.use(function *(next){
|
||||||
return function *(){
|
throw new Error('boom!');
|
||||||
throw new Error('boom!');
|
this.body = 'Oh no';
|
||||||
this.body = 'Oh no';
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var server = app.listen();
|
var server = app.listen();
|
||||||
|
@ -339,12 +305,10 @@ describe('app.context(obj)', function(){
|
||||||
b: 2
|
b: 2
|
||||||
});
|
});
|
||||||
|
|
||||||
app.use(function(next){
|
app.use(function *(next){
|
||||||
return function *(){
|
this.a.should.equal(1);
|
||||||
this.a.should.equal(1);
|
this.b.should.equal(2);
|
||||||
this.b.should.equal(2);
|
this.status = 204;
|
||||||
this.status = 204;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var server = app.listen();
|
var server = app.listen();
|
||||||
|
@ -368,13 +332,11 @@ describe('app.context(obj)', function(){
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
app.use(function(next){
|
app.use(function *(next){
|
||||||
return function *(){
|
this.something.should.equal('hi');
|
||||||
this.something.should.equal('hi');
|
this.something = 'hello';
|
||||||
this.something = 'hello';
|
this.something.should.equal('hello');
|
||||||
this.something.should.equal('hello');
|
this.status = 204;
|
||||||
this.status = 204;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var server = app.listen();
|
var server = app.listen();
|
||||||
|
@ -396,12 +358,10 @@ describe('app.context(obj)', function(){
|
||||||
b: 2
|
b: 2
|
||||||
});
|
});
|
||||||
|
|
||||||
app.use(function(next){
|
app.use(function *(){
|
||||||
return function *(){
|
this.a.should.equal(1);
|
||||||
this.a.should.equal(1);
|
this.b.should.equal(2);
|
||||||
this.b.should.equal(2);
|
this.status = 204;
|
||||||
this.status = 204;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var server = app.listen();
|
var server = app.listen();
|
||||||
|
@ -420,11 +380,9 @@ describe('app.context(obj)', function(){
|
||||||
a: 1
|
a: 1
|
||||||
});
|
});
|
||||||
|
|
||||||
app2.use(function(next){
|
app2.use(function *(next){
|
||||||
return function *(){
|
assert.equal(this.a, undefined);
|
||||||
assert.equal(this.a, undefined);
|
this.status = 204;
|
||||||
this.status = 204;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var server = http.createServer(app2.callback());
|
var server = http.createServer(app2.callback());
|
||||||
|
|
Loading…
Reference in a new issue