From 06f3fc839a8c82d7c2c8b9c7ad12d622a62b2e32 Mon Sep 17 00:00:00 2001 From: Alex Liu Date: Fri, 8 Jun 2018 00:23:08 -0700 Subject: [PATCH] chore: lift json regex to top of file (#1670) --- lib/plugins/bodyParser.js | 19 +++++++++++++------ lib/plugins/jsonBodyParser.js | 14 +++++++++----- lib/plugins/utils/regex.js | 5 +++++ 3 files changed, 27 insertions(+), 11 deletions(-) create mode 100644 lib/plugins/utils/regex.js diff --git a/lib/plugins/bodyParser.js b/lib/plugins/bodyParser.js index e42331fed..aaf4d5fac 100644 --- a/lib/plugins/bodyParser.js +++ b/lib/plugins/bodyParser.js @@ -10,6 +10,7 @@ var jsonParser = require('./jsonBodyParser'); var formParser = require('./formBodyParser'); var multipartParser = require('./multipartBodyParser'); var fieldedTextParser = require('./fieldedTextBodyParser.js'); +var regex = require('./utils/regex'); ///--- Globals @@ -162,12 +163,6 @@ function bodyParser(options) { var parser; var type = req.contentType().toLowerCase(); - var jsonPatternMatcher = new RegExp('^application/[a-zA-Z.]+\\+json'); - // map any +json to application/json - if (jsonPatternMatcher.test(type)) { - type = 'application/json'; - } - switch (type) { case 'application/json': parser = parseJson[0]; @@ -192,6 +187,18 @@ function bodyParser(options) { break; } + // if we find no matches from the direct string comparisons, perform + // more expensive regex matches. map any +json to application/json. + // theoretically these could be mapped to application/json prior to the + // switch statement, but putting it here allows us to skip the regex + // entirely unless absolutely necessary. additional types could be + // added later at some point. + if (!parser) { + if (regex.jsonContentType.test(type)) { + parser = parseJson[0]; + } + } + if (parser) { parser(req, res, next); } else if (opts && opts.rejectUnknown) { diff --git a/lib/plugins/jsonBodyParser.js b/lib/plugins/jsonBodyParser.js index 97b20eaed..ebc7f8a8b 100644 --- a/lib/plugins/jsonBodyParser.js +++ b/lib/plugins/jsonBodyParser.js @@ -6,6 +6,7 @@ var assert = require('assert-plus'); var errors = require('restify-errors'); var bodyReader = require('./bodyReader'); +var regex = require('./utils/regex'); ///--- API @@ -28,13 +29,16 @@ function jsonBodyParser(options) { // save original body on req.rawBody and req._body req.rawBody = req._body = req.body; - var jsonPatternMatcher = new RegExp('^application/[a-zA-Z.]+\\+json'); var contentType = req.getContentType(); - if (contentType !== 'application/json' || !req.body) { - if (!jsonPatternMatcher.test(contentType)) { - return next(); - } + // check for empty body first, don't pay regex tax unless necessary. + // for content type, check for exact match and any of the *+json types + if ( + !req.body || + (contentType !== 'application/json' && + !regex.jsonContentType.test(contentType)) + ) { + return next(); } var params; diff --git a/lib/plugins/utils/regex.js b/lib/plugins/utils/regex.js new file mode 100644 index 000000000..13aa439b7 --- /dev/null +++ b/lib/plugins/utils/regex.js @@ -0,0 +1,5 @@ +'use strict'; + +module.exports = { + jsonContentType: new RegExp('^application/[a-zA-Z.]+\\+json') +};