Skip to content

Commit 11c288d

Browse files
authored
Merge pull request #112 from particle-iot/downloadBinaryFix
fixes #110
2 parents bde184c + 2dd6a63 commit 11c288d

File tree

4 files changed

+97
-31
lines changed

4 files changed

+97
-31
lines changed

src/Agent.js

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,19 @@ export default class Agent {
5959
* @parma {Object} context the invocation context, describing the tool and project.
6060
* @return {Promise} A promise. fulfilled with {body, statusCode}, rejected with { statusCode, errorDescription, error, body }
6161
*/
62-
request({ uri, method, data = undefined, auth, query = undefined, form = undefined, files = undefined, context = undefined }) {
62+
request({
63+
uri,
64+
method,
65+
data = undefined,
66+
auth,
67+
query = undefined,
68+
form = undefined,
69+
files = undefined,
70+
context = undefined,
71+
raw = false
72+
}) {
6373
const requestFiles = this._sanitizeFiles(files);
64-
return this._request({ uri, method, data, auth, query, form, context, files: requestFiles });
74+
return this._request({ uri, method, data, auth, query, form, context, files: requestFiles, raw });
6575
}
6676

6777
/**
@@ -76,8 +86,12 @@ export default class Agent {
7686
* @param {Object} context the invocation context
7787
* @return {Promise} A promise. fulfilled with {body, statusCode}, rejected with { statusCode, errorDescription, error, body }
7888
*/
79-
_request({ uri, method, data, auth, query, form, files, context }) {
89+
_request({ uri, method, data, auth, query, form, files, context, raw }) {
8090
const req = this._buildRequest({ uri, method, data, auth, query, form, context, files });
91+
92+
if (raw){
93+
return req;
94+
}
8195
return this._promiseResponse(req);
8296
}
8397

@@ -123,7 +137,7 @@ export default class Agent {
123137
});
124138
}
125139

126-
_buildRequest({ uri, method, data, auth, query, form, files, context, makerequest=request }) {
140+
_buildRequest({ uri, method, data, auth, query, form, files, context, makerequest = request }) {
127141
const req = makerequest(method, uri);
128142
if (this.prefix) {
129143
req.use(this.prefix);
@@ -141,7 +155,7 @@ export default class Agent {
141155
let options = {
142156
filepath: file.path
143157
};
144-
if (this._inBrowser(makerequest)) {
158+
if (this.isForBrowser(makerequest)) {
145159
options = file.path;
146160
}
147161
req.attach(name, file.data, options);
@@ -160,7 +174,7 @@ export default class Agent {
160174
return req;
161175
}
162176

163-
_inBrowser(makerequest) {
177+
isForBrowser(makerequest = request) {
164178
// superagent only has the getXHR method in the browser version
165179
return !!makerequest.getXHR;
166180
}

src/Particle.js

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import request from 'superagent';
21
import binaryParser from './superagent-binary-parser';
32
import Defaults from './Defaults';
43
import EventStream from './EventStream';
@@ -588,11 +587,14 @@ class Particle {
588587
* @returns {Request} A promise
589588
*/
590589
downloadFirmwareBinary({ binaryId, auth }){
591-
const uri = `/v1/binaries/${binaryId}`;
592-
const req = request('get', uri);
593-
req.use(this.prefix);
594-
this.headers(req, auth);
595-
return req;
590+
let req = this.request({
591+
uri: `/v1/binaries/${binaryId}`,
592+
method: 'get',
593+
raw: true,
594+
auth
595+
});
596+
597+
return this._provideFileData(req);
596598
}
597599

598600
/**
@@ -1131,17 +1133,8 @@ class Particle {
11311133
* @returns {Promise} Resolves to a buffer with the file data
11321134
*/
11331135
downloadFile({ url }){
1134-
let req = request.get(url);
1135-
// Different API in Node and browser
1136-
if (!request.getXHR){
1137-
req = req.buffer(true).parse(binaryParser);
1138-
} else if (req.responseType){
1139-
req = req.responseType('arraybuffer').then(res => {
1140-
res.body = res.xhr.response;
1141-
return res;
1142-
});
1143-
}
1144-
return req.then(res => res.body);
1136+
let req = this.request({ uri: url, method: 'get', raw: true });
1137+
return this._provideFileData(req);
11451138
}
11461139

11471140
/**
@@ -1299,11 +1292,26 @@ class Particle {
12991292
* @returns {Request} A promise
13001293
*/
13011294
downloadProductFirmware({ version, product, auth }){
1302-
const uri = `/v1/products/${product}/firmware/${version}/binary`;
1303-
const req = request('get', uri);
1304-
req.use(this.prefix);
1305-
this.headers(req, auth);
1306-
return req;
1295+
let req = this.request({
1296+
uri: `/v1/products/${product}/firmware/${version}/binary`,
1297+
method: 'get',
1298+
raw: true,
1299+
auth
1300+
});
1301+
1302+
return this._provideFileData(req);
1303+
}
1304+
1305+
_provideFileData(req){
1306+
if (this.agent.isForBrowser()){
1307+
req = req.responseType('arraybuffer').then(res => {
1308+
res.body = res.xhr.response;
1309+
return res;
1310+
});
1311+
} else {
1312+
req = req.buffer(true).parse(binaryParser);
1313+
}
1314+
return req.then(res => res.body);
13071315
}
13081316

13091317
/**

test/Agent.spec.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,8 @@ describe('Agent', () => {
304304
query: 'all',
305305
form:form,
306306
files: sanitizedFiles,
307-
context: undefined
307+
context: undefined,
308+
raw: false
308309
});
309310
});
310311

@@ -323,7 +324,8 @@ describe('Agent', () => {
323324
files: undefined,
324325
form: undefined,
325326
query: undefined,
326-
context: undefined
327+
context: undefined,
328+
raw: false
327329
});
328330
});
329331

test/Particle.spec.js

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ const props = {
2929
files: {
3030
'app.ino': new Buffer('void(){}\nsetup(){}\n')
3131
},
32+
binaryId: '123456',
3233
targetVersion: '0.4.7',
3334
requestType: 'GET',
3435
headers: {
@@ -712,6 +713,21 @@ describe('ParticleAPI', () => {
712713
});
713714
});
714715
});
716+
describe('.downloadFirmwareBinary', () => {
717+
it('generates request', () => {
718+
sinon.stub(api, '_provideFileData').callsFake(x => Promise.resolve(x));
719+
const req = api.downloadFirmwareBinary(propsWithProduct);
720+
api._provideFileData.callCount.should.equal(1);
721+
return req.then((results) => {
722+
results.should.match({
723+
uri: `/v1/binaries/${props.binaryId}`,
724+
method: 'get',
725+
auth: props.auth,
726+
raw: true
727+
});
728+
});
729+
});
730+
});
715731
describe('.sendPublicKey', () => {
716732
it('generates request', () => {
717733
return api.sendPublicKey(props).then(Common.expectDeviceUrlAndToken);
@@ -1574,7 +1590,17 @@ describe('ParticleAPI', () => {
15741590
});
15751591
});
15761592
});
1577-
1593+
describe('.downloadFile', () => {
1594+
it('generates request', () => {
1595+
sinon.stub(api, '_provideFileData').callsFake(x => Promise.resolve(x));
1596+
const uri = 'http://example.com/path/to/file.png';
1597+
const req = api.downloadFile({ url: uri });
1598+
api._provideFileData.callCount.should.equal(1);
1599+
return req.then((results) => {
1600+
results.should.match({ uri, method: 'get', raw: true });
1601+
});
1602+
});
1603+
});
15781604
describe('.listOAuthClients', () => {
15791605
describe('user scope', () => {
15801606
it('generates request', () => {
@@ -1751,6 +1777,22 @@ describe('ParticleAPI', () => {
17511777
});
17521778
});
17531779

1780+
describe('.downloadProductFirmware', () => {
1781+
it('generates request', () => {
1782+
sinon.stub(api, '_provideFileData').callsFake(x => Promise.resolve(x));
1783+
const req = api.downloadProductFirmware(propsWithProduct);
1784+
api._provideFileData.callCount.should.equal(1);
1785+
return req.then((results) => {
1786+
results.should.match({
1787+
uri: `/v1/products/${product}/firmware/${props.version}/binary`,
1788+
method: 'get',
1789+
auth: props.auth,
1790+
raw: true
1791+
});
1792+
});
1793+
});
1794+
});
1795+
17541796
describe('.getProductFirmware', () => {
17551797
it('generates request', () => {
17561798
return api.getProductFirmware(propsWithProduct).then((results) => {

0 commit comments

Comments
 (0)