diff --git a/lib/contentTypeParser.js b/lib/contentTypeParser.js index a01c866dd1..474eb5bfc6 100644 --- a/lib/contentTypeParser.js +++ b/lib/contentTypeParser.js @@ -67,9 +67,7 @@ ContentTypeParser.prototype.add = function (contentType, opts, parserFn) { this.customParsers[''] = parser } else { if (contentTypeIsString) { - if (contentType !== 'application/json' && contentType !== 'text/plain') { - this.parserList.unshift(contentType) - } + this.parserList.unshift(contentType) } else { this.parserRegExpList.unshift(contentType) } @@ -83,10 +81,10 @@ ContentTypeParser.prototype.hasParser = function (contentType) { ContentTypeParser.prototype.existingParser = function (contentType) { if (contentType === 'application/json') { - return this.customParsers['application/json'].fn !== this[kDefaultJsonParse] + return this.customParsers['application/json'] && this.customParsers['application/json'].fn !== this[kDefaultJsonParse] } if (contentType === 'text/plain') { - return this.customParsers['text/plain'].fn !== defaultPlainTextParser + return this.customParsers['text/plain'] && this.customParsers['text/plain'].fn !== defaultPlainTextParser } return contentType in this.customParsers diff --git a/test/custom-parser.test.js b/test/custom-parser.test.js index a7b467b21d..e85f3a71e7 100644 --- a/test/custom-parser.test.js +++ b/test/custom-parser.test.js @@ -1707,3 +1707,114 @@ test('cannot remove content type parsers after binding', t => { t.throws(() => fastify.removeContentTypeParser('application/json')) }) }) + +test('should be able to override the default json parser after removeAllContentTypeParsers', t => { + t.plan(5) + + const fastify = Fastify() + + fastify.post('/', (req, reply) => { + reply.send(req.body) + }) + + fastify.removeAllContentTypeParsers() + + fastify.addContentTypeParser('application/json', function (req, payload, done) { + t.ok('called') + jsonParser(payload, function (err, body) { + done(err, body) + }) + }) + + fastify.listen(0, err => { + t.error(err) + + sget({ + method: 'POST', + url: 'http://localhost:' + fastify.server.address().port, + body: '{"hello":"world"}', + headers: { + 'Content-Type': 'application/json' + } + }, (err, response, body) => { + t.error(err) + t.equal(response.statusCode, 200) + t.same(body.toString(), JSON.stringify({ hello: 'world' })) + fastify.close() + }) + }) +}) + +test('should be able to override the default plain text parser after removeAllContentTypeParsers', t => { + t.plan(5) + + const fastify = Fastify() + + fastify.post('/', (req, reply) => { + reply.send(req.body) + }) + + fastify.removeAllContentTypeParsers() + + fastify.addContentTypeParser('text/plain', function (req, payload, done) { + t.ok('called') + plainTextParser(payload, function (err, body) { + done(err, body) + }) + }) + + fastify.listen(0, err => { + t.error(err) + + sget({ + method: 'POST', + url: 'http://localhost:' + fastify.server.address().port, + body: 'hello world', + headers: { + 'Content-Type': 'text/plain' + } + }, (err, response, body) => { + t.error(err) + t.equal(response.statusCode, 200) + t.equal(body.toString(), 'hello world') + fastify.close() + }) + }) +}) + +test('should be able to add a custom content type parser after removeAllContentTypeParsers', t => { + t.plan(5) + + const fastify = Fastify() + + fastify.post('/', (req, reply) => { + reply.send(req.body) + }) + + fastify.removeAllContentTypeParsers() + + fastify.addContentTypeParser('application/jsoff', function (req, payload, done) { + t.ok('called') + jsonParser(payload, function (err, body) { + done(err, body) + }) + }) + + fastify.listen(0, err => { + t.error(err) + + sget({ + method: 'POST', + url: 'http://localhost:' + fastify.server.address().port, + body: '{"hello":"world"}', + headers: { + 'Content-Type': 'application/jsoff' + } + }, (err, response, body) => { + t.error(err) + t.equal(response.statusCode, 200) + t.same(body.toString(), JSON.stringify({ hello: 'world' })) + fastify.close() + }) + }) +})