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