From c5a23e584c5833597df18c98f6797dabeb3e77c0 Mon Sep 17 00:00:00 2001 From: Derek Wickern Date: Thu, 8 Jun 2017 15:17:27 -0700 Subject: [PATCH] Fix #2922: file uploads fail to render curl command The request body is an immutable.js OrderedMap rather than a string, so this fixes the type error: TypeError: request.get(...).split is not a function Adds a special curl command argument for files, e.g. curl -F "param=value" -F "file=@filename.txt;type=text/plain" --- src/core/components/curl.jsx | 2 +- src/core/curlify.js | 12 ++++++++---- src/core/utils.js | 4 ++++ src/core/window.js | 3 ++- test/core/curlify.js | 28 ++++++++++++++++++++++++++-- 5 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/core/components/curl.jsx b/src/core/components/curl.jsx index b278512b..5bbc242b 100644 --- a/src/core/components/curl.jsx +++ b/src/core/components/curl.jsx @@ -19,7 +19,7 @@ export default class Curl extends React.Component {

Curl

- +
) diff --git a/src/core/curlify.js b/src/core/curlify.js index e3981515..2564ed92 100644 --- a/src/core/curlify.js +++ b/src/core/curlify.js @@ -1,3 +1,5 @@ +import win from "./window" + export default function curl( request ){ let curlified = [] let type = "" @@ -18,11 +20,13 @@ export default function curl( request ){ if ( request.get("body") ){ if(type === "multipart/form-data" && request.get("method") === "POST") { - let formDataBody = request.get("body").split("&") - - for(var data in formDataBody) { + for( let [ k,v ] of request.get("body").values()) { curlified.push( "-F" ) - curlified.push(formDataBody[data]) + if (v instanceof win.File) { + curlified.push( `"${k}=@${v.name};type=${v.type}"` ) + } else { + curlified.push( `"${k}=${v}"` ) + } } } else { curlified.push( "-d" ) diff --git a/src/core/utils.js b/src/core/utils.js index ecb53ad7..9bf8bd22 100644 --- a/src/core/utils.js +++ b/src/core/utils.js @@ -7,6 +7,7 @@ import _memoize from "lodash/memoize" import some from "lodash/some" import eq from "lodash/eq" import { memoizedSampleFromSchema, memoizedCreateXMLExample } from "core/plugins/samples/fn" +import win from "./window" const DEFAULT_REPONSE_KEY = "default" @@ -34,6 +35,9 @@ export function fromJSOrdered (js) { if(isImmutable(js)) return js // Can't do much here + if (js instanceof win.File) + return js + return !isObject(js) ? js : Array.isArray(js) ? Im.Seq(js).map(fromJSOrdered).toList() : diff --git a/src/core/window.js b/src/core/window.js index 1ee90912..9a364ee2 100644 --- a/src/core/window.js +++ b/src/core/window.js @@ -3,7 +3,8 @@ function makeWindow() { location: {}, history: {}, open: () => {}, - close: () => {} + close: () => {}, + File: function() {} } if(typeof window === "undefined") { diff --git a/test/core/curlify.js b/test/core/curlify.js index 69ffdaa4..82ee6a8a 100644 --- a/test/core/curlify.js +++ b/test/core/curlify.js @@ -1,6 +1,7 @@ import expect from "expect" import Im from "immutable" import curl from "core/curlify" +import win from "core/window" describe("curlify", function() { @@ -131,12 +132,35 @@ describe("curlify", function() { url: "http://example.com", method: "POST", headers: { "content-type": "multipart/form-data" }, - body: "id=123&name=Sahar" + body: [ + ["id", "123"], + ["name", "Sahar"] + ] } let curlified = curl(Im.fromJS(req)) - expect(curlified).toEqual("curl -X POST \"http://example.com\" -H \"content-type: multipart/form-data\" -F id=123 -F name=Sahar") + expect(curlified).toEqual("curl -X POST \"http://example.com\" -H \"content-type: multipart/form-data\" -F \"id=123\" -F \"name=Sahar\"") + }) + + it("should print a curl with formData and file", function() { + var file = new win.File() + file.name = "file.txt" + file.type = "text/plain" + + var req = { + url: "http://example.com", + method: "POST", + headers: { "content-type": "multipart/form-data" }, + body: [ + ["id", "123"], + ["file", file] + ] + } + + let curlified = curl(Im.fromJS(req)) + + expect(curlified).toEqual("curl -X POST \"http://example.com\" -H \"content-type: multipart/form-data\" -F \"id=123\" -F \"file=@file.txt;type=text/plain\"") }) it("prints a curl post statement from an object", function() {