Skip to content

Commit e22ecf6

Browse files
binghaiwangPeterRao
authored andcommitted
fix(Browser): multipartUpload callback resumble parse error (#442)
* 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
1 parent 37f65f0 commit e22ecf6

File tree

10 files changed

+142
-48
lines changed

10 files changed

+142
-48
lines changed

lib/browser/managed_upload.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ proto.multipartUpload = function* multipartUpload(name, file, options) {
6868
etag: result.res.headers.etag,
6969
};
7070

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

lib/browser/object.js

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const path = require('path');
1212
const mime = require('mime');
1313
const callback = require('../common/callback');
1414
const signHelper = require('../common/signUtils');
15+
1516
// var assert = require('assert');
1617

1718

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

8788
const method = options.method || 'PUT';
8889
const params = this._objectRequestParams(method, name, options);
90+
callback.encodeCallback(params, options);
8991
params.mime = options.mime;
9092
params.content = content;
9193
params.successStatuses = [200];
9294

93-
callback.encodeCallback(options);
94-
9595
const result = yield this.request(params);
9696

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

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

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

128128
const method = options.method || 'PUT';
129129
const params = this._objectRequestParams(method, name, options);
130-
130+
callback.encodeCallback(params, options);
131131
params.mime = options.mime;
132132
params.stream = stream;
133133
params.successStatuses = [200];
134134

135-
callback.encodeCallback(options);
136-
137135
const result = yield this.request(params);
138136

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

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

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

506504
if (options.headers) {
507-
params.headers = options.headers;
505+
params.headers = {};
506+
copy(options.headers).to(params.headers);
508507
}
509508
return params;
510509
};

lib/common/callback.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11

22

3-
exports.encodeCallback = function (options) {
4-
options.headers = options.headers || {};
5-
if (!Object.prototype.hasOwnProperty.call(options.headers, 'x-oss-callback')) {
3+
exports.encodeCallback = function encodeCallback(reqParams, options) {
4+
reqParams.headers = reqParams.headers || {};
5+
if (!Object.prototype.hasOwnProperty.call(reqParams.headers, 'x-oss-callback')) {
66
if (options.callback) {
77
const json = {
88
callbackUrl: encodeURI(options.callback.url),
@@ -15,14 +15,14 @@ exports.encodeCallback = function (options) {
1515
json.callbackBodyType = options.callback.contentType;
1616
}
1717
const callback = new Buffer(JSON.stringify(json)).toString('base64');
18-
options.headers['x-oss-callback'] = callback;
18+
reqParams.headers['x-oss-callback'] = callback;
1919

2020
if (options.callback.customValue) {
2121
const callbackVar = {};
2222
Object.keys(options.callback.customValue).forEach((key) => {
2323
callbackVar[`x:${key}`] = options.callback.customValue[key];
2424
});
25-
options.headers['x-oss-callback-var'] = new Buffer(JSON.stringify(callbackVar)).toString('base64');
25+
reqParams.headers['x-oss-callback-var'] = new Buffer(JSON.stringify(callbackVar)).toString('base64');
2626
}
2727
}
2828
}

lib/common/multipart.js

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
2+
const copy = require('copy-to');
33
const callback = require('./callback');
44

55
const proto = exports;
@@ -13,8 +13,10 @@ const proto = exports;
1313
*/
1414
proto.listUploads = function* listUploads(query, options) {
1515
options = options || {};
16-
options.subres = 'uploads';
17-
const params = this._objectRequestParams('GET', '', options);
16+
const opt = {};
17+
copy(options).to(opt);
18+
opt.subres = 'uploads';
19+
const params = this._objectRequestParams('GET', '', opt);
1820
params.query = query;
1921
params.xmlResponse = true;
2022
params.successStatuses = [200];
@@ -53,10 +55,12 @@ proto.listUploads = function* listUploads(query, options) {
5355
*/
5456
proto.listParts = function* listParts(name, uploadId, query, options) {
5557
options = options || {};
56-
options.subres = {
58+
const opt = {};
59+
copy(options).to(opt);
60+
opt.subres = {
5761
uploadId,
5862
};
59-
const params = this._objectRequestParams('GET', name, options);
63+
const params = this._objectRequestParams('GET', name, opt);
6064
params.query = query;
6165
params.xmlResponse = true;
6266
params.successStatuses = [200];
@@ -85,8 +89,10 @@ proto.listParts = function* listParts(name, uploadId, query, options) {
8589
proto.abortMultipartUpload = function* abortMultipartUpload(name, uploadId, options) {
8690
this.cancel();
8791
options = options || {};
88-
options.subres = { uploadId };
89-
const params = this._objectRequestParams('DELETE', name, options);
92+
const opt = {};
93+
copy(options).to(opt);
94+
opt.subres = { uploadId };
95+
const params = this._objectRequestParams('DELETE', name, opt);
9096
params.successStatuses = [204];
9197

9298
const result = yield this.request(params);
@@ -103,11 +109,13 @@ proto.abortMultipartUpload = function* abortMultipartUpload(name, uploadId, opti
103109
*/
104110
proto.initMultipartUpload = function* initMultipartUpload(name, options) {
105111
options = options || {};
106-
options.headers = options.headers || {};
107-
this._convertMetaToHeaders(options.meta, options.headers);
112+
const opt = {};
113+
copy(options).to(opt);
114+
opt.headers = opt.headers || {};
115+
this._convertMetaToHeaders(options.meta, opt.headers);
108116

109-
options.subres = 'uploads';
110-
const params = this._objectRequestParams('POST', name, options);
117+
opt.subres = 'uploads';
118+
const params = this._objectRequestParams('POST', name, opt);
111119
params.mime = options.mime;
112120
params.xmlResponse = true;
113121
params.successStatuses = [200];
@@ -173,14 +181,16 @@ proto.completeMultipartUpload = function* completeMultipartUpload(name, uploadId
173181
xml += '</CompleteMultipartUpload>';
174182

175183
options = options || {};
176-
options.subres = { uploadId };
177-
const params = this._objectRequestParams('POST', name, options);
184+
const opt = {};
185+
copy(options).to(opt);
186+
opt.subres = { uploadId };
187+
188+
const params = this._objectRequestParams('POST', name, opt);
189+
callback.encodeCallback(params, opt);
178190
params.mime = 'xml';
179191
params.content = xml;
180192

181-
callback.encodeCallback(options);
182-
183-
if (!(options.headers && options.headers['x-oss-callback'])) {
193+
if (!(params.headers && params.headers['x-oss-callback'])) {
184194
params.xmlResponse = true;
185195
}
186196
params.successStatuses = [200];
@@ -193,7 +203,7 @@ proto.completeMultipartUpload = function* completeMultipartUpload(name, uploadId
193203
etag: result.res.headers.etag,
194204
};
195205

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

@@ -210,16 +220,18 @@ proto.completeMultipartUpload = function* completeMultipartUpload(name, uploadId
210220
*/
211221
proto._uploadPart = function* _uploadPart(name, uploadId, partNo, data, options) {
212222
options = options || {};
213-
options.headers = {
223+
const opt = {};
224+
copy(options).to(opt);
225+
opt.headers = {
214226
'Content-Length': data.size,
215227
};
216228

217-
options.subres = {
229+
opt.subres = {
218230
partNumber: partNo,
219231
uploadId,
220232
};
221-
const params = this._objectRequestParams('PUT', name, options);
222-
params.mime = options.mime;
233+
const params = this._objectRequestParams('PUT', name, opt);
234+
params.mime = opt.mime;
223235
params.stream = data.stream;
224236
params.successStatuses = [200];
225237

lib/managed_upload.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ proto.multipartUpload = function* multipartUpload(name, file, options) {
5858
etag: result.res.headers.etag,
5959
};
6060

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

lib/object.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,11 @@ proto.put = function* put(name, file, options) {
7777
options.headers = options.headers || {};
7878
this._convertMetaToHeaders(options.meta, options.headers);
7979

80-
callback.encodeCallback(options);
81-
8280
const method = options.method || 'PUT';
8381
const params = this._objectRequestParams(method, name, options);
82+
83+
callback.encodeCallback(params, options);
84+
8485
params.mime = options.mime;
8586
params.content = content;
8687
params.successStatuses = [200];
@@ -93,7 +94,7 @@ proto.put = function* put(name, file, options) {
9394
res: result.res,
9495
};
9596

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

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

121-
callback.encodeCallback(options);
122-
123122
const method = options.method || 'PUT';
124123
const params = this._objectRequestParams(method, name, options);
125-
124+
callback.encodeCallback(params, options);
126125
params.mime = options.mime;
127126
params.stream = stream;
128127
params.successStatuses = [200];
@@ -135,7 +134,7 @@ proto.putStream = function* putStream(name, stream, options) {
135134
res: result.res,
136135
};
137136

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

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

505504
if (options.headers) {
506-
params.headers = options.headers;
505+
params.headers = {};
506+
copy(options.headers).to(params.headers);
507507
}
508508
return params;
509509
};

publish.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,10 @@ var store = oss({
1010
bucket: env.ALI_SDK_OSS_CDN_BUCKET,
1111
});
1212

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

1716
co(function* () {
18-
yield store.put(latest, dist);
1917
yield store.put(current, dist);
2018
}).catch(function (err) {
2119
console.log(err);

test/browser/browser.test.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1049,6 +1049,72 @@ describe('browser', () => {
10491049
assert.equal(result.res.status, 200);
10501050
assert.equal(result.data.Status, 'OK');
10511051
});
1052+
1053+
it('should upload file with cancel and callback', function* () {
1054+
const client = this.store;
1055+
// create a file with 1M random data
1056+
const fileContent = Array(1024 * 1024).fill('a').join('');
1057+
const file = new File([fileContent], 'multipart-upload-file');
1058+
1059+
const name = `${prefix}multipart/upload-file-cancel-callback`;
1060+
1061+
let tempCheckpoint = null;
1062+
const options = {
1063+
progress(p, checkpoint) {
1064+
return function (done) {
1065+
tempCheckpoint = checkpoint;
1066+
if (p > 0.5) {
1067+
client.cancel();
1068+
}
1069+
done();
1070+
};
1071+
},
1072+
partSize: 100 * 1024,
1073+
callback: {
1074+
url: 'http://oss-demo.aliyuncs.com:23450',
1075+
host: 'oss-cn-hangzhou.aliyuncs.com',
1076+
/* eslint no-template-curly-in-string: [0] */
1077+
body: 'bucket=${bucket}&object=${object}&var1=${x:var1}',
1078+
contentType: 'application/x-www-form-urlencoded',
1079+
customValue: {
1080+
var1: 'value1',
1081+
var2: 'value2',
1082+
},
1083+
},
1084+
};
1085+
try {
1086+
yield client.multipartUpload(name, file, options);
1087+
} catch (err) {
1088+
assert.equal(true, client.isCancel());
1089+
}
1090+
1091+
assert.equal(true, tempCheckpoint && Object.keys(tempCheckpoint).length !== 0);
1092+
1093+
const options2 = {
1094+
progress(p) {
1095+
return function (done) {
1096+
assert.equal(true, p > 0.5);
1097+
done();
1098+
};
1099+
},
1100+
partSize: 100 * 1024,
1101+
checkpoint: tempCheckpoint,
1102+
callback: {
1103+
url: 'http://oss-demo.aliyuncs.com:23450',
1104+
host: 'oss-cn-hangzhou.aliyuncs.com',
1105+
/* eslint no-template-curly-in-string: [0] */
1106+
body: 'bucket=${bucket}&object=${object}&var1=${x:var1}',
1107+
contentType: 'application/x-www-form-urlencoded',
1108+
customValue: {
1109+
var1: 'value1',
1110+
var2: 'value2',
1111+
},
1112+
},
1113+
};
1114+
const result = yield client.multipartUpload(name, file, options2);
1115+
1116+
assert.equal(result.res.status, 200);
1117+
});
10521118
});
10531119
});
10541120

test/node/callback.test.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,5 +142,24 @@ describe('test/callback.test.js', () => {
142142
assert.equal(result.res.status, 200);
143143
assert.equal(result.data.Status, 'OK');
144144
});
145+
146+
it('should multipart upload with no more 100k file use header x-oss-callback', function* () {
147+
// create a file with 1M random data
148+
const fileName = yield utils.createTempFile('upload-with-callback', 50 * 1024);
149+
const callback = {
150+
url: callbackServer,
151+
body: 'bucket=${bucket}&object=${object}&var1=${x:var1}',
152+
};
153+
const name = `${prefix}multipart/upload-with-callback`;
154+
/* eslint no-mixed-spaces-and-tabs: [0] */
155+
const result = yield this.store.multipartUpload(name, fileName, {
156+
partSize: 100 * 1024,
157+
headers: {
158+
'x-oss-callback': utils.encodeCallback(callback),
159+
},
160+
});
161+
assert.equal(result.res.status, 200);
162+
assert.equal(result.data.Status, 'OK');
163+
});
145164
});
146165
});

0 commit comments

Comments
 (0)