From 8836cd30d140ec285e3ceadbeadeda1f1796af24 Mon Sep 17 00:00:00 2001 From: Lee Bousfield Date: Thu, 27 Oct 2016 23:13:07 -0600 Subject: [PATCH 1/2] Return middleware chain promise from `callback()` Without this, there's no way of hooking into after Koa is done with the response. This can be extremely important if used with `ctx.respond = false`, as in #846 (see there for use case). While this is technically a breaking change, I don't expect it to break anything. --- lib/application.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/application.js b/lib/application.js index 8b6a78bcc..b15b80dbd 100644 --- a/lib/application.js +++ b/lib/application.js @@ -133,7 +133,7 @@ app.callback = function(){ res.statusCode = 404; var ctx = self.createContext(req, res); onFinished(res, ctx.onerror); - fn.call(ctx).then(function handleResponse() { + return fn.call(ctx).then(function handleResponse() { respond.call(ctx); }).catch(ctx.onerror); } From 734a62cd88f2c2cf8b5bf91d4b5b716b619c643c Mon Sep 17 00:00:00 2001 From: Lee Bousfield Date: Fri, 28 Oct 2016 09:14:32 -0600 Subject: [PATCH 2/2] Added app.usedAsMiddleware Disables default response handler. See docs for more info. --- docs/api/index.md | 6 ++++++ lib/application.js | 7 ++++++- test/application.js | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/docs/api/index.md b/docs/api/index.md index e5a0614cb..cd64cb269 100644 --- a/docs/api/index.md +++ b/docs/api/index.md @@ -169,6 +169,12 @@ this.cookies.set('name', 'tobi', { signed: true }); app.context.db = db(); ``` +## app.usedAsMiddleware + + Disables the default 404 status code and empty response. + This is very useful if you're using Koa as part of another framework, where Koa tries + to handle a request first and then falls back to the legacy framework. + ## Error Handling By default outputs all errors to stderr unless __NODE_ENV__ is "test" or `app.silent` is `true`. diff --git a/lib/application.js b/lib/application.js index b15b80dbd..0198422d1 100644 --- a/lib/application.js +++ b/lib/application.js @@ -130,7 +130,10 @@ app.callback = function(){ if (!this.listeners('error').length) this.on('error', this.onerror); return function handleRequest(req, res){ - res.statusCode = 404; + // don't set the default status code if Koa is part of a larger framework + if (!self.usedAsMiddleware) { + res.statusCode = 404; + } var ctx = self.createContext(req, res); onFinished(res, ctx.onerror); return fn.call(ctx).then(function handleResponse() { @@ -215,6 +218,8 @@ function respond() { // status body if (null == body) { + // don't send back the default empty response if Koa is part of a larger framework + if (this.app.usedAsMiddleware) return; this.type = 'text'; body = this.message || String(code); this.length = Buffer.byteLength(body); diff --git a/test/application.js b/test/application.js index d114f2269..d9d087350 100644 --- a/test/application.js +++ b/test/application.js @@ -1110,3 +1110,41 @@ describe('app.response', function(){ .expect(204, done); }) }) + +describe('app.usedAsMiddleware', function(){ + var app = koa() + app.use(function *(next) { + if (this.url.indexOf('/koa') == 0) { + this.statusCode = 200 + this.body = 'Hello from Koa!' + } else { + yield next + } + }) + app.usedAsMiddleware = true + var koaHandle = app.callback() + function handle(req, res){ + koaHandle(req, res).then(function(){ + if (!res.finished) { + res.end('Hello from other framework!') + } + }) + } + var server = http.createServer(handle).listen(0) + + it('should not touch res if middleware doesn\'t', function(done){ + request(server) + .get('/') + .expect(200) + .expect('Hello from other framework!') + .end(done) + }) + + it('should let middleware handle res', function(done){ + request(server) + .get('/koa') + .expect(200) + .expect('Hello from Koa!') + .end(done) + }) +})