diff --git a/index.js b/index.js index c4b4c6df..d879cf22 100644 --- a/index.js +++ b/index.js @@ -63,9 +63,11 @@ module.exports = fp(function from (fastify, opts, next) { if (this.request.body instanceof Stream) { body = this.request.body } else { - body = JSON.stringify(this.request.body) + // Per RFC 7231 ยง3.1.1.5 if this header is not present we MAY assume application/octet-stream + const contentType = req.headers['content-type'] || 'application/octet-stream' + body = contentType.toLowerCase() === 'application/json' ? JSON.stringify(this.request.body) : this.request.body headers['content-length'] = Buffer.byteLength(body) - headers['content-type'] = 'application/json' + headers['content-type'] = contentType } } diff --git a/test/post-plain-text.js b/test/post-plain-text.js new file mode 100644 index 00000000..0220505a --- /dev/null +++ b/test/post-plain-text.js @@ -0,0 +1,56 @@ +'use strict' + +const t = require('tap') +const Fastify = require('fastify') +const From = require('..') +const http = require('http') +const get = require('simple-get').concat + +const instance = Fastify() +instance.register(From) + +t.plan(9) +t.tearDown(instance.close.bind(instance)) + +const target = http.createServer((req, res) => { + t.pass('request proxied') + t.equal(req.method, 'POST') + t.equal(req.headers['content-type'], 'text/plain') + var data = '' + req.setEncoding('utf8') + req.on('data', (d) => { + data += d + }) + req.on('end', () => { + const str = data.toString() + t.deepEqual(str, 'this is plain text') + res.statusCode = 200 + res.setHeader('content-type', 'text/plain') + res.end(str) + }) +}) + +instance.post('/', (request, reply) => { + reply.from(`http://localhost:${target.address().port}`) +}) + +t.tearDown(target.close.bind(target)) + +instance.listen(0, (err) => { + t.error(err) + + target.listen(0, (err) => { + t.error(err) + + get({ + url: `http://localhost:${instance.server.address().port}`, + method: 'POST', + headers: { 'content-type': 'text/plain' }, + body: 'this is plain text' + }, (err, res, data) => { + t.error(err) + t.equal(res.headers['content-type'], 'text/plain') + t.deepEqual(data.toString(), 'this is plain text') + }) + }) +})