Skip to content

Commit

Permalink
fix(Browser): multipartUpload callback resumble parse error (#442)
Browse files Browse the repository at this point in the history
* opti: use internal headers, copy options headers

* opti: use internal headers, copy options headers

* opti: use internal headers, copy options headers

* refactor(callback): use options params with copy

* feat: add test case

* feat: add test case prefix time timestamp

* feat: rm publish to cdn about latest
  • Loading branch information
binghaiwang authored and PeterRao committed Apr 16, 2018
1 parent 37f65f0 commit e22ecf6
Show file tree
Hide file tree
Showing 10 changed files with 142 additions and 48 deletions.
2 changes: 1 addition & 1 deletion lib/browser/managed_upload.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ proto.multipartUpload = function* multipartUpload(name, file, options) {
etag: result.res.headers.etag,
};

if (options.headers && options.headers['x-oss-callback']) {
if ((options.headers && options.headers['x-oss-callback']) || options.callback) {
ret.data = result.data;
}

Expand Down
15 changes: 7 additions & 8 deletions lib/browser/object.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const path = require('path');
const mime = require('mime');
const callback = require('../common/callback');
const signHelper = require('../common/signUtils');

// var assert = require('assert');


Expand Down Expand Up @@ -86,12 +87,11 @@ proto.put = function* put(name, file, options) {

const method = options.method || 'PUT';
const params = this._objectRequestParams(method, name, options);
callback.encodeCallback(params, options);
params.mime = options.mime;
params.content = content;
params.successStatuses = [200];

callback.encodeCallback(options);

const result = yield this.request(params);

const ret = {
Expand All @@ -100,7 +100,7 @@ proto.put = function* put(name, file, options) {
res: result.res,
};

if (options.headers && options.headers['x-oss-callback']) {
if (params.headers && params.headers['x-oss-callback']) {
ret.data = JSON.parse(result.data.toString());
}

Expand All @@ -127,13 +127,11 @@ proto.putStream = function* putStream(name, stream, options) {

const method = options.method || 'PUT';
const params = this._objectRequestParams(method, name, options);

callback.encodeCallback(params, options);
params.mime = options.mime;
params.stream = stream;
params.successStatuses = [200];

callback.encodeCallback(options);

const result = yield this.request(params);

const ret = {
Expand All @@ -142,7 +140,7 @@ proto.putStream = function* putStream(name, stream, options) {
res: result.res,
};

if (options.headers && options.headers['x-oss-callback']) {
if (params.headers && params.headers['x-oss-callback']) {
ret.data = JSON.parse(result.data.toString());
}

Expand Down Expand Up @@ -504,7 +502,8 @@ proto._objectRequestParams = function (method, name, options) {
};

if (options.headers) {
params.headers = options.headers;
params.headers = {};
copy(options.headers).to(params.headers);
}
return params;
};
Expand Down
10 changes: 5 additions & 5 deletions lib/common/callback.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@


exports.encodeCallback = function (options) {
options.headers = options.headers || {};
if (!Object.prototype.hasOwnProperty.call(options.headers, 'x-oss-callback')) {
exports.encodeCallback = function encodeCallback(reqParams, options) {
reqParams.headers = reqParams.headers || {};
if (!Object.prototype.hasOwnProperty.call(reqParams.headers, 'x-oss-callback')) {
if (options.callback) {
const json = {
callbackUrl: encodeURI(options.callback.url),
Expand All @@ -15,14 +15,14 @@ exports.encodeCallback = function (options) {
json.callbackBodyType = options.callback.contentType;
}
const callback = new Buffer(JSON.stringify(json)).toString('base64');
options.headers['x-oss-callback'] = callback;
reqParams.headers['x-oss-callback'] = callback;

if (options.callback.customValue) {
const callbackVar = {};
Object.keys(options.callback.customValue).forEach((key) => {
callbackVar[`x:${key}`] = options.callback.customValue[key];
});
options.headers['x-oss-callback-var'] = new Buffer(JSON.stringify(callbackVar)).toString('base64');
reqParams.headers['x-oss-callback-var'] = new Buffer(JSON.stringify(callbackVar)).toString('base64');
}
}
}
Expand Down
54 changes: 33 additions & 21 deletions lib/common/multipart.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@


const copy = require('copy-to');
const callback = require('./callback');

const proto = exports;
Expand All @@ -13,8 +13,10 @@ const proto = exports;
*/
proto.listUploads = function* listUploads(query, options) {
options = options || {};
options.subres = 'uploads';
const params = this._objectRequestParams('GET', '', options);
const opt = {};
copy(options).to(opt);
opt.subres = 'uploads';
const params = this._objectRequestParams('GET', '', opt);
params.query = query;
params.xmlResponse = true;
params.successStatuses = [200];
Expand Down Expand Up @@ -53,10 +55,12 @@ proto.listUploads = function* listUploads(query, options) {
*/
proto.listParts = function* listParts(name, uploadId, query, options) {
options = options || {};
options.subres = {
const opt = {};
copy(options).to(opt);
opt.subres = {
uploadId,
};
const params = this._objectRequestParams('GET', name, options);
const params = this._objectRequestParams('GET', name, opt);
params.query = query;
params.xmlResponse = true;
params.successStatuses = [200];
Expand Down Expand Up @@ -85,8 +89,10 @@ proto.listParts = function* listParts(name, uploadId, query, options) {
proto.abortMultipartUpload = function* abortMultipartUpload(name, uploadId, options) {
this.cancel();
options = options || {};
options.subres = { uploadId };
const params = this._objectRequestParams('DELETE', name, options);
const opt = {};
copy(options).to(opt);
opt.subres = { uploadId };
const params = this._objectRequestParams('DELETE', name, opt);
params.successStatuses = [204];

const result = yield this.request(params);
Expand All @@ -103,11 +109,13 @@ proto.abortMultipartUpload = function* abortMultipartUpload(name, uploadId, opti
*/
proto.initMultipartUpload = function* initMultipartUpload(name, options) {
options = options || {};
options.headers = options.headers || {};
this._convertMetaToHeaders(options.meta, options.headers);
const opt = {};
copy(options).to(opt);
opt.headers = opt.headers || {};
this._convertMetaToHeaders(options.meta, opt.headers);

options.subres = 'uploads';
const params = this._objectRequestParams('POST', name, options);
opt.subres = 'uploads';
const params = this._objectRequestParams('POST', name, opt);
params.mime = options.mime;
params.xmlResponse = true;
params.successStatuses = [200];
Expand Down Expand Up @@ -173,14 +181,16 @@ proto.completeMultipartUpload = function* completeMultipartUpload(name, uploadId
xml += '</CompleteMultipartUpload>';

options = options || {};
options.subres = { uploadId };
const params = this._objectRequestParams('POST', name, options);
const opt = {};
copy(options).to(opt);
opt.subres = { uploadId };

const params = this._objectRequestParams('POST', name, opt);
callback.encodeCallback(params, opt);
params.mime = 'xml';
params.content = xml;

callback.encodeCallback(options);

if (!(options.headers && options.headers['x-oss-callback'])) {
if (!(params.headers && params.headers['x-oss-callback'])) {
params.xmlResponse = true;
}
params.successStatuses = [200];
Expand All @@ -193,7 +203,7 @@ proto.completeMultipartUpload = function* completeMultipartUpload(name, uploadId
etag: result.res.headers.etag,
};

if (options.headers && options.headers['x-oss-callback']) {
if (params.headers && params.headers['x-oss-callback']) {
ret.data = JSON.parse(result.data.toString());
}

Expand All @@ -210,16 +220,18 @@ proto.completeMultipartUpload = function* completeMultipartUpload(name, uploadId
*/
proto._uploadPart = function* _uploadPart(name, uploadId, partNo, data, options) {
options = options || {};
options.headers = {
const opt = {};
copy(options).to(opt);
opt.headers = {
'Content-Length': data.size,
};

options.subres = {
opt.subres = {
partNumber: partNo,
uploadId,
};
const params = this._objectRequestParams('PUT', name, options);
params.mime = options.mime;
const params = this._objectRequestParams('PUT', name, opt);
params.mime = opt.mime;
params.stream = data.stream;
params.successStatuses = [200];

Expand Down
2 changes: 1 addition & 1 deletion lib/managed_upload.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ proto.multipartUpload = function* multipartUpload(name, file, options) {
etag: result.res.headers.etag,
};

if (options.headers && options.headers['x-oss-callback']) {
if ((options.headers && options.headers['x-oss-callback']) || options.callback) {
ret.data = result.data;
}

Expand Down
16 changes: 8 additions & 8 deletions lib/object.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,11 @@ proto.put = function* put(name, file, options) {
options.headers = options.headers || {};
this._convertMetaToHeaders(options.meta, options.headers);

callback.encodeCallback(options);

const method = options.method || 'PUT';
const params = this._objectRequestParams(method, name, options);

callback.encodeCallback(params, options);

params.mime = options.mime;
params.content = content;
params.successStatuses = [200];
Expand All @@ -93,7 +94,7 @@ proto.put = function* put(name, file, options) {
res: result.res,
};

if (options.headers && options.headers['x-oss-callback']) {
if (params.headers && params.headers['x-oss-callback']) {
ret.data = JSON.parse(result.data.toString());
}

Expand All @@ -118,11 +119,9 @@ proto.putStream = function* putStream(name, stream, options) {
}
this._convertMetaToHeaders(options.meta, options.headers);

callback.encodeCallback(options);

const method = options.method || 'PUT';
const params = this._objectRequestParams(method, name, options);

callback.encodeCallback(params, options);
params.mime = options.mime;
params.stream = stream;
params.successStatuses = [200];
Expand All @@ -135,7 +134,7 @@ proto.putStream = function* putStream(name, stream, options) {
res: result.res,
};

if (options.headers && options.headers['x-oss-callback']) {
if (params.headers && params.headers['x-oss-callback']) {
ret.data = JSON.parse(result.data.toString());
}

Expand Down Expand Up @@ -503,7 +502,8 @@ proto._objectRequestParams = function (method, name, options) {
};

if (options.headers) {
params.headers = options.headers;
params.headers = {};
copy(options.headers).to(params.headers);
}
return params;
};
Expand Down
2 changes: 0 additions & 2 deletions publish.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,10 @@ var store = oss({
bucket: env.ALI_SDK_OSS_CDN_BUCKET,
});

var latest = 'aliyun-oss-sdk.min.js';
var current = 'aliyun-oss-sdk-' + pkg.version + '.min.js';
var dist = './dist/aliyun-oss-sdk.min.js';

co(function* () {
yield store.put(latest, dist);
yield store.put(current, dist);
}).catch(function (err) {
console.log(err);
Expand Down
66 changes: 66 additions & 0 deletions test/browser/browser.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1049,6 +1049,72 @@ describe('browser', () => {
assert.equal(result.res.status, 200);
assert.equal(result.data.Status, 'OK');
});

it('should upload file with cancel and callback', function* () {
const client = this.store;
// create a file with 1M random data
const fileContent = Array(1024 * 1024).fill('a').join('');
const file = new File([fileContent], 'multipart-upload-file');

const name = `${prefix}multipart/upload-file-cancel-callback`;

let tempCheckpoint = null;
const options = {
progress(p, checkpoint) {
return function (done) {
tempCheckpoint = checkpoint;
if (p > 0.5) {
client.cancel();
}
done();
};
},
partSize: 100 * 1024,
callback: {
url: 'http://oss-demo.aliyuncs.com:23450',
host: 'oss-cn-hangzhou.aliyuncs.com',
/* eslint no-template-curly-in-string: [0] */
body: 'bucket=${bucket}&object=${object}&var1=${x:var1}',
contentType: 'application/x-www-form-urlencoded',
customValue: {
var1: 'value1',
var2: 'value2',
},
},
};
try {
yield client.multipartUpload(name, file, options);
} catch (err) {
assert.equal(true, client.isCancel());
}

assert.equal(true, tempCheckpoint && Object.keys(tempCheckpoint).length !== 0);

const options2 = {
progress(p) {
return function (done) {
assert.equal(true, p > 0.5);
done();
};
},
partSize: 100 * 1024,
checkpoint: tempCheckpoint,
callback: {
url: 'http://oss-demo.aliyuncs.com:23450',
host: 'oss-cn-hangzhou.aliyuncs.com',
/* eslint no-template-curly-in-string: [0] */
body: 'bucket=${bucket}&object=${object}&var1=${x:var1}',
contentType: 'application/x-www-form-urlencoded',
customValue: {
var1: 'value1',
var2: 'value2',
},
},
};
const result = yield client.multipartUpload(name, file, options2);

assert.equal(result.res.status, 200);
});
});
});

Expand Down
19 changes: 19 additions & 0 deletions test/node/callback.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,5 +142,24 @@ describe('test/callback.test.js', () => {
assert.equal(result.res.status, 200);
assert.equal(result.data.Status, 'OK');
});

it('should multipart upload with no more 100k file use header x-oss-callback', function* () {
// create a file with 1M random data
const fileName = yield utils.createTempFile('upload-with-callback', 50 * 1024);
const callback = {
url: callbackServer,
body: 'bucket=${bucket}&object=${object}&var1=${x:var1}',
};
const name = `${prefix}multipart/upload-with-callback`;
/* eslint no-mixed-spaces-and-tabs: [0] */
const result = yield this.store.multipartUpload(name, fileName, {
partSize: 100 * 1024,
headers: {
'x-oss-callback': utils.encodeCallback(callback),
},
});
assert.equal(result.res.status, 200);
assert.equal(result.data.Status, 'OK');
});
});
});
Loading

0 comments on commit e22ecf6

Please sign in to comment.