From 2d35cdff500bee091d4428c7b1bc463171490137 Mon Sep 17 00:00:00 2001 From: TJ Holowaychuk Date: Thu, 7 Nov 2013 16:15:47 -0800 Subject: [PATCH] add new style middleware support through @jonathanong's koa-compose patch --- benchmarks/middleware.js | 14 ++- lib/application.js | 108 +++++++++++------------ package.json | 4 +- test/application.js | 180 +++++++++++++++------------------------ 4 files changed, 124 insertions(+), 182 deletions(-) diff --git a/benchmarks/middleware.js b/benchmarks/middleware.js index f13748f..bd1ed07 100644 --- a/benchmarks/middleware.js +++ b/benchmarks/middleware.js @@ -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); diff --git a/lib/application.js b/lib/application.js index 5ac6102..0d34769 100644 --- a/lib/application.js +++ b/lib/application.js @@ -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. * diff --git a/package.json b/package.json index 68194e6..c11f3cc 100644 --- a/package.json +++ b/package.json @@ -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": { diff --git a/test/application.js b/test/application.js index d2241fd..9f96ef3 100644 --- a/test/application.js +++ b/test/application.js @@ -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());