Skip to content

Commit e6c48f3

Browse files
committed
修复 getObject 大文件报错,添加 onProgress 支持
1 parent 9dc7f54 commit e6c48f3

File tree

2 files changed

+142
-44
lines changed

2 files changed

+142
-44
lines changed

demo/demo.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -330,14 +330,20 @@ function getObject() {
330330
Bucket: config.Bucket,
331331
Region: config.Region,
332332
Key: '1mb.zip',
333+
onProgress: function (progressData) {
334+
console.log(JSON.stringify(progressData));
335+
}
333336
}, function (err, data) {
334337
fs.writeFileSync(filepath1, data.Body);
335338
});
336339
cos.getObject({
337340
Bucket: config.Bucket,
338341
Region: config.Region,
339342
Key: '1mb.zip',
340-
Output: fs.createWriteStream(filepath2)
343+
Output: fs.createWriteStream(filepath2),
344+
onProgress: function (progressData) {
345+
console.log(JSON.stringify(progressData));
346+
}
341347
}, function (err, data) {
342348
console.log(err || data);
343349
});
@@ -473,10 +479,10 @@ function restartTask() {
473479
console.log('restart');
474480
}
475481

476-
getService();
482+
// getService();
477483
// getAuth();
478484
// putBucket();
479-
// getBucket();
485+
getBucket();
480486
// headBucket();
481487
// putBucketAcl();
482488
// getBucketAcl();

sdk/base.js

Lines changed: 133 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,7 @@ function headObject(params, callback) {
783783
* @param {Object} data 为对应的 object 数据,包括 body 和 headers
784784
*/
785785
function getObject(params, callback) {
786+
var self = this;
786787
var headers = {};
787788
var reqParams = {};
788789

@@ -811,6 +812,47 @@ function getObject(params, callback) {
811812
BodyType = util.isBrowser ? 'string' : 'buffer';
812813
}
813814

815+
var onProgress = params.onProgress;
816+
var onDownloadProgress = (function () {
817+
var time0 = Date.now();
818+
var size0 = 0;
819+
var FinishSize = 0;
820+
var FileSize = 0;
821+
var progressTimer;
822+
var update = function () {
823+
progressTimer = 0;
824+
if (onProgress && (typeof onProgress === 'function')) {
825+
var time1 = Date.now();
826+
var speed = parseInt((FinishSize - size0) / ((time1 - time0) / 1000) * 100) / 100 || 0;
827+
var percent = parseInt(FinishSize / FileSize * 100) / 100 || 0;
828+
time0 = time1;
829+
size0 = FinishSize;
830+
try {
831+
onProgress({
832+
loaded: FinishSize,
833+
total: FileSize,
834+
speed: speed,
835+
percent: percent
836+
});
837+
} catch (e) {
838+
}
839+
}
840+
};
841+
return function (info, immediately) {
842+
if (info && info.loaded) {
843+
FinishSize = info.loaded;
844+
FileSize = info.total;
845+
}
846+
if (immediately) {
847+
clearTimeout(progressTimer);
848+
update();
849+
} else {
850+
if (progressTimer) return;
851+
progressTimer = setTimeout(update, self.options.ProgressInterval || 1000);
852+
}
853+
};
854+
})();
855+
814856
// 如果用户自己传入了 output
815857
submitRequest.call(this, {
816858
method: 'GET',
@@ -822,7 +864,9 @@ function getObject(params, callback) {
822864
qs: reqParams,
823865
rawBody: true,
824866
outputStream: outputStream,
867+
onDownloadProgress: onDownloadProgress,
825868
}, function (err, data) {
869+
onDownloadProgress(null, true);
826870
if (err) {
827871
var statusCode = err.statusCode;
828872
if (headers['If-Modified-Since'] && statusCode && statusCode === 304) {
@@ -1740,56 +1784,80 @@ function submitRequest(params, callback) {
17401784
}
17411785
opt = util.clearKey(opt);
17421786

1743-
var sender = REQUEST(opt, function (err, response, body) {
1744-
1745-
// 返回内容添加 状态码 和 headers
1746-
var cb = function (err, data) {
1747-
if (err) {
1748-
err = err || {};
1749-
response && response.statusCode && (err.statusCode = response.statusCode);
1750-
callback(err, null);
1751-
} else {
1752-
data = data || {};
1753-
response && response.statusCode && (data.statusCode = response.statusCode);
1754-
response && response.headers && (data.headers = response.headers);
1755-
callback(null, data);
1756-
}
1757-
};
1758-
1759-
// 请求错误,发生网络错误
1787+
var sender = REQUEST(opt);
1788+
var retResponse;
1789+
var hasReturned;
1790+
var cb = function (err, data) {
1791+
if (hasReturned) return;
1792+
hasReturned = true;
17601793
if (err) {
1761-
cb({error: err});
1762-
return;
1794+
err = err || {};
1795+
retResponse && retResponse.statusCode && (err.statusCode = retResponse.statusCode);
1796+
callback(err, null);
1797+
} else {
1798+
data = data || {};
1799+
retResponse && retResponse.statusCode && (data.statusCode = retResponse.statusCode);
1800+
retResponse && retResponse.headers && (data.headers = retResponse.headers);
1801+
callback(null, data);
17631802
}
1764-
1765-
var jsonRes;
1803+
};
1804+
var xml2json = function (body) {
17661805
try {
1767-
jsonRes = util.xml2json(body) || {};
1806+
json = util.xml2json(body) || {};
17681807
} catch (e) {
1769-
jsonRes = body || {};
1808+
json = body || {};
17701809
}
1771-
1772-
// 请求返回码不为 200
1810+
return json;
1811+
};
1812+
sender.on('error', function (err) {
1813+
cb({error: err});
1814+
});
1815+
sender.on('response', function (response) {
1816+
retResponse = response;
1817+
var contentLength = response.headers['content-length'] || 0;
17731818
var statusCode = response.statusCode;
1774-
if (statusCode !== 200 && statusCode !== 204 && statusCode !== 206) {
1775-
cb({error: jsonRes.Error || jsonRes});
1776-
return;
1777-
}
1778-
1779-
// 不对 body 进行转换,body 直接挂载返回
1780-
if (rawBody) {
1781-
jsonRes = {};
1782-
jsonRes.body = body;
1783-
}
1784-
1785-
if (jsonRes.Error) {
1786-
cb({error: jsonRes.Error});
1787-
return;
1819+
var chunkList = [];
1820+
var statusSuccess = statusCode === 200 || statusCode === 204 || statusCode === 206;
1821+
if (statusSuccess && params.outputStream) {
1822+
sender.on('end', function () {
1823+
cb(null, {});
1824+
});
1825+
} else if (contentLength >= process.binding('buffer').kMaxLength) {
1826+
cb({error: 'file size large than ' + process.binding('buffer').kMaxLength + ', please use "Output" Stream to getObject.'});
1827+
} else {
1828+
sender.on('data', function (chunk) {
1829+
chunkList.push(chunk);
1830+
});
1831+
sender.on('end', function () {
1832+
var json;
1833+
try {
1834+
var body = Buffer.concat(chunkList);
1835+
} catch (e) {
1836+
cb({error: e});
1837+
return;
1838+
}
1839+
if (statusSuccess) {
1840+
if (rawBody) { // 不对 body 进行转换,body 直接挂载返回
1841+
cb(null, {body: body});
1842+
} else if (body.length) {
1843+
json = xml2json(body.toString());
1844+
if (json && json.Error) {
1845+
cb({error: json.Error});
1846+
} else {
1847+
cb(null, json);
1848+
}
1849+
} else {
1850+
cb(null, {});
1851+
}
1852+
} else {
1853+
json = xml2json(body.toString());
1854+
cb({error: json && json.Error || json});
1855+
}
1856+
});
17881857
}
1789-
cb(null, jsonRes);
17901858
});
17911859

1792-
// progress
1860+
// upload progress
17931861
if (params.onProgress && typeof params.onProgress === 'function') {
17941862
var contentLength = opt.headers['Content-Length'];
17951863
var time0 = Date.now();
@@ -1814,6 +1882,30 @@ function submitRequest(params, callback) {
18141882
});
18151883
});
18161884
}
1885+
// download progress
1886+
if (params.onDownloadProgress && typeof params.onDownloadProgress === 'function') {
1887+
var time0 = Date.now();
1888+
var size0 = 0;
1889+
var loaded = 0;
1890+
var total = 0;
1891+
sender.on('response', function (res) {
1892+
total = res.headers['content-length'];
1893+
sender.on('data', function (chunk) {
1894+
loaded += chunk.length;
1895+
var time1 = Date.now();
1896+
var speed = parseInt((loaded - size0) / ((time1 - time0) / 1000) * 100) / 100;
1897+
var percent = total ? (parseInt(loaded / total * 100) / 100) : 0;
1898+
time0 = time1;
1899+
size0 = loaded;
1900+
params.onDownloadProgress({
1901+
loaded: loaded,
1902+
total: total,
1903+
speed: speed,
1904+
percent: percent,
1905+
});
1906+
});
1907+
});
1908+
}
18171909

18181910
// pipe 输入
18191911
if (params.inputStream) {

0 commit comments

Comments
 (0)