source: node_modules/body-parser/lib/read.js

main
Last change on this file was d24f17c, checked in by Aleksandar Panovski <apano77@…>, 15 months ago

Initial commit

  • Property mode set to 100644
File size: 4.2 KB
RevLine 
[d24f17c]1/*!
2 * body-parser
3 * Copyright(c) 2014-2015 Douglas Christopher Wilson
4 * MIT Licensed
5 */
6
7'use strict'
8
9/**
10 * Module dependencies.
11 * @private
12 */
13
14var createError = require('http-errors')
15var destroy = require('destroy')
16var getBody = require('raw-body')
17var iconv = require('iconv-lite')
18var onFinished = require('on-finished')
19var unpipe = require('unpipe')
20var zlib = require('zlib')
21
22/**
23 * Module exports.
24 */
25
26module.exports = read
27
28/**
29 * Read a request into a buffer and parse.
30 *
31 * @param {object} req
32 * @param {object} res
33 * @param {function} next
34 * @param {function} parse
35 * @param {function} debug
36 * @param {object} options
37 * @private
38 */
39
40function read (req, res, next, parse, debug, options) {
41 var length
42 var opts = options
43 var stream
44
45 // flag as parsed
46 req._body = true
47
48 // read options
49 var encoding = opts.encoding !== null
50 ? opts.encoding
51 : null
52 var verify = opts.verify
53
54 try {
55 // get the content stream
56 stream = contentstream(req, debug, opts.inflate)
57 length = stream.length
58 stream.length = undefined
59 } catch (err) {
60 return next(err)
61 }
62
63 // set raw-body options
64 opts.length = length
65 opts.encoding = verify
66 ? null
67 : encoding
68
69 // assert charset is supported
70 if (opts.encoding === null && encoding !== null && !iconv.encodingExists(encoding)) {
71 return next(createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', {
72 charset: encoding.toLowerCase(),
73 type: 'charset.unsupported'
74 }))
75 }
76
77 // read body
78 debug('read body')
79 getBody(stream, opts, function (error, body) {
80 if (error) {
81 var _error
82
83 if (error.type === 'encoding.unsupported') {
84 // echo back charset
85 _error = createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', {
86 charset: encoding.toLowerCase(),
87 type: 'charset.unsupported'
88 })
89 } else {
90 // set status code on error
91 _error = createError(400, error)
92 }
93
94 // unpipe from stream and destroy
95 if (stream !== req) {
96 unpipe(req)
97 destroy(stream, true)
98 }
99
100 // read off entire request
101 dump(req, function onfinished () {
102 next(createError(400, _error))
103 })
104 return
105 }
106
107 // verify
108 if (verify) {
109 try {
110 debug('verify body')
111 verify(req, res, body, encoding)
112 } catch (err) {
113 next(createError(403, err, {
114 body: body,
115 type: err.type || 'entity.verify.failed'
116 }))
117 return
118 }
119 }
120
121 // parse
122 var str = body
123 try {
124 debug('parse body')
125 str = typeof body !== 'string' && encoding !== null
126 ? iconv.decode(body, encoding)
127 : body
128 req.body = parse(str)
129 } catch (err) {
130 next(createError(400, err, {
131 body: str,
132 type: err.type || 'entity.parse.failed'
133 }))
134 return
135 }
136
137 next()
138 })
139}
140
141/**
142 * Get the content stream of the request.
143 *
144 * @param {object} req
145 * @param {function} debug
146 * @param {boolean} [inflate=true]
147 * @return {object}
148 * @api private
149 */
150
151function contentstream (req, debug, inflate) {
152 var encoding = (req.headers['content-encoding'] || 'identity').toLowerCase()
153 var length = req.headers['content-length']
154 var stream
155
156 debug('content-encoding "%s"', encoding)
157
158 if (inflate === false && encoding !== 'identity') {
159 throw createError(415, 'content encoding unsupported', {
160 encoding: encoding,
161 type: 'encoding.unsupported'
162 })
163 }
164
165 switch (encoding) {
166 case 'deflate':
167 stream = zlib.createInflate()
168 debug('inflate body')
169 req.pipe(stream)
170 break
171 case 'gzip':
172 stream = zlib.createGunzip()
173 debug('gunzip body')
174 req.pipe(stream)
175 break
176 case 'identity':
177 stream = req
178 stream.length = length
179 break
180 default:
181 throw createError(415, 'unsupported content encoding "' + encoding + '"', {
182 encoding: encoding,
183 type: 'encoding.unsupported'
184 })
185 }
186
187 return stream
188}
189
190/**
191 * Dump the contents of a request.
192 *
193 * @param {object} req
194 * @param {function} callback
195 * @api private
196 */
197
198function dump (req, callback) {
199 if (onFinished.isFinished(req)) {
200 callback(null)
201 } else {
202 onFinished(req, callback)
203 req.resume()
204 }
205}
Note: See TracBrowser for help on using the repository browser.