mirror of
https://github.com/koajs/examples.git
synced 2026-01-18 14:38:19 +00:00
simplify body parsing example
for the average use-case
This commit is contained in:
parent
70df2fd232
commit
abeabcc268
@ -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);
|
||||
|
||||
@ -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);
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
@ -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": "*",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user