Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Avatar for KuCalc : devops.
Download
50650 views
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
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')
19
20
/**
21
* Module exports.
22
*/
23
24
module.exports = read
25
26
/**
27
* Read a request into a buffer and parse.
28
*
29
* @param {object} req
30
* @param {object} res
31
* @param {function} next
32
* @param {function} parse
33
* @param {function} debug
34
* @param {object} options
35
* @private
36
*/
37
38
function read (req, res, next, parse, debug, options) {
39
var length
40
var opts = options
41
var stream
42
43
// flag as parsed
44
req._body = true
45
46
// read options
47
var encoding = opts.encoding !== null
48
? opts.encoding
49
: null
50
var verify = opts.verify
51
52
try {
53
// get the content stream
54
stream = contentstream(req, debug, opts.inflate)
55
length = stream.length
56
stream.length = undefined
57
} catch (err) {
58
return next(err)
59
}
60
61
// set raw-body options
62
opts.length = length
63
opts.encoding = verify
64
? null
65
: encoding
66
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
}))
72
}
73
74
// read body
75
debug('read body')
76
getBody(stream, opts, function (err, body) {
77
if (err) {
78
// default to 400
79
setErrorStatus(err, 400)
80
81
// echo back charset
82
if (err.type === 'encoding.unsupported') {
83
err = createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', {
84
charset: encoding.toLowerCase()
85
})
86
}
87
88
// read off entire request
89
stream.resume()
90
onFinished(req, function onfinished () {
91
next(err)
92
})
93
return
94
}
95
96
// verify
97
if (verify) {
98
try {
99
debug('verify body')
100
verify(req, res, body, encoding)
101
} catch (err) {
102
// default to 403
103
setErrorStatus(err, 403)
104
next(err)
105
return
106
}
107
}
108
109
// parse
110
var str
111
try {
112
debug('parse body')
113
str = typeof body !== 'string' && encoding !== null
114
? iconv.decode(body, encoding)
115
: body
116
req.body = parse(str)
117
} catch (err) {
118
// istanbul ignore next
119
err.body = str === undefined
120
? body
121
: str
122
123
// default to 400
124
setErrorStatus(err, 400)
125
126
next(err)
127
return
128
}
129
130
next()
131
})
132
}
133
134
/**
135
* Get the content stream of the request.
136
*
137
* @param {object} req
138
* @param {function} debug
139
* @param {boolean} [inflate=true]
140
* @return {object}
141
* @api private
142
*/
143
144
function contentstream (req, debug, inflate) {
145
var encoding = (req.headers['content-encoding'] || 'identity').toLowerCase()
146
var length = req.headers['content-length']
147
var stream
148
149
debug('content-encoding "%s"', encoding)
150
151
if (inflate === false && encoding !== 'identity') {
152
throw createError(415, 'content encoding unsupported')
153
}
154
155
switch (encoding) {
156
case 'deflate':
157
stream = zlib.createInflate()
158
debug('inflate body')
159
req.pipe(stream)
160
break
161
case 'gzip':
162
stream = zlib.createGunzip()
163
debug('gunzip body')
164
req.pipe(stream)
165
break
166
case 'identity':
167
stream = req
168
stream.length = length
169
break
170
default:
171
throw createError(415, 'unsupported content encoding "' + encoding + '"', {
172
encoding: encoding
173
})
174
}
175
176
return stream
177
}
178
179
/**
180
* Set a status on an error object, if ones does not exist
181
* @private
182
*/
183
184
function setErrorStatus (error, status) {
185
if (!error.status && !error.statusCode) {
186
error.status = status
187
error.statusCode = status
188
}
189
}
190
191