diff --git a/README.md b/README.md index 7243b9f..e1dd143 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,13 @@ app.use(async (ctx, next) => { app.use(bodyparser()); ``` +## Raw Body + +You can access raw request body by `ctx.request.rawBody` after `koa-bodyparser` when: + +1. `koa-bodyparser` parsed the request body. +2. `ctx.request.rawBody` is not present before `koa-bodyparser`. + ## Koa 1 Support To use `koa-bodyparser` with koa@1, please use [bodyparser 2.x](https://github.com/koajs/bodyparser/tree/2.x). diff --git a/index.js b/index.js index 5f2f91c..51e57f1 100644 --- a/index.js +++ b/index.js @@ -38,6 +38,9 @@ module.exports = function (opts) { opts.detectJSON = undefined; opts.onerror = undefined; + // force co-body return raw body + opts.returnRawBody = true; + // default json types var jsonTypes = [ 'application/json', @@ -70,7 +73,9 @@ module.exports = function (opts) { if (ctx.request.body !== undefined) return await next(); if (ctx.disableBodyParser) return await next(); try { - ctx.request.body = await parseBody(ctx); + const res = await parseBody(ctx); + ctx.request.body = 'parsed' in res ? res.parsed : {}; + if (ctx.request.rawBody === undefined) ctx.request.rawBody = res.raw; } catch (err) { if (onerror) { onerror(err, ctx); diff --git a/package.json b/package.json index 282d71f..3193e1f 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "supertest": "^3.0.0" }, "dependencies": { - "co-body": "^5.0.0", + "co-body": "^5.1.0", "copy-to": "^2.0.1" }, "engines": { diff --git a/test/middleware.test.js b/test/middleware.test.js index bfff2f0..13f029a 100644 --- a/test/middleware.test.js +++ b/test/middleware.test.js @@ -25,7 +25,10 @@ var fixtures = path.join(__dirname, 'fixtures'); describe('test/middleware.test.js', function () { describe('json body', function () { - var app = App(); + var app; + beforeEach(function() { + app = App(); + }); it('should parse json body ok', function (done) { // should work when use body parser again @@ -33,6 +36,7 @@ describe('test/middleware.test.js', function () { app.use(async (ctx) => { ctx.request.body.should.eql( {foo: 'bar'} ); + ctx.request.rawBody.should.equal('{"foo":"bar"}'); ctx.body = ctx.request.body; }); request(app.listen()) @@ -47,6 +51,7 @@ describe('test/middleware.test.js', function () { app.use(async (ctx) => { ctx.request.body.should.eql( {foo: 'bar'} ); + ctx.request.rawBody.should.equal('{"foo": "bar"}'); ctx.body = ctx.request.body; }); request(app.listen()) @@ -61,6 +66,7 @@ describe('test/middleware.test.js', function () { var app = App(); app.use(async (ctx) => { ctx.request.body.should.eql( [{op: 'add', path: '/foo', value: 'bar'}] ); + ctx.request.rawBody.should.equal('[{"op": "add", "path": "/foo", "value": "bar"}]'); ctx.body = ctx.request.body; }); request(app.listen()) @@ -84,6 +90,7 @@ describe('test/middleware.test.js', function () { it('should json body error with string in strict mode', function (done) { var app = App({jsonLimit: 100}); app.use(async (ctx) => { + ctx.request.rawBody.should.equal('"invalid"'); ctx.body = ctx.request.body; }); request(app.listen()) @@ -96,6 +103,7 @@ describe('test/middleware.test.js', function () { it('should json body ok with string not in strict mode', function (done) { var app = App({jsonLimit: 100, strict: false}); app.use(async (ctx) => { + ctx.request.rawBody.should.equal('"valid"'); ctx.body = ctx.request.body; }); request(app.listen()) @@ -116,6 +124,7 @@ describe('test/middleware.test.js', function () { app.use(async (ctx) => { ctx.request.body.should.eql( {foo: 'bar'} ); + ctx.request.rawBody.should.equal('{"foo":"bar"}'); ctx.body = ctx.request.body; }); @@ -133,6 +142,7 @@ describe('test/middleware.test.js', function () { }); app.use(async (ctx) => { + ctx.request.rawBody.should.equal('{"foo":"bar"}'); ctx.body = ctx.request.body; }); @@ -150,6 +160,7 @@ describe('test/middleware.test.js', function () { it('should parse form body ok', function (done) { app.use(async (ctx) => { ctx.request.body.should.eql( { foo: {bar: 'baz'} } ); + ctx.request.rawBody.should.equal('foo%5Bbar%5D=baz'); ctx.body = ctx.request.body; }); request(app.listen()) @@ -176,6 +187,7 @@ describe('test/middleware.test.js', function () { }); app.use(async (ctx) => { ctx.request.body.should.equal('body'); + ctx.request.rawBody.should.equal('body'); ctx.body = ctx.request.body; }); request(app.listen()) @@ -293,6 +305,7 @@ describe('test/middleware.test.js', function () { }); app.use(bodyParser()); app.use(async (ctx) => { + (undefined === ctx.request.rawBody).should.equal(true); ctx.body = ctx.request.body ? 'parsed' : 'empty'; }); request(app.listen())