From b6223f598c100ffad94c96c527286076ed560342 Mon Sep 17 00:00:00 2001 From: Florent Vilmart Date: Tue, 23 Feb 2016 08:17:48 -0500 Subject: [PATCH] Adds support for application/x-www-form-urlencoded - Now the body encoding is inferred on the headers as supposed --- spec/HTTPRequest.spec.js | 27 +++++++++++++++++++++++++++ src/httpRequest.js | 33 ++++++++++++++++++++++++++------- 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/spec/HTTPRequest.spec.js b/spec/HTTPRequest.spec.js index bf68fd7c..01efe42b 100644 --- a/spec/HTTPRequest.spec.js +++ b/spec/HTTPRequest.spec.js @@ -139,6 +139,9 @@ describe("httpRequest", () => { body: { foo: "bar" }, + headers: { + 'Content-Type': 'application/json' + }, success: function() { calls++; }, error: function() { calls++; } }).then(function(httpResponse){ @@ -150,5 +153,29 @@ describe("httpRequest", () => { fail("should not fail"); done(); }) + }); + it("should encode a JSON body", (done) => { + + var result = httpRequest.encodeBody({"foo": "bar"}, {'Content-Type': 'application/json'}); + expect(result).toEqual('{"foo":"bar"}'); + done(); + + }) + it("should encode a www-form body", (done) => { + + var result = httpRequest.encodeBody({"foo": "bar", "bar": "baz"}, {'cOntent-tYpe': 'application/x-www-form-urlencoded'}); + expect(result).toEqual("foo=bar&bar=baz"); + done(); + }); + it("should not encode a wrong content type", (done) => { + + var result = httpRequest.encodeBody({"foo": "bar", "bar": "baz"}, {'cOntent-tYpe': 'mime/jpeg'}); + expect(result).toEqual({"foo": "bar", "bar": "baz"}); + done(); + }); + it("should not encode when missing content type", (done) => { + var result = httpRequest.encodeBody({"foo": "bar", "bar": "baz"}, {'X-Custom-Header': 'my-header'}); + expect(result).toEqual({"foo": "bar", "bar": "baz"}); + done(); }) }); diff --git a/src/httpRequest.js b/src/httpRequest.js index 29912f12..2b5f9bff 100644 --- a/src/httpRequest.js +++ b/src/httpRequest.js @@ -1,6 +1,27 @@ var request = require("request"), Parse = require('parse/node').Parse; +var encodeBody = function(body, headers = {}) { + if (typeof body !== 'object') { + return body; + } + var contentTypeKeys = Object.keys(headers).filter((key) => { + return key.match(/content-type/i) != null; + }); + + if (contentTypeKeys.length == 1) { + var contentType = contentTypeKeys[0]; + if (headers[contentType].match(/application\/json/i)) { + body = JSON.stringify(body); + } else if(headers[contentType].match(/application\/x-www-form-urlencoded/i)) { + body = Object.keys(body).map(function(key){ + return `${key}=${encodeURIComponent(body[key])}` + }).join("&"); + } + } + return body; +} + module.exports = function(options) { var promise = new Parse.Promise(); var callbacks = { @@ -10,13 +31,9 @@ module.exports = function(options) { delete options.success; delete options.error; delete options.uri; // not supported - if (typeof options.body === 'object') { - options.body = JSON.stringify(options.body); - options.headers = options.headers || {}; - options.headers['Content-Type'] = "application/json"; - } + options.body = encodeBody(options.body, options.headers); // set follow redirects to false by default - options.followRedirect = options.followRedirects == true ? true : false; + options.followRedirect = options.followRedirects == true; request(options, (error, response, body) => { var httpResponse = {}; @@ -42,4 +59,6 @@ module.exports = function(options) { } }); return promise; -}; \ No newline at end of file +}; + +module.exports.encodeBody = encodeBody;