Skip to content

Commit 9871e65

Browse files
committed
refactor: optimize internal read function
1 parent 5d691ff commit 9871e65

File tree

1 file changed

+41
-67
lines changed

1 file changed

+41
-67
lines changed

lib/read.js

Lines changed: 41 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -64,61 +64,68 @@ function read (req, res, next, parse, debug, options) {
6464
return
6565
}
6666

67-
var encoding = null
67+
var charset = null
6868
if (options?.skipCharset !== true) {
69-
encoding = getCharset(req) || options.defaultCharset
69+
charset = getCharset(req) || options.defaultCharset
7070

7171
// validate charset
72-
if (!!options?.isValidCharset && !options.isValidCharset(encoding)) {
72+
if (!!options?.isValidCharset && !options.isValidCharset(charset)) {
7373
debug('invalid charset')
74-
next(createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', {
75-
charset: encoding,
74+
next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', {
75+
charset,
7676
type: 'charset.unsupported'
7777
}))
7878
return
7979
}
8080
}
8181

82-
var length
83-
var opts = options
84-
var stream
82+
// get the content stream
83+
const contentEncoding = (req.headers['content-encoding'] || 'identity').toLowerCase()
84+
debug('content-encoding "%s"', contentEncoding)
8585

86-
// read options
87-
var verify = opts.verify
88-
89-
try {
90-
// get the content stream
91-
stream = contentstream(req, debug, opts.inflate)
92-
length = stream.length
93-
stream.length = undefined
94-
} catch (err) {
95-
return next(err)
86+
if (options.inflate === false && contentEncoding !== 'identity') {
87+
return next(createError(415, 'content encoding unsupported', {
88+
encoding: contentEncoding,
89+
type: 'encoding.unsupported'
90+
}))
9691
}
9792

98-
// set raw-body options
99-
opts.length = length
100-
opts.encoding = verify
101-
? null
102-
: encoding
93+
let stream
94+
if (contentEncoding === 'identity') {
95+
// set raw-body expected length
96+
stream = req
97+
options.length = req.headers['content-length']
98+
} else {
99+
try {
100+
stream = createDecompressionStream(contentEncoding, debug)
101+
req.pipe(stream)
102+
options.length = undefined
103+
} catch (err) {
104+
return next(err)
105+
}
106+
}
103107

104108
// assert charset is supported
105-
if (opts.encoding === null && encoding !== null && !iconv.encodingExists(encoding)) {
106-
return next(createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', {
107-
charset: encoding.toLowerCase(),
109+
if (options.verify && charset !== null && !iconv.encodingExists(charset)) {
110+
return next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', {
111+
charset: charset.toLowerCase(),
108112
type: 'charset.unsupported'
109113
}))
110114
}
111115

116+
// set raw-body encoding
117+
options.encoding = options.verify ? null : charset
118+
112119
// read body
113120
debug('read body')
114-
getBody(stream, opts, function (error, body) {
121+
getBody(stream, options, function (error, body) {
115122
if (error) {
116123
var _error
117124

118125
if (error.type === 'encoding.unsupported') {
119126
// echo back charset
120-
_error = createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', {
121-
charset: encoding.toLowerCase(),
127+
_error = createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', {
128+
charset: charset.toLowerCase(),
122129
type: 'charset.unsupported'
123130
})
124131
} else {
@@ -140,10 +147,10 @@ function read (req, res, next, parse, debug, options) {
140147
}
141148

142149
// verify
143-
if (verify) {
150+
if (options.verify) {
144151
try {
145152
debug('verify body')
146-
verify(req, res, body, encoding)
153+
options.verify(req, res, body, charset)
147154
} catch (err) {
148155
next(createError(403, err, {
149156
body: body,
@@ -157,10 +164,10 @@ function read (req, res, next, parse, debug, options) {
157164
var str = body
158165
try {
159166
debug('parse body')
160-
str = typeof body !== 'string' && encoding !== null
161-
? iconv.decode(body, encoding)
167+
str = typeof body !== 'string' && charset !== null
168+
? iconv.decode(body, charset)
162169
: body
163-
req.body = parse(str, encoding)
170+
req.body = parse(str, charset)
164171
} catch (err) {
165172
next(createError(400, err, {
166173
body: str,
@@ -173,39 +180,6 @@ function read (req, res, next, parse, debug, options) {
173180
})
174181
}
175182

176-
/**
177-
* Get the content stream of the request.
178-
*
179-
* @param {object} req
180-
* @param {function} debug
181-
* @param {boolean} [inflate=true]
182-
* @return {object}
183-
* @api private
184-
*/
185-
186-
function contentstream (req, debug, inflate) {
187-
var encoding = (req.headers['content-encoding'] || 'identity').toLowerCase()
188-
var length = req.headers['content-length']
189-
190-
debug('content-encoding "%s"', encoding)
191-
192-
if (inflate === false && encoding !== 'identity') {
193-
throw createError(415, 'content encoding unsupported', {
194-
encoding: encoding,
195-
type: 'encoding.unsupported'
196-
})
197-
}
198-
199-
if (encoding === 'identity') {
200-
req.length = length
201-
return req
202-
}
203-
204-
var stream = createDecompressionStream(encoding, debug)
205-
req.pipe(stream)
206-
return stream
207-
}
208-
209183
/**
210184
* Create a decompression stream for the given encoding.
211185
* @param {string} encoding

0 commit comments

Comments
 (0)