2023-10-03 11:14:36 +08:00
|
|
|
var util = require('./util');
|
|
|
|
// 按照文件特征值,缓存 UploadId
|
|
|
|
var cacheKey = 'cos_sdk_upload_cache';
|
|
|
|
var expires = 30 * 24 * 3600;
|
|
|
|
var store;
|
|
|
|
var cache;
|
|
|
|
var timer;
|
|
|
|
|
|
|
|
var getCache = function () {
|
|
|
|
var val,
|
|
|
|
opt = { configName: 'cos-nodejs-sdk-v5-storage' };
|
|
|
|
if (this.options.ConfCwd) opt.cwd = this.options.ConfCwd;
|
|
|
|
try {
|
|
|
|
var Conf = require('conf');
|
|
|
|
store = new Conf(opt);
|
|
|
|
val = store.get(cacheKey);
|
|
|
|
} catch (e) {}
|
|
|
|
if (!val || !(val instanceof Array)) val = [];
|
|
|
|
cache = val;
|
|
|
|
};
|
|
|
|
var setCache = function () {
|
|
|
|
try {
|
|
|
|
if (cache.length) store.set(cacheKey, cache);
|
|
|
|
else store.delete(cacheKey);
|
|
|
|
} catch (e) {}
|
|
|
|
};
|
|
|
|
|
|
|
|
var init = function () {
|
|
|
|
if (cache) return;
|
|
|
|
getCache.call(this);
|
|
|
|
// 清理太老旧的数据
|
|
|
|
var changed = false;
|
|
|
|
var now = Math.round(Date.now() / 1000);
|
|
|
|
for (var i = cache.length - 1; i >= 0; i--) {
|
|
|
|
var mtime = cache[i][2];
|
|
|
|
if (!mtime || mtime + expires < now) {
|
|
|
|
cache.splice(i, 1);
|
|
|
|
changed = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
changed && setCache();
|
|
|
|
};
|
|
|
|
|
|
|
|
// 把缓存存到本地
|
|
|
|
var save = function () {
|
|
|
|
if (timer) return;
|
|
|
|
timer = setTimeout(function () {
|
|
|
|
setCache();
|
|
|
|
timer = null;
|
|
|
|
}, 400);
|
|
|
|
};
|
|
|
|
|
|
|
|
var mod = {
|
|
|
|
using: {},
|
|
|
|
// 标记 UploadId 正在使用
|
|
|
|
setUsing: function (uuid) {
|
|
|
|
mod.using[uuid] = true;
|
|
|
|
},
|
|
|
|
// 标记 UploadId 已经没在使用
|
|
|
|
removeUsing: function (uuid) {
|
|
|
|
delete mod.using[uuid];
|
|
|
|
},
|
|
|
|
// 用上传参数生成哈希值
|
|
|
|
getFileId: function (FileStat, ChunkSize, Bucket, Key) {
|
|
|
|
if (FileStat && FileStat.FilePath && FileStat.size && FileStat.ctime && FileStat.mtime && ChunkSize) {
|
|
|
|
return (
|
|
|
|
util.md5([FileStat.FilePath].join('::')) +
|
|
|
|
'-' +
|
|
|
|
util.md5([FileStat.size, FileStat.ctime, FileStat.mtime, ChunkSize, Bucket, Key].join('::'))
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
// 用上传参数生成哈希值
|
|
|
|
getCopyFileId: function (copySource, sourceHeaders, ChunkSize, Bucket, Key) {
|
|
|
|
var size = sourceHeaders['content-length'];
|
|
|
|
var etag = sourceHeaders.etag || '';
|
|
|
|
var lastModified = sourceHeaders['last-modified'];
|
|
|
|
if (copySource && ChunkSize) {
|
|
|
|
return util.md5([copySource, size, etag, lastModified, ChunkSize, Bucket, Key].join('::'));
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
// 获取文件对应的 UploadId 列表
|
|
|
|
getUploadIdList: function (uuid) {
|
|
|
|
if (!uuid) return null;
|
|
|
|
init.call(this);
|
|
|
|
var list = [];
|
|
|
|
for (var i = 0; i < cache.length; i++) {
|
|
|
|
if (cache[i][0] === uuid) list.push(cache[i][1]);
|
|
|
|
}
|
|
|
|
return list.length ? list : null;
|
|
|
|
},
|
|
|
|
// 缓存 UploadId
|
|
|
|
saveUploadId: function (uuid, UploadId, limit) {
|
|
|
|
init.call(this);
|
|
|
|
if (!uuid) return;
|
|
|
|
// 清理没用的 UploadId
|
|
|
|
var part1 = uuid.substr(0, uuid.indexOf('-') + 1);
|
|
|
|
for (var i = cache.length - 1; i >= 0; i--) {
|
|
|
|
var item = cache[i];
|
|
|
|
if (item[0] === uuid && item[1] === UploadId) {
|
|
|
|
cache.splice(i, 1);
|
|
|
|
} else if (uuid !== item[0] && item[0].indexOf(part1) === 0) {
|
|
|
|
// 文件路径相同,但其他信息不同,说明文件改变了或上传参数(存储桶、路径、分片大小)变了,直接清理掉
|
|
|
|
cache.splice(i, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cache.unshift([uuid, UploadId, Math.round(Date.now() / 1000)]);
|
|
|
|
if (cache.length > limit) cache.splice(limit);
|
|
|
|
save();
|
|
|
|
},
|
|
|
|
// UploadId 已用完,移除掉
|
|
|
|
removeUploadId: function (UploadId) {
|
|
|
|
init.call(this);
|
|
|
|
delete mod.using[UploadId];
|
|
|
|
for (var i = cache.length - 1; i >= 0; i--) {
|
|
|
|
if (cache[i][1] === UploadId) cache.splice(i, 1);
|
|
|
|
}
|
|
|
|
save();
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
module.exports = mod;
|