diff --git a/src/node/index.js b/src/node/index.js index bfb01aa73..468da2c88 100644 --- a/src/node/index.js +++ b/src/node/index.js @@ -1066,7 +1066,7 @@ Request.prototype._end = function () { const form = formidable(); parser = form.parse.bind(form); buffer = true; - } else if (isImageOrVideo(mime)) { + } else if (isBinary(mime)) { parser = exports.parse.image; buffer = true; // For backwards-compatibility buffering default is ad-hoc MIME-dependent } else if (exports.parse[mime]) { @@ -1074,7 +1074,6 @@ Request.prototype._end = function () { } else if (type === 'text') { parser = exports.parse.text; buffer = buffer !== false; - // everyone wants their own white-labeled json } else if (isJSON(mime)) { parser = exports.parse['application/json']; @@ -1345,11 +1344,22 @@ function isText(mime) { return type === 'text' || subtype === 'x-www-form-urlencoded'; } -function isImageOrVideo(mime) { - let type = mime.split('/')[0]; - if (type) type = type.toLowerCase().trim(); - - return type === 'image' || type === 'video'; +// This is not a catchall, but a start. It might be useful +// in the long run to have file that includes all binary +// content types from https://www.iana.org/assignments/media-types/media-types.xhtml +function isBinary(mime) { + let [ registry, name ] = mime.split('/'); + if (registry) registry = registry.toLowerCase().trim(); + if (name) name = name.toLowerCase().trim(); + return [ + 'audio', + 'font', + 'image', + 'video' + ].includes(registry) || [ + 'gz', + 'gzip', + ].includes(name); } /** diff --git a/src/node/parsers/index.js b/src/node/parsers/index.js index 08c9b95c0..7fb67af31 100644 --- a/src/node/parsers/index.js +++ b/src/node/parsers/index.js @@ -1,6 +1,7 @@ exports['application/x-www-form-urlencoded'] = require('./urlencoded'); exports['application/json'] = require('./json'); exports.text = require('./text'); +exports['application/json-seq'] = exports.text; const binary = require('./image'); diff --git a/test/node/exports.js b/test/node/exports.js index 37a954b44..62c5230ae 100644 --- a/test/node/exports.js +++ b/test/node/exports.js @@ -18,6 +18,7 @@ describe('exports', () => { 'application/x-www-form-urlencoded', 'application/json', 'text', + 'application/json-seq', 'application/octet-stream', 'application/pdf', 'image' diff --git a/test/node/fixtures/test.aac b/test/node/fixtures/test.aac new file mode 100644 index 000000000..8b91d23e7 Binary files /dev/null and b/test/node/fixtures/test.aac differ diff --git a/test/request.js b/test/request.js index 29f10dffd..e57e58cd7 100644 --- a/test/request.js +++ b/test/request.js @@ -1,7 +1,10 @@ +const fs = require('fs'); + const assert = require('assert'); const getSetup = require('./support/setup'); const request = require('./support/client'); +const binData = fs.readFileSync(`${__dirname}/node/fixtures/test.aac`); describe('request', function () { let setup; @@ -630,6 +633,21 @@ describe('request', function () { }); }); + it('GET binary data', (next) => { + request + .get(`${uri}/binary-data`) + .buffer() + .end((error, res) => { + try { + assert.ifError(error); + assert.deepEqual(res.body, binData); + next(); + } catch (err) { + next(err); + } + }); + }); + it('GET x-www-form-urlencoded', (next) => { request.get(`${uri}/foo`).end((error, res) => { try { diff --git a/test/support/server.js b/test/support/server.js index 39e402999..1e5d3dda0 100644 --- a/test/support/server.js +++ b/test/support/server.js @@ -1,4 +1,5 @@ const fs = require('fs'); +const path = require('path'); let http = require('http'); const multer = require('multer'); const bodyParser = require('body-parser'); @@ -502,6 +503,12 @@ app.get('/image-as-octets', (request, res) => { serveImageWithType(res, 'application/octet-stream'); }); +app.get('/binary-data', (request, res) => { + const binData = fs.readFileSync(`${__dirname}/../node/fixtures/test.aac`); + res.writeHead(200, { 'Content-type': 'audio/aac' }); + res.end(binData, 'binary') +}); + app.get('/chunked-json', (request, res) => { res.set('content-type', 'application/json'); res.set('Transfer-Encoding', 'chunked');