3 * Copyright(c) 2014-2015 Douglas Christopher Wilson
10 * Module dependencies.
14 var createError = require('http-errors')
15 var getBody = require('raw-body')
16 var iconv = require('iconv-lite')
17 var onFinished = require('on-finished')
18 var zlib = require('zlib')
27 * Read a request into a buffer and parse.
31 * @param {function} next
32 * @param {function} parse
33 * @param {function} debug
34 * @param {object} options
38 function read (req, res, next, parse, debug, options) {
47 var encoding = opts.encoding !== null
50 var verify = opts.verify
53 // get the content stream
54 stream = contentstream(req, debug, opts.inflate)
55 length = stream.length
56 stream.length = undefined
61 // set raw-body options
63 opts.encoding = verify
67 // assert charset is supported
68 if (opts.encoding === null && encoding !== null && !iconv.encodingExists(encoding)) {
69 return next(createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', {
70 charset: encoding.toLowerCase(),
71 type: 'charset.unsupported'
77 getBody(stream, opts, function (error, body) {
81 if (error.type === 'encoding.unsupported') {
83 _error = createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', {
84 charset: encoding.toLowerCase(),
85 type: 'charset.unsupported'
88 // set status code on error
89 _error = createError(400, error)
92 // read off entire request
94 onFinished(req, function onfinished () {
95 next(createError(400, _error))
104 verify(req, res, body, encoding)
106 next(createError(403, err, {
108 type: err.type || 'entity.verify.failed'
118 str = typeof body !== 'string' && encoding !== null
119 ? iconv.decode(body, encoding)
121 req.body = parse(str)
123 next(createError(400, err, {
125 type: err.type || 'entity.parse.failed'
135 * Get the content stream of the request.
137 * @param {object} req
138 * @param {function} debug
139 * @param {boolean} [inflate=true]
144 function contentstream (req, debug, inflate) {
145 var encoding = (req.headers['content-encoding'] || 'identity').toLowerCase()
146 var length = req.headers['content-length']
149 debug('content-encoding "%s"', encoding)
151 if (inflate === false && encoding !== 'identity') {
152 throw createError(415, 'content encoding unsupported', {
154 type: 'encoding.unsupported'
160 stream = zlib.createInflate()
161 debug('inflate body')
165 stream = zlib.createGunzip()
171 stream.length = length
174 throw createError(415, 'unsupported content encoding "' + encoding + '"', {
176 type: 'encoding.unsupported'