From abeabcc2686a8fb6dd6eefdb8a789119d7e3bd8a Mon Sep 17 00:00:00 2001 From: TJ Holowaychuk Date: Sun, 8 Dec 2013 10:50:57 -0800 Subject: [PATCH] simplify body parsing example for the average use-case --- body-parsing/app.js | 63 +++++-------------------------- body-parsing/test.js | 88 +++++++------------------------------------- package.json | 3 +- 3 files changed, 26 insertions(+), 128 deletions(-) diff --git a/body-parsing/app.js b/body-parsing/app.js index cbcd791..dcf4803 100644 --- a/body-parsing/app.js +++ b/body-parsing/app.js @@ -1,62 +1,19 @@ -/** - * Example for handling JSON and urlencoded request bodies. - * All the throws at the beginning of the middleware are all app-dependent and may not be suited for your use-case. - * For the actual body parsing (yield rawBody and down), - * you most may be interested in modules that already do this for you: - * - * - [body](https://github.com/raynos/body) - * - [co-body](https://github.com/visionmedia/co-body) - */ var koa = require('koa'); var qs = require('querystring'); -var rawBody = require('raw-body'); +var parse = require('co-body'); var app = module.exports = koa(); -// only json requests +// POST .name to /uppercase +// co-body accepts application/json +// and application/x-www-form-urlencoded + app.use(function *(next){ - if (this.path !== '/json') return yield next; - if (this.length == 0) this.throw(400, 'no request body'); - if (this.length == null) this.throw(411, 'content length required'); - if (!this.is('application/json')) this.throw(415, 'json bodies only'); - - var body = yield rawBody(this.req, { - length: this.length, - limit: 25, // bytes - encoding: 'utf8' - }); - - body = body.trim(); - if (body[0] != '{') this.throw(400, 'request body must be a JSON object'); - - try { - this.body = JSON.parse(body); - } catch (err) { - err.status = 400; - throw err; - } -}) - -// only urlencoded requests -app.use(function *(next){ - if (this.path !== '/urlencoded') return yield next; - if (this.length == 0) this.throw(400, 'no request body'); - if (this.length == null) this.throw(411, 'content length required'); - if (!this.is('application/x-www-form-urlencoded')) this.throw(415, 'urlencoded bodies only'); - - var body = yield rawBody(this.req, { - length: this.length, - limit: 25, // bytes - encoding: 'utf8' - }); - - try { - this.body = qs.parse(body); - } catch (err) { - err.status = 400; - throw err; - } -}) + if ('POST' != this.method) return yield next; + var body = yield parse(this, { limit: '1kb' }); + if (!body.name) this.throw(400, '.name required'); + this.body = { name: body.name.toUpperCase() }; +}); if (!module.parent) app.listen(3000); diff --git a/body-parsing/test.js b/body-parsing/test.js index 376f608..18f2911 100644 --- a/body-parsing/test.js +++ b/body-parsing/test.js @@ -2,95 +2,35 @@ var app = require('./app'); var request = require('supertest').agent(app.listen()); describe('Body Parsing', function(){ - describe('/json', function(){ - describe('when POSTing JSON', function(){ - it('should return a JSON body', function(done){ + describe('POST /uppercase', function(){ + describe('with JSON', function(){ + it('should work', function(done){ request - .post('/json') - .send({ - message: 'hello' - }) + .post('/uppercase') + .send({ name: 'tobi' }) .expect(200) - .expect(/"message": "hello"/, done); + .expect({ name: 'TOBI' }, done); }) }) - describe('when POSTing urlencoded', function(){ - it('should 415', function(done){ + describe('with urlencoded', function(){ + it('should work', function(done){ request - .post('/json') - .send('message=hello') - .expect(415, done); + .post('/uppercase') + .send('name=tj') + .expect(200) + .expect({ name: 'TJ' }, done); }) }) - describe('when POSTing a JSON primitive', function(){ - it('should 400', function(done){ - request - .post('/json') - .send(JSON.stringify(null)) - .set('Content-Type', 'application/json') - .expect(400, done); - }) - }) - describe('when POSTing with length > limit', function(){ + describe('when length > limit', function(){ it('should 413', function(done){ request .post('/json') - .send({ - some_really_long_string: Math.random() - }) + .send({ name: Array(5000).join('a') }) .expect(413, done); }) }) - - describe('when POSTing an empty body', function(){ - it('should 411', function(done){ - request - .post('/json') - .expect(411, done); - }) - }) - }) - - describe('/urlencoded', function(){ - describe('when POSTing urlencoded', function(){ - it('should return a JSON body', function(done){ - request - .post('/urlencoded') - .send('message=hello') - .expect(200) - .expect(/"message": "hello"/, done); - }) - }) - - describe('when POSTing JSON', function(){ - it('should 415', function(done){ - request - .post('/urlencoded') - .send({ - message: 'hello' - }) - .expect(415, done); - }) - }) - - describe('when POSTing with length > limit', function(){ - it('should 413', function(done){ - request - .post('/urlencoded') - .send('some_really_long_string=' + Math.random()) - .expect(413, done); - }) - }) - - describe('when POSTing an empty body', function(){ - it('should 411', function(done){ - request - .post('/urlencoded') - .expect(411, done); - }) - }) }) }) \ No newline at end of file diff --git a/package.json b/package.json index f014d6e..8dbb921 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ "co-busboy": "cojs/busboy", "save-to": "~1.0.0", "raw-body": "~1.1.1", - "co-fs": "~1.1.1" + "co-fs": "~1.1.1", + "co-body": "0.0.1" }, "devDependencies": { "co": "*",