From 0d5f462a426145405e59f0476e359b4873c457b7 Mon Sep 17 00:00:00 2001 From: Phillip9587 Date: Sun, 16 Feb 2025 00:01:45 +0100 Subject: [PATCH] refactor: optimize internal read function --- lib/read.js | 103 +++++++++++++++------------------------- lib/types/json.js | 2 +- lib/types/raw.js | 2 +- lib/types/text.js | 2 +- lib/types/urlencoded.js | 2 +- 5 files changed, 42 insertions(+), 69 deletions(-) diff --git a/lib/read.js b/lib/read.js index eee8b111..69ab3875 100644 --- a/lib/read.js +++ b/lib/read.js @@ -36,49 +36,55 @@ module.exports = read */ function read (req, res, next, parse, debug, options) { - var length - var opts = options - var stream - // read options - var encoding = opts.encoding !== null - ? opts.encoding - : null - var verify = opts.verify - - try { - // get the content stream - stream = contentstream(req, debug, opts.inflate) - length = stream.length - stream.length = undefined - } catch (err) { - return next(err) + const charset = options.charset + + // get the content stream + const contentEncoding = (req.headers['content-encoding'] || 'identity').toLowerCase() + debug('content-encoding "%s"', contentEncoding) + + if (options.inflate === false && contentEncoding !== 'identity') { + return next(createError(415, 'content encoding unsupported', { + encoding: contentEncoding, + type: 'encoding.unsupported' + })) } - // set raw-body options - opts.length = length - opts.encoding = verify - ? null - : encoding + let stream + if (contentEncoding === 'identity') { + // set raw-body expected length + stream = req + options.length = req.headers['content-length'] + } else { + try { + stream = createDecompressionStream(contentEncoding, debug) + req.pipe(stream) + } catch (err) { + return next(err) + } + } // assert charset is supported - if (opts.encoding === null && encoding !== null && !iconv.encodingExists(encoding)) { - return next(createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', { - charset: encoding.toLowerCase(), + if (options.verify && charset !== null && !iconv.encodingExists(charset)) { + return next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', { + charset: charset.toLowerCase(), type: 'charset.unsupported' })) } + // set raw-body encoding + options.encoding = options.verify ? null : charset + // read body debug('read body') - getBody(stream, opts, function (error, body) { + getBody(stream, options, function (error, body) { if (error) { var _error if (error.type === 'encoding.unsupported') { // echo back charset - _error = createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', { - charset: encoding.toLowerCase(), + _error = createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', { + charset: charset.toLowerCase(), type: 'charset.unsupported' }) } else { @@ -100,10 +106,10 @@ function read (req, res, next, parse, debug, options) { } // verify - if (verify) { + if (options.verify) { try { debug('verify body') - verify(req, res, body, encoding) + options.verify(req, res, body, charset) } catch (err) { next(createError(403, err, { body: body, @@ -117,10 +123,10 @@ function read (req, res, next, parse, debug, options) { var str = body try { debug('parse body') - str = typeof body !== 'string' && encoding !== null - ? iconv.decode(body, encoding) + str = typeof body !== 'string' && charset !== null + ? iconv.decode(body, charset) : body - req.body = parse(str, encoding) + req.body = parse(str, charset) } catch (err) { next(createError(400, err, { body: str, @@ -133,39 +139,6 @@ function read (req, res, next, parse, debug, options) { }) } -/** - * Get the content stream of the request. - * - * @param {object} req - * @param {function} debug - * @param {boolean} [inflate=true] - * @return {object} - * @api private - */ - -function contentstream (req, debug, inflate) { - var encoding = (req.headers['content-encoding'] || 'identity').toLowerCase() - var length = req.headers['content-length'] - - debug('content-encoding "%s"', encoding) - - if (inflate === false && encoding !== 'identity') { - throw createError(415, 'content encoding unsupported', { - encoding: encoding, - type: 'encoding.unsupported' - }) - } - - if (encoding === 'identity') { - req.length = length - return req - } - - var stream = createDecompressionStream(encoding, debug) - req.pipe(stream) - return stream -} - /** * Create a decompression stream for the given encoding. * @param {string} encoding diff --git a/lib/types/json.js b/lib/types/json.js index 078ce710..07d0fb6f 100644 --- a/lib/types/json.js +++ b/lib/types/json.js @@ -123,7 +123,7 @@ function json (options) { // read read(req, res, next, parse, debug, { - encoding: charset, + charset, inflate, limit, verify diff --git a/lib/types/raw.js b/lib/types/raw.js index 3788ff27..74aff21c 100644 --- a/lib/types/raw.js +++ b/lib/types/raw.js @@ -66,7 +66,7 @@ function raw (options) { // read read(req, res, next, parse, debug, { - encoding: null, + charset: null, inflate, limit, verify diff --git a/lib/types/text.js b/lib/types/text.js index 3e0ab1bb..c6811a9a 100644 --- a/lib/types/text.js +++ b/lib/types/text.js @@ -71,7 +71,7 @@ function text (options) { // read read(req, res, next, parse, debug, { - encoding: charset, + charset, inflate, limit, verify diff --git a/lib/types/urlencoded.js b/lib/types/urlencoded.js index f993425e..cff9aecf 100644 --- a/lib/types/urlencoded.js +++ b/lib/types/urlencoded.js @@ -91,7 +91,7 @@ function urlencoded (options) { // read read(req, res, next, parse, debug, { - encoding: charset, + charset, inflate, limit, verify