Skip to content

Commit e42a534

Browse files
binghaiwangPeterRao
authored andcommitted
feat: multipart copy support (#371)
* feat: support upload part copy, init , uploadpart, complete * feat: multipart copy support * feat: initMultipart uploadpart uploadPartCopy completeMultipart operaition * feat: check readme doc * feat: change doc with params * feat: add list part api to node and browser * refactor: multipart uplaod upload part with options * test: add initMutipartUpload case
1 parent c87f6da commit e42a534

File tree

11 files changed

+1288
-358
lines changed

11 files changed

+1288
-358
lines changed

README.md

Lines changed: 438 additions & 2 deletions
Large diffs are not rendered by default.

lib/browser/bucket.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,15 @@ proto.useBucket = function useBucket(name, region) {
5656
return this;
5757
};
5858

59+
proto.setBucket = function useBucket(name) {
60+
this.options.bucket = name;
61+
return this;
62+
};
63+
64+
proto.getBucket = function getBucket() {
65+
return this.options.bucket;
66+
};
67+
5968
proto.putBucket = function* putBucket(name, region, options) {
6069
var params = this._bucketRequestParams('PUT', name, '', options);
6170
if (region) {

lib/browser/client.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,12 @@ merge(proto, require('./object'));
109109
// * Bucket operations
110110
// */
111111
// merge(proto, require('./bucket'));
112+
//multipart upload
113+
merge(proto, require('./managed_upload'));
112114
/**
113115
* Multipart operations
114116
*/
115-
merge(proto, require('./multipart'));
117+
merge(proto, require('../common/multipart'));
116118

117119
/**
118120
* Common module

lib/browser/multipart.js renamed to lib/browser/managed_upload.js

Lines changed: 3 additions & 165 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
'use strict';
22

33
// var debug = require('debug')('ali-oss:multipart');
4-
// var fs = require('fs');
54
var is = require('is-type-of');
6-
// var destroy = require('destroy');
7-
// var eoe = require('end-or-error');
85
var util = require('util');
96
var path = require('path');
107
var mime = require('mime');
@@ -61,7 +58,7 @@ proto.multipartUpload = function* multipartUpload(name, file, options) {
6158
throw new Error('partSize must not be smaller than ' + minPartSize);
6259
}
6360

64-
var result = yield this._initMultipartUpload(name, options);
61+
var result = yield this.initMultipartUpload(name, options);
6562
var uploadId = result.uploadId;
6663
var partSize = this._getPartSize(fileSize, options.partSize);
6764

@@ -111,7 +108,7 @@ proto._resumeMultipart = function* _resumeMultipart(checkpoint, options) {
111108
size: pi.end - pi.start
112109
};
113110

114-
var result = yield self._uploadPart(name, uploadId, partNo, data);
111+
var result = yield self._uploadPart(name, uploadId, partNo, data, options);
115112
doneParts.push({
116113
number: partNo,
117114
etag: result.res.headers.etag
@@ -163,169 +160,10 @@ proto._resumeMultipart = function* _resumeMultipart(checkpoint, options) {
163160
throw err;
164161
}
165162
}
166-
return yield this._completeMultipartUpload(name, uploadId, doneParts, options);
163+
return yield this.completeMultipartUpload(name, uploadId, doneParts, options);
167164
};
168165

169-
/**
170-
* List the on-going multipart uploads
171-
* https://help.aliyun.com/document_detail/31997.html
172-
* @param {Object} options
173-
* @return {Array} the multipart uploads
174-
*/
175-
proto.listUploads = function* listUploads(query, options) {
176-
options = options || {};
177-
options.subres = 'uploads';
178-
var params = this._objectRequestParams('GET', '', options)
179-
params.query = query;
180-
params.xmlResponse = true;
181-
params.successStatuses = [200];
182-
183-
var result = yield this.request(params);
184-
var uploads = result.data.Upload || [];
185-
if (!Array.isArray(uploads)) {
186-
uploads = [uploads];
187-
}
188-
uploads = uploads.map(function (up) {
189-
return {
190-
name: up.Key,
191-
uploadId: up.UploadId,
192-
initiated: up.Initiated
193-
};
194-
});
195-
196-
return {
197-
res: result.res,
198-
uploads: uploads,
199-
bucket: result.data.Bucket,
200-
nextKeyMarker: result.data.NextKeyMarker,
201-
nextUploadIdMarker: result.data.NextUploadIdMarker,
202-
isTruncated: result.data.IsTruncated === 'true'
203-
};
204-
};
205-
206-
/**
207-
* Abort a multipart upload transaction
208-
* @param {String} name the object name
209-
* @param {String} uploadId the upload id
210-
* @param {Object} options
211-
*/
212-
proto.abortMultipartUpload = function* abortMultipartUpload(name, uploadId, options) {
213-
this.cancel();
214-
options = options || {};
215-
options.subres = {uploadId: uploadId};
216-
var params = this._objectRequestParams('DELETE', name, options);
217-
params.successStatuses = [204];
218-
219-
var result = yield this.request(params);
220-
return {
221-
res: result.res
222-
};
223-
};
224-
225-
/**
226-
* Initiate a multipart upload transaction
227-
* @param {String} name the object name
228-
* @param {Object} options
229-
* @return {String} upload id
230-
*/
231-
proto._initMultipartUpload = function* _initMultipartUpload(name, options) {
232-
options = options || {};
233-
options.headers = options.headers || {};
234-
this._convertMetaToHeaders(options.meta, options.headers);
235-
236-
options.subres = 'uploads';
237-
var params = this._objectRequestParams('POST', name, options);
238-
params.mime = options.mime;
239-
params.xmlResponse = true;
240-
params.successStatuses = [200];
241-
242-
var result = yield this.request(params);
243-
244-
return {
245-
res: result.res,
246-
bucket: result.data.Bucket,
247-
name: result.data.Key,
248-
uploadId: result.data.UploadId
249-
};
250-
};
251166

252-
/**
253-
* Upload a part in a multipart upload transaction
254-
* @param {String} name the object name
255-
* @param {String} uploadId the upload id
256-
* @param {Integer} partNo the part number
257-
* @param {Object} data the body data
258-
* @param {Object} options
259-
*/
260-
proto._uploadPart = function* _uploadPart(name, uploadId, partNo, data, options) {
261-
options = options || {};
262-
options.headers = {
263-
'Content-Length': data.size
264-
};
265-
266-
options.subres = {
267-
partNumber: partNo,
268-
uploadId: uploadId
269-
};
270-
var params = this._objectRequestParams('PUT', name, options);
271-
params.mime = options.mime;
272-
params.stream = data.stream;
273-
params.successStatuses = [200];
274-
275-
var result = yield this.request(params);
276-
277-
data.stream = null;
278-
params.stream = null;
279-
return {
280-
name: name,
281-
etag: result.res.headers.etag,
282-
res: result.res
283-
};
284-
};
285-
286-
/**
287-
* Complete a multipart upload transaction
288-
* @param {String} name the object name
289-
* @param {String} uploadId the upload id
290-
* @param {Array} parts the uploaded parts
291-
* @param {Object} options
292-
*/
293-
proto._completeMultipartUpload = function* _completeMultipartUpload(name, uploadId, parts, options) {
294-
parts.sort((a, b) => a.number - b.number);
295-
var xml = '<?xml version="1.0" encoding="UTF-8"?>\n<CompleteMultipartUpload>\n';
296-
for (var i = 0; i < parts.length; i++) {
297-
var p = parts[i];
298-
xml += '<Part>\n';
299-
xml += '<PartNumber>' + p.number + '</PartNumber>\n';
300-
xml += '<ETag>' + p.etag + '</ETag>\n';
301-
xml += '</Part>\n';
302-
}
303-
xml += '</CompleteMultipartUpload>';
304-
305-
options = options || {};
306-
options.subres = {uploadId: uploadId};
307-
var params = this._objectRequestParams('POST', name, options);
308-
params.mime = 'xml';
309-
params.content = xml;
310-
if (!(options.headers && options.headers['x-oss-callback'])) {
311-
params.xmlResponse = true;
312-
}
313-
params.successStatuses = [200];
314-
var result = yield this.request(params);
315-
316-
var ret = {
317-
res: result.res,
318-
bucket: params.bucket,
319-
name: name,
320-
etag: result.res.headers['etag']
321-
};
322-
323-
if (options.headers && options.headers['x-oss-callback']) {
324-
ret.data = JSON.parse(result.data.toString());
325-
}
326-
327-
return ret;
328-
};
329167

330168
is.file = function (file) {
331169
return typeof(File) !== 'undefined' && file instanceof File;

lib/bucket.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,15 @@ proto.useBucket = function useBucket(name, region) {
5555
return this;
5656
};
5757

58+
proto.setBucket = function useBucket(name) {
59+
this.options.bucket = name;
60+
return this;
61+
};
62+
63+
proto.getBucket = function getBucket() {
64+
return this.options.bucket;
65+
};
66+
5867
proto.putBucket = function* putBucket(name, region, options) {
5968
var params = this._bucketRequestParams('PUT', name, '', options);
6069
if (region) {

lib/client.js

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,15 +103,22 @@ merge(proto, require('./object'));
103103
* Bucket operations
104104
*/
105105
merge(proto, require('./bucket'));
106-
/**
107-
* Multipart operations
108-
*/
109-
merge(proto, require('./multipart'));
106+
//multipart upload
107+
merge(proto, require('./managed_upload'));
110108
/**
111109
* RTMP operations
112110
*/
113111
merge(proto, require('./rtmp'));
114112

113+
/**
114+
* common multipart-copy support node and browser
115+
*/
116+
merge(proto, require('./common/multipart-copy.js'));
117+
merge(proto, require('./common/thunkpool.js'));
118+
/**
119+
* Multipart operations
120+
*/
121+
merge(proto, require('./common/multipart'));
115122
/**
116123
* ImageClient class
117124
*/

0 commit comments

Comments
 (0)