Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

koa-body-parser

Package Overview
Dependencies
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

koa-body-parser - npm Package Compare versions

Comparing version 0.0.1 to 0.1.0

239

index.js

@@ -1,205 +0,80 @@

var bytes = require('bytes')
var getRawBody = require('raw-body')
var zlib = require('zlib')
exports = module.exports = function (app) {
app.context(context)
module.exports = function (app, options) {
options = options || {}
app.__defineGetter__('bodyLimit', function () {
return this._bodyLimit || 0
})
var limit = options.limit || '1mb'
var strict = options.strict !== false
var reviver = options.reviver
var querystring = options.querystring || require('querystring')
app.__defineSetter__('bodyLimit', function (val) {
this._bodyLimit = parseBytes(val)
})
app.request.urlencoded = function* (lim) {
if (!this.is('application/x-www-form-urlencoded') || this.length === 0)
return
// Default urlencoded parser
app.urlencodedParser = require('querystring').parse
var str = yield* this.string(lim)
return app
}
var context = exports.context = {
// Check whether to allow unstrict JSON
// Does not allow strict JSON by default
get strictJSON() {
return firstBoolean([
this.app.strictJSON,
this._strictJSON,
true
])
},
set strictJSON(val) {
// Should always be boolean
this._strictJSON = !!val
},
// Check whether the request has a body
get hasBody() {
return !!(this.get('transfer-encoding') || this.length)
},
// Check the body limit
// "falsey" means no body limit
// contextual body limit takes precedence over app options
get bodyLimit() {
return this._bodyLimit
|| this.app.bodyLimit
|| 0
},
// Either a human readable string or a number
// this.bodyLimit = 1024 // 1kb
// this.bodyLimit = '1kb'
set bodyLimit(val) {
this._bodyLimit = parseBytes(val)
try {
return querystring.parse(str, options)
} catch (err) {
err.status = 400
throw err
}
}
}
/*
Parse the JSON body asynchronously.
Should be used like:
var form = yield this.parseJSON
@api public
*/
context.parseJSON = function (done) {
if (!this.hasBody || !this.is('json'))
return done()
var limit = this.checkLimit()
var ctx = this
var req = this.req
var strict = this.strictJSON
var received = 0
var buf = ''
req.setEncoding('utf8')
req.on('data', onData)
req.on('end', onEnd)
function onData(chunk) {
buf += chunk
if (!limit)
app.request.json = function* (lim) {
if (!this.is('json') || this.length === 0)
return
received += chunk.length
if (received <= limit)
return
var str = yield* this.string(lim)
str = str.trim()
// Received > limit, so we destroy the request
cleanup()
ctx.error(createError(413))
}
if (!str.length)
this.ctx.error(400, 'invalid json, empty body')
function onEnd() {
if (!buf.length) {
cleanup()
return ctx.error(createError(400, 'invalid json, empty body'))
if (strict !== false) {
var first = str[0]
if ('{' !== first && '[' !== first)
this.ctx.error(400, 'invalid json')
}
if (strict) {
var first = buf.trim()[0]
if ('{' !== first && '[' !== first) {
cleanup()
return ctx.error(createError(400, 'invalid json'))
}
try {
return JSON.parse(str, reviver)
} catch (err) {
err.status = 400
throw err
}
done(null, JSON.parse(buf, ctx.JSONReviver))
cleanup()
}
function cleanup() {
buf = received = null
req.removeListener('data', onData)
req.removeListener('end', onEnd)
app.request.string = function* (lim) {
var buffer = yield* this.buffer(lim)
return buffer.toString('utf8')
}
}
/*
app.request.buffer = function* (lim) {
var decoder
switch (this.get('content-encoding') || 'identity') {
case 'gzip':
decoder = zlib.createGunzip()
break
case 'deflate':
decoder = zlib.createInflate()
break
case 'identity':
break
default:
this.ctx.error(415, 'invalid content-encoding')
}
Parse the url encoded body asynchronously.
var stream = decoder
? this.req.pipe(decoder)
: this.req
var form = yield this.parseURLEncoded
@api public
*/
context.parseUrlencoded =
context.parseURLEncoded = function (done) {
if (!this.hasBody || !this.is('application/x-www-form-urlencoded'))
return done()
var limit = this.checkLimit()
var ctx = this
var req = this.req
var received = 0
var buf = ''
req.setEncoding('utf8')
req.on('data', onData)
req.on('end', onEnd)
function onData(chunk) {
buf += chunk
if (!limit)
return
received += chunk.length
if (received <= limit)
return
// Received > limit, so we destroy the request
cleanup()
ctx.error(createError(413))
return yield getRawBody(stream, {
limit: lim || limit
})
}
function onEnd() {
done(null, buf.length ? ctx.app.urlencodedParser(buf) : {})
cleanup()
}
function cleanup() {
buf = received = null
req.removeListener('data', onData)
req.removeListener('end', onEnd)
}
}
// Check the content-length and return the limit
context.checkLimit = function () {
var limit = this.bodyLimit
var contentLength = this.length
// Could be chunked response
if (contentLength) {
if (limit && contentLength > limit)
throw createError(413)
// We limit the body by the content-length
// in case they lie
limit = contentLength
}
return limit || 0
}
function parseBytes(val) {
if (typeof val === 'string')
val = bytes(val)
if (!val)
val = 0
if (typeof val !== 'number')
throw TypeError('this.bodyLimit must either be a string, number, or falsey value')
return val || 0
}
function firstBoolean(arr) {
for (var i = 0, l = arr.length; i < l; i++)
if (typeof arr[i] === 'boolean')
return arr[i]
}
function createError(status, message) {
var err = new Error(message || '')
err.status = status || 400
return err
return app
}
{
"name": "koa-body-parser",
"description": "Request body parser for koa",
"version": "0.0.1",
"version": "0.1.0",
"author": {

@@ -14,10 +14,10 @@ "name": "Jonathan Ong",

"type": "git",
"url": "https://github.com/jonathanong/koa-body-parser.git"
"url": "https://github.com/koajs/body-parser.git"
},
"bugs": {
"mail": "me@jongleberry.com",
"url": "https://github.com/jonathanong/koa-body-parser/issues"
"url": "https://github.com/koajs/body-parser/issues"
},
"dependencies": {
"bytes": "~0.2.1"
"raw-body": "~0.1.1"
},

@@ -28,6 +28,6 @@ "peerDependencies": {

"devDependencies": {
"koa": "*",
"mocha": "~1.12.0",
"should": "~1.2.2",
"supertest": "~0.7.1"
"koa": "koajs/koa",
"mocha": "*",
"should": "*",
"supertest": "*"
},

@@ -40,2 +40,2 @@ "scripts": {

}
}
}

@@ -1,19 +0,14 @@

# Koa Body Parser [![Build Status](https://travis-ci.org/jonathanong/koa-body-parser.png)](https://travis-ci.org/jonathanong/koa-body-parser)
# Koa Body Parser [![Build Status](https://travis-ci.org/koajs/body-parser.png)](https://travis-ci.org/koajs/body-parser)
Form and JSON body parser for Koa.
This purposely does not support multipart request bodies.
It also supports request body limits.
JSON and urlencoded body parser for Koa.
This does not support multipart request bodies.
It supports request body limits and encoded request bodies.
## Example
## Installation
```js
app.use(function (next) {
return function* () {
var body = (yield this.parseJSON) || (yield this.parseUrlencoded)
// do stuff with your body
}
})
```bash
$ npm install koa-body-parser
```
## API
## Example

@@ -25,48 +20,98 @@ ```js

var app = koa()
bodyParser(app)
bodyParser(app, {
limit: '100kb'
})
// Buffer an image upload
app.use(function* () {
if (this.path !== '/images' || this.method !== 'POST')
return yield next
if (!this.is('image/'))
this.error(415, 'must be an image')
var imageBuffer = yield* this.request.buffer('25mb')
})
// Parse a form
app.use(function* () {
var body = (yield* this.request.json())
|| (yield* this.request.form())
// do stuff with your body
})
```
### yield this.parseJSON
## Philosophy
Parses the JSON body.
If you're a masochist, you can also use a callback:
This module aims to create helpful utilities while being as unopinionated as possible.
Thus, these methods may be a little inconvenient, especially when they're only available on `this.request`.
You may want to create your own helper or middleware to parse the body the way you like.
Here is an example:
```js
this.parseJSON(function (err, body) {
function* bodyParser() {
if (this.req.checkContinue)
this.req.writeContinue()
var body = (yield* this.request.urlencoded())
|| (yield* this.request.json())
if (!body)
this.error(400, 'no body!?')
return body
}
app.use(function* (next) {
if (this.path !== '/posts' || this.method !== 'POST')
return yield next
var body = yield* bodyParser()
})
```
### yield this.parseUrlencoded
Of course, there are many ways to do this!
Parses the urlencoded body.
Same signature as `this.parseJSON`
## API
### app.strictJSON, this.strictJSON
### bodyParser(app, [options])
By default, JSON must be strict.
You may override the default behavior by doing `app.strictJSON = false` or `this.strictJSON = false`.
`this.strictJSON` takes precedent over `app.strictJSON`.
Buffer options:
### app.bodyLimit, this.bodyLimit
- `limit` [1mb] - request body byte limit.
Sets the request body limit.
By default, there is no limit.
You can either set it app wide, or context wide.
`this.bodyLimit` takes precence over `app.bodyLimit`.
JSON parsing options:
You can set it using numerical bytes like `app.bodyLimit = 5 * 1024 * 1024`, or you can set it in human readable form like `app.bodyLimit = '5mb'`.
- `strict` [true] - if `false`, anything `JSON.parse()` accepts will be parsed as JSON,
otherwise only objects and arrays will be accepted.
- `reviver` - used as the second `reviver` argument for `JSON.parse()`.
For example, you can set a app-wide limit of `100kb` by setting `app.bodyLimit = '1mb'`.
Then, perhaps for a route in which users upload an image, you can manually set the limit to `this.bodyLimit = '10mb'`.
Urlencoded options:
### app.urlencodedParser
- `querystring` [require('querystring')] - the querystring parser. Node's by default. If you want to use `qs`, set it as `require('qs')`.
- `maxKeys` [1000] - maximum number of keys. Passed to [querystring.parse](http://nodejs.org/api/querystring.html#querystring_querystring_parse_str_sep_eq_options)
By default, url encoded bodies are parsed using the native `querystring` module.
If you want to use your own parser, for example the `qs` library, you can overwrite this method.
### yield* this.request.json([limit])
```js
app.urlencodedParser = require('qs').parse
```
Parses the JSON body.
The function call is required.
`limit` is the optional limit in bytes integer for the body that overrides the default.
### yield* this.request.urlencoded([limit])
Parses the urlencoded body.
The function call is required.
`limit` is the optional limit in bytes integer for the body that overrides the default.
### yield* this.request.string([limit])
Buffers the response and returns a utf8 string.
The function call is required.
`limit` is the optional limit in bytes integer for the body that overrides the default.
### yields* this.request.buffer([limit])
Buffers the response and returns a raw `Buffer` instance.
The function call is required.
`limit` is the optional limit in bytes integer for the body that overrides the default.
## License

@@ -94,2 +139,2 @@

OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
THE SOFTWARE.

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc