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) {
40 var opts = options || {}
47 var encoding = opts.encoding !== null
48 ? opts.encoding || 'utf-8'
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()
76 getBody(stream, opts, function (err, body) {
79 setErrorStatus(err, 400)
82 if (err.type === 'encoding.unsupported') {
83 err = createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', {
84 charset: encoding.toLowerCase()
88 // read off entire request
90 onFinished(req, function onfinished() {
100 verify(req, res, body, encoding)
103 setErrorStatus(err, 403)
113 str = typeof body !== 'string' && encoding !== null
114 ? iconv.decode(body, encoding)
116 req.body = parse(str)
118 err.body = str === undefined
123 setErrorStatus(err, 400)
134 * Get the content stream of the request.
136 * @param {object} req
137 * @param {function} debug
138 * @param {boolean} [inflate=true]
143 function contentstream(req, debug, inflate) {
144 var encoding = (req.headers['content-encoding'] || 'identity').toLowerCase()
145 var length = req.headers['content-length']
148 debug('content-encoding "%s"', encoding)
150 if (inflate === false && encoding !== 'identity') {
151 throw createError(415, 'content encoding unsupported')
156 stream = zlib.createInflate()
157 debug('inflate body')
161 stream = zlib.createGunzip()
167 stream.length = length
170 throw createError(415, 'unsupported content encoding "' + encoding + '"', {
179 * Set a status on an error object, if ones does not exist
183 function setErrorStatus(error, status) {
184 if (!error.status && !error.statusCode) {
185 error.status = status
186 error.statusCode = status