2025-04-24 17:03:28 +08:00

419 lines
12 KiB
JavaScript

'use strict';
const assert = require('assert');
var proto = exports;
/**
* Bucket opertaions
*/
proto.listBuckets = function* listBuckets(query, options) {
// prefix, marker, max-keys
var result = yield this.request({
method: 'GET',
query: query,
timeout: options && options.timeout,
ctx: options && options.ctx,
});
if (result.status === 200) {
var data = yield this.parseXML(result.data);
var buckets = data.Buckets || null;
if (buckets) {
if (buckets.Bucket) {
buckets = buckets.Bucket;
}
if (!isArray(buckets)) {
buckets = [buckets];
}
buckets = buckets.map(function (item) {
return {
name: item.Name,
region: item.Location,
creationDate: item.CreationDate,
};
});
}
return {
buckets: buckets,
owner: {
id: data.Owner.ID,
displayName: data.Owner.DisplayName,
},
isTruncated: data.IsTruncated === 'true',
nextMarker: data.NextMarker || null,
res: result.res
};
}
throw yield this.requestError(result);
};
proto.useBucket = function useBucket(name, region) {
this.options.bucket = name;
return this;
};
proto.setBucket = function useBucket(name) {
this.options.bucket = name;
return this;
};
proto.getBucket = function getBucket() {
return this.options.bucket;
};
proto.putBucket = function* putBucket(name, region, options) {
var params = this._bucketRequestParams('PUT', name, '', options);
if (region) {
params.mime = 'xml';
params.content = '<?xml version="1.0" encoding="UTF-8"?>\n' +
'<CreateBucketConfiguration><LocationConstraint>' + region +
'</LocationConstraint></CreateBucketConfiguration>';
}
params.successStatuses = [200];
var result = yield this.request(params);
return {
bucket: result.headers.location && result.headers.location.substring(1) || null,
res: result.res
};
};
proto.deleteBucket = function* deleteBucket(name, region, options) {
var params = this._bucketRequestParams('DELETE', name, '', options);
var result = yield this.request(params);
if (result.status === 200 || result.status === 204) {
return {
res: result.res
};
}
throw yield this.requestError(result);
};
// acl
proto.putBucketACL = function* putBucketACL(name, region, acl, options) {
var params = this._bucketRequestParams('PUT', name, 'acl', options);
params.headers = {
'x-oss-acl': acl
};
params.successStatuses = [200];
var result = yield this.request(params);
return {
bucket: result.headers.location && result.headers.location.substring(1) || null,
res: result.res
};
};
proto.getBucketACL = function* getBucketACL(name, region, options) {
var params = this._bucketRequestParams('GET', name, 'acl', options);
params.successStatuses = [200];
params.xmlResponse = true;
var result = yield this.request(params);
return {
acl: result.data.AccessControlList.Grant,
owner: {
id: result.data.Owner.ID,
displayName: result.data.Owner.DisplayName,
},
res: result.res
};
};
// logging
proto.putBucketLogging = function* putBucketLogging(name, region, prefix, options) {
var params = this._bucketRequestParams('PUT', name, 'logging', options);
var xml = '<?xml version="1.0" encoding="UTF-8"?>\n<BucketLoggingStatus>\n' +
'<LoggingEnabled>\n<TargetBucket>' + name + '</TargetBucket>\n';
if (prefix) {
xml += '<TargetPrefix>' + prefix + '</TargetPrefix>\n';
}
xml += '</LoggingEnabled>\n</BucketLoggingStatus>';
params.content = xml;
params.mime = 'xml';
params.successStatuses = [200];
var result = yield this.request(params);
return {
res: result.res
};
};
proto.getBucketLogging = function* getBucketLogging(name, region, options) {
var params = this._bucketRequestParams('GET', name, 'logging', options);
params.successStatuses = [200];
params.xmlResponse = true;
var result = yield this.request(params);
var enable = result.data.LoggingEnabled;
return {
enable: !!enable,
prefix: enable && enable.TargetPrefix || null,
res: result.res,
};
};
proto.deleteBucketLogging = function* deleteBucketLogging(name, region, options) {
var params = this._bucketRequestParams('DELETE', name, 'logging', options);
params.successStatuses = [204, 200];
var result = yield this.request(params);
return {
res: result.res,
};
};
// website
proto.putBucketWebsite = function* putBucketWebsite(name, region, config, options) {
// config: index, [error]
var params = this._bucketRequestParams('PUT', name, 'website', options);
config = config || {};
config.index = config.index || 'index.html';
var xml = '<?xml version="1.0" encoding="UTF-8"?>\n<WebsiteConfiguration>\n' +
' <IndexDocument><Suffix>' + config.index + '</Suffix></IndexDocument>\n';
if (config.error) {
xml += '<ErrorDocument><Key>' + config.error + '</Key></ErrorDocument>\n';
}
xml += '</WebsiteConfiguration>';
params.content = xml;
params.mime = 'xml';
params.successStatuses = [200];
var result = yield* this.request(params);
return {
res: result.res
};
};
proto.getBucketWebsite = function* getBucketWebsite(name, region, options) {
var params = this._bucketRequestParams('GET', name, 'website', options);
params.successStatuses = [200];
params.xmlResponse = true;
var result = yield this.request(params);
return {
index: result.data.IndexDocument.Suffix,
error: result.data.ErrorDocument && result.data.ErrorDocument.Key || null,
res: result.res
};
};
proto.deleteBucketWebsite = function* deleteBucketWebsite(name, region, options) {
var params = this._bucketRequestParams('DELETE', name, 'website', options);
params.successStatuses = [204];
var result = yield this.request(params);
return {
res: result.res
};
};
// lifecycle
proto.putBucketLifecycle = function* putBucketLifecycle(name, region, rules, options) {
// rules: [rule, ...]
// rule: [id], prefix, status, expiration, [days or date]
// status: 'Enabled' or 'Disabled'
var params = this._bucketRequestParams('PUT', name, 'lifecycle', options);
var xml = '<?xml version="1.0" encoding="UTF-8"?>\n<LifecycleConfiguration>\n';
for (var i = 0; i < rules.length; i++) {
var rule = rules[i];
var expiration = rule.days ?
'<Days>' + rule.days + '</Days>'
:
'<Date>' + rule.date + '</Date>';
var id = rule.id ? '<ID>' + rule.id + '</ID>\n' : '';
xml += ' <Rule>\n' + id +
' <Prefix>' + rule.prefix + '</Prefix>\n' +
' <Status>' + rule.status + '</Status>\n' +
' <Expiration>' + expiration + '</Expiration>\n' +
' </Rule>\n';
}
xml += '</LifecycleConfiguration>';
params.content = xml;
params.mime = 'xml';
params.successStatuses = [200];
var result = yield this.request(params);
return {
res: result.res
};
};
proto.getBucketLifecycle = function* getBucketLifecycle(name, region, options) {
var params = this._bucketRequestParams('GET', name, 'lifecycle', options);
params.successStatuses = [200];
params.xmlResponse = true;
var result = yield this.request(params);
var rules = result.data.Rule || null;
if (rules) {
if (!isArray(rules)) {
rules = [rules];
}
rules = rules.map(function (rule) {
var item = {
id: rule.ID,
prefix: rule.Prefix,
status: rule.Status,
};
if (rule.Expiration.Days) {
item.days = rule.Expiration.Days;
} else {
item.date = rule.Expiration.Date;
}
return item;
});
}
return {
rules: rules,
res: result.res
};
};
proto.deleteBucketLifecycle = function* deleteBucketLifecycle(name, region, options) {
var params = this._bucketRequestParams('DELETE', name, 'lifecycle', options);
params.successStatuses = [204];
var result = yield this.request(params);
return {
res: result.res
};
};
proto.putBucketCORS = function* (name, region, rules, options) {
rules = rules || [];
assert(rules.length, 'rules is required');
rules.forEach(rule => {
assert(rule.allowedOrigin, 'allowedOrigin is required');
assert(rule.allowedMethod, 'allowedMethod is required');
});
var params = this._bucketRequestParams('PUT', name, 'cors', options);
var xml = '<?xml version="1.0" encoding="UTF-8"?>\n<CORSConfiguration>';
for (var i = 0, l = rules.length; i < l; i++) {
var rule = rules[i];
xml += '<CORSRule>';
toArray(rule.allowedOrigin).forEach(function(val) {
xml += '<AllowedOrigin>' + val + '</AllowedOrigin>';
});
toArray(rule.allowedMethod).forEach(function(val) {
xml += '<AllowedMethod>' + val + '</AllowedMethod>';
});
toArray(rule.allowedHeader).forEach(function(val) {
xml += '<AllowedHeader>' + val + '</AllowedHeader>';
});
toArray(rule.exposeHeader).forEach(function(val) {
xml += '<ExposeHeader>' + val + '</ExposeHeader>';
});
if (rule.maxAgeSeconds) {
xml += '<MaxAgeSeconds>' + rule.maxAgeSeconds + '</MaxAgeSeconds>';
}
xml += '</CORSRule>';
}
xml += '</CORSConfiguration>';
params.content = xml;
params.mime = 'xml';
params.successStatuses = [200];
var result = yield this.request(params);
return {
res: result.res
};
};
proto.getBucketCORS = function* (name, region, options) {
var params = this._bucketRequestParams('GET', name, 'cors', options);
params.successStatuses = [200];
params.xmlResponse = true;
var result = yield this.request(params);
var rules = [];
if (result.data && result.data.CORSRule) {
var CORSRule = result.data.CORSRule;
if (!isArray(CORSRule)) CORSRule = [ CORSRule ];
CORSRule.forEach(function(rule) {
var r = {};
for (const name in rule) {
r[name.slice(0, 1).toLowerCase() + name.slice(1, name.length)] = rule[name];
}
rules.push(r);
});
}
return {
rules: rules,
res: result.res
};
};
proto.deleteBucketCORS = function* (name, region, options) {
var params = this._bucketRequestParams('DELETE', name, 'cors', options);
params.successStatuses = [204];
var result = yield this.request(params);
return {
res: result.res
};
};
// referer
proto.putBucketReferer = function* putBucketReferer(name, region, allowEmpty, referers, options) {
var params = this._bucketRequestParams('PUT', name, 'referer', options);
var xml = '<?xml version="1.0" encoding="UTF-8"?>\n<RefererConfiguration>\n';
xml += ' <AllowEmptyReferer>' + (allowEmpty ? 'true' : 'false') + '</AllowEmptyReferer>\n';
if (referers && referers.length > 0) {
xml += ' <RefererList>\n';
for (var i = 0; i < referers.length; i++) {
xml += ' <Referer>' + referers[i] + '</Referer>\n';
}
xml += ' </RefererList>\n';
} else {
xml += ' <RefererList />\n';
}
xml += '</RefererConfiguration>';
params.content = xml;
params.mime = 'xml';
params.successStatuses = [200];
var result = yield this.request(params);
return {
res: result.res,
};
};
proto.getBucketReferer = function* getBucketReferer(name, region, options) {
var params = this._bucketRequestParams('GET', name, 'referer', options);
params.successStatuses = [200];
params.xmlResponse = true;
var result = yield this.request(params);
var referers = result.data.RefererList.Referer || null;
if (referers) {
if (!isArray(referers)) {
referers = [referers];
}
}
return {
allowEmpty: result.data.AllowEmptyReferer === 'true',
referers: referers,
res: result.res
};
};
proto.deleteBucketReferer = function* deleteBucketReferer(name, region, options) {
return yield this.putBucketReferer(name, region, true, null, options);
};
// private apis
proto._bucketRequestParams = function _bucketRequestParams(method, bucket, subres, options) {
return {
method: method,
bucket: bucket,
subres: subres,
timeout: options && options.timeout,
ctx: options && options.ctx,
};
};
function isArray(arr) {
if (Array.isArray) return Array.isArray(arr);
return Object.prototype.toString.call(arr) === '[object Array]';
}
function toArray(obj) {
if (!obj) return [];
if (isArray(obj)) return obj;
return [ obj ];
}