From 89ce1b70b6a70b4c37ce795a6da66a57b86a51fd Mon Sep 17 00:00:00 2001 From: David Frank Date: Wed, 23 Mar 2016 15:02:04 +0800 Subject: [PATCH 1/2] fix formdata support when you are trying to wrap the request --- lib/body.js | 5 ++++- test/test.js | 22 +++++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/lib/body.js b/lib/body.js index fdc1139..b32b0d5 100644 --- a/lib/body.js +++ b/lib/body.js @@ -206,11 +206,14 @@ Body.prototype._clone = function(instance) { var pass; var body = instance.body; + // don't allow cloning a used body if (instance.bodyUsed) { throw new Error('cannot clone body after it is used'); } - if (bodyStream(body)) { + // check that body is a stream and not form-data object + // note: we can't clone the form-data object without having it as a dependency + if (bodyStream(body) && typeof body.getBoundary !== 'function') { pass = new PassThrough(); body.pipe(pass); body = pass; diff --git a/test/test.js b/test/test.js index 1a7fe08..0de4e12 100644 --- a/test/test.js +++ b/test/test.js @@ -942,15 +942,23 @@ describe('node-fetch', function() { it('should support wrapping Request instance', function() { url = base + '/hello'; + + var form = new FormData(); + form.append('a', '1'); + var r1 = new Request(url, { method: 'POST' , follow: 1 + , body: form }); var r2 = new Request(r1, { follow: 2 - }) + }); + expect(r2.url).to.equal(url); expect(r2.method).to.equal('POST'); + // note that we didn't clone the body + expect(r2.body).to.equal(form); expect(r1.follow).to.equal(1); expect(r2.follow).to.equal(2); }); @@ -1009,7 +1017,9 @@ describe('node-fetch', function() { }); it('should support clone() method in Response constructor', function() { - var res = new Response('a=1', { + var body = resumer().queue('a=1').end(); + body = body.pipe(new stream.PassThrough()); + var res = new Response(body, { headers: { a: '1' } @@ -1023,6 +1033,8 @@ describe('node-fetch', function() { expect(cl.status).to.equal(346); expect(cl.statusText).to.equal('production'); expect(cl.ok).to.be.false; + // clone body shouldn't be the same body + expect(cl.body).to.not.equal(body); return cl.text().then(function(result) { expect(result).to.equal('a=1'); }); @@ -1086,9 +1098,11 @@ describe('node-fetch', function() { it('should support clone() method in Request constructor', function() { url = base; + var body = resumer().queue('a=1').end(); + body = body.pipe(new stream.PassThrough()); var agent = new http.Agent(); var req = new Request(url, { - body: 'a=1' + body: body , method: 'POST' , headers: { b: '2' @@ -1106,6 +1120,8 @@ describe('node-fetch', function() { expect(cl.method).to.equal('POST'); expect(cl.counter).to.equal(3); expect(cl.agent).to.equal(agent); + // clone body shouldn't be the same body + expect(cl.body).to.not.equal(body); return fetch.Promise.all([cl.text(), req.text()]).then(function(results) { expect(results[0]).to.equal('a=1'); expect(results[1]).to.equal('a=1'); From 4d63427123a5c8d5824cd0187c375ada0a9de05d Mon Sep 17 00:00:00 2001 From: David Frank Date: Wed, 23 Mar 2016 15:23:56 +0800 Subject: [PATCH 2/2] demostrate restream more clearly in tests --- test/test.js | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/test/test.js b/test/test.js index 0de4e12..262ed79 100644 --- a/test/test.js +++ b/test/test.js @@ -800,13 +800,26 @@ describe('node-fetch', function() { }); }); - it('should allow cloning a json response, and log it as text response', function() { + it('should allow cloning a json response and log it as text response', function() { url = base + '/json'; return fetch(url).then(function(res) { var r1 = res.clone(); - return fetch.Promise.all([r1.text(), res.json()]).then(function(results) { - expect(results[0]).to.equal('{"name":"value"}'); - expect(results[1]).to.deep.equal({name: 'value'}); + return fetch.Promise.all([res.json(), r1.text()]).then(function(results) { + expect(results[0]).to.deep.equal({name: 'value'}); + expect(results[1]).to.equal('{"name":"value"}'); + }); + }); + }); + + it('should allow cloning a json response, and then log it as text response', function() { + url = base + '/json'; + return fetch(url).then(function(res) { + var r1 = res.clone(); + return res.json().then(function(result) { + expect(result).to.deep.equal({name: 'value'}); + return r1.text().then(function(result) { + expect(result).to.equal('{"name":"value"}'); + }); }); }); });